RE: MHI code review

2019-06-12 Thread Sujeev Dias
Our team also monitoring following thread
https://lkml.kernel.org/lkml/20190531035348.7194-1-el...@linaro.org/

Since this also has implication on MHI as well.

Thanks
Sujeev

-Original Message-
From: Sujeev Dias  
Sent: Wednesday, June 12, 2019 10:55 AM
To: 'Daniele Palmas' 
Cc: 'linux-kernel@vger.kernel.org' ;
'tru...@codeaurora.org' 
Subject: RE: MHI code review

Hi Daniels

Sorry for delay response.  Yes, we will be pushing new set of series very
soon that will have support for 55 as well.  The series that's pushed should
already work for SDX20, 24 and 55.   There are some new features related to
55 that's not yet in series.

Thanks
Sujeev 

-Original Message-
From: Daniele Palmas 
Sent: Tuesday, April 30, 2019 8:11 AM
To: sd...@codeaurora.org
Cc: linux-kernel@vger.kernel.org; tru...@codeaurora.org; dnl...@gmail.com
Subject: Re: MHI code review

Hi Sujeev,

> Hi Greg Kroah-Hartman\Arnd Bergmann and community
>
> Thank you for all the feedback, I believe I have addressed all the 
> comments from previous patches. Also, I am excluding mhi network 
> driver in this series. I still have some modifications to do.
>
> Please review the new patch series and share your feedback.
>
> Thanks again
>
> Sincerely,
> Sujeev

are you going to continue working on this series?

Can this series be used with PCIe SDX20/24/55 based modems?

If yes, it would really be important to have this integrated into an
official kernel.

Thanks,
Daniele



RE: MHI code review

2019-06-12 Thread Sujeev Dias
Hi Daniels

Sorry for delay response.  Yes, we will be pushing new set of series very
soon that will have support for 55 as well.  The series that's pushed should
already work for SDX20, 24 and 55.   There are some new features related to
55 that's not yet in series.

Thanks
Sujeev 

-Original Message-
From: Daniele Palmas  
Sent: Tuesday, April 30, 2019 8:11 AM
To: sd...@codeaurora.org
Cc: linux-kernel@vger.kernel.org; tru...@codeaurora.org; dnl...@gmail.com
Subject: Re: MHI code review

Hi Sujeev,

> Hi Greg Kroah-Hartman\Arnd Bergmann and community
>
> Thank you for all the feedback, I believe I have addressed all the 
> comments from previous patches. Also, I am excluding mhi network 
> driver in this series. I still have some modifications to do.
>
> Please review the new patch series and share your feedback.
>
> Thanks again
>
> Sincerely,
> Sujeev

are you going to continue working on this series?

Can this series be used with PCIe SDX20/24/55 based modems?

If yes, it would really be important to have this integrated into an
official kernel.

Thanks,
Daniele



[PATCH v2 2/7] mhi_bus: core: add power management support

2018-07-09 Thread Sujeev Dias
Add support for MHI power management operations such as
power on, off, suspend, and resume.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 drivers/bus/mhi/core/Makefile   |2 +-
 drivers/bus/mhi/core/mhi_boot.c |  533 ++
 drivers/bus/mhi/core/mhi_init.c |  695 +++-
 drivers/bus/mhi/core/mhi_internal.h |  491 +
 drivers/bus/mhi/core/mhi_main.c |  528 +-
 drivers/bus/mhi/core/mhi_pm.c   | 1027 +++
 include/linux/mhi.h |  121 +
 7 files changed, 3394 insertions(+), 3 deletions(-)
 create mode 100644 drivers/bus/mhi/core/mhi_boot.c
 create mode 100644 drivers/bus/mhi/core/mhi_pm.c

diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/core/Makefile
index a015809..a6015ab 100644
--- a/drivers/bus/mhi/core/Makefile
+++ b/drivers/bus/mhi/core/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o
+obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o
diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c
new file mode 100644
index 000..a8e4a15
--- /dev/null
+++ b/drivers/bus/mhi/core/mhi_boot.c
@@ -0,0 +1,533 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mhi_internal.h"
+
+
+/* setup rddm vector table for rddm transfer */
+static void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
+struct image_info *img_info)
+{
+   struct mhi_buf *mhi_buf = img_info->mhi_buf;
+   struct bhi_vec_entry *bhi_vec = img_info->bhi_vec;
+   int i = 0;
+
+   for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) {
+   bhi_vec->dma_addr = mhi_buf->dma_addr;
+   bhi_vec->size = mhi_buf->len;
+   }
+}
+
+/* collect rddm during kernel panic */
+static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl)
+{
+   int ret;
+   struct mhi_buf *mhi_buf;
+   u32 sequence_id;
+   u32 rx_status;
+   enum MHI_EE ee;
+   struct image_info *rddm_image = mhi_cntrl->rddm_image;
+   const u32 delayus = 100;
+   u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
+   void __iomem *base = mhi_cntrl->bhie;
+
+   dev_info(mhi_cntrl->dev,
+"Entered with pm_state:%s dev_state:%s ee:%s\n",
+   to_mhi_pm_state_str(mhi_cntrl->pm_state),
+   TO_MHI_STATE_STR(mhi_cntrl->dev_state),
+   TO_MHI_EXEC_STR(mhi_cntrl->ee));
+
+   /*
+* This should only be executing during a kernel panic, we expect all
+* other cores to shutdown while we're collecting rddm buffer. After
+* returning from this function, we expect device to reset.
+*
+* Normaly, we would read/write pm_state only after grabbing
+* pm_lock, since we're in a panic, skipping it.
+*/
+
+   if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
+   return -EIO;
+
+   /*
+* There is no gurantee this state change would take effect since
+* we're setting it w/o grabbing pmlock, it's best effort
+*/
+   mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT;
+   /* update should take the effect immediately */
+   smp_wmb();
+
+   /* setup the RX vector table */
+   mhi_rddm_prepare(mhi_cntrl, rddm_image);
+   mhi_buf = _image->mhi_buf[rddm_image->entries - 1];
+
+   mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS,
+ upper_32_bits(mhi_buf->dma_addr));
+
+   mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS,
+ lower_32_bits(mhi_buf->dma_addr));
+
+   mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
+   sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
+
+   if (unlikely(!sequence_id))
+   sequence_id = 1;
+
+
+   mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS,
+   BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT,
+   sequence_id);
+
+   mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR);
+
+   while (retry--) {
+   ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS,
+BHIE_RXVECSTATUS_STATUS_BMSK,
+BHIE_RXVECSTATUS_STATUS_SHFT,
+_status);
+   if (ret)
+   return -EIO;
+
+   if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL)
+   return 0;
+
+   

[PATCH v2 3/7] mhi_bus: core: add support for data transfer

2018-07-09 Thread Sujeev Dias
Add support for transferring data between external
modem and MHI host using MHI protocol.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 drivers/bus/mhi/core/mhi_init.c |  76 +++-
 drivers/bus/mhi/core/mhi_internal.h |   8 -
 drivers/bus/mhi/core/mhi_main.c | 803 +++-
 include/linux/mhi.h |  78 
 4 files changed, 950 insertions(+), 15 deletions(-)

diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c
index 7b3d12a..43a700d 100644
--- a/drivers/bus/mhi/core/mhi_init.c
+++ b/drivers/bus/mhi/core/mhi_init.c
@@ -548,6 +548,66 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
return 0;
 }
 
+int mhi_device_configure(struct mhi_device *mhi_dev,
+enum dma_data_direction dir,
+struct mhi_buf *cfg_tbl,
+int elements)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   struct mhi_chan *mhi_chan;
+   struct mhi_event_ctxt *er_ctxt;
+   struct mhi_chan_ctxt *ch_ctxt;
+   int er_index, chan;
+
+   switch (dir) {
+   case DMA_TO_DEVICE:
+   mhi_chan = mhi_dev->ul_chan;
+   break;
+   case DMA_BIDIRECTIONAL:
+   case DMA_FROM_DEVICE:
+   case DMA_NONE:
+   mhi_chan = mhi_dev->dl_chan;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   er_index = mhi_chan->er_index;
+   chan = mhi_chan->chan;
+
+   for (; elements > 0; elements--, cfg_tbl++) {
+   /* update event context array */
+   if (!strcmp(cfg_tbl->name, "ECA")) {
+   er_ctxt = _cntrl->mhi_ctxt->er_ctxt[er_index];
+   if (sizeof(*er_ctxt) != cfg_tbl->len) {
+   dev_err(mhi_cntrl->dev,
+   "Invalid ECA size, expected:%zu 
actual%zu\n",
+   sizeof(*er_ctxt), cfg_tbl->len);
+   return -EINVAL;
+   }
+   memcpy((void *)er_ctxt, cfg_tbl->buf, sizeof(*er_ctxt));
+   continue;
+   }
+
+   /* update channel context array */
+   if (!strcmp(cfg_tbl->name, "CCA")) {
+   ch_ctxt = _cntrl->mhi_ctxt->chan_ctxt[chan];
+   if (cfg_tbl->len != sizeof(*ch_ctxt)) {
+   dev_err(mhi_cntrl->dev,
+   "Invalid CCA size, expected:%zu 
actual:%zu\n",
+   sizeof(*ch_ctxt), cfg_tbl->len);
+   return -EINVAL;
+   }
+   memcpy((void *)ch_ctxt, cfg_tbl->buf, sizeof(*ch_ctxt));
+   continue;
+   }
+
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
   struct device_node *of_node)
 {
@@ -1067,6 +1127,9 @@ static int mhi_driver_probe(struct device *dev)
struct mhi_event *mhi_event;
struct mhi_chan *ul_chan = mhi_dev->ul_chan;
struct mhi_chan *dl_chan = mhi_dev->dl_chan;
+   bool auto_start = false;
+   int ret;
+
 
if (ul_chan) {
/* lpm notification require status_cb */
@@ -1078,6 +1141,7 @@ static int mhi_driver_probe(struct device *dev)
 
ul_chan->xfer_cb = mhi_drv->ul_xfer_cb;
mhi_dev->status_cb = mhi_drv->status_cb;
+   auto_start = ul_chan->auto_start;
}
 
if (dl_chan) {
@@ -1101,9 +1165,15 @@ static int mhi_driver_probe(struct device *dev)
 
/* ul & dl uses same status cb */
mhi_dev->status_cb = mhi_drv->status_cb;
+   auto_start = (auto_start || dl_chan->auto_start);
}
 
-   return mhi_drv->probe(mhi_dev, mhi_dev->id);
+   ret = mhi_drv->probe(mhi_dev, mhi_dev->id);
+
+   if (!ret && auto_start)
+   mhi_prepare_for_transfer(mhi_dev);
+
+   return ret;
 }
 
 static int mhi_driver_remove(struct device *dev)
@@ -1141,6 +1211,10 @@ static int mhi_driver_remove(struct device *dev)
ch_state[dir] = mhi_chan->ch_state;
mhi_chan->ch_state = MHI_CH_STATE_DISABLED;
write_unlock_irq(_chan->lock);
+
+   /* reset the channel */
+   if (!mhi_chan->offload_ch)
+   mhi_reset_chan(mhi_cntrl, mhi_chan);
}
 
/* destroy the device */
diff --git a/drivers/bus/mhi/core/mhi_internal.h 
b/drivers/bus/mhi/core/mhi_internal.h
index 0091245..1167d75 100644
--- a/drivers/bus/mhi

[PATCH v2 2/7] mhi_bus: core: add power management support

2018-07-09 Thread Sujeev Dias
Add support for MHI power management operations such as
power on, off, suspend, and resume.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 drivers/bus/mhi/core/Makefile   |2 +-
 drivers/bus/mhi/core/mhi_boot.c |  533 ++
 drivers/bus/mhi/core/mhi_init.c |  695 +++-
 drivers/bus/mhi/core/mhi_internal.h |  491 +
 drivers/bus/mhi/core/mhi_main.c |  528 +-
 drivers/bus/mhi/core/mhi_pm.c   | 1027 +++
 include/linux/mhi.h |  121 +
 7 files changed, 3394 insertions(+), 3 deletions(-)
 create mode 100644 drivers/bus/mhi/core/mhi_boot.c
 create mode 100644 drivers/bus/mhi/core/mhi_pm.c

diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/core/Makefile
index a015809..a6015ab 100644
--- a/drivers/bus/mhi/core/Makefile
+++ b/drivers/bus/mhi/core/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o
+obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o
diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c
new file mode 100644
index 000..a8e4a15
--- /dev/null
+++ b/drivers/bus/mhi/core/mhi_boot.c
@@ -0,0 +1,533 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mhi_internal.h"
+
+
+/* setup rddm vector table for rddm transfer */
+static void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
+struct image_info *img_info)
+{
+   struct mhi_buf *mhi_buf = img_info->mhi_buf;
+   struct bhi_vec_entry *bhi_vec = img_info->bhi_vec;
+   int i = 0;
+
+   for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) {
+   bhi_vec->dma_addr = mhi_buf->dma_addr;
+   bhi_vec->size = mhi_buf->len;
+   }
+}
+
+/* collect rddm during kernel panic */
+static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl)
+{
+   int ret;
+   struct mhi_buf *mhi_buf;
+   u32 sequence_id;
+   u32 rx_status;
+   enum MHI_EE ee;
+   struct image_info *rddm_image = mhi_cntrl->rddm_image;
+   const u32 delayus = 100;
+   u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
+   void __iomem *base = mhi_cntrl->bhie;
+
+   dev_info(mhi_cntrl->dev,
+"Entered with pm_state:%s dev_state:%s ee:%s\n",
+   to_mhi_pm_state_str(mhi_cntrl->pm_state),
+   TO_MHI_STATE_STR(mhi_cntrl->dev_state),
+   TO_MHI_EXEC_STR(mhi_cntrl->ee));
+
+   /*
+* This should only be executing during a kernel panic, we expect all
+* other cores to shutdown while we're collecting rddm buffer. After
+* returning from this function, we expect device to reset.
+*
+* Normaly, we would read/write pm_state only after grabbing
+* pm_lock, since we're in a panic, skipping it.
+*/
+
+   if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
+   return -EIO;
+
+   /*
+* There is no gurantee this state change would take effect since
+* we're setting it w/o grabbing pmlock, it's best effort
+*/
+   mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT;
+   /* update should take the effect immediately */
+   smp_wmb();
+
+   /* setup the RX vector table */
+   mhi_rddm_prepare(mhi_cntrl, rddm_image);
+   mhi_buf = _image->mhi_buf[rddm_image->entries - 1];
+
+   mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS,
+ upper_32_bits(mhi_buf->dma_addr));
+
+   mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS,
+ lower_32_bits(mhi_buf->dma_addr));
+
+   mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
+   sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
+
+   if (unlikely(!sequence_id))
+   sequence_id = 1;
+
+
+   mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS,
+   BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT,
+   sequence_id);
+
+   mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR);
+
+   while (retry--) {
+   ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS,
+BHIE_RXVECSTATUS_STATUS_BMSK,
+BHIE_RXVECSTATUS_STATUS_SHFT,
+_status);
+   if (ret)
+   return -EIO;
+
+   if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL)
+   return 0;
+
+   

[PATCH v2 3/7] mhi_bus: core: add support for data transfer

2018-07-09 Thread Sujeev Dias
Add support for transferring data between external
modem and MHI host using MHI protocol.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 drivers/bus/mhi/core/mhi_init.c |  76 +++-
 drivers/bus/mhi/core/mhi_internal.h |   8 -
 drivers/bus/mhi/core/mhi_main.c | 803 +++-
 include/linux/mhi.h |  78 
 4 files changed, 950 insertions(+), 15 deletions(-)

diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c
index 7b3d12a..43a700d 100644
--- a/drivers/bus/mhi/core/mhi_init.c
+++ b/drivers/bus/mhi/core/mhi_init.c
@@ -548,6 +548,66 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
return 0;
 }
 
+int mhi_device_configure(struct mhi_device *mhi_dev,
+enum dma_data_direction dir,
+struct mhi_buf *cfg_tbl,
+int elements)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   struct mhi_chan *mhi_chan;
+   struct mhi_event_ctxt *er_ctxt;
+   struct mhi_chan_ctxt *ch_ctxt;
+   int er_index, chan;
+
+   switch (dir) {
+   case DMA_TO_DEVICE:
+   mhi_chan = mhi_dev->ul_chan;
+   break;
+   case DMA_BIDIRECTIONAL:
+   case DMA_FROM_DEVICE:
+   case DMA_NONE:
+   mhi_chan = mhi_dev->dl_chan;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   er_index = mhi_chan->er_index;
+   chan = mhi_chan->chan;
+
+   for (; elements > 0; elements--, cfg_tbl++) {
+   /* update event context array */
+   if (!strcmp(cfg_tbl->name, "ECA")) {
+   er_ctxt = _cntrl->mhi_ctxt->er_ctxt[er_index];
+   if (sizeof(*er_ctxt) != cfg_tbl->len) {
+   dev_err(mhi_cntrl->dev,
+   "Invalid ECA size, expected:%zu 
actual%zu\n",
+   sizeof(*er_ctxt), cfg_tbl->len);
+   return -EINVAL;
+   }
+   memcpy((void *)er_ctxt, cfg_tbl->buf, sizeof(*er_ctxt));
+   continue;
+   }
+
+   /* update channel context array */
+   if (!strcmp(cfg_tbl->name, "CCA")) {
+   ch_ctxt = _cntrl->mhi_ctxt->chan_ctxt[chan];
+   if (cfg_tbl->len != sizeof(*ch_ctxt)) {
+   dev_err(mhi_cntrl->dev,
+   "Invalid CCA size, expected:%zu 
actual:%zu\n",
+   sizeof(*ch_ctxt), cfg_tbl->len);
+   return -EINVAL;
+   }
+   memcpy((void *)ch_ctxt, cfg_tbl->buf, sizeof(*ch_ctxt));
+   continue;
+   }
+
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
   struct device_node *of_node)
 {
@@ -1067,6 +1127,9 @@ static int mhi_driver_probe(struct device *dev)
struct mhi_event *mhi_event;
struct mhi_chan *ul_chan = mhi_dev->ul_chan;
struct mhi_chan *dl_chan = mhi_dev->dl_chan;
+   bool auto_start = false;
+   int ret;
+
 
if (ul_chan) {
/* lpm notification require status_cb */
@@ -1078,6 +1141,7 @@ static int mhi_driver_probe(struct device *dev)
 
ul_chan->xfer_cb = mhi_drv->ul_xfer_cb;
mhi_dev->status_cb = mhi_drv->status_cb;
+   auto_start = ul_chan->auto_start;
}
 
if (dl_chan) {
@@ -1101,9 +1165,15 @@ static int mhi_driver_probe(struct device *dev)
 
/* ul & dl uses same status cb */
mhi_dev->status_cb = mhi_drv->status_cb;
+   auto_start = (auto_start || dl_chan->auto_start);
}
 
-   return mhi_drv->probe(mhi_dev, mhi_dev->id);
+   ret = mhi_drv->probe(mhi_dev, mhi_dev->id);
+
+   if (!ret && auto_start)
+   mhi_prepare_for_transfer(mhi_dev);
+
+   return ret;
 }
 
 static int mhi_driver_remove(struct device *dev)
@@ -1141,6 +1211,10 @@ static int mhi_driver_remove(struct device *dev)
ch_state[dir] = mhi_chan->ch_state;
mhi_chan->ch_state = MHI_CH_STATE_DISABLED;
write_unlock_irq(_chan->lock);
+
+   /* reset the channel */
+   if (!mhi_chan->offload_ch)
+   mhi_reset_chan(mhi_cntrl, mhi_chan);
}
 
/* destroy the device */
diff --git a/drivers/bus/mhi/core/mhi_internal.h 
b/drivers/bus/mhi/core/mhi_internal.h
index 0091245..1167d75 100644
--- a/drivers/bus/mhi

[PATCH v2 1/7] mhi_bus: core: initial checkin for modem host interface bus driver

2018-07-09 Thread Sujeev Dias
This is the initial skeleton driver for mhi bus stack. MHI Host
Interface is a communication protocol to be used by the host to
control and communcate with modem over a high speed peripheral bus.
This module will allow host to communicate with external devices that
support MHI protocol.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 Documentation/00-INDEX|   2 +
 Documentation/devicetree/bindings/bus/mhi.txt | 258 
 Documentation/mhi.txt | 235 +++
 drivers/bus/Kconfig   |   8 +
 drivers/bus/Makefile  |   1 +
 drivers/bus/mhi/Makefile  |   6 +
 drivers/bus/mhi/core/Makefile |   1 +
 drivers/bus/mhi/core/mhi_init.c   | 538 ++
 drivers/bus/mhi/core/mhi_internal.h   | 238 
 drivers/bus/mhi/core/mhi_main.c   | 122 ++
 include/linux/mhi.h   | 341 
 include/linux/mod_devicetable.h   |  12 +
 12 files changed, 1762 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/mhi.txt
 create mode 100644 Documentation/mhi.txt
 create mode 100644 drivers/bus/mhi/Makefile
 create mode 100644 drivers/bus/mhi/core/Makefile
 create mode 100644 drivers/bus/mhi/core/mhi_init.c
 create mode 100644 drivers/bus/mhi/core/mhi_internal.h
 create mode 100644 drivers/bus/mhi/core/mhi_main.c
 create mode 100644 include/linux/mhi.h

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 708dc4c..44e2c6b 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -270,6 +270,8 @@ memory-hotplug.txt
- Hotpluggable memory support, how to use and current status.
 men-chameleon-bus.txt
- info on MEN chameleon bus.
+mhi.txt
+   - Modem Host Interface
 mic/
- Intel Many Integrated Core (MIC) architecture device driver.
 mips/
diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
new file mode 100644
index 000..19deb84
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -0,0 +1,258 @@
+MHI Host Interface
+
+MHI used by the host to control and communicate with modem over
+high speed peripheral bus.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- mhi,max-channels
+  Usage: required
+  Value type: 
+  Definition: Maximum number of channels supported by this controller
+
+- mhi,timeout
+  Usage: optional
+  Value type: 
+  Definition: Maximum timeout in ms wait for state and cmd completion
+
+- mhi,use-bb
+  Usage: optional
+  Value type: 
+  Definition: Set true, if PCIe controller does not have full access to host
+   DDR, and we're using a dedicated memory pool like cma, or
+   carveout pool. Pool must support atomic allocation.
+
+- mhi,buffer-len
+  Usage: optional
+  Value type: 
+  Definition: MHI automatically pre-allocate buffers for some channel.
+   Set the length of buffer size to allocate. If not default
+   size MHI_MAX_MTU will be used.
+
+
+mhi channel node properties:
+
+
+- reg
+  Usage: required
+  Value type: 
+  Definition: physical channel number
+
+- label
+  Usage: required
+  Value type: 
+  Definition: given name for the channel
+
+- mhi,num-elements
+  Usage: optional
+  Value type: 
+  Definition: Number of elements transfer ring support
+
+- mhi,event-ring
+  Usage: required
+  Value type: 
+  Definition: Event ring index associated with this channel
+
+- mhi,chan-dir
+  Usage: required
+  Value type: 
+  Definition: Channel direction as defined by enum dma_data_direction
+   0 = Bidirectional data transfer
+   1 = UL data transfer
+   2 = DL data transfer
+   3 = No direction, not a regular data transfer channel
+
+- mhi,ee
+  Usage: required
+  Value type: 
+  Definition: Channel execution enviornment as defined by enum MHI_EE
+   1 = Bootloader stage
+   2 = AMSS mode
+
+- mhi,pollcfg
+  Usage: optional
+  Value type: 
+  Definition: MHI poll configuration, valid only when burst mode is enabled
+   0 = Use default (device specific) polling configuration
+   For UL channels, value specifies the timer to poll MHI context in
+   milliseconds.
+   For DL channels, the threshold to poll the MHI context in multiple of
+   eight ring element.
+
+- mhi,data-type
+  Usage: required
+  Value type: 
+  Definition: Data transfer type accepted as defined by enum MHI_XFER_TYPE
+   0 = accept cpu address for buffer
+   1 = accept skb
+   2 = accept scatterlist
+   3 = offload channel, does not accept any transfer type
+
+- mhi,doorbell-mode
+  Usage: required
+  Value type: 
+  Definition: Channel doorbell mode configuration as defined by enum
+   MHI_BRSTMODE
+   2 = burst mode disabled
+   3 = burst

[PATCH v2 1/7] mhi_bus: core: initial checkin for modem host interface bus driver

2018-07-09 Thread Sujeev Dias
This is the initial skeleton driver for mhi bus stack. MHI Host
Interface is a communication protocol to be used by the host to
control and communcate with modem over a high speed peripheral bus.
This module will allow host to communicate with external devices that
support MHI protocol.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 Documentation/00-INDEX|   2 +
 Documentation/devicetree/bindings/bus/mhi.txt | 258 
 Documentation/mhi.txt | 235 +++
 drivers/bus/Kconfig   |   8 +
 drivers/bus/Makefile  |   1 +
 drivers/bus/mhi/Makefile  |   6 +
 drivers/bus/mhi/core/Makefile |   1 +
 drivers/bus/mhi/core/mhi_init.c   | 538 ++
 drivers/bus/mhi/core/mhi_internal.h   | 238 
 drivers/bus/mhi/core/mhi_main.c   | 122 ++
 include/linux/mhi.h   | 341 
 include/linux/mod_devicetable.h   |  12 +
 12 files changed, 1762 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/mhi.txt
 create mode 100644 Documentation/mhi.txt
 create mode 100644 drivers/bus/mhi/Makefile
 create mode 100644 drivers/bus/mhi/core/Makefile
 create mode 100644 drivers/bus/mhi/core/mhi_init.c
 create mode 100644 drivers/bus/mhi/core/mhi_internal.h
 create mode 100644 drivers/bus/mhi/core/mhi_main.c
 create mode 100644 include/linux/mhi.h

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 708dc4c..44e2c6b 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -270,6 +270,8 @@ memory-hotplug.txt
- Hotpluggable memory support, how to use and current status.
 men-chameleon-bus.txt
- info on MEN chameleon bus.
+mhi.txt
+   - Modem Host Interface
 mic/
- Intel Many Integrated Core (MIC) architecture device driver.
 mips/
diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
new file mode 100644
index 000..19deb84
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -0,0 +1,258 @@
+MHI Host Interface
+
+MHI used by the host to control and communicate with modem over
+high speed peripheral bus.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- mhi,max-channels
+  Usage: required
+  Value type: 
+  Definition: Maximum number of channels supported by this controller
+
+- mhi,timeout
+  Usage: optional
+  Value type: 
+  Definition: Maximum timeout in ms wait for state and cmd completion
+
+- mhi,use-bb
+  Usage: optional
+  Value type: 
+  Definition: Set true, if PCIe controller does not have full access to host
+   DDR, and we're using a dedicated memory pool like cma, or
+   carveout pool. Pool must support atomic allocation.
+
+- mhi,buffer-len
+  Usage: optional
+  Value type: 
+  Definition: MHI automatically pre-allocate buffers for some channel.
+   Set the length of buffer size to allocate. If not default
+   size MHI_MAX_MTU will be used.
+
+
+mhi channel node properties:
+
+
+- reg
+  Usage: required
+  Value type: 
+  Definition: physical channel number
+
+- label
+  Usage: required
+  Value type: 
+  Definition: given name for the channel
+
+- mhi,num-elements
+  Usage: optional
+  Value type: 
+  Definition: Number of elements transfer ring support
+
+- mhi,event-ring
+  Usage: required
+  Value type: 
+  Definition: Event ring index associated with this channel
+
+- mhi,chan-dir
+  Usage: required
+  Value type: 
+  Definition: Channel direction as defined by enum dma_data_direction
+   0 = Bidirectional data transfer
+   1 = UL data transfer
+   2 = DL data transfer
+   3 = No direction, not a regular data transfer channel
+
+- mhi,ee
+  Usage: required
+  Value type: 
+  Definition: Channel execution enviornment as defined by enum MHI_EE
+   1 = Bootloader stage
+   2 = AMSS mode
+
+- mhi,pollcfg
+  Usage: optional
+  Value type: 
+  Definition: MHI poll configuration, valid only when burst mode is enabled
+   0 = Use default (device specific) polling configuration
+   For UL channels, value specifies the timer to poll MHI context in
+   milliseconds.
+   For DL channels, the threshold to poll the MHI context in multiple of
+   eight ring element.
+
+- mhi,data-type
+  Usage: required
+  Value type: 
+  Definition: Data transfer type accepted as defined by enum MHI_XFER_TYPE
+   0 = accept cpu address for buffer
+   1 = accept skb
+   2 = accept scatterlist
+   3 = offload channel, does not accept any transfer type
+
+- mhi,doorbell-mode
+  Usage: required
+  Value type: 
+  Definition: Channel doorbell mode configuration as defined by enum
+   MHI_BRSTMODE
+   2 = burst mode disabled
+   3 = burst

MHI code review

2018-07-09 Thread Sujeev Dias
Hi Greg Kroah-Hartman\Arnd Bergmann and community

Thank you for all the feedback, I believe I have addressed all the comments 
from previous
patches. Also, I am excluding mhi network driver in this series. I still have 
some modifications
to do.

Please review the new patch series and share your feedback.

Thanks again

Sincerely,
Sujeev




[PATCH v2 6/7] mhi_bus: controller: MHI support for QCOM modems

2018-07-09 Thread Sujeev Dias
QCOM PCIe based modems uses MHI as the communication protocol.
MHI control driver is the bus master for such modems. As the bus
master driver, it oversees power management operations
such as suspend, resume, powering on and off the device.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 Documentation/devicetree/bindings/bus/mhi_qcom.txt |  58 +++
 arch/arm64/configs/defconfig   |   1 +
 drivers/bus/Kconfig|   1 +
 drivers/bus/mhi/Makefile   |   1 +
 drivers/bus/mhi/controllers/Kconfig|  13 +
 drivers/bus/mhi/controllers/Makefile   |   1 +
 drivers/bus/mhi/controllers/mhi_qcom.c | 461 +
 drivers/bus/mhi/controllers/mhi_qcom.h |  67 +++
 8 files changed, 603 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/mhi_qcom.txt
 create mode 100644 drivers/bus/mhi/controllers/Kconfig
 create mode 100644 drivers/bus/mhi/controllers/Makefile
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.c
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.h

diff --git a/Documentation/devicetree/bindings/bus/mhi_qcom.txt 
b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
new file mode 100644
index 000..0a48a50
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
@@ -0,0 +1,58 @@
+Qualcomm Technologies Inc MHI Bus controller
+
+MHI control driver enables clients to communicate with external mode
+using MHI protocol.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- reg
+  Usage: required
+  Value type: Array (5-cell PCI resource) of 
+  Definition: First cell is devfn, which is determined by pci bus topology.
+   Assign the other cells 0 since they are not used.
+
+- qcom,smmu-cfg
+  Usage: required
+  Value type: 
+  Definition: Required SMMU configuration bitmask for PCIe bus.
+   BIT mask:
+   BIT(0) : Attach address mapping to endpoint device
+   BIT(1) : Set attribute S1_BYPASS
+   BIT(2) : Set attribute FAST
+   BIT(3) : Set attribute ATOMIC
+   BIT(4) : Set attribute FORCE_COHERENT
+
+- qcom,addr-win
+  Usage: required if SMMU S1 translation is enabled
+  Value type: Array of 
+  Definition: Pair of values describing iova start and stop address
+
+- MHI bus settings
+  Usage: required
+  Values: as defined by mhi.txt
+  Definition: Per definition of devicetree/bindings/bus/mhi.txt, define device
+   specific MHI configuration parameters.
+
+
+Example:
+
+
+/* pcie domain (root complex) modem connected to */
+ {
+   /* pcie bus modem connected to */
+   pci,bus@1 {
+   reg = <0 0 0 0 0>;
+
+   qcom,mhi {
+   reg = <0 0 0 0 0>;
+   qcom,smmu-cfg = <0x3d>;
+   qcom,addr-win = <0x0 0x2000 0x0 0x3fff>;
+
+   
+   };
+   };
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 3562026..fd36426 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -168,6 +168,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_MHI_BUS=y
+CONFIG_MHI_QCOM=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 080d3c2..8c6827a 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -180,5 +180,6 @@ config MHI_BUS
  devices that support MHI protocol.
 
 source "drivers/bus/fsl-mc/Kconfig"
+source drivers/bus/mhi/controllers/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index f8f14f7..3458ba3 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -4,3 +4,4 @@
 
 # core layer
 obj-y += core/
+obj-y += controllers/
\ No newline at end of file
diff --git a/drivers/bus/mhi/controllers/Kconfig 
b/drivers/bus/mhi/controllers/Kconfig
new file mode 100644
index 000..2586cc4
--- /dev/null
+++ b/drivers/bus/mhi/controllers/Kconfig
@@ -0,0 +1,13 @@
+menu "MHI controllers"
+
+config MHI_QCOM
+   tristate "MHI QCOM"
+   depends on MHI_BUS
+   help
+ If you say yes to this option, MHI bus support for QCOM modem chipsets
+ will be enabled. QCOM PCIe based modems uses MHI as the communication
+ protocol. MHI control driver is the bus master for such modems. As the
+ bus master driver, it oversees power management operations such as
+ suspend, resume, powering on and off the device.
+
+endmenu
diff --git a/drivers/bus/mhi/controllers/Makefile 
b/drivers/bus/mhi/controllers/Makefile
new file mode 100644
index 000..292f696
--- /dev/null
+++ b/drivers/bus/mhi/controllers/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MHI_QCOM) += mhi_qcom.o
diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c 
b/drive

MHI code review

2018-07-09 Thread Sujeev Dias
Hi Greg Kroah-Hartman\Arnd Bergmann and community

Thank you for all the feedback, I believe I have addressed all the comments 
from previous
patches. Also, I am excluding mhi network driver in this series. I still have 
some modifications
to do.

Please review the new patch series and share your feedback.

Thanks again

Sincerely,
Sujeev




[PATCH v2 6/7] mhi_bus: controller: MHI support for QCOM modems

2018-07-09 Thread Sujeev Dias
QCOM PCIe based modems uses MHI as the communication protocol.
MHI control driver is the bus master for such modems. As the bus
master driver, it oversees power management operations
such as suspend, resume, powering on and off the device.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 Documentation/devicetree/bindings/bus/mhi_qcom.txt |  58 +++
 arch/arm64/configs/defconfig   |   1 +
 drivers/bus/Kconfig|   1 +
 drivers/bus/mhi/Makefile   |   1 +
 drivers/bus/mhi/controllers/Kconfig|  13 +
 drivers/bus/mhi/controllers/Makefile   |   1 +
 drivers/bus/mhi/controllers/mhi_qcom.c | 461 +
 drivers/bus/mhi/controllers/mhi_qcom.h |  67 +++
 8 files changed, 603 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/mhi_qcom.txt
 create mode 100644 drivers/bus/mhi/controllers/Kconfig
 create mode 100644 drivers/bus/mhi/controllers/Makefile
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.c
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.h

diff --git a/Documentation/devicetree/bindings/bus/mhi_qcom.txt 
b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
new file mode 100644
index 000..0a48a50
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
@@ -0,0 +1,58 @@
+Qualcomm Technologies Inc MHI Bus controller
+
+MHI control driver enables clients to communicate with external mode
+using MHI protocol.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- reg
+  Usage: required
+  Value type: Array (5-cell PCI resource) of 
+  Definition: First cell is devfn, which is determined by pci bus topology.
+   Assign the other cells 0 since they are not used.
+
+- qcom,smmu-cfg
+  Usage: required
+  Value type: 
+  Definition: Required SMMU configuration bitmask for PCIe bus.
+   BIT mask:
+   BIT(0) : Attach address mapping to endpoint device
+   BIT(1) : Set attribute S1_BYPASS
+   BIT(2) : Set attribute FAST
+   BIT(3) : Set attribute ATOMIC
+   BIT(4) : Set attribute FORCE_COHERENT
+
+- qcom,addr-win
+  Usage: required if SMMU S1 translation is enabled
+  Value type: Array of 
+  Definition: Pair of values describing iova start and stop address
+
+- MHI bus settings
+  Usage: required
+  Values: as defined by mhi.txt
+  Definition: Per definition of devicetree/bindings/bus/mhi.txt, define device
+   specific MHI configuration parameters.
+
+
+Example:
+
+
+/* pcie domain (root complex) modem connected to */
+ {
+   /* pcie bus modem connected to */
+   pci,bus@1 {
+   reg = <0 0 0 0 0>;
+
+   qcom,mhi {
+   reg = <0 0 0 0 0>;
+   qcom,smmu-cfg = <0x3d>;
+   qcom,addr-win = <0x0 0x2000 0x0 0x3fff>;
+
+   
+   };
+   };
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 3562026..fd36426 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -168,6 +168,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_MHI_BUS=y
+CONFIG_MHI_QCOM=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 080d3c2..8c6827a 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -180,5 +180,6 @@ config MHI_BUS
  devices that support MHI protocol.
 
 source "drivers/bus/fsl-mc/Kconfig"
+source drivers/bus/mhi/controllers/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index f8f14f7..3458ba3 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -4,3 +4,4 @@
 
 # core layer
 obj-y += core/
+obj-y += controllers/
\ No newline at end of file
diff --git a/drivers/bus/mhi/controllers/Kconfig 
b/drivers/bus/mhi/controllers/Kconfig
new file mode 100644
index 000..2586cc4
--- /dev/null
+++ b/drivers/bus/mhi/controllers/Kconfig
@@ -0,0 +1,13 @@
+menu "MHI controllers"
+
+config MHI_QCOM
+   tristate "MHI QCOM"
+   depends on MHI_BUS
+   help
+ If you say yes to this option, MHI bus support for QCOM modem chipsets
+ will be enabled. QCOM PCIe based modems uses MHI as the communication
+ protocol. MHI control driver is the bus master for such modems. As the
+ bus master driver, it oversees power management operations such as
+ suspend, resume, powering on and off the device.
+
+endmenu
diff --git a/drivers/bus/mhi/controllers/Makefile 
b/drivers/bus/mhi/controllers/Makefile
new file mode 100644
index 000..292f696
--- /dev/null
+++ b/drivers/bus/mhi/controllers/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MHI_QCOM) += mhi_qcom.o
diff --git a/drivers/bus/mhi/controllers/mhi_qcom.c 
b/drive

[PATCH v2 7/7] mhi_bus: dev: uci: add user space interface driver

2018-07-09 Thread Sujeev Dias
This module allows user space clients to transfer data
between external modem and host using standard file
operations.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 arch/arm64/configs/defconfig  |   1 +
 drivers/bus/Kconfig   |   1 +
 drivers/bus/mhi/Makefile  |   3 +-
 drivers/bus/mhi/devices/Kconfig   |  13 +
 drivers/bus/mhi/devices/Makefile  |   1 +
 drivers/bus/mhi/devices/mhi_uci.c | 590 ++
 6 files changed, 608 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/mhi/devices/Kconfig
 create mode 100644 drivers/bus/mhi/devices/Makefile
 create mode 100644 drivers/bus/mhi/devices/mhi_uci.c

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fd36426..7f68d706 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -169,6 +169,7 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_MHI_BUS=y
 CONFIG_MHI_QCOM=y
+CONFIG_MHI_UCI=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 8c6827a..cb10366 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -181,5 +181,6 @@ config MHI_BUS
 
 source "drivers/bus/fsl-mc/Kconfig"
 source drivers/bus/mhi/controllers/Kconfig
+source drivers/bus/mhi/devices/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index 3458ba3..2382e04 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -4,4 +4,5 @@
 
 # core layer
 obj-y += core/
-obj-y += controllers/
\ No newline at end of file
+obj-y += controllers/
+obj-y += devices/
diff --git a/drivers/bus/mhi/devices/Kconfig b/drivers/bus/mhi/devices/Kconfig
new file mode 100644
index 000..45cd742
--- /dev/null
+++ b/drivers/bus/mhi/devices/Kconfig
@@ -0,0 +1,13 @@
+menu "MHI device support"
+
+config MHI_UCI
+   tristate "MHI UCI"
+   depends on MHI_BUS
+   help
+ MHI based uci driver is for transferring data between host and
+ modem using standard file operations from user space. Open, read,
+ write, ioctl, and close operations are supported by this driver.
+ Please check mhi_uci_match_table for all supported channels that
+ are exposed to userspace.
+
+endmenu
diff --git a/drivers/bus/mhi/devices/Makefile b/drivers/bus/mhi/devices/Makefile
new file mode 100644
index 000..ddc0613
--- /dev/null
+++ b/drivers/bus/mhi/devices/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MHI_UCI) +=mhi_uci.o
diff --git a/drivers/bus/mhi/devices/mhi_uci.c 
b/drivers/bus/mhi/devices/mhi_uci.c
new file mode 100644
index 000..ad60a15
--- /dev/null
+++ b/drivers/bus/mhi/devices/mhi_uci.c
@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEVICE_NAME "mhi"
+#define MHI_UCI_DRIVER_NAME "mhi_uci"
+
+struct uci_chan {
+   wait_queue_head_t wq;
+   spinlock_t lock;
+   struct list_head pending; /* user space waiting to read */
+   struct uci_buf *cur_buf; /* current buffer user space reading */
+   size_t rx_size;
+};
+
+struct uci_buf {
+   void *data;
+   size_t len;
+   struct list_head node;
+};
+
+struct uci_dev {
+   struct list_head node;
+   dev_t devt;
+   struct device *dev;
+   struct mhi_device *mhi_dev;
+   const char *chan;
+   struct mutex mutex; /* sync open and close */
+   struct uci_chan ul_chan;
+   struct uci_chan dl_chan;
+   size_t mtu;
+   int ref_count;
+   bool enabled;
+};
+
+struct mhi_uci_drv {
+   struct list_head head;
+   struct mutex lock;
+   struct class *class;
+   int major;
+   dev_t dev_t;
+};
+
+#define MAX_UCI_DEVICES (64)
+
+static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
+static struct mhi_uci_drv mhi_uci_drv;
+
+static int mhi_queue_inbound(struct uci_dev *uci_dev)
+{
+   struct mhi_device *mhi_dev = uci_dev->mhi_dev;
+   int nr_trbs = mhi_get_no_free_descriptors(mhi_dev, DMA_FROM_DEVICE);
+   size_t mtu = uci_dev->mtu;
+   void *buf;
+   struct uci_buf *uci_buf;
+   int ret = -EIO, i;
+
+   for (i = 0; i < nr_trbs; i++) {
+   buf = kmalloc(mtu + sizeof(*uci_buf), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   uci_buf = buf + mtu;
+   uci_buf->data = buf;
+
+   ret = mhi_queue_transfer(mhi_dev, DMA_FROM_DEVICE, buf, mtu,
+MHI_EOT);
+   if (ret) {
+   kfree(buf);
+   return ret;
+   }
+   }
+
+   return ret;
+}
+
+static long mhi_uci_ioctl

[PATCH v2 5/7] mhi_bus: core: add support to get external modem time

2018-07-09 Thread Sujeev Dias
For accurate synchronizations between external modem and
host processor, mhi host will capture modem time relative
to host time. Client may use time measurements for adjusting
any drift between host and modem.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 Documentation/devicetree/bindings/bus/mhi.txt |   7 +
 Documentation/mhi.txt |  41 
 drivers/bus/mhi/core/mhi_init.c   | 111 +++
 drivers/bus/mhi/core/mhi_internal.h   |  57 +-
 drivers/bus/mhi/core/mhi_main.c   | 263 +-
 drivers/bus/mhi/core/mhi_pm.c |   7 +
 include/linux/mhi.h   |   7 +
 7 files changed, 486 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
index 19deb84..1012ff2 100644
--- a/Documentation/devicetree/bindings/bus/mhi.txt
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -19,6 +19,13 @@ Main node properties:
   Value type: 
   Definition: Maximum timeout in ms wait for state and cmd completion
 
+- mhi,time-sync
+  Usage: optional
+  Value type: 
+  Definition: Set true, if the external device support MHI get time
+   feature for time synchronization between host processor and
+   external modem.
+
 - mhi,use-bb
   Usage: optional
   Value type: 
diff --git a/Documentation/mhi.txt b/Documentation/mhi.txt
index 1c501f1..9287899 100644
--- a/Documentation/mhi.txt
+++ b/Documentation/mhi.txt
@@ -137,6 +137,47 @@ Example Operation for data transfer:
 8. Host wakes up and check event ring for completion event
 9. Host update the Event[i].ctxt.WP to indicate processed of completion event.
 
+Time sync
+-
+To synchronize two applications between host and external modem, MHI provide
+native support to get external modems free running timer value in a fast
+reliable method. MHI clients do not need to create client specific methods to
+get modem time.
+
+When client requests modem time, MHI host will automatically capture host time
+at that moment so clients are able to do accurate drift adjustment.
+
+Example:
+
+Client request time @ time T1
+
+Host Time: Tx
+Modem Time: Ty
+
+Client request time @ time T2
+Host Time: Txx
+Modem Time: Tyy
+
+Then drift is:
+Tyy - Ty +  == Txx - Tx
+
+Clients are free to implement their own drift algorithms, what MHI host provide
+is a way to accurately correlate host time with external modem time.
+
+To avoid link level latencies, controller must support capabilities to disable
+any link level latency.
+
+During Time capture host will:
+   1. Capture host time
+   2. Trigger doorbell to capture modem time
+
+It's important time between Step 2 to Step 1 is deterministic as possible.
+Therefore, MHI host will:
+   1. Disable any MHI related to low power modes.
+   2. Disable preemption
+   3. Request bus master to disable any link level latencies. Controller
+   should disable all low power modes such as L0s, L1, L1ss.
+
 MHI States
 --
 
diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c
index b09767a..e1e1b8c 100644
--- a/drivers/bus/mhi/core/mhi_init.c
+++ b/drivers/bus/mhi/core/mhi_init.c
@@ -362,6 +362,69 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl)
return ret;
 }
 
+int mhi_init_timesync(struct mhi_controller *mhi_cntrl)
+{
+   struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync;
+   u32 time_offset, db_offset;
+   int ret;
+
+   reinit_completion(_tsync->completion);
+   read_lock_bh(_cntrl->pm_lock);
+   if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
+   read_unlock_bh(_cntrl->pm_lock);
+   return -EIO;
+   }
+
+   mhi_cntrl->wake_get(mhi_cntrl, false);
+   read_unlock_bh(_cntrl->pm_lock);
+   mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data);
+   mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data);
+
+   ret = mhi_send_cmd(mhi_cntrl, NULL, MHI_CMD_TIMSYNC_CFG);
+   if (ret)
+   goto error_send_cmd;
+
+   ret = wait_for_completion_timeout(_tsync->completion,
+   msecs_to_jiffies(mhi_cntrl->timeout_ms));
+
+   if (!ret || mhi_tsync->ccs != MHI_EV_CC_SUCCESS) {
+   ret = -EIO;
+   goto error_send_cmd;
+   }
+
+   read_lock_bh(_cntrl->pm_lock);
+   mhi_cntrl->wake_put(mhi_cntrl, false);
+
+   ret = -EIO;
+
+   if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
+   goto error_sync_cap;
+
+   ret = mhi_get_capability_offset(mhi_cntrl, TIMESYNC_CAP_ID,
+   _offset);
+   if (ret)
+   goto error_sync_cap;
+
+   ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs,
+  time_offset + TIMESYNC_DB_OFFSET, _offset)

[PATCH v2 7/7] mhi_bus: dev: uci: add user space interface driver

2018-07-09 Thread Sujeev Dias
This module allows user space clients to transfer data
between external modem and host using standard file
operations.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 arch/arm64/configs/defconfig  |   1 +
 drivers/bus/Kconfig   |   1 +
 drivers/bus/mhi/Makefile  |   3 +-
 drivers/bus/mhi/devices/Kconfig   |  13 +
 drivers/bus/mhi/devices/Makefile  |   1 +
 drivers/bus/mhi/devices/mhi_uci.c | 590 ++
 6 files changed, 608 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/mhi/devices/Kconfig
 create mode 100644 drivers/bus/mhi/devices/Makefile
 create mode 100644 drivers/bus/mhi/devices/mhi_uci.c

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fd36426..7f68d706 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -169,6 +169,7 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_MHI_BUS=y
 CONFIG_MHI_QCOM=y
+CONFIG_MHI_UCI=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 8c6827a..cb10366 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -181,5 +181,6 @@ config MHI_BUS
 
 source "drivers/bus/fsl-mc/Kconfig"
 source drivers/bus/mhi/controllers/Kconfig
+source drivers/bus/mhi/devices/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index 3458ba3..2382e04 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -4,4 +4,5 @@
 
 # core layer
 obj-y += core/
-obj-y += controllers/
\ No newline at end of file
+obj-y += controllers/
+obj-y += devices/
diff --git a/drivers/bus/mhi/devices/Kconfig b/drivers/bus/mhi/devices/Kconfig
new file mode 100644
index 000..45cd742
--- /dev/null
+++ b/drivers/bus/mhi/devices/Kconfig
@@ -0,0 +1,13 @@
+menu "MHI device support"
+
+config MHI_UCI
+   tristate "MHI UCI"
+   depends on MHI_BUS
+   help
+ MHI based uci driver is for transferring data between host and
+ modem using standard file operations from user space. Open, read,
+ write, ioctl, and close operations are supported by this driver.
+ Please check mhi_uci_match_table for all supported channels that
+ are exposed to userspace.
+
+endmenu
diff --git a/drivers/bus/mhi/devices/Makefile b/drivers/bus/mhi/devices/Makefile
new file mode 100644
index 000..ddc0613
--- /dev/null
+++ b/drivers/bus/mhi/devices/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MHI_UCI) +=mhi_uci.o
diff --git a/drivers/bus/mhi/devices/mhi_uci.c 
b/drivers/bus/mhi/devices/mhi_uci.c
new file mode 100644
index 000..ad60a15
--- /dev/null
+++ b/drivers/bus/mhi/devices/mhi_uci.c
@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEVICE_NAME "mhi"
+#define MHI_UCI_DRIVER_NAME "mhi_uci"
+
+struct uci_chan {
+   wait_queue_head_t wq;
+   spinlock_t lock;
+   struct list_head pending; /* user space waiting to read */
+   struct uci_buf *cur_buf; /* current buffer user space reading */
+   size_t rx_size;
+};
+
+struct uci_buf {
+   void *data;
+   size_t len;
+   struct list_head node;
+};
+
+struct uci_dev {
+   struct list_head node;
+   dev_t devt;
+   struct device *dev;
+   struct mhi_device *mhi_dev;
+   const char *chan;
+   struct mutex mutex; /* sync open and close */
+   struct uci_chan ul_chan;
+   struct uci_chan dl_chan;
+   size_t mtu;
+   int ref_count;
+   bool enabled;
+};
+
+struct mhi_uci_drv {
+   struct list_head head;
+   struct mutex lock;
+   struct class *class;
+   int major;
+   dev_t dev_t;
+};
+
+#define MAX_UCI_DEVICES (64)
+
+static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
+static struct mhi_uci_drv mhi_uci_drv;
+
+static int mhi_queue_inbound(struct uci_dev *uci_dev)
+{
+   struct mhi_device *mhi_dev = uci_dev->mhi_dev;
+   int nr_trbs = mhi_get_no_free_descriptors(mhi_dev, DMA_FROM_DEVICE);
+   size_t mtu = uci_dev->mtu;
+   void *buf;
+   struct uci_buf *uci_buf;
+   int ret = -EIO, i;
+
+   for (i = 0; i < nr_trbs; i++) {
+   buf = kmalloc(mtu + sizeof(*uci_buf), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   uci_buf = buf + mtu;
+   uci_buf->data = buf;
+
+   ret = mhi_queue_transfer(mhi_dev, DMA_FROM_DEVICE, buf, mtu,
+MHI_EOT);
+   if (ret) {
+   kfree(buf);
+   return ret;
+   }
+   }
+
+   return ret;
+}
+
+static long mhi_uci_ioctl

[PATCH v2 5/7] mhi_bus: core: add support to get external modem time

2018-07-09 Thread Sujeev Dias
For accurate synchronizations between external modem and
host processor, mhi host will capture modem time relative
to host time. Client may use time measurements for adjusting
any drift between host and modem.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 Documentation/devicetree/bindings/bus/mhi.txt |   7 +
 Documentation/mhi.txt |  41 
 drivers/bus/mhi/core/mhi_init.c   | 111 +++
 drivers/bus/mhi/core/mhi_internal.h   |  57 +-
 drivers/bus/mhi/core/mhi_main.c   | 263 +-
 drivers/bus/mhi/core/mhi_pm.c |   7 +
 include/linux/mhi.h   |   7 +
 7 files changed, 486 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
index 19deb84..1012ff2 100644
--- a/Documentation/devicetree/bindings/bus/mhi.txt
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -19,6 +19,13 @@ Main node properties:
   Value type: 
   Definition: Maximum timeout in ms wait for state and cmd completion
 
+- mhi,time-sync
+  Usage: optional
+  Value type: 
+  Definition: Set true, if the external device support MHI get time
+   feature for time synchronization between host processor and
+   external modem.
+
 - mhi,use-bb
   Usage: optional
   Value type: 
diff --git a/Documentation/mhi.txt b/Documentation/mhi.txt
index 1c501f1..9287899 100644
--- a/Documentation/mhi.txt
+++ b/Documentation/mhi.txt
@@ -137,6 +137,47 @@ Example Operation for data transfer:
 8. Host wakes up and check event ring for completion event
 9. Host update the Event[i].ctxt.WP to indicate processed of completion event.
 
+Time sync
+-
+To synchronize two applications between host and external modem, MHI provide
+native support to get external modems free running timer value in a fast
+reliable method. MHI clients do not need to create client specific methods to
+get modem time.
+
+When client requests modem time, MHI host will automatically capture host time
+at that moment so clients are able to do accurate drift adjustment.
+
+Example:
+
+Client request time @ time T1
+
+Host Time: Tx
+Modem Time: Ty
+
+Client request time @ time T2
+Host Time: Txx
+Modem Time: Tyy
+
+Then drift is:
+Tyy - Ty +  == Txx - Tx
+
+Clients are free to implement their own drift algorithms, what MHI host provide
+is a way to accurately correlate host time with external modem time.
+
+To avoid link level latencies, controller must support capabilities to disable
+any link level latency.
+
+During Time capture host will:
+   1. Capture host time
+   2. Trigger doorbell to capture modem time
+
+It's important time between Step 2 to Step 1 is deterministic as possible.
+Therefore, MHI host will:
+   1. Disable any MHI related to low power modes.
+   2. Disable preemption
+   3. Request bus master to disable any link level latencies. Controller
+   should disable all low power modes such as L0s, L1, L1ss.
+
 MHI States
 --
 
diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c
index b09767a..e1e1b8c 100644
--- a/drivers/bus/mhi/core/mhi_init.c
+++ b/drivers/bus/mhi/core/mhi_init.c
@@ -362,6 +362,69 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl)
return ret;
 }
 
+int mhi_init_timesync(struct mhi_controller *mhi_cntrl)
+{
+   struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync;
+   u32 time_offset, db_offset;
+   int ret;
+
+   reinit_completion(_tsync->completion);
+   read_lock_bh(_cntrl->pm_lock);
+   if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
+   read_unlock_bh(_cntrl->pm_lock);
+   return -EIO;
+   }
+
+   mhi_cntrl->wake_get(mhi_cntrl, false);
+   read_unlock_bh(_cntrl->pm_lock);
+   mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data);
+   mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data);
+
+   ret = mhi_send_cmd(mhi_cntrl, NULL, MHI_CMD_TIMSYNC_CFG);
+   if (ret)
+   goto error_send_cmd;
+
+   ret = wait_for_completion_timeout(_tsync->completion,
+   msecs_to_jiffies(mhi_cntrl->timeout_ms));
+
+   if (!ret || mhi_tsync->ccs != MHI_EV_CC_SUCCESS) {
+   ret = -EIO;
+   goto error_send_cmd;
+   }
+
+   read_lock_bh(_cntrl->pm_lock);
+   mhi_cntrl->wake_put(mhi_cntrl, false);
+
+   ret = -EIO;
+
+   if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
+   goto error_sync_cap;
+
+   ret = mhi_get_capability_offset(mhi_cntrl, TIMESYNC_CAP_ID,
+   _offset);
+   if (ret)
+   goto error_sync_cap;
+
+   ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->regs,
+  time_offset + TIMESYNC_DB_OFFSET, _offset)

[PATCH v2 4/7] mhi_bus: core: add support for handling ioctl cmds

2018-07-09 Thread Sujeev Dias
User space clients use RS232 control signaling mechanism to
communicate call status between host and modem. Adding support
to handle ioctl commands from user space.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 drivers/bus/mhi/core/Makefile   |   2 +-
 drivers/bus/mhi/core/mhi_dtr.c  | 218 
 drivers/bus/mhi/core/mhi_init.c |   8 +-
 3 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 drivers/bus/mhi/core/mhi_dtr.c

diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/core/Makefile
index a6015ab..a743fbf 100644
--- a/drivers/bus/mhi/core/Makefile
+++ b/drivers/bus/mhi/core/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o
+obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o mhi_dtr.o
diff --git a/drivers/bus/mhi/core/mhi_dtr.c b/drivers/bus/mhi/core/mhi_dtr.c
new file mode 100644
index 000..5c2409b
--- /dev/null
+++ b/drivers/bus/mhi/core/mhi_dtr.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mhi_internal.h"
+
+struct __packed dtr_ctrl_msg {
+   u32 preamble;
+   u32 msg_id;
+   u32 dest_id;
+   u32 size;
+   u32 msg;
+};
+
+#define CTRL_MAGIC (0x4C525443)
+#define CTRL_MSG_DTR BIT(0)
+#define CTRL_MSG_RTS BIT(1)
+#define CTRL_MSG_DCD BIT(0)
+#define CTRL_MSG_DSR BIT(1)
+#define CTRL_MSG_RI BIT(3)
+#define CTRL_HOST_STATE (0x10)
+#define CTRL_DEVICE_STATE (0x11)
+#define CTRL_GET_CHID(dtr) (dtr->dest_id & 0xFF)
+
+static int mhi_dtr_tiocmset(struct mhi_controller *mhi_cntrl,
+   struct mhi_device *mhi_dev,
+   u32 tiocm)
+{
+   struct dtr_ctrl_msg *dtr_msg = NULL;
+   struct mhi_chan *dtr_chan = mhi_cntrl->dtr_dev->ul_chan;
+   spinlock_t *res_lock = _dev->dev.devres_lock;
+   u32 cur_tiocm;
+   int ret = 0;
+
+   cur_tiocm = mhi_dev->tiocm & ~(TIOCM_CD | TIOCM_DSR | TIOCM_RI);
+
+   tiocm &= (TIOCM_DTR | TIOCM_RTS);
+
+   /* state did not changed */
+   if (cur_tiocm == tiocm)
+   return 0;
+
+   mutex_lock(_chan->mutex);
+
+   dtr_msg = kzalloc(sizeof(*dtr_msg), GFP_KERNEL);
+   if (!dtr_msg) {
+   ret = -ENOMEM;
+   goto tiocm_exit;
+   }
+
+   dtr_msg->preamble = CTRL_MAGIC;
+   dtr_msg->msg_id = CTRL_HOST_STATE;
+   dtr_msg->dest_id = mhi_dev->ul_chan_id;
+   dtr_msg->size = sizeof(u32);
+   if (tiocm & TIOCM_DTR)
+   dtr_msg->msg |= CTRL_MSG_DTR;
+   if (tiocm & TIOCM_RTS)
+   dtr_msg->msg |= CTRL_MSG_RTS;
+
+   reinit_completion(_chan->completion);
+   ret = mhi_queue_transfer(mhi_cntrl->dtr_dev, DMA_TO_DEVICE, dtr_msg,
+sizeof(*dtr_msg), MHI_EOT);
+   if (ret)
+   goto tiocm_exit;
+
+   ret = wait_for_completion_timeout(_chan->completion,
+   msecs_to_jiffies(mhi_cntrl->timeout_ms));
+   if (!ret) {
+   dev_err(mhi_cntrl->dev, "Failed to recv transfer callback\n");
+   ret = -EIO;
+   goto tiocm_exit;
+   }
+
+   ret = 0;
+   spin_lock_irq(res_lock);
+   mhi_dev->tiocm &= ~(TIOCM_DTR | TIOCM_RTS);
+   mhi_dev->tiocm |= tiocm;
+   spin_unlock_irq(res_lock);
+
+tiocm_exit:
+   kfree(dtr_msg);
+   mutex_unlock(_chan->mutex);
+
+   return ret;
+}
+
+long mhi_ioctl(struct mhi_device *mhi_dev, unsigned int cmd, unsigned long arg)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   int ret;
+
+   /* ioctl not supported by this controller */
+   if (!mhi_cntrl->dtr_dev)
+   return -EIO;
+
+   switch (cmd) {
+   case TIOCMGET:
+   return mhi_dev->tiocm;
+   case TIOCMSET:
+   {
+   u32 tiocm;
+
+   ret = get_user(tiocm, (u32 *)arg);
+   if (ret)
+   return ret;
+
+   return mhi_dtr_tiocmset(mhi_cntrl, mhi_dev, tiocm);
+   }
+   default:
+   break;
+   }
+
+   return -EINVAL;
+}
+EXPORT_SYMBOL(mhi_ioctl);
+
+static void mhi_dtr_dl_xfer_cb(struct mhi_device *mhi_dev,
+  struct mhi_result *mhi_result)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   struct dtr_ctrl_msg *dtr_msg = mhi_result->buf_addr;
+   u32 chan;
+   spinlock_t *res_lock;
+
+   if (mhi_result->bytes_xferd != sizeof(*dtr_msg)) {
+   dev_err(mhi_cntrl->dev, "Unexpected length %zu received\n",
+  

[PATCH v2 4/7] mhi_bus: core: add support for handling ioctl cmds

2018-07-09 Thread Sujeev Dias
User space clients use RS232 control signaling mechanism to
communicate call status between host and modem. Adding support
to handle ioctl commands from user space.

Signed-off-by: Sujeev Dias 
Reviewed-by: Tony Truong 
Signed-off-by: Siddartha Mohanadoss 
---
 drivers/bus/mhi/core/Makefile   |   2 +-
 drivers/bus/mhi/core/mhi_dtr.c  | 218 
 drivers/bus/mhi/core/mhi_init.c |   8 +-
 3 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 drivers/bus/mhi/core/mhi_dtr.c

diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/core/Makefile
index a6015ab..a743fbf 100644
--- a/drivers/bus/mhi/core/Makefile
+++ b/drivers/bus/mhi/core/Makefile
@@ -1 +1 @@
-obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o
+obj-$(CONFIG_MHI_BUS) +=mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o mhi_dtr.o
diff --git a/drivers/bus/mhi/core/mhi_dtr.c b/drivers/bus/mhi/core/mhi_dtr.c
new file mode 100644
index 000..5c2409b
--- /dev/null
+++ b/drivers/bus/mhi/core/mhi_dtr.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "mhi_internal.h"
+
+struct __packed dtr_ctrl_msg {
+   u32 preamble;
+   u32 msg_id;
+   u32 dest_id;
+   u32 size;
+   u32 msg;
+};
+
+#define CTRL_MAGIC (0x4C525443)
+#define CTRL_MSG_DTR BIT(0)
+#define CTRL_MSG_RTS BIT(1)
+#define CTRL_MSG_DCD BIT(0)
+#define CTRL_MSG_DSR BIT(1)
+#define CTRL_MSG_RI BIT(3)
+#define CTRL_HOST_STATE (0x10)
+#define CTRL_DEVICE_STATE (0x11)
+#define CTRL_GET_CHID(dtr) (dtr->dest_id & 0xFF)
+
+static int mhi_dtr_tiocmset(struct mhi_controller *mhi_cntrl,
+   struct mhi_device *mhi_dev,
+   u32 tiocm)
+{
+   struct dtr_ctrl_msg *dtr_msg = NULL;
+   struct mhi_chan *dtr_chan = mhi_cntrl->dtr_dev->ul_chan;
+   spinlock_t *res_lock = _dev->dev.devres_lock;
+   u32 cur_tiocm;
+   int ret = 0;
+
+   cur_tiocm = mhi_dev->tiocm & ~(TIOCM_CD | TIOCM_DSR | TIOCM_RI);
+
+   tiocm &= (TIOCM_DTR | TIOCM_RTS);
+
+   /* state did not changed */
+   if (cur_tiocm == tiocm)
+   return 0;
+
+   mutex_lock(_chan->mutex);
+
+   dtr_msg = kzalloc(sizeof(*dtr_msg), GFP_KERNEL);
+   if (!dtr_msg) {
+   ret = -ENOMEM;
+   goto tiocm_exit;
+   }
+
+   dtr_msg->preamble = CTRL_MAGIC;
+   dtr_msg->msg_id = CTRL_HOST_STATE;
+   dtr_msg->dest_id = mhi_dev->ul_chan_id;
+   dtr_msg->size = sizeof(u32);
+   if (tiocm & TIOCM_DTR)
+   dtr_msg->msg |= CTRL_MSG_DTR;
+   if (tiocm & TIOCM_RTS)
+   dtr_msg->msg |= CTRL_MSG_RTS;
+
+   reinit_completion(_chan->completion);
+   ret = mhi_queue_transfer(mhi_cntrl->dtr_dev, DMA_TO_DEVICE, dtr_msg,
+sizeof(*dtr_msg), MHI_EOT);
+   if (ret)
+   goto tiocm_exit;
+
+   ret = wait_for_completion_timeout(_chan->completion,
+   msecs_to_jiffies(mhi_cntrl->timeout_ms));
+   if (!ret) {
+   dev_err(mhi_cntrl->dev, "Failed to recv transfer callback\n");
+   ret = -EIO;
+   goto tiocm_exit;
+   }
+
+   ret = 0;
+   spin_lock_irq(res_lock);
+   mhi_dev->tiocm &= ~(TIOCM_DTR | TIOCM_RTS);
+   mhi_dev->tiocm |= tiocm;
+   spin_unlock_irq(res_lock);
+
+tiocm_exit:
+   kfree(dtr_msg);
+   mutex_unlock(_chan->mutex);
+
+   return ret;
+}
+
+long mhi_ioctl(struct mhi_device *mhi_dev, unsigned int cmd, unsigned long arg)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   int ret;
+
+   /* ioctl not supported by this controller */
+   if (!mhi_cntrl->dtr_dev)
+   return -EIO;
+
+   switch (cmd) {
+   case TIOCMGET:
+   return mhi_dev->tiocm;
+   case TIOCMSET:
+   {
+   u32 tiocm;
+
+   ret = get_user(tiocm, (u32 *)arg);
+   if (ret)
+   return ret;
+
+   return mhi_dtr_tiocmset(mhi_cntrl, mhi_dev, tiocm);
+   }
+   default:
+   break;
+   }
+
+   return -EINVAL;
+}
+EXPORT_SYMBOL(mhi_ioctl);
+
+static void mhi_dtr_dl_xfer_cb(struct mhi_device *mhi_dev,
+  struct mhi_result *mhi_result)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   struct dtr_ctrl_msg *dtr_msg = mhi_result->buf_addr;
+   u32 chan;
+   spinlock_t *res_lock;
+
+   if (mhi_result->bytes_xferd != sizeof(*dtr_msg)) {
+   dev_err(mhi_cntrl->dev, "Unexpected length %zu received\n",
+  

Re: [PATCH v1 1/4] mhi_bus: core: Add support for MHI host interface

2018-05-03 Thread Sujeev Dias

Hi Pavel


On 05/03/2018 12:21 PM, Pavel Machek wrote:

Hi!


MHI Host Interface is a communication protocol to be used by the host
to control and communcate with modem over a high speed peripheral bus.
This module will allow host to communicate with external devices that
support MHI protocol.

I have Motorola Droid 4 cellphone here, with Qualcomm GSM modem. But
it talks over serial line and USB. I guess MHI is not applicable to my
hardware?

MHI is for PCIe based modem, in any case I can't comment about 
commercial devices.

+MHI Devices
+---
+Logical device that bind to maximum of two physical MHI channels. Once MHI is 
in
+powered on state, each supported channel by controller will be allocated as a
+mhi_device.

What kind of protocol is running over MHI? I guess its not AT
commands. QMI? Or something entirely different?

All modem services between external modem and host go over MHI.
So QMI, AT, all other data and control services go thru MHI host driver.

Pavel


Thanks
Sujeev

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 1/4] mhi_bus: core: Add support for MHI host interface

2018-05-03 Thread Sujeev Dias

Hi Pavel


On 05/03/2018 12:21 PM, Pavel Machek wrote:

Hi!


MHI Host Interface is a communication protocol to be used by the host
to control and communcate with modem over a high speed peripheral bus.
This module will allow host to communicate with external devices that
support MHI protocol.

I have Motorola Droid 4 cellphone here, with Qualcomm GSM modem. But
it talks over serial line and USB. I guess MHI is not applicable to my
hardware?

MHI is for PCIe based modem, in any case I can't comment about 
commercial devices.

+MHI Devices
+---
+Logical device that bind to maximum of two physical MHI channels. Once MHI is 
in
+powered on state, each supported channel by controller will be allocated as a
+mhi_device.

What kind of protocol is running over MHI? I guess its not AT
commands. QMI? Or something entirely different?

All modem services between external modem and host go over MHI.
So QMI, AT, all other data and control services go thru MHI host driver.

Pavel


Thanks
Sujeev

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 1/4] mhi_bus: core: Add support for MHI host interface

2018-04-28 Thread Sujeev Dias



On 04/27/2018 05:18 AM, Arnd Bergmann wrote:

On Fri, Apr 27, 2018 at 4:23 AM, Sujeev Dias <sd...@codeaurora.org> wrote:


diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
new file mode 100644
index 000..ea1b620
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -0,0 +1,141 @@
+MHI Host Interface
+
+MHI used by the host to control and communicate with modem over
+high speed peripheral bus.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- mhi,max-channels
+  Usage: required
+  Value type: 
+  Definition: Maximum number of channels supported by this controller
+
+- mhi,chan-cfg
+  Usage: required
+  Value type: Array of 
+  Definition: Array of tuples describe channel configuration.
+   1st element: Physical channel number
+   2nd element: Transfer ring length in elements
+   3rd element: Event ring associated with this channel
+   4th element: Channel direction as defined by enum dma_data_direction
+   1 = UL data transfer
+   2 = DL data transfer
+   5th element: Channel doorbell mode configuration as defined by
+   enum MHI_BRSTMODE
+   2 = burst mode disabled
+   3 = burst mode enabled
+   6th element: mhi doorbell configuration, valid only when burst mode
+   enabled.
+   0 = Use default (device specific) polling configuration
+   For UL channels, value specifies the timer to poll MHI context
+   in milliseconds.
+   For DL channels, the threshold to poll the MHI context
+   in multiple of eight ring element.
+   7th element: Channel execution enviornment as defined by enum MHI_EE
+   1 = Bootloader stage
+   2 = AMSS mode
+   8th element: data transfer type accepted as defined by enum
+   MHI_XFER_TYPE
+   0 = accept cpu address for buffer
+   1 = accept skb
+   2 = accept scatterlist
+   3 = offload channel, does not accept any transfer type
+   9th element: Bitwise configuration settings for the channel
+   Bit mask:
+   BIT(0) : LPM notify, this channel master requre lpm enter/exit
+   notifications.
+   BIT(1) : Offload channel, MHI host only involved in setting up
+   the data pipe. Not involved in active data transfer.
+   BIT(2) : Must switch to doorbell mode whenever MHI M0 state
+   transition happens.
+   BIT(3) : MHI bus driver pre-allocate buffer for this channel.
+   If set, clients not allowed to queue buffers. Valid only for DL
+   direction.
+
+- mhi,chan-names
+  Usage: required
+  Value type: Array of 
+  Definition: Channel names configured in mhi,chan-cfg.

I think the top-level structure would be better done by requiring
a child for each channel and moving the mhi,chan-cfg
into the children nodes, either as separate properties, or
some of the fields combined into a 'reg' property.


+- mhi,fw-name
+  Usage: optional
+  Value type: 
+  Definition: Firmware image name to upload

The device tree should have no knowledge of a firmware file name.

What you should do instead is to have the driver generate the file
name from the "compatible" property. You could use a lookup table
in the driver, or have some algorithmic way of doing that, but you
want the driver to have some form of intelligence to let it pick
a different firmware image, e.g. when you have added new
capabilities to the driver and the firmware but want to use an
existing device tree.


+Data structures
+---
+Host memory : Directly accessed by the host to manage the MHI data structures
+and buffers. The device accesses the host memory over the PCIe interface.
+
+Channel context array : All channel configurations are organized in channel
+context data array.
+
+struct __packed mhi_chan_ctxt;
+struct mhi_ctxt.chan_ctxt;
+
+Transfer rings : Used by host to schedule work items for a channel and 
organized
+as a circular queue of transfer descriptors (TD).
+
+struct __packed mhi_tre;
+struct mhi_chan.tre_ring;
+

This looks like you reinvented virtio. What are the reasons for not just
using virtio directly as we do for other modem interfaces?


+static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl,
+  void *buf,
+  size_t size)
+{
+   u32 tx_status, val;
+   int i, ret;
+   void __iomem *base = mhi_cntrl->bhi;
+   rwlock_t *pm_lock = _cntrl->pm_lock;
+   dma_addr_t phys = dma_map_single(mhi_cntrl->dev, buf, size,
+DMA_TO_DEVICE);

Please don't name a dma address 'phys', it's very confusing ;-)


+struct mhi_bus mhi_bus;

One global instance? I suspec this duplicates data that is already
in the bus_type structure, so just 

Re: [PATCH v1 1/4] mhi_bus: core: Add support for MHI host interface

2018-04-28 Thread Sujeev Dias



On 04/27/2018 05:18 AM, Arnd Bergmann wrote:

On Fri, Apr 27, 2018 at 4:23 AM, Sujeev Dias  wrote:


diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
new file mode 100644
index 000..ea1b620
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -0,0 +1,141 @@
+MHI Host Interface
+
+MHI used by the host to control and communicate with modem over
+high speed peripheral bus.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- mhi,max-channels
+  Usage: required
+  Value type: 
+  Definition: Maximum number of channels supported by this controller
+
+- mhi,chan-cfg
+  Usage: required
+  Value type: Array of 
+  Definition: Array of tuples describe channel configuration.
+   1st element: Physical channel number
+   2nd element: Transfer ring length in elements
+   3rd element: Event ring associated with this channel
+   4th element: Channel direction as defined by enum dma_data_direction
+   1 = UL data transfer
+   2 = DL data transfer
+   5th element: Channel doorbell mode configuration as defined by
+   enum MHI_BRSTMODE
+   2 = burst mode disabled
+   3 = burst mode enabled
+   6th element: mhi doorbell configuration, valid only when burst mode
+   enabled.
+   0 = Use default (device specific) polling configuration
+   For UL channels, value specifies the timer to poll MHI context
+   in milliseconds.
+   For DL channels, the threshold to poll the MHI context
+   in multiple of eight ring element.
+   7th element: Channel execution enviornment as defined by enum MHI_EE
+   1 = Bootloader stage
+   2 = AMSS mode
+   8th element: data transfer type accepted as defined by enum
+   MHI_XFER_TYPE
+   0 = accept cpu address for buffer
+   1 = accept skb
+   2 = accept scatterlist
+   3 = offload channel, does not accept any transfer type
+   9th element: Bitwise configuration settings for the channel
+   Bit mask:
+   BIT(0) : LPM notify, this channel master requre lpm enter/exit
+   notifications.
+   BIT(1) : Offload channel, MHI host only involved in setting up
+   the data pipe. Not involved in active data transfer.
+   BIT(2) : Must switch to doorbell mode whenever MHI M0 state
+   transition happens.
+   BIT(3) : MHI bus driver pre-allocate buffer for this channel.
+   If set, clients not allowed to queue buffers. Valid only for DL
+   direction.
+
+- mhi,chan-names
+  Usage: required
+  Value type: Array of 
+  Definition: Channel names configured in mhi,chan-cfg.

I think the top-level structure would be better done by requiring
a child for each channel and moving the mhi,chan-cfg
into the children nodes, either as separate properties, or
some of the fields combined into a 'reg' property.


+- mhi,fw-name
+  Usage: optional
+  Value type: 
+  Definition: Firmware image name to upload

The device tree should have no knowledge of a firmware file name.

What you should do instead is to have the driver generate the file
name from the "compatible" property. You could use a lookup table
in the driver, or have some algorithmic way of doing that, but you
want the driver to have some form of intelligence to let it pick
a different firmware image, e.g. when you have added new
capabilities to the driver and the firmware but want to use an
existing device tree.


+Data structures
+---
+Host memory : Directly accessed by the host to manage the MHI data structures
+and buffers. The device accesses the host memory over the PCIe interface.
+
+Channel context array : All channel configurations are organized in channel
+context data array.
+
+struct __packed mhi_chan_ctxt;
+struct mhi_ctxt.chan_ctxt;
+
+Transfer rings : Used by host to schedule work items for a channel and 
organized
+as a circular queue of transfer descriptors (TD).
+
+struct __packed mhi_tre;
+struct mhi_chan.tre_ring;
+

This looks like you reinvented virtio. What are the reasons for not just
using virtio directly as we do for other modem interfaces?


+static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl,
+  void *buf,
+  size_t size)
+{
+   u32 tx_status, val;
+   int i, ret;
+   void __iomem *base = mhi_cntrl->bhi;
+   rwlock_t *pm_lock = _cntrl->pm_lock;
+   dma_addr_t phys = dma_map_single(mhi_cntrl->dev, buf, size,
+DMA_TO_DEVICE);

Please don't name a dma address 'phys', it's very confusing ;-)


+struct mhi_bus mhi_bus;

One global instance? I suspec this duplicates data that is already
in the bus_type structure, so just use that instead.


+void mhi_

Re: [PATCH v1 2/4] mhi_bus: controller: MHI support for QCOM modems

2018-04-28 Thread Sujeev Dias



On 04/27/2018 04:32 AM, Arnd Bergmann wrote:

On Fri, Apr 27, 2018 at 4:23 AM, Sujeev Dias <sd...@codeaurora.org> wrote:

QCOM PCIe based modems uses MHI as the communication protocol.
MHI control driver is the bus master for such modems. As the bus
master driver, it oversees power management operations
such as suspend, resume, powering on and off the device.

+- compatible
+  Usage: required
+  Value type: 
+  Definition: "qcom,mhi"
+
+- qcom,pci-dev-id
+  Usage: optional
+  Value type: 
+  Definition: PCIe device id of external modem to bind. If not set, any
+   device is compatible with this node.
+
+- qcom,pci-domain
+  Usage: required
+  Value type: 
+  Definition: PCIe root complex external modem connected to
+
+- qcom,pci-bus
+  Usage: required
+  Value type: 
+  Definition: PCIe bus external modem connected to
+
+- qcom,pci-slot
+  Usage: required
+  Value type: 
+  Definition: PCIe slot as assigned by pci framework to external modem

These don't seem to make any sense: You seem to have access to
a regular pci_device already, so why do you need to duplicate the
information about it in DT?

I will remove the platform device, original hardware design we had a 
complicated power on
sequence that require platform device to come up first and follow a 
strict power on sequence to power on modem
before pci device can enumerate.  I stored the BDF in DT to correlate 
the platform device with pci device. platform device

is no longer needed so I can remove it.

+- qcom,smmu-cfg
+  Usage: required
+  Value type: 
+  Definition: Required SMMU configuration bitmask for PCIe bus.
+   BIT mask:
+   BIT(0) : Attach address mapping to endpoint device
+   BIT(1) : Set attribute S1_BYPASS
+   BIT(2) : Set attribute FAST
+   BIT(3) : Set attribute ATOMIC
+   BIT(4) : Set attribute FORCE_COHERENT
+
+- qcom,addr-win
+  Usage: required if SMMU S1 translation is enabled
+  Value type: Array of 
+  Definition: Pair of values describing iova start and stop address

Why do you need these? Can't that be handled by the PCI
layer?
I will move this to end point DT.  PCIe end point driver does the iommu 
configuration

+- qcom,msm-bus,name
+  Usage: required
+  Value type: 
+  Definition: string representing the bus scale client name to register

This probably belongs into a separate binding for the bus
scale driver, right?
Yes, this is for qcom bus scale driver which I don't think is upstreamed 
yet. Will confirm.

+static struct pci_driver mhi_pcie_driver;

Please try to reorder the symbols to avoid forward declarations.


+static int mhi_platform_probe(struct platform_device *pdev)
+{
+   struct mhi_controller *mhi_cntrl;
+   struct mhi_dev *mhi_dev;
+   struct device_node *of_node = pdev->dev.of_node;
+   u64 addr_win[2];
+   int ret;
+
+   if (!of_node)
+   return -ENODEV;
+
+   mhi_cntrl = mhi_alloc_controller(sizeof(*mhi_dev));
+   if (!mhi_cntrl)
+   return -ENOMEM;
+
+   mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
+
+   /* get pci bus topology for this node */
+   ret = of_property_read_u32(of_node, "qcom,pci-dev-id",
+  _cntrl->dev_id);
+   if (ret)
+   mhi_cntrl->dev_id = PCI_ANY_ID;
+
+   ret = of_property_read_u32(of_node, "qcom,pci-domain",
+  _cntrl->domain);
+   if (ret)
+   goto error_probe;
+
+   ret = of_property_read_u32(of_node, "qcom,pci-bus", _cntrl->bus);
+   if (ret)
+   goto error_probe;
+
+   ret = of_property_read_u32(of_node, "qcom,pci-slot", _cntrl->slot);
+   if (ret)
+   goto error_probe;

Please explain what you are trying to do here, why do you register
two device drivers? It looks like they both refer to the same
hardware, so why isn't it sufficient to have the pci_driver?
As I explained earlier, it's now. Original hardware design we had 
chicken egg situation where
some driver has to come up and power on device before pcie enumeration 
can take place.




Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Thanks again
Sujeev

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 2/4] mhi_bus: controller: MHI support for QCOM modems

2018-04-28 Thread Sujeev Dias



On 04/27/2018 04:32 AM, Arnd Bergmann wrote:

On Fri, Apr 27, 2018 at 4:23 AM, Sujeev Dias  wrote:

QCOM PCIe based modems uses MHI as the communication protocol.
MHI control driver is the bus master for such modems. As the bus
master driver, it oversees power management operations
such as suspend, resume, powering on and off the device.

+- compatible
+  Usage: required
+  Value type: 
+  Definition: "qcom,mhi"
+
+- qcom,pci-dev-id
+  Usage: optional
+  Value type: 
+  Definition: PCIe device id of external modem to bind. If not set, any
+   device is compatible with this node.
+
+- qcom,pci-domain
+  Usage: required
+  Value type: 
+  Definition: PCIe root complex external modem connected to
+
+- qcom,pci-bus
+  Usage: required
+  Value type: 
+  Definition: PCIe bus external modem connected to
+
+- qcom,pci-slot
+  Usage: required
+  Value type: 
+  Definition: PCIe slot as assigned by pci framework to external modem

These don't seem to make any sense: You seem to have access to
a regular pci_device already, so why do you need to duplicate the
information about it in DT?

I will remove the platform device, original hardware design we had a 
complicated power on
sequence that require platform device to come up first and follow a 
strict power on sequence to power on modem
before pci device can enumerate.  I stored the BDF in DT to correlate 
the platform device with pci device. platform device

is no longer needed so I can remove it.

+- qcom,smmu-cfg
+  Usage: required
+  Value type: 
+  Definition: Required SMMU configuration bitmask for PCIe bus.
+   BIT mask:
+   BIT(0) : Attach address mapping to endpoint device
+   BIT(1) : Set attribute S1_BYPASS
+   BIT(2) : Set attribute FAST
+   BIT(3) : Set attribute ATOMIC
+   BIT(4) : Set attribute FORCE_COHERENT
+
+- qcom,addr-win
+  Usage: required if SMMU S1 translation is enabled
+  Value type: Array of 
+  Definition: Pair of values describing iova start and stop address

Why do you need these? Can't that be handled by the PCI
layer?
I will move this to end point DT.  PCIe end point driver does the iommu 
configuration

+- qcom,msm-bus,name
+  Usage: required
+  Value type: 
+  Definition: string representing the bus scale client name to register

This probably belongs into a separate binding for the bus
scale driver, right?
Yes, this is for qcom bus scale driver which I don't think is upstreamed 
yet. Will confirm.

+static struct pci_driver mhi_pcie_driver;

Please try to reorder the symbols to avoid forward declarations.


+static int mhi_platform_probe(struct platform_device *pdev)
+{
+   struct mhi_controller *mhi_cntrl;
+   struct mhi_dev *mhi_dev;
+   struct device_node *of_node = pdev->dev.of_node;
+   u64 addr_win[2];
+   int ret;
+
+   if (!of_node)
+   return -ENODEV;
+
+   mhi_cntrl = mhi_alloc_controller(sizeof(*mhi_dev));
+   if (!mhi_cntrl)
+   return -ENOMEM;
+
+   mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
+
+   /* get pci bus topology for this node */
+   ret = of_property_read_u32(of_node, "qcom,pci-dev-id",
+  _cntrl->dev_id);
+   if (ret)
+   mhi_cntrl->dev_id = PCI_ANY_ID;
+
+   ret = of_property_read_u32(of_node, "qcom,pci-domain",
+  _cntrl->domain);
+   if (ret)
+   goto error_probe;
+
+   ret = of_property_read_u32(of_node, "qcom,pci-bus", _cntrl->bus);
+   if (ret)
+   goto error_probe;
+
+   ret = of_property_read_u32(of_node, "qcom,pci-slot", _cntrl->slot);
+   if (ret)
+   goto error_probe;

Please explain what you are trying to do here, why do you register
two device drivers? It looks like they both refer to the same
hardware, so why isn't it sufficient to have the pci_driver?
As I explained earlier, it's now. Original hardware design we had 
chicken egg situation where
some driver has to come up and power on device before pcie enumeration 
can take place.




Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Thanks again
Sujeev

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 3/4] mhi_bus: dev: netdev: add network interface driver

2018-04-28 Thread Sujeev Dias



On 04/27/2018 04:19 AM, Arnd Bergmann wrote:

On Fri, Apr 27, 2018 at 4:23 AM, Sujeev Dias <sd...@codeaurora.org> wrote:

MHI based net device driver is used for transferring IP
traffic between host and modem. Driver allows clients to
transfer data using standard network interface.

Signed-off-by: Sujeev Dias <sd...@codeaurora.org>
---
  Documentation/devicetree/bindings/bus/mhi.txt |  36 ++
  drivers/bus/Kconfig   |   1 +
  drivers/bus/mhi/Makefile  |   2 +-
  drivers/bus/mhi/devices/Kconfig   |  10 +
  drivers/bus/mhi/devices/Makefile  |   1 +
  drivers/bus/mhi/devices/mhi_netdev.c  | 893 ++

Network drivers go into drivers/net/, not into the bus subsystem.
You also need to Cc the netdev mailing list for review.

will do, thanks.

  6 files changed, 942 insertions(+), 1 deletion(-)
  create mode 100644 drivers/bus/mhi/devices/Kconfig
  create mode 100644 drivers/bus/mhi/devices/Makefile
  create mode 100644 drivers/bus/mhi/devices/mhi_netdev.c

diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
index ea1b620..172ae7b 100644
--- a/Documentation/devicetree/bindings/bus/mhi.txt
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -139,3 +139,39 @@ mhi_controller {
 
 };
  };
+
+
+Children Devices
+
+
+MHI netdev properties
+
+- mhi,chan
+  Usage: required
+  Value type: 
+  Definition: Channel name MHI netdev support

+- mhi,mru
+  Usage: required
+  Value type: 
+  Definition: Largest packet size interface can receive in bytes.
+
+- mhi,interface-name
+  Usage: optional
+  Value type: 
+  Definition: Interface name to be given so clients can identify it
+
+- mhi,recycle-buf
+  Usage: optional
+  Value type: 
+  Definition: Set true if interface support recycling buffers.



+
+Example:
+
+
+mhi_rmnet@0 {
+   mhi,chan = "IP_HW0";
+   mhi,interface-name = "rmnet_mhi";
+   mhi,mru = <0x4000>;
+};

Who defines the "IP_HW0" and "rmnet_mhi" strings?

Shouldn't there be a "compatible" property?

IP_HW0 is the a dedicated channel for IP traffic.  It's defined  by MHI 
specification.  Supported channel names are fixed and
dedicated per device. Interface name is a network iface name given so 
clients can identify the netdevice under /net/.


Similar how pci framework bind DT based on bdf with pci end point 
driver, MHI bus uses mhi,chan property to bind children

DT node before calling probe.
mhi_main.c/mhi_create_device()

mhi_main.c/mhi_create_device()
 /* add if there is a matching DT node */
controller = mhi_cntrl->of_node;
 for_each_available_child_of_node(controller, node) {
 ret = of_property_read_string(node, "mhi,chan",
   _name);
 if (ret)
 continue;
 if (!strcmp(mhi_dev->chan_name, dt_name))
  mhi_dev->dev.of_node = node;

+#define MHI_NETDEV_DRIVER_NAME "mhi_netdev"
+#define WATCHDOG_TIMEOUT (30 * HZ)
+
+#ifdef CONFIG_MHI_DEBUG
+
+#define MHI_ASSERT(cond, msg) do { \
+   if (cond) \
+   panic(msg); \
+} while (0)
+
+#define MSG_VERB(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_err("[D][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MSG_LOG(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_INFO) \
+   pr_err("[I][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MSG_ERR(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS__); \
+} while (0)
+

Please remove these macros and use the normal kernel
helpers we have.

Will do on next patch set.

+struct mhi_stats {
+   u32 rx_int;
+   u32 tx_full;
+   u32 tx_pkts;
+   u32 rx_budget_overflow;
+   u32 rx_frag;
+   u32 alloc_failed;
+};
+
+/* important: do not exceed sk_buf->cb (48 bytes) */
+struct mhi_skb_priv {
+   void *buf;
+   size_t size;
+   struct mhi_netdev *mhi_netdev;
+};

Shouldn't all three members already be part of an skb?

You initialize them as


+   u32 cur_mru = mhi_netdev->mru;
+   skb_priv = (struct mhi_skb_priv *)skb->cb;
+   skb_priv->buf = skb->data;
+   skb_priv->size = cur_mru;
+   skb_priv->mhi_netdev = mhi_netdev;

so I think you can remove the structure completely.

Will confirm and remove it if it's not needed.

+struct mhi_netdev {
+   int alias;
+   struct mhi_device *mhi_dev;
+   spinlock_t rx_lock;
+   bool enabled;
+   rwlock_t pm_lock; /* state change lock */
+   int (*rx_queue)(struct mhi_netdev *mhi_netdev, gfp_t gfp_t);
+   struct work_struct alloc_work

Re: [PATCH v1 3/4] mhi_bus: dev: netdev: add network interface driver

2018-04-28 Thread Sujeev Dias



On 04/27/2018 04:19 AM, Arnd Bergmann wrote:

On Fri, Apr 27, 2018 at 4:23 AM, Sujeev Dias  wrote:

MHI based net device driver is used for transferring IP
traffic between host and modem. Driver allows clients to
transfer data using standard network interface.

Signed-off-by: Sujeev Dias 
---
  Documentation/devicetree/bindings/bus/mhi.txt |  36 ++
  drivers/bus/Kconfig   |   1 +
  drivers/bus/mhi/Makefile  |   2 +-
  drivers/bus/mhi/devices/Kconfig   |  10 +
  drivers/bus/mhi/devices/Makefile  |   1 +
  drivers/bus/mhi/devices/mhi_netdev.c  | 893 ++

Network drivers go into drivers/net/, not into the bus subsystem.
You also need to Cc the netdev mailing list for review.

will do, thanks.

  6 files changed, 942 insertions(+), 1 deletion(-)
  create mode 100644 drivers/bus/mhi/devices/Kconfig
  create mode 100644 drivers/bus/mhi/devices/Makefile
  create mode 100644 drivers/bus/mhi/devices/mhi_netdev.c

diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
index ea1b620..172ae7b 100644
--- a/Documentation/devicetree/bindings/bus/mhi.txt
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -139,3 +139,39 @@ mhi_controller {
 
 };
  };
+
+
+Children Devices
+
+
+MHI netdev properties
+
+- mhi,chan
+  Usage: required
+  Value type: 
+  Definition: Channel name MHI netdev support

+- mhi,mru
+  Usage: required
+  Value type: 
+  Definition: Largest packet size interface can receive in bytes.
+
+- mhi,interface-name
+  Usage: optional
+  Value type: 
+  Definition: Interface name to be given so clients can identify it
+
+- mhi,recycle-buf
+  Usage: optional
+  Value type: 
+  Definition: Set true if interface support recycling buffers.



+
+Example:
+
+
+mhi_rmnet@0 {
+   mhi,chan = "IP_HW0";
+   mhi,interface-name = "rmnet_mhi";
+   mhi,mru = <0x4000>;
+};

Who defines the "IP_HW0" and "rmnet_mhi" strings?

Shouldn't there be a "compatible" property?

IP_HW0 is the a dedicated channel for IP traffic.  It's defined  by MHI 
specification.  Supported channel names are fixed and
dedicated per device. Interface name is a network iface name given so 
clients can identify the netdevice under /net/.


Similar how pci framework bind DT based on bdf with pci end point 
driver, MHI bus uses mhi,chan property to bind children

DT node before calling probe.
mhi_main.c/mhi_create_device()

mhi_main.c/mhi_create_device()
 /* add if there is a matching DT node */
controller = mhi_cntrl->of_node;
 for_each_available_child_of_node(controller, node) {
 ret = of_property_read_string(node, "mhi,chan",
   _name);
 if (ret)
 continue;
 if (!strcmp(mhi_dev->chan_name, dt_name))
  mhi_dev->dev.of_node = node;

+#define MHI_NETDEV_DRIVER_NAME "mhi_netdev"
+#define WATCHDOG_TIMEOUT (30 * HZ)
+
+#ifdef CONFIG_MHI_DEBUG
+
+#define MHI_ASSERT(cond, msg) do { \
+   if (cond) \
+   panic(msg); \
+} while (0)
+
+#define MSG_VERB(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_err("[D][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MSG_LOG(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_INFO) \
+   pr_err("[I][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MSG_ERR(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS__); \
+} while (0)
+

Please remove these macros and use the normal kernel
helpers we have.

Will do on next patch set.

+struct mhi_stats {
+   u32 rx_int;
+   u32 tx_full;
+   u32 tx_pkts;
+   u32 rx_budget_overflow;
+   u32 rx_frag;
+   u32 alloc_failed;
+};
+
+/* important: do not exceed sk_buf->cb (48 bytes) */
+struct mhi_skb_priv {
+   void *buf;
+   size_t size;
+   struct mhi_netdev *mhi_netdev;
+};

Shouldn't all three members already be part of an skb?

You initialize them as


+   u32 cur_mru = mhi_netdev->mru;
+   skb_priv = (struct mhi_skb_priv *)skb->cb;
+   skb_priv->buf = skb->data;
+   skb_priv->size = cur_mru;
+   skb_priv->mhi_netdev = mhi_netdev;

so I think you can remove the structure completely.

Will confirm and remove it if it's not needed.

+struct mhi_netdev {
+   int alias;
+   struct mhi_device *mhi_dev;
+   spinlock_t rx_lock;
+   bool enabled;
+   rwlock_t pm_lock; /* state change lock */
+   int (*rx_queue)(struct mhi_netdev *mhi_netdev, gfp_t gfp_t);
+   struct work_struct alloc_work;
+   int wake;
+
+   struct sk_buff_head rx_allocated;

Re: [PATCH v1 1/4] mhi_bus: core: Add support for MHI host interface

2018-04-28 Thread Sujeev Dias

Thanks for quick feedback


On 04/27/2018 12:22 AM, Greg Kroah-Hartman wrote:

On Thu, Apr 26, 2018 at 07:23:28PM -0700, Sujeev Dias wrote:

MHI Host Interface is a communication protocol to be used by the host
to control and communcate with modem over a high speed peripheral bus.
This module will allow host to communicate with external devices that
support MHI protocol.

Signed-off-by: Sujeev Dias <sd...@codeaurora.org>

No one else has ever reviewed this code before?  That's not good, please
at the very least, have someone else at your company go over it first.
I don't want to be the ones having to point out all of the "obvious"
issues :)

This code has gone thru rigorous code review and testing, before I 
submit next patch

I will have multiple people sign off on it.

---
  Documentation/00-INDEX|2 +
  Documentation/devicetree/bindings/bus/mhi.txt |  141 +++
  Documentation/mhi.txt |  235 
  drivers/bus/Kconfig   |   17 +
  drivers/bus/Makefile  |1 +
  drivers/bus/mhi/Makefile  |8 +
  drivers/bus/mhi/core/Makefile |1 +
  drivers/bus/mhi/core/mhi_boot.c   |  593 ++
  drivers/bus/mhi/core/mhi_dtr.c|  177 +++
  drivers/bus/mhi/core/mhi_init.c   | 1290 +
  drivers/bus/mhi/core/mhi_internal.h   |  732 
  drivers/bus/mhi/core/mhi_main.c   | 1476 +
  drivers/bus/mhi/core/mhi_pm.c | 1177 
  include/linux/mhi.h   |  694 
  include/linux/mod_devicetable.h   |   11 +
  15 files changed, 6555 insertions(+)

And a 6555 line patch is a bit hard to consume all at once.  Can't this
be split up into much more reviewable chunks?  Look at how some of the
other new bus subsystems got added to the tree recently.  They were
submitted in longer patch series, but smaller sized patches
individually.  That makes things much easier to review.

For example, there is no reason your debugfs stuff needs to be in this
initial patch.  That should be in a separate one, right?  Same for
firmware download.  Please take the time to break this up into logical
steps.

Like my son's math teacher keeps telling him, "show your work, not just
an answer at the bottom of the page".

Also, it is required by the DT maintainers to split that file alone up
into a separate patch to be even considered for merging.

One thing I can tell you right now that isn't acceptable:
That is interesting because internally it's separated, and I squash them 
thinking

it was preferred. I will separate them out to functional blocks

+#ifdef CONFIG_MHI_DEBUG

Don't have a separate config option for debugging.  No one will enable
it, which makes it pointless.   Everything has to be dynamic these days.
Intention was to completely compile out MHI_VERB messages because we 
have those messages in
data path.  For release build, we wanted to reduce as much mips as 
possible. However, for

debugging these messages are extremely helpful.

I will look into tracepoints...

+
+#define MHI_VERB(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_debug("[D][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#else
+
+#define MHI_VERB(fmt, ...)
+
+#endif
+
+#define MHI_LOG(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_INFO) \
+   pr_info("[I][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MHI_ERR(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS__); \
+} while (0)
+
+#define MHI_CRITICAL(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_CRITICAL) \
+   pr_alert("[C][%s] " fmt, __func__, ##__VA_ARGS__); \
+} while (0)
+

And do not roll your own debugging/logging macros.  Use what is given to
you (dev_info(), dev_err(), dev_dbg()), they are there for a reason.  By
going around them, you circumvent the whole of the kernel logging
infrastructure and declare that your tiny bus is somehow more "special"
than it.

And I doubt you want to make such a statement :)


well :).. I will remove them in next revision.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Thanks
Sujeev
--

Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v1 1/4] mhi_bus: core: Add support for MHI host interface

2018-04-28 Thread Sujeev Dias

Thanks for quick feedback


On 04/27/2018 12:22 AM, Greg Kroah-Hartman wrote:

On Thu, Apr 26, 2018 at 07:23:28PM -0700, Sujeev Dias wrote:

MHI Host Interface is a communication protocol to be used by the host
to control and communcate with modem over a high speed peripheral bus.
This module will allow host to communicate with external devices that
support MHI protocol.

Signed-off-by: Sujeev Dias 

No one else has ever reviewed this code before?  That's not good, please
at the very least, have someone else at your company go over it first.
I don't want to be the ones having to point out all of the "obvious"
issues :)

This code has gone thru rigorous code review and testing, before I 
submit next patch

I will have multiple people sign off on it.

---
  Documentation/00-INDEX|2 +
  Documentation/devicetree/bindings/bus/mhi.txt |  141 +++
  Documentation/mhi.txt |  235 
  drivers/bus/Kconfig   |   17 +
  drivers/bus/Makefile  |1 +
  drivers/bus/mhi/Makefile  |8 +
  drivers/bus/mhi/core/Makefile |1 +
  drivers/bus/mhi/core/mhi_boot.c   |  593 ++
  drivers/bus/mhi/core/mhi_dtr.c|  177 +++
  drivers/bus/mhi/core/mhi_init.c   | 1290 +
  drivers/bus/mhi/core/mhi_internal.h   |  732 
  drivers/bus/mhi/core/mhi_main.c   | 1476 +
  drivers/bus/mhi/core/mhi_pm.c | 1177 
  include/linux/mhi.h   |  694 
  include/linux/mod_devicetable.h   |   11 +
  15 files changed, 6555 insertions(+)

And a 6555 line patch is a bit hard to consume all at once.  Can't this
be split up into much more reviewable chunks?  Look at how some of the
other new bus subsystems got added to the tree recently.  They were
submitted in longer patch series, but smaller sized patches
individually.  That makes things much easier to review.

For example, there is no reason your debugfs stuff needs to be in this
initial patch.  That should be in a separate one, right?  Same for
firmware download.  Please take the time to break this up into logical
steps.

Like my son's math teacher keeps telling him, "show your work, not just
an answer at the bottom of the page".

Also, it is required by the DT maintainers to split that file alone up
into a separate patch to be even considered for merging.

One thing I can tell you right now that isn't acceptable:
That is interesting because internally it's separated, and I squash them 
thinking

it was preferred. I will separate them out to functional blocks

+#ifdef CONFIG_MHI_DEBUG

Don't have a separate config option for debugging.  No one will enable
it, which makes it pointless.   Everything has to be dynamic these days.
Intention was to completely compile out MHI_VERB messages because we 
have those messages in
data path.  For release build, we wanted to reduce as much mips as 
possible. However, for

debugging these messages are extremely helpful.

I will look into tracepoints...

+
+#define MHI_VERB(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_debug("[D][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#else
+
+#define MHI_VERB(fmt, ...)
+
+#endif
+
+#define MHI_LOG(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_INFO) \
+   pr_info("[I][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MHI_ERR(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS__); \
+} while (0)
+
+#define MHI_CRITICAL(fmt, ...) do { \
+   if (mhi_cntrl->klog_lvl <= MHI_MSG_LVL_CRITICAL) \
+   pr_alert("[C][%s] " fmt, __func__, ##__VA_ARGS__); \
+} while (0)
+

And do not roll your own debugging/logging macros.  Use what is given to
you (dev_info(), dev_err(), dev_dbg()), they are there for a reason.  By
going around them, you circumvent the whole of the kernel logging
infrastructure and declare that your tiny bus is somehow more "special"
than it.

And I doubt you want to make such a statement :)


well :).. I will remove them in next revision.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Thanks
Sujeev
--

Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



MHI initial design review

2018-04-26 Thread Sujeev Dias
Hi Greg Kroah-Hartman\All

This is the initial submit of Modem Host Interface (MHI) stack for upstream
consideration. MHI is a communication protocol to communicate with external
Qualcomm modems and Wi-Fi chipsets over high speed peripheral buses. Even
though MHI doesn’t dictate underlying physical layer, protocol and mhi stack
is structured for PCIe based devices.

For additional details related to MHI interface please see 
Documentation/mhi.txt.

MHI stack partitioned into three main components:
1. Core layer  handles all MHI protocol specific actions such as firmware 
download,
   and data transfer
   /drivers/bus/mhi/core/*
2. Control layer  bus master, manages power transitions of external modem.
  /drivers/bus/mhi/controllers/*
3. Device drivers  MHI channels (physical transport channels) exposed as mhi 
devices
   for clients to send and receive data.
  /drivers/bus/mhi/device/*

There are three ways which clients can interface with MHI framework to send and 
receive
data from external modem.

1. Register directly with mhi core layer as a mhi device driver
2. User space clients can interface via mhi_uci driver.
3. For net traffic, mhi_netdev can be used.

Can you please do a high-level design review of the MHI driver and let me know 
if I need to
make any design changes before the drivers can be considered for upstream.

Thanks
Sujeev

   



MHI initial design review

2018-04-26 Thread Sujeev Dias
Hi Greg Kroah-Hartman\All

This is the initial submit of Modem Host Interface (MHI) stack for upstream
consideration. MHI is a communication protocol to communicate with external
Qualcomm modems and Wi-Fi chipsets over high speed peripheral buses. Even
though MHI doesn’t dictate underlying physical layer, protocol and mhi stack
is structured for PCIe based devices.

For additional details related to MHI interface please see 
Documentation/mhi.txt.

MHI stack partitioned into three main components:
1. Core layer  handles all MHI protocol specific actions such as firmware 
download,
   and data transfer
   /drivers/bus/mhi/core/*
2. Control layer  bus master, manages power transitions of external modem.
  /drivers/bus/mhi/controllers/*
3. Device drivers  MHI channels (physical transport channels) exposed as mhi 
devices
   for clients to send and receive data.
  /drivers/bus/mhi/device/*

There are three ways which clients can interface with MHI framework to send and 
receive
data from external modem.

1. Register directly with mhi core layer as a mhi device driver
2. User space clients can interface via mhi_uci driver.
3. For net traffic, mhi_netdev can be used.

Can you please do a high-level design review of the MHI driver and let me know 
if I need to
make any design changes before the drivers can be considered for upstream.

Thanks
Sujeev

   



[PATCH v1 2/4] mhi_bus: controller: MHI support for QCOM modems

2018-04-26 Thread Sujeev Dias
QCOM PCIe based modems uses MHI as the communication protocol.
MHI control driver is the bus master for such modems. As the bus
master driver, it oversees power management operations
such as suspend, resume, powering on and off the device.

Signed-off-by: Sujeev Dias <sd...@codeaurora.org>
---
 Documentation/devicetree/bindings/bus/mhi_qcom.txt | 110 
 drivers/bus/Kconfig|   1 +
 drivers/bus/mhi/Makefile   |   2 +-
 drivers/bus/mhi/controllers/Kconfig|  10 +
 drivers/bus/mhi/controllers/Makefile   |   1 +
 drivers/bus/mhi/controllers/mhi_qcom.c | 686 +
 drivers/bus/mhi/controllers/mhi_qcom.h |  85 +++
 7 files changed, 894 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/bus/mhi_qcom.txt
 create mode 100644 drivers/bus/mhi/controllers/Kconfig
 create mode 100644 drivers/bus/mhi/controllers/Makefile
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.c
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.h

diff --git a/Documentation/devicetree/bindings/bus/mhi_qcom.txt 
b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
new file mode 100644
index 000..c0f8d86
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
@@ -0,0 +1,110 @@
+Qualcomm Technologies Inc MHI Bus controller
+
+MHI control driver enables clients to communicate with external mode
+using MHI protocol.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- compatible
+  Usage: required
+  Value type: 
+  Definition: "qcom,mhi"
+
+- qcom,pci-dev-id
+  Usage: optional
+  Value type: 
+  Definition: PCIe device id of external modem to bind. If not set, any
+   device is compatible with this node.
+
+- qcom,pci-domain
+  Usage: required
+  Value type: 
+  Definition: PCIe root complex external modem connected to
+
+- qcom,pci-bus
+  Usage: required
+  Value type: 
+  Definition: PCIe bus external modem connected to
+
+- qcom,pci-slot
+  Usage: required
+  Value type: 
+  Definition: PCIe slot as assigned by pci framework to external modem
+
+- qcom,smmu-cfg
+  Usage: required
+  Value type: 
+  Definition: Required SMMU configuration bitmask for PCIe bus.
+   BIT mask:
+   BIT(0) : Attach address mapping to endpoint device
+   BIT(1) : Set attribute S1_BYPASS
+   BIT(2) : Set attribute FAST
+   BIT(3) : Set attribute ATOMIC
+   BIT(4) : Set attribute FORCE_COHERENT
+
+- qcom,addr-win
+  Usage: required if SMMU S1 translation is enabled
+  Value type: Array of 
+  Definition: Pair of values describing iova start and stop address
+
+- qcom,msm-bus,name
+  Usage: required
+  Value type: 
+  Definition: string representing the bus scale client name to register
+
+- qcom,msm-bus,num-cases
+  Usage: required
+  Value type: 
+  Definition: Must be set to two, MHI support two scales
+
+- qcom,msm-bus,num-paths
+  Usage: required
+  Value type: 
+  Definition: Total number of master-slave pairs MHI host will vote. Must be 
set
+   to one.
+
+- qcom,msm-bus,vectors-KBps
+  Usage: required
+  Value type: Array of 
+  Definition: Array of tuples which define the bus bandwidth requirements.
+   Each tuple is of length 4, values are master-id, slave-id,
+   arbitrated bandwidth in KBps, and instantaneous bandwidth in
+   KBps.
+
+- esoc-names
+  Usage: optional
+  Value type: 
+  Definition: if external modem managed by esoc framework, set string to "mdm"
+
+- esoc-0
+  Usage: required if device is managed by esoc framework
+  Value type: phandle
+  Definition: A esoc phandle pointing to external modem
+
+- MHI bus settings
+  Usage: required
+  Values: as defined by mhi.txt
+  Definition: Per definition of devicetree/bindings/bus/mhi.txt, define device
+   specific MHI configuration parameters.
+
+
+Example:
+
+qcom,mhi {
+   compatible = "qcom,mhi";
+   qcom,pci-domain = <0>;
+   qcom,pci-bus = <1>;
+   qcom,pci-slot = <0>;
+   qcom,smmu-cfg = <0x3d>;
+   qcom,addr-win = <0x0 0x2000 0x0 0x3fff>;
+   qcom,msm-bus,name = "mhi";
+   qcom,msm-bus,num-cases = <2>;
+   qcom,msm-bus,num-paths = <1>;
+   qcom,msm-bus,vectors-KBps = <45 512 0 0>,
+   <45 512 12 65000>;
+   
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index e15d56d..fb28002 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -189,5 +189,6 @@ config MHI_DEBUG
   will be logged.
 
 source "drivers/bus/fsl-mc/Kconfig"
+source drivers/bus/mhi/controllers/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index 9f8f3ac..c6a2a91 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -4,5 +4,5 @@
 
 # core layer
 obj-y += core/
-#obj-y 

[PATCH v1 2/4] mhi_bus: controller: MHI support for QCOM modems

2018-04-26 Thread Sujeev Dias
QCOM PCIe based modems uses MHI as the communication protocol.
MHI control driver is the bus master for such modems. As the bus
master driver, it oversees power management operations
such as suspend, resume, powering on and off the device.

Signed-off-by: Sujeev Dias 
---
 Documentation/devicetree/bindings/bus/mhi_qcom.txt | 110 
 drivers/bus/Kconfig|   1 +
 drivers/bus/mhi/Makefile   |   2 +-
 drivers/bus/mhi/controllers/Kconfig|  10 +
 drivers/bus/mhi/controllers/Makefile   |   1 +
 drivers/bus/mhi/controllers/mhi_qcom.c | 686 +
 drivers/bus/mhi/controllers/mhi_qcom.h |  85 +++
 7 files changed, 894 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/bus/mhi_qcom.txt
 create mode 100644 drivers/bus/mhi/controllers/Kconfig
 create mode 100644 drivers/bus/mhi/controllers/Makefile
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.c
 create mode 100644 drivers/bus/mhi/controllers/mhi_qcom.h

diff --git a/Documentation/devicetree/bindings/bus/mhi_qcom.txt 
b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
new file mode 100644
index 000..c0f8d86
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mhi_qcom.txt
@@ -0,0 +1,110 @@
+Qualcomm Technologies Inc MHI Bus controller
+
+MHI control driver enables clients to communicate with external mode
+using MHI protocol.
+
+==
+Node Structure
+==
+
+Main node properties:
+
+- compatible
+  Usage: required
+  Value type: 
+  Definition: "qcom,mhi"
+
+- qcom,pci-dev-id
+  Usage: optional
+  Value type: 
+  Definition: PCIe device id of external modem to bind. If not set, any
+   device is compatible with this node.
+
+- qcom,pci-domain
+  Usage: required
+  Value type: 
+  Definition: PCIe root complex external modem connected to
+
+- qcom,pci-bus
+  Usage: required
+  Value type: 
+  Definition: PCIe bus external modem connected to
+
+- qcom,pci-slot
+  Usage: required
+  Value type: 
+  Definition: PCIe slot as assigned by pci framework to external modem
+
+- qcom,smmu-cfg
+  Usage: required
+  Value type: 
+  Definition: Required SMMU configuration bitmask for PCIe bus.
+   BIT mask:
+   BIT(0) : Attach address mapping to endpoint device
+   BIT(1) : Set attribute S1_BYPASS
+   BIT(2) : Set attribute FAST
+   BIT(3) : Set attribute ATOMIC
+   BIT(4) : Set attribute FORCE_COHERENT
+
+- qcom,addr-win
+  Usage: required if SMMU S1 translation is enabled
+  Value type: Array of 
+  Definition: Pair of values describing iova start and stop address
+
+- qcom,msm-bus,name
+  Usage: required
+  Value type: 
+  Definition: string representing the bus scale client name to register
+
+- qcom,msm-bus,num-cases
+  Usage: required
+  Value type: 
+  Definition: Must be set to two, MHI support two scales
+
+- qcom,msm-bus,num-paths
+  Usage: required
+  Value type: 
+  Definition: Total number of master-slave pairs MHI host will vote. Must be 
set
+   to one.
+
+- qcom,msm-bus,vectors-KBps
+  Usage: required
+  Value type: Array of 
+  Definition: Array of tuples which define the bus bandwidth requirements.
+   Each tuple is of length 4, values are master-id, slave-id,
+   arbitrated bandwidth in KBps, and instantaneous bandwidth in
+   KBps.
+
+- esoc-names
+  Usage: optional
+  Value type: 
+  Definition: if external modem managed by esoc framework, set string to "mdm"
+
+- esoc-0
+  Usage: required if device is managed by esoc framework
+  Value type: phandle
+  Definition: A esoc phandle pointing to external modem
+
+- MHI bus settings
+  Usage: required
+  Values: as defined by mhi.txt
+  Definition: Per definition of devicetree/bindings/bus/mhi.txt, define device
+   specific MHI configuration parameters.
+
+
+Example:
+
+qcom,mhi {
+   compatible = "qcom,mhi";
+   qcom,pci-domain = <0>;
+   qcom,pci-bus = <1>;
+   qcom,pci-slot = <0>;
+   qcom,smmu-cfg = <0x3d>;
+   qcom,addr-win = <0x0 0x2000 0x0 0x3fff>;
+   qcom,msm-bus,name = "mhi";
+   qcom,msm-bus,num-cases = <2>;
+   qcom,msm-bus,num-paths = <1>;
+   qcom,msm-bus,vectors-KBps = <45 512 0 0>,
+   <45 512 12 65000>;
+   
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index e15d56d..fb28002 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -189,5 +189,6 @@ config MHI_DEBUG
   will be logged.
 
 source "drivers/bus/fsl-mc/Kconfig"
+source drivers/bus/mhi/controllers/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index 9f8f3ac..c6a2a91 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -4,5 +4,5 @@
 
 # core layer
 obj-y += core/
-#obj-y += controllers/
+obj-y += controll

[PATCH v1 3/4] mhi_bus: dev: netdev: add network interface driver

2018-04-26 Thread Sujeev Dias
MHI based net device driver is used for transferring IP
traffic between host and modem. Driver allows clients to
transfer data using standard network interface.

Signed-off-by: Sujeev Dias <sd...@codeaurora.org>
---
 Documentation/devicetree/bindings/bus/mhi.txt |  36 ++
 drivers/bus/Kconfig   |   1 +
 drivers/bus/mhi/Makefile  |   2 +-
 drivers/bus/mhi/devices/Kconfig   |  10 +
 drivers/bus/mhi/devices/Makefile  |   1 +
 drivers/bus/mhi/devices/mhi_netdev.c  | 893 ++
 6 files changed, 942 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/mhi/devices/Kconfig
 create mode 100644 drivers/bus/mhi/devices/Makefile
 create mode 100644 drivers/bus/mhi/devices/mhi_netdev.c

diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
index ea1b620..172ae7b 100644
--- a/Documentation/devicetree/bindings/bus/mhi.txt
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -139,3 +139,39 @@ mhi_controller {

};
 };
+
+
+Children Devices
+
+
+MHI netdev properties
+
+- mhi,chan
+  Usage: required
+  Value type: 
+  Definition: Channel name MHI netdev support
+
+- mhi,mru
+  Usage: required
+  Value type: 
+  Definition: Largest packet size interface can receive in bytes.
+
+- mhi,interface-name
+  Usage: optional
+  Value type: 
+  Definition: Interface name to be given so clients can identify it
+
+- mhi,recycle-buf
+  Usage: optional
+  Value type: 
+  Definition: Set true if interface support recycling buffers.
+
+
+Example:
+
+
+mhi_rmnet@0 {
+   mhi,chan = "IP_HW0";
+   mhi,interface-name = "rmnet_mhi";
+   mhi,mru = <0x4000>;
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index fb28002..cc03762 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -190,5 +190,6 @@ config MHI_DEBUG
 
 source "drivers/bus/fsl-mc/Kconfig"
 source drivers/bus/mhi/controllers/Kconfig
+source drivers/bus/mhi/devices/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index c6a2a91..2382e04 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -5,4 +5,4 @@
 # core layer
 obj-y += core/
 obj-y += controllers/
-#obj-y += devices/
+obj-y += devices/
diff --git a/drivers/bus/mhi/devices/Kconfig b/drivers/bus/mhi/devices/Kconfig
new file mode 100644
index 000..40f964d
--- /dev/null
+++ b/drivers/bus/mhi/devices/Kconfig
@@ -0,0 +1,10 @@
+menu "MHI device support"
+
+config MHI_NETDEV
+   tristate "MHI NETDEV"
+   depends on MHI_BUS
+   help
+ MHI based net device driver for transferring IP traffic
+ between host and modem. By enabling this driver, clients
+ can transfer data using standard network interface.
+endmenu
diff --git a/drivers/bus/mhi/devices/Makefile b/drivers/bus/mhi/devices/Makefile
new file mode 100644
index 000..ee12a64
--- /dev/null
+++ b/drivers/bus/mhi/devices/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MHI_NETDEV) +=mhi_netdev.o
diff --git a/drivers/bus/mhi/devices/mhi_netdev.c 
b/drivers/bus/mhi/devices/mhi_netdev.c
new file mode 100644
index 000..23881a9
--- /dev/null
+++ b/drivers/bus/mhi/devices/mhi_netdev.c
@@ -0,0 +1,893 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MHI_NETDEV_DRIVER_NAME "mhi_netdev"
+#define WATCHDOG_TIMEOUT (30 * HZ)
+
+#ifdef CONFIG_MHI_DEBUG
+
+#define MHI_ASSERT(cond, msg) do { \
+   if (cond) \
+   panic(msg); \
+} while (0)
+
+#define MSG_VERB(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_err("[D][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#else
+
+#define MHI_ASSERT(cond, msg) do { \
+   if (cond) { \
+   MSG_ERR(msg); \
+   WARN_ON(cond); \
+   } \
+} while (0)
+
+#define MSG_VERB(fmt, ...)
+
+#endif
+
+#define MSG_LOG(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_INFO) \
+   pr_err("[I][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MSG_ERR(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " 

[PATCH v1 3/4] mhi_bus: dev: netdev: add network interface driver

2018-04-26 Thread Sujeev Dias
MHI based net device driver is used for transferring IP
traffic between host and modem. Driver allows clients to
transfer data using standard network interface.

Signed-off-by: Sujeev Dias 
---
 Documentation/devicetree/bindings/bus/mhi.txt |  36 ++
 drivers/bus/Kconfig   |   1 +
 drivers/bus/mhi/Makefile  |   2 +-
 drivers/bus/mhi/devices/Kconfig   |  10 +
 drivers/bus/mhi/devices/Makefile  |   1 +
 drivers/bus/mhi/devices/mhi_netdev.c  | 893 ++
 6 files changed, 942 insertions(+), 1 deletion(-)
 create mode 100644 drivers/bus/mhi/devices/Kconfig
 create mode 100644 drivers/bus/mhi/devices/Makefile
 create mode 100644 drivers/bus/mhi/devices/mhi_netdev.c

diff --git a/Documentation/devicetree/bindings/bus/mhi.txt 
b/Documentation/devicetree/bindings/bus/mhi.txt
index ea1b620..172ae7b 100644
--- a/Documentation/devicetree/bindings/bus/mhi.txt
+++ b/Documentation/devicetree/bindings/bus/mhi.txt
@@ -139,3 +139,39 @@ mhi_controller {

};
 };
+
+
+Children Devices
+
+
+MHI netdev properties
+
+- mhi,chan
+  Usage: required
+  Value type: 
+  Definition: Channel name MHI netdev support
+
+- mhi,mru
+  Usage: required
+  Value type: 
+  Definition: Largest packet size interface can receive in bytes.
+
+- mhi,interface-name
+  Usage: optional
+  Value type: 
+  Definition: Interface name to be given so clients can identify it
+
+- mhi,recycle-buf
+  Usage: optional
+  Value type: 
+  Definition: Set true if interface support recycling buffers.
+
+
+Example:
+
+
+mhi_rmnet@0 {
+   mhi,chan = "IP_HW0";
+   mhi,interface-name = "rmnet_mhi";
+   mhi,mru = <0x4000>;
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index fb28002..cc03762 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -190,5 +190,6 @@ config MHI_DEBUG
 
 source "drivers/bus/fsl-mc/Kconfig"
 source drivers/bus/mhi/controllers/Kconfig
+source drivers/bus/mhi/devices/Kconfig
 
 endmenu
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index c6a2a91..2382e04 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -5,4 +5,4 @@
 # core layer
 obj-y += core/
 obj-y += controllers/
-#obj-y += devices/
+obj-y += devices/
diff --git a/drivers/bus/mhi/devices/Kconfig b/drivers/bus/mhi/devices/Kconfig
new file mode 100644
index 000..40f964d
--- /dev/null
+++ b/drivers/bus/mhi/devices/Kconfig
@@ -0,0 +1,10 @@
+menu "MHI device support"
+
+config MHI_NETDEV
+   tristate "MHI NETDEV"
+   depends on MHI_BUS
+   help
+ MHI based net device driver for transferring IP traffic
+ between host and modem. By enabling this driver, clients
+ can transfer data using standard network interface.
+endmenu
diff --git a/drivers/bus/mhi/devices/Makefile b/drivers/bus/mhi/devices/Makefile
new file mode 100644
index 000..ee12a64
--- /dev/null
+++ b/drivers/bus/mhi/devices/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MHI_NETDEV) +=mhi_netdev.o
diff --git a/drivers/bus/mhi/devices/mhi_netdev.c 
b/drivers/bus/mhi/devices/mhi_netdev.c
new file mode 100644
index 000..23881a9
--- /dev/null
+++ b/drivers/bus/mhi/devices/mhi_netdev.c
@@ -0,0 +1,893 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MHI_NETDEV_DRIVER_NAME "mhi_netdev"
+#define WATCHDOG_TIMEOUT (30 * HZ)
+
+#ifdef CONFIG_MHI_DEBUG
+
+#define MHI_ASSERT(cond, msg) do { \
+   if (cond) \
+   panic(msg); \
+} while (0)
+
+#define MSG_VERB(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_err("[D][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#else
+
+#define MHI_ASSERT(cond, msg) do { \
+   if (cond) { \
+   MSG_ERR(msg); \
+   WARN_ON(cond); \
+   } \
+} while (0)
+
+#define MSG_VERB(fmt, ...)
+
+#endif
+
+#define MSG_LOG(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_INFO) \
+   pr_err("[I][%s] " fmt, __func__, ##__VA_ARGS__);\
+} while (0)
+
+#define MSG_ERR(fmt, ...) do { \
+   if (mhi_netdev->msg_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS_

[PATCH v1 4/4] mhi_bus: dev: uci: add user space interface driver

2018-04-26 Thread Sujeev Dias
This module allows user space clients to transfer data
between external modem and host using standard file
operations.

Signed-off-by: Sujeev Dias <sd...@codeaurora.org>
---
 drivers/bus/mhi/devices/Kconfig   |   9 +
 drivers/bus/mhi/devices/Makefile  |   1 +
 drivers/bus/mhi/devices/mhi_uci.c | 662 ++
 3 files changed, 672 insertions(+)
 create mode 100644 drivers/bus/mhi/devices/mhi_uci.c

diff --git a/drivers/bus/mhi/devices/Kconfig b/drivers/bus/mhi/devices/Kconfig
index 40f964d..83b9673 100644
--- a/drivers/bus/mhi/devices/Kconfig
+++ b/drivers/bus/mhi/devices/Kconfig
@@ -7,4 +7,13 @@ config MHI_NETDEV
  MHI based net device driver for transferring IP traffic
  between host and modem. By enabling this driver, clients
  can transfer data using standard network interface.
+
+config MHI_UCI
+   tristate "MHI UCI"
+   depends on MHI_BUS
+   help
+ MHI based uci driver is for transferring data between host and
+ modem using standard file operations from user space. Open, read,
+ write, ioctl, and close operations are supported by this driver.
+
 endmenu
diff --git a/drivers/bus/mhi/devices/Makefile b/drivers/bus/mhi/devices/Makefile
index ee12a64..300eed1 100644
--- a/drivers/bus/mhi/devices/Makefile
+++ b/drivers/bus/mhi/devices/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MHI_NETDEV) +=mhi_netdev.o
+obj-$(CONFIG_MHI_UCI) +=mhi_uci.o
diff --git a/drivers/bus/mhi/devices/mhi_uci.c 
b/drivers/bus/mhi/devices/mhi_uci.c
new file mode 100644
index 000..11b7b1f
--- /dev/null
+++ b/drivers/bus/mhi/devices/mhi_uci.c
@@ -0,0 +1,662 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEVICE_NAME "mhi"
+#define MHI_UCI_DRIVER_NAME "mhi_uci"
+
+struct uci_chan {
+   wait_queue_head_t wq;
+   spinlock_t lock;
+   struct list_head pending; /* user space waiting to read */
+   struct uci_buf *cur_buf; /* current buffer user space reading */
+   size_t rx_size;
+};
+
+struct uci_buf {
+   void *data;
+   size_t len;
+   struct list_head node;
+};
+
+struct uci_dev {
+   struct list_head node;
+   dev_t devt;
+   struct device *dev;
+   struct mhi_device *mhi_dev;
+   const char *chan;
+   struct mutex mutex; /* sync open and close */
+   struct uci_chan ul_chan;
+   struct uci_chan dl_chan;
+   size_t mtu;
+   int ref_count;
+   bool enabled;
+};
+
+struct mhi_uci_drv {
+   struct list_head head;
+   struct mutex lock;
+   struct class *class;
+   int major;
+   dev_t dev_t;
+};
+
+enum MHI_DEBUG_LEVEL msg_lvl = MHI_MSG_LVL_ERROR;
+
+#ifdef CONFIG_MHI_DEBUG
+
+#define MSG_VERB(fmt, ...) do { \
+   if (msg_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_err("[D][%s] " fmt, __func__, ##__VA_ARGS__); \
+   } while (0)
+
+#else
+
+#define MSG_VERB(fmt, ...)
+
+#endif
+
+#define MSG_LOG(fmt, ...) do { \
+   if (msg_lvl <= MHI_MSG_LVL_INFO) \
+   pr_err("[I][%s] " fmt, __func__, ##__VA_ARGS__); \
+   } while (0)
+
+#define MSG_ERR(fmt, ...) do { \
+   if (msg_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS__); \
+   } while (0)
+
+#define MAX_UCI_DEVICES (64)
+
+static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
+static struct mhi_uci_drv mhi_uci_drv;
+
+static int mhi_queue_inbound(struct uci_dev *uci_dev)
+{
+   struct mhi_device *mhi_dev = uci_dev->mhi_dev;
+   int nr_trbs = mhi_get_no_free_descriptors(mhi_dev, DMA_FROM_DEVICE);
+   size_t mtu = uci_dev->mtu;
+   void *buf;
+   struct uci_buf *uci_buf;
+   int ret = -EIO, i;
+
+   for (i = 0; i < nr_trbs; i++) {
+   buf = kmalloc(mtu + sizeof(*uci_buf), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   uci_buf = buf + mtu;
+   uci_buf->data = buf;
+
+   MSG_VERB("Allocated buf %d of %d size %ld\n", i, nr_trbs, mtu);
+
+   ret = mhi_queue_transfer(mhi_dev, DMA_FROM_DEVICE, buf, mtu,
+MHI_EOT);
+   if (ret) {
+   kfree(buf);
+   

[PATCH v1 4/4] mhi_bus: dev: uci: add user space interface driver

2018-04-26 Thread Sujeev Dias
This module allows user space clients to transfer data
between external modem and host using standard file
operations.

Signed-off-by: Sujeev Dias 
---
 drivers/bus/mhi/devices/Kconfig   |   9 +
 drivers/bus/mhi/devices/Makefile  |   1 +
 drivers/bus/mhi/devices/mhi_uci.c | 662 ++
 3 files changed, 672 insertions(+)
 create mode 100644 drivers/bus/mhi/devices/mhi_uci.c

diff --git a/drivers/bus/mhi/devices/Kconfig b/drivers/bus/mhi/devices/Kconfig
index 40f964d..83b9673 100644
--- a/drivers/bus/mhi/devices/Kconfig
+++ b/drivers/bus/mhi/devices/Kconfig
@@ -7,4 +7,13 @@ config MHI_NETDEV
  MHI based net device driver for transferring IP traffic
  between host and modem. By enabling this driver, clients
  can transfer data using standard network interface.
+
+config MHI_UCI
+   tristate "MHI UCI"
+   depends on MHI_BUS
+   help
+ MHI based uci driver is for transferring data between host and
+ modem using standard file operations from user space. Open, read,
+ write, ioctl, and close operations are supported by this driver.
+
 endmenu
diff --git a/drivers/bus/mhi/devices/Makefile b/drivers/bus/mhi/devices/Makefile
index ee12a64..300eed1 100644
--- a/drivers/bus/mhi/devices/Makefile
+++ b/drivers/bus/mhi/devices/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MHI_NETDEV) +=mhi_netdev.o
+obj-$(CONFIG_MHI_UCI) +=mhi_uci.o
diff --git a/drivers/bus/mhi/devices/mhi_uci.c 
b/drivers/bus/mhi/devices/mhi_uci.c
new file mode 100644
index 000..11b7b1f
--- /dev/null
+++ b/drivers/bus/mhi/devices/mhi_uci.c
@@ -0,0 +1,662 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEVICE_NAME "mhi"
+#define MHI_UCI_DRIVER_NAME "mhi_uci"
+
+struct uci_chan {
+   wait_queue_head_t wq;
+   spinlock_t lock;
+   struct list_head pending; /* user space waiting to read */
+   struct uci_buf *cur_buf; /* current buffer user space reading */
+   size_t rx_size;
+};
+
+struct uci_buf {
+   void *data;
+   size_t len;
+   struct list_head node;
+};
+
+struct uci_dev {
+   struct list_head node;
+   dev_t devt;
+   struct device *dev;
+   struct mhi_device *mhi_dev;
+   const char *chan;
+   struct mutex mutex; /* sync open and close */
+   struct uci_chan ul_chan;
+   struct uci_chan dl_chan;
+   size_t mtu;
+   int ref_count;
+   bool enabled;
+};
+
+struct mhi_uci_drv {
+   struct list_head head;
+   struct mutex lock;
+   struct class *class;
+   int major;
+   dev_t dev_t;
+};
+
+enum MHI_DEBUG_LEVEL msg_lvl = MHI_MSG_LVL_ERROR;
+
+#ifdef CONFIG_MHI_DEBUG
+
+#define MSG_VERB(fmt, ...) do { \
+   if (msg_lvl <= MHI_MSG_LVL_VERBOSE) \
+   pr_err("[D][%s] " fmt, __func__, ##__VA_ARGS__); \
+   } while (0)
+
+#else
+
+#define MSG_VERB(fmt, ...)
+
+#endif
+
+#define MSG_LOG(fmt, ...) do { \
+   if (msg_lvl <= MHI_MSG_LVL_INFO) \
+   pr_err("[I][%s] " fmt, __func__, ##__VA_ARGS__); \
+   } while (0)
+
+#define MSG_ERR(fmt, ...) do { \
+   if (msg_lvl <= MHI_MSG_LVL_ERROR) \
+   pr_err("[E][%s] " fmt, __func__, ##__VA_ARGS__); \
+   } while (0)
+
+#define MAX_UCI_DEVICES (64)
+
+static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
+static struct mhi_uci_drv mhi_uci_drv;
+
+static int mhi_queue_inbound(struct uci_dev *uci_dev)
+{
+   struct mhi_device *mhi_dev = uci_dev->mhi_dev;
+   int nr_trbs = mhi_get_no_free_descriptors(mhi_dev, DMA_FROM_DEVICE);
+   size_t mtu = uci_dev->mtu;
+   void *buf;
+   struct uci_buf *uci_buf;
+   int ret = -EIO, i;
+
+   for (i = 0; i < nr_trbs; i++) {
+   buf = kmalloc(mtu + sizeof(*uci_buf), GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   uci_buf = buf + mtu;
+   uci_buf->data = buf;
+
+   MSG_VERB("Allocated buf %d of %d size %ld\n", i, nr_trbs, mtu);
+
+   ret = mhi_queue_transfer(mhi_dev, DMA_FROM_DEVICE, buf, mtu,
+MHI_EOT);
+   if (ret) {
+   kfree(buf);
+