Re: [PATCH 1/6] dt-bindings: soc: qcom: Add interconnect binding for GENI QUP

2019-01-30 Thread alokc

On 2019-01-23 10:35, Georgi Djakov wrote:

Hi Alok,

Thanks for the patches!

On 1/22/19 08:33, Alok Chauhan wrote:

Add documentation for the interconnect and interconnect-names bindings


s/interconnect /interconnects /

for the GENI QUP as detailed by 
bindings/interconnect/interconnect.txt.


Signed-off-by: Alok Chauhan 
---
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt | 10 
++

 1 file changed, 10 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt

index dab7ca9..44d7e02 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -17,6 +17,12 @@ Required properties if child node exists:
 - #address-cells:  Must be <1> for Serial Engine Address
 - #size-cells: Must be <1> for Serial Engine Address Size
 - ranges:  Must be present
+- interconnects:   phandle to a interconnect provider. Please refer


s/a interconnect/an interconnect/

sure, will do.



+   ../interconnect/interconnect.txt for details.
+   Must be 2 paths corresponding to 2 AXI ports.
+- interconnect-names:  Port names to differentiate between the
+   2 interconnect paths defined with interconnect
+   specifier.

 Properties for children:

@@ -67,6 +73,10 @@ Example:
#size-cells = <1>;
ranges;

+   interconnects = < 11  512>,
+   < 0  543>;


Please take a snippet from your patch 6/6 and put it here instead of 
the

hard-coded integers above.

sure



+   interconnect-names = "qup-memory", "qup-config";
+
i2c0: i2c@a94000 {
compatible = "qcom,geni-i2c";
reg = <0xa94000 0x4000>;



When you post a new version, please change the subject of the patch
series to PATCH v2, PATCH v3 etc, in order to be able to distinguish
between different versions.

sure, will do this.


Thanks,
Georgi


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


Re: [PATCH 1/6] dt-bindings: soc: qcom: Add interconnect binding for GENI QUP

2019-01-30 Thread alokc

On 2019-01-23 17:10, Evan Green wrote:
On Mon, Jan 21, 2019 at 10:34 PM Alok Chauhan  
wrote:


Add documentation for the interconnect and interconnect-names bindings
for the GENI QUP as detailed by 
bindings/interconnect/interconnect.txt.


Signed-off-by: Alok Chauhan 
---
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt | 10 
++

 1 file changed, 10 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt

index dab7ca9..44d7e02 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -17,6 +17,12 @@ Required properties if child node exists:
 - #address-cells:  Must be <1> for Serial Engine Address
 - #size-cells: Must be <1> for Serial Engine Address 
Size

 - ranges:  Must be present
+- interconnects:   phandle to a interconnect provider. Please 
refer

+   ../interconnect/interconnect.txt for details.


This path to the interconnect documentation is not correct.

sorry, i will correct this in next patch.
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum,a Linux Foundation Collaborative Project


Re: [PATCH 4/6] spi: spi-geni-qcom: Add interconnect support

2019-01-22 Thread alokc

On 2019-01-23 01:59, Mark Brown wrote:

On Tue, Jan 22, 2019 at 12:03:34PM +0530, Alok Chauhan wrote:


Get the interconnect paths for SPI based Serial Engine device
and vote accordingly based on maximum supported SPI frequency.


Still not seeing anything except this patch here in my inbox - like I
said what's the story with dependencies?


I've added linux-spi mailing list to all the patches sent as part of 
this series. Not sure why you didn't get other patches. Today I've 
explicitly added you in all the patches.
This change series basically enabled interconnect (as per 
bindings/interconnect/interconnect.txt) support in GENI QUPs based 
drivers so appropriate BW request can be put based on SE usages.
here is my complete change series: 
https://lore.kernel.org/lkml/1548069703-26595-1-git-send-email-al...@codeaurora.org/

I hope I answer to your question properly.


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


Re: [PATCH 2/6] soc: qcom: Add wrapper to support for Interconnect path

2019-01-22 Thread alokc

+Mark Brown

On 2019-01-22 12:03, Alok Chauhan wrote:

Add the wrapper to support for interconnect path voting
from GENI QUP. This wrapper provides the functionalities
to individual Serial Engine device to get the interconnect
path and to vote for bandwidth based on their need.

This wrapper maintains bandwidth votes from each Serial Engine
and send the aggregated vote from GENI QUP to interconnect
framework.

Signed-off-by: Alok Chauhan 
---
 drivers/soc/qcom/qcom-geni-se.c | 129 


 include/linux/qcom-geni-se.h|  11 
 2 files changed, 140 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c 
b/drivers/soc/qcom/qcom-geni-se.c

index 6b8ef01..1d8dcb1 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 

 /**
  * DOC: Overview
@@ -84,11 +85,21 @@
  * @dev:   Device pointer of the QUP wrapper core
  * @base:  Base address of this instance of QUP wrapper core
  * @ahb_clks:  Handle to the primary & secondary AHB clocks
+ * @icc_path:  Array of interconnect path handles
+ * @geni_wrapper_lock: Lock to protect the bus bandwidth request
+ * @cur_avg_bw:Current Bus Average BW request value from GENI 
QUP
+ * @cur_peak_bw:   Current Bus Peak BW request value from GENI QUP
+ * @peak_bw_list_head: Sorted resource list based on peak bus BW
  */
 struct geni_wrapper {
struct device *dev;
void __iomem *base;
struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
+   struct icc_path *icc_path[2];
+   struct mutex geni_wrapper_lock;
+   u32 cur_avg_bw;
+   u32 cur_peak_bw;
+   struct list_head peak_bw_list_head;
 };

 #define QUP_HW_VER_REG 0x4
@@ -440,6 +451,71 @@ static void geni_se_clks_off(struct geni_se *se)
 }

 /**
+ * geni_icc_update_bw() - Request to update bw vote on an interconnect 
path

+ * @se:Pointer to the concerned serial engine.
+ * @update:Flag to update bw vote.
+ *
+ * This function is used to request set bw vote on interconnect path 
handle.

+ */
+void geni_icc_update_bw(struct geni_se *se, bool update)
+{
+   struct geni_se *temp = NULL;
+   struct list_head *ins_list_head;
+   struct geni_wrapper *wrapper;
+
+   mutex_lock(>wrapper->geni_wrapper_lock);
+
+   wrapper = se->wrapper;
+
+   if (update) {
+   wrapper->cur_avg_bw += se->avg_bw;
+   ins_list_head = >peak_bw_list_head;
+   list_for_each_entry(temp, >peak_bw_list_head,
+   peak_bw_list) {
+   if (temp->peak_bw < se->peak_bw)
+   break;
+   ins_list_head = >peak_bw_list;
+   }
+
+   list_add(>peak_bw_list, ins_list_head);
+
+   if (ins_list_head == >peak_bw_list_head)
+   wrapper->cur_peak_bw = se->peak_bw;
+   } else {
+   if (unlikely(list_empty(>peak_bw_list))) {
+   mutex_unlock(>geni_wrapper_lock);
+   return;
+   }
+
+   wrapper->cur_avg_bw -= se->avg_bw;
+
+   list_del_init(>peak_bw_list);
+   temp = list_first_entry_or_null(>peak_bw_list_head,
+   struct geni_se, peak_bw_list);
+   if (temp && temp->peak_bw != wrapper->cur_peak_bw)
+   wrapper->cur_peak_bw = temp->peak_bw;
+   else if (!temp && wrapper->cur_peak_bw)
+   wrapper->cur_peak_bw = 0;
+   }
+
+   /*
+* This bw vote is to enable internal QUP core clock as well as to
+* enable path towards memory.
+*/
+   icc_set_bw(wrapper->icc_path[0], wrapper->cur_avg_bw,
+   wrapper->cur_peak_bw);
+
+   /*
+* This is just register configuration path so doesn't need avg bw.
+* Set only peak bw to enable this path.
+*/
+   icc_set_bw(wrapper->icc_path[1], 0, wrapper->cur_peak_bw);
+
+   mutex_unlock(>geni_wrapper_lock);
+}
+EXPORT_SYMBOL(geni_icc_update_bw);
+
+/**
  * geni_se_resources_off() - Turn off resources associated with the 
serial

  *   engine
  * @se:Pointer to the concerned serial engine.
@@ -707,6 +783,47 @@ void geni_se_rx_dma_unprep(struct geni_se *se,
dma_addr_t iova, size_t len)
 }
 EXPORT_SYMBOL(geni_se_rx_dma_unprep);

+/**
+ * geni_interconnect_init() - Request to get interconnect path handle
+ * @se:Pointer to the concerned serial engine.
+ *
+ * This function is used to get interconnect path handle.
+ */
+int geni_interconnect_init(struct geni_se *se)
+{
+   struct geni_wrapper *wrapper_rsc;
+
+   if (unlikely(!se || !se->wrapper))
+   return -EINVAL;
+
+   wrapper_rsc = se->wrapper;
+
+   if 

Re: [PATCH 6/6] arm64: dts: sdm845: Add interconnect for GENI QUP

2019-01-22 Thread alokc

+Mark Brown

On 2019-01-22 12:03, Alok Chauhan wrote:

Add interconnect ports for GENI QUPs to set bus
capabilities.

Signed-off-by: Alok Chauhan 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index c27cbd3..fb0a8a7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -374,6 +374,13 @@
#address-cells = <1>;
#size-cells = <1>;
ranges;
+
+   interconnects = <_hlos MASTER_BLSP_1
+   _hlos SLAVE_EBI1>,
+   <_hlos MASTER_APPSS_PROC
+   _hlos SLAVE_BLSP_1>;
+   interconnect-names = "qup-memory", "qup-config";
+
status = "disabled";

i2c0: i2c@88 {
@@ -682,6 +689,13 @@
#address-cells = <1>;
#size-cells = <1>;
ranges;
+
+   interconnects = <_hlos MASTER_BLSP_2
+   _hlos SLAVE_EBI1>,
+   <_hlos MASTER_APPSS_PROC
+   _hlos SLAVE_BLSP_2>;
+   interconnect-names = "qup-memory", "qup-config";
+
status = "disabled";

i2c8: i2c@a8 {


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


Re: [PATCH 5/6] tty: serial: qcom_geni_serial: Add interconnect support

2019-01-22 Thread alokc

+Mark Brown

On 2019-01-22 12:03, Alok Chauhan wrote:

Get the interconnect paths for Uart based Serial Engine device
and vote accordingly based on maximum supported Uart frequency.

Signed-off-by: Alok Chauhan 
---
 drivers/tty/serial/qcom_geni_serial.c | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c
b/drivers/tty/serial/qcom_geni_serial.c
index a72d6d9..e2ea499 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 

 /* UART specific GENI registers */
 #define SE_UART_LOOPBACK_CFG   0x22c
@@ -1348,6 +1349,22 @@ static int qcom_geni_serial_probe(struct
platform_device *pdev)
return ret;
}

+   /* Set the bus quota to a reasonable value */
+   port->se.avg_bw = console ? Bps_to_icc(1000) : Bps_to_icc(2500);
+   port->se.peak_bw = Bps_to_icc(7680);
+   ret = geni_interconnect_init(>se);
+   if (ret) {
+   dev_err(>dev, "interconnect_init failed %d\n", ret);
+   return ret;
+   }
+
+   /*
+* Vote for interconnect path early. This has to move as part of
+* Runtime PM APIs when implemented for better control betwen
+* console and non-console usecases
+*/
+   geni_icc_update_bw(>se, true);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
@@ -1385,8 +1402,15 @@ static int __maybe_unused
qcom_geni_serial_sys_suspend(struct device *dev)
 {
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = >uport;
+   int ret;
+
+   ret = uart_suspend_port(uport->private_data, uport);
+   if (ret)
+   return ret;
+
+   geni_icc_update_bw(>se, false);

-   return uart_suspend_port(uport->private_data, uport);
+   return 0;
 }

 static int __maybe_unused qcom_geni_serial_sys_resume(struct device 
*dev)

@@ -1394,6 +1418,7 @@ static int __maybe_unused
qcom_geni_serial_sys_resume(struct device *dev)
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = >uport;

+   geni_icc_update_bw(>se, true);
return uart_resume_port(uport->private_data, uport);
 }


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


Re: [PATCH 3/6] i2c: i2c-qcom-geni: Add interconnect support

2019-01-22 Thread alokc

On 2019-01-22 14:43, Peter Rosin wrote:

On 2019-01-22 07:33, Alok Chauhan wrote:

Get the interconnect paths for I2C based Serial Engine device
and vote accordingly based on maximum supported I2C frequency.

Signed-off-by: Alok Chauhan 
---
 drivers/i2c/busses/i2c-qcom-geni.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c 
b/drivers/i2c/busses/i2c-qcom-geni.c

index db075bc..e8fe63a 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 


Please keep the includes sorted. Probably applies for the other patches
in the series as well?

Cheers,
Peter


Sure, will do. Thanks for your comment.

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


Re: [PATCH 2/6] soc: qcom: Add wrapper to support for Interconnect path

2019-01-22 Thread alokc

+Mark Brown

On 2019-01-22 12:03, Alok Chauhan wrote:

Add the wrapper to support for interconnect path voting
from GENI QUP. This wrapper provides the functionalities
to individual Serial Engine device to get the interconnect
path and to vote for bandwidth based on their need.

This wrapper maintains bandwidth votes from each Serial Engine
and send the aggregated vote from GENI QUP to interconnect
framework.

Signed-off-by: Alok Chauhan 
---
 drivers/soc/qcom/qcom-geni-se.c | 129 


 include/linux/qcom-geni-se.h|  11 
 2 files changed, 140 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c 
b/drivers/soc/qcom/qcom-geni-se.c

index 6b8ef01..1d8dcb1 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 

 /**
  * DOC: Overview
@@ -84,11 +85,21 @@
  * @dev:   Device pointer of the QUP wrapper core
  * @base:  Base address of this instance of QUP wrapper core
  * @ahb_clks:  Handle to the primary & secondary AHB clocks
+ * @icc_path:  Array of interconnect path handles
+ * @geni_wrapper_lock: Lock to protect the bus bandwidth request
+ * @cur_avg_bw:Current Bus Average BW request value from GENI 
QUP
+ * @cur_peak_bw:   Current Bus Peak BW request value from GENI QUP
+ * @peak_bw_list_head: Sorted resource list based on peak bus BW
  */
 struct geni_wrapper {
struct device *dev;
void __iomem *base;
struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
+   struct icc_path *icc_path[2];
+   struct mutex geni_wrapper_lock;
+   u32 cur_avg_bw;
+   u32 cur_peak_bw;
+   struct list_head peak_bw_list_head;
 };

 #define QUP_HW_VER_REG 0x4
@@ -440,6 +451,71 @@ static void geni_se_clks_off(struct geni_se *se)
 }

 /**
+ * geni_icc_update_bw() - Request to update bw vote on an interconnect 
path

+ * @se:Pointer to the concerned serial engine.
+ * @update:Flag to update bw vote.
+ *
+ * This function is used to request set bw vote on interconnect path 
handle.

+ */
+void geni_icc_update_bw(struct geni_se *se, bool update)
+{
+   struct geni_se *temp = NULL;
+   struct list_head *ins_list_head;
+   struct geni_wrapper *wrapper;
+
+   mutex_lock(>wrapper->geni_wrapper_lock);
+
+   wrapper = se->wrapper;
+
+   if (update) {
+   wrapper->cur_avg_bw += se->avg_bw;
+   ins_list_head = >peak_bw_list_head;
+   list_for_each_entry(temp, >peak_bw_list_head,
+   peak_bw_list) {
+   if (temp->peak_bw < se->peak_bw)
+   break;
+   ins_list_head = >peak_bw_list;
+   }
+
+   list_add(>peak_bw_list, ins_list_head);
+
+   if (ins_list_head == >peak_bw_list_head)
+   wrapper->cur_peak_bw = se->peak_bw;
+   } else {
+   if (unlikely(list_empty(>peak_bw_list))) {
+   mutex_unlock(>geni_wrapper_lock);
+   return;
+   }
+
+   wrapper->cur_avg_bw -= se->avg_bw;
+
+   list_del_init(>peak_bw_list);
+   temp = list_first_entry_or_null(>peak_bw_list_head,
+   struct geni_se, peak_bw_list);
+   if (temp && temp->peak_bw != wrapper->cur_peak_bw)
+   wrapper->cur_peak_bw = temp->peak_bw;
+   else if (!temp && wrapper->cur_peak_bw)
+   wrapper->cur_peak_bw = 0;
+   }
+
+   /*
+* This bw vote is to enable internal QUP core clock as well as to
+* enable path towards memory.
+*/
+   icc_set_bw(wrapper->icc_path[0], wrapper->cur_avg_bw,
+   wrapper->cur_peak_bw);
+
+   /*
+* This is just register configuration path so doesn't need avg bw.
+* Set only peak bw to enable this path.
+*/
+   icc_set_bw(wrapper->icc_path[1], 0, wrapper->cur_peak_bw);
+
+   mutex_unlock(>geni_wrapper_lock);
+}
+EXPORT_SYMBOL(geni_icc_update_bw);
+
+/**
  * geni_se_resources_off() - Turn off resources associated with the 
serial

  *   engine
  * @se:Pointer to the concerned serial engine.
@@ -707,6 +783,47 @@ void geni_se_rx_dma_unprep(struct geni_se *se,
dma_addr_t iova, size_t len)
 }
 EXPORT_SYMBOL(geni_se_rx_dma_unprep);

+/**
+ * geni_interconnect_init() - Request to get interconnect path handle
+ * @se:Pointer to the concerned serial engine.
+ *
+ * This function is used to get interconnect path handle.
+ */
+int geni_interconnect_init(struct geni_se *se)
+{
+   struct geni_wrapper *wrapper_rsc;
+
+   if (unlikely(!se || !se->wrapper))
+   return -EINVAL;
+
+   wrapper_rsc = se->wrapper;
+
+   if 

Re: [PATCH 1/6] dt-bindings: soc: qcom: Add interconnect binding for GENI QUP

2019-01-22 Thread alokc

+Mark Brown

On 2019-01-22 12:03, Alok Chauhan wrote:

Add documentation for the interconnect and interconnect-names bindings
for the GENI QUP as detailed by bindings/interconnect/interconnect.txt.

Signed-off-by: Alok Chauhan 
---
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt | 10 
++

 1 file changed, 10 insertions(+)

diff --git
a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
index dab7ca9..44d7e02 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -17,6 +17,12 @@ Required properties if child node exists:
 - #address-cells:  Must be <1> for Serial Engine Address
 - #size-cells: Must be <1> for Serial Engine Address Size
 - ranges:  Must be present
+- interconnects:   phandle to a interconnect provider. Please refer
+   ../interconnect/interconnect.txt for details.
+   Must be 2 paths corresponding to 2 AXI ports.
+- interconnect-names:  Port names to differentiate between the
+   2 interconnect paths defined with interconnect
+   specifier.

 Properties for children:

@@ -67,6 +73,10 @@ Example:
#size-cells = <1>;
ranges;

+   interconnects = < 11  512>,
+   < 0  543>;
+   interconnect-names = "qup-memory", "qup-config";
+
i2c0: i2c@a94000 {
compatible = "qcom,geni-i2c";
reg = <0xa94000 0x4000>;


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


Re: [PATCH 0/6] Add interconnect support for GENI QUPs

2019-01-22 Thread alokc

+Mark Brown

On 2019-01-22 12:03, Alok Chauhan wrote:

This patch series contains following:
* Add wrapper framework to support interconnect path from GENI QUPs.
  This wrapper enabled and help individual SEs to put their BW request.
  Adding this wrapper make sense because we don't want individual SEs
  to request to interconnect driver separately and put individual bw
  votes from QUP.

  This wrapper framework does the following:
  - Request for interconnect path handle
  - Maintain record of individual SEs' avg/peak bw.
  - Aggregated avg/peak bw based on how many SE's are active and put
single bw request from QUP

* Interconnect wrapper API calling from I2C, SPI & Uart driver
* dt binding in sdm845 soc for Interconnect path for GENI QUPs
* dt binding documentation


Alok Chauhan (6):
  dt-bindings: soc: qcom: Add interconnect binding for GENI QUP
  soc: qcom: Add wrapper to support for Interconnect path
  i2c: i2c-qcom-geni: Add interconnect support
  spi: spi-geni-qcom: Add interconnect support
  tty: serial: qcom_geni_serial: Add interconnect support
  arm64: dts: sdm845: Add interconnect for GENI QUP

 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  10 ++
 arch/arm64/boot/dts/qcom/sdm845.dtsi   |  14 +++
 drivers/i2c/busses/i2c-qcom-geni.c |  13 +++
 drivers/soc/qcom/qcom-geni-se.c| 129 
+

 drivers/spi/spi-geni-qcom.c|  20 +++-
 drivers/tty/serial/qcom_geni_serial.c  |  27 -
 include/linux/qcom-geni-se.h   |  11 ++
 7 files changed, 222 insertions(+), 2 deletions(-)


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


Re: [PATCH 3/6] i2c: i2c-qcom-geni: Add interconnect support

2019-01-21 Thread alokc
Please don't review this patch. I've resend patches after adding all the 
mailing list.
Sorry for inconvenience. Please review patches with spi/i2c/uart/kernel 
mailing list added.


On 2019-01-21 16:51, Alok Chauhan wrote:

Get the interconnect paths for I2C based Serial Engine device
and vote accordingly based on maximum supported I2C frequency.

Signed-off-by: Alok Chauhan 
---
 drivers/i2c/busses/i2c-qcom-geni.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c
b/drivers/i2c/busses/i2c-qcom-geni.c
index db075bc..e8fe63a 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 

 #define SE_I2C_TX_TRANS_LEN0x26c
 #define SE_I2C_RX_TRANS_LEN0x270
@@ -508,6 +509,15 @@ static int geni_i2c_probe(struct platform_device 
*pdev)

return ret;
}

+   /* Set the bus quota to a reasonable value */
+   gi2c->se.avg_bw = Bps_to_icc(1000);
+   gi2c->se.peak_bw = Bps_to_icc(7680);
+   ret = geni_interconnect_init(>se);
+   if (ret) {
+   dev_err(>dev, "interconnect_init failed %d\n", ret);
+   return ret;
+   }
+
ret = device_property_read_u32(>dev, "clock-frequency",
>clk_freq_out);
if (ret) {
@@ -611,6 +621,8 @@ static int __maybe_unused
geni_i2c_runtime_suspend(struct device *dev)
gi2c->suspended = 1;
}

+   geni_icc_update_bw(>se, false);
+
return 0;
 }

@@ -619,6 +631,7 @@ static int __maybe_unused
geni_i2c_runtime_resume(struct device *dev)
int ret;
struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);

+   geni_icc_update_bw(>se, true);
ret = geni_se_resources_on(>se);
if (ret)
return ret;


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


Re: [PATCH 2/6] soc: qcom: Add wrapper to support for Interconnect path

2019-01-21 Thread alokc
Please don't review this patch. I've resend patches after adding all the 
mailing list.

Sorry for inconvenience.

On 2019-01-21 16:51, Alok Chauhan wrote:

Add the wrapper to support for interconnect path voting
from GENI QUP. This wrapper provides the functionalities
to individual Serial Engine device to get the interconnect
path and to vote for bandwidth based on their need.

This wrapper maintains bandwidth votes from each Serial Engine
and send the aggregated vote from GENI QUP to interconnect
framework.

Signed-off-by: Alok Chauhan 
---
 drivers/soc/qcom/qcom-geni-se.c | 129 


 include/linux/qcom-geni-se.h|  11 
 2 files changed, 140 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c 
b/drivers/soc/qcom/qcom-geni-se.c

index 6b8ef01..1d8dcb1 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 

 /**
  * DOC: Overview
@@ -84,11 +85,21 @@
  * @dev:   Device pointer of the QUP wrapper core
  * @base:  Base address of this instance of QUP wrapper core
  * @ahb_clks:  Handle to the primary & secondary AHB clocks
+ * @icc_path:  Array of interconnect path handles
+ * @geni_wrapper_lock: Lock to protect the bus bandwidth request
+ * @cur_avg_bw:Current Bus Average BW request value from GENI 
QUP
+ * @cur_peak_bw:   Current Bus Peak BW request value from GENI QUP
+ * @peak_bw_list_head: Sorted resource list based on peak bus BW
  */
 struct geni_wrapper {
struct device *dev;
void __iomem *base;
struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
+   struct icc_path *icc_path[2];
+   struct mutex geni_wrapper_lock;
+   u32 cur_avg_bw;
+   u32 cur_peak_bw;
+   struct list_head peak_bw_list_head;
 };

 #define QUP_HW_VER_REG 0x4
@@ -440,6 +451,71 @@ static void geni_se_clks_off(struct geni_se *se)
 }

 /**
+ * geni_icc_update_bw() - Request to update bw vote on an interconnect 
path

+ * @se:Pointer to the concerned serial engine.
+ * @update:Flag to update bw vote.
+ *
+ * This function is used to request set bw vote on interconnect path 
handle.

+ */
+void geni_icc_update_bw(struct geni_se *se, bool update)
+{
+   struct geni_se *temp = NULL;
+   struct list_head *ins_list_head;
+   struct geni_wrapper *wrapper;
+
+   mutex_lock(>wrapper->geni_wrapper_lock);
+
+   wrapper = se->wrapper;
+
+   if (update) {
+   wrapper->cur_avg_bw += se->avg_bw;
+   ins_list_head = >peak_bw_list_head;
+   list_for_each_entry(temp, >peak_bw_list_head,
+   peak_bw_list) {
+   if (temp->peak_bw < se->peak_bw)
+   break;
+   ins_list_head = >peak_bw_list;
+   }
+
+   list_add(>peak_bw_list, ins_list_head);
+
+   if (ins_list_head == >peak_bw_list_head)
+   wrapper->cur_peak_bw = se->peak_bw;
+   } else {
+   if (unlikely(list_empty(>peak_bw_list))) {
+   mutex_unlock(>geni_wrapper_lock);
+   return;
+   }
+
+   wrapper->cur_avg_bw -= se->avg_bw;
+
+   list_del_init(>peak_bw_list);
+   temp = list_first_entry_or_null(>peak_bw_list_head,
+   struct geni_se, peak_bw_list);
+   if (temp && temp->peak_bw != wrapper->cur_peak_bw)
+   wrapper->cur_peak_bw = temp->peak_bw;
+   else if (!temp && wrapper->cur_peak_bw)
+   wrapper->cur_peak_bw = 0;
+   }
+
+   /*
+* This bw vote is to enable internal QUP core clock as well as to
+* enable path towards memory.
+*/
+   icc_set_bw(wrapper->icc_path[0], wrapper->cur_avg_bw,
+   wrapper->cur_peak_bw);
+
+   /*
+* This is just register configuration path so doesn't need avg bw.
+* Set only peak bw to enable this path.
+*/
+   icc_set_bw(wrapper->icc_path[1], 0, wrapper->cur_peak_bw);
+
+   mutex_unlock(>geni_wrapper_lock);
+}
+EXPORT_SYMBOL(geni_icc_update_bw);
+
+/**
  * geni_se_resources_off() - Turn off resources associated with the 
serial

  *   engine
  * @se:Pointer to the concerned serial engine.
@@ -707,6 +783,47 @@ void geni_se_rx_dma_unprep(struct geni_se *se,
dma_addr_t iova, size_t len)
 }
 EXPORT_SYMBOL(geni_se_rx_dma_unprep);

+/**
+ * geni_interconnect_init() - Request to get interconnect path handle
+ * @se:Pointer to the concerned serial engine.
+ *
+ * This function is used to get interconnect path handle.
+ */
+int geni_interconnect_init(struct geni_se *se)
+{
+   struct geni_wrapper *wrapper_rsc;
+
+   if (unlikely(!se || 

Re: [PATCH 1/6] dt-bindings: soc: qcom: Add interconnect binding for GENI QUP

2019-01-21 Thread alokc
Please don't review this patch. I've resend patches after adding all the 
mailing list.

Sorry for inconvenience.

On 2019-01-21 16:51, Alok Chauhan wrote:

Add documentation for the interconnect and interconnect-names bindings
for the GENI QUP as detailed by bindings/interconnect/interconnect.txt.

Signed-off-by: Alok Chauhan 
---
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt | 10 
++

 1 file changed, 10 insertions(+)

diff --git
a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
index dab7ca9..44d7e02 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -17,6 +17,12 @@ Required properties if child node exists:
 - #address-cells:  Must be <1> for Serial Engine Address
 - #size-cells: Must be <1> for Serial Engine Address Size
 - ranges:  Must be present
+- interconnects:   phandle to a interconnect provider. Please refer
+   ../interconnect/interconnect.txt for details.
+   Must be 2 paths corresponding to 2 AXI ports.
+- interconnect-names:  Port names to differentiate between the
+   2 interconnect paths defined with interconnect
+   specifier.

 Properties for children:

@@ -67,6 +73,10 @@ Example:
#size-cells = <1>;
ranges;

+   interconnects = < 11  512>,
+   < 0  543>;
+   interconnect-names = "qup-memory", "qup-config";
+
i2c0: i2c@a94000 {
compatible = "qcom,geni-i2c";
reg = <0xa94000 0x4000>;


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


Re: [PATCH 4/6] spi: spi-geni-qcom: Add interconnect support

2019-01-21 Thread alokc

On 2019-01-21 18:13, Mark Brown wrote:

On Mon, Jan 21, 2019 at 04:51:41PM +0530, Alok Chauhan wrote:

Get the interconnect paths for SPI based Serial Engine device
and vote accordingly based on maximum supported SPI frequency.


I don't have any of the other patches in this series or a cover letter 
-

what's going on with dependencies here?


I am extremely sorry to waste your time. Looks like I missed some 
mailing list while sending patches upstream. I will resend patches 
today.


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


Re: [PATCH 0/2] spi-geni-qcom: Cleanup nitpicks and simplify probe function

2018-10-25 Thread alokc

On 2018-10-25 22:10, Alok Chauhan wrote:

This patch series fixed the following:
* nitpicks from the previous review
 (https://patchwork.kernel.org/patch/10624849/)
* Cleanup probe function by re-arranging existing APIs to starting of
  function and hence avoiding one goto jump and remove few redundant
  variables.

Alok Chauhan (2):
  spi: spi-geni-qcom: fix nitpicks
  spi: spi-geni-qcom: Simplify probe function

 drivers/spi/spi-geni-qcom.c | 64 
+

 1 file changed, 30 insertions(+), 34 deletions(-)


Added more folks as some them got missed by get_maintainer.pl for this 
patch.


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


Re: [PATCH 0/2] spi-geni-qcom: Cleanup nitpicks and simplify probe function

2018-10-25 Thread alokc

On 2018-10-25 22:10, Alok Chauhan wrote:

This patch series fixed the following:
* nitpicks from the previous review
 (https://patchwork.kernel.org/patch/10624849/)
* Cleanup probe function by re-arranging existing APIs to starting of
  function and hence avoiding one goto jump and remove few redundant
  variables.

Alok Chauhan (2):
  spi: spi-geni-qcom: fix nitpicks
  spi: spi-geni-qcom: Simplify probe function

 drivers/spi/spi-geni-qcom.c | 64 
+

 1 file changed, 30 insertions(+), 34 deletions(-)


Added more folks as some them got missed by get_maintainer.pl for this 
patch.


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


Re: [PATCH V5 3/3] spi: spi-geni-qcom: Add SPI driver support for GENI based QUP

2018-10-11 Thread alokc

+static irqreturn_t geni_spi_isr(int irq, void *data)
+{
+   struct spi_master *spi = data;
+   struct spi_geni_master *mas = spi_master_get_devdata(spi);
+   struct geni_se *se = >se;
+   u32 m_irq;
+   unsigned long flags;
+   irqreturn_t ret = IRQ_HANDLED;
+
+   if (mas->cur_mcmd == CMD_NONE)
+   return IRQ_NONE;
+
+   spin_lock_irqsave(>lock, flags);
+   m_irq = readl(se->base + SE_GENI_M_IRQ_STATUS);
+
+   if ((m_irq & M_RX_FIFO_WATERMARK_EN) || (m_irq & 
M_RX_FIFO_LAST_EN))

+   geni_spi_handle_rx(mas);
+
+   if (m_irq & M_TX_FIFO_WATERMARK_EN)
+   geni_spi_handle_tx(mas);
+
+   if (m_irq & M_CMD_DONE_EN) {
+   if (mas->cur_mcmd == CMD_XFER)
+   spi_finalize_current_transfer(spi);
+   else if (mas->cur_mcmd == CMD_CS)
+   complete(>xfer_done);
+   mas->cur_mcmd = CMD_NONE;
+   /*
+* If this happens, then a CMD_DONE came before all 
the Tx
+* buffer bytes were sent out. This is unusual, log 
this
+* condition and disable the WM interrupt to prevent 
the

+* system from stalling due an interrupt storm.
+* If this happens when all Rx bytes haven't been 
received, log

+* the condition.
+* The only known time this can happen is if 
bits_per_word != 8
+* and some registers that expect xfer lengths in num 
spi_words

+* weren't written correctly.
+*/
+   if (mas->tx_rem_bytes) {
+   writel(0, se->base + 
SE_GENI_TX_WATERMARK_REG);
+   dev_err(mas->dev, "Premature done. tx_rem = %d 
bpw%d\n",
+   mas->tx_rem_bytes, 
mas->cur_bits_per_word);

+   }
+   if (mas->rx_rem_bytes)
+   dev_err(mas->dev, "Premature done. rx_rem = %d 
bpw%d\n",
+   mas->rx_rem_bytes, 
mas->cur_bits_per_word);

+   }
+
+   if ((m_irq & M_CMD_CANCEL_EN) || (m_irq & M_CMD_ABORT_EN)) {
+   mas->cur_mcmd = CMD_NONE;
+   complete(>xfer_done);
+   }
+
+   writel(m_irq, se->base + SE_GENI_M_IRQ_CLEAR);
+   spin_unlock_irqrestore(>lock, flags);
+   return ret;


Nitpick: Now this always returns IRQ_HANDLED, and we assign ret just to
do that. Perhaps only return IRQ_HANDLED if one of the above if
conditions is taken?


Not always. If ISR get triggered without setting proper cur_mcmd then it 
will return IRQ_NONE.


Re: [PATCH V5 3/3] spi: spi-geni-qcom: Add SPI driver support for GENI based QUP

2018-10-11 Thread alokc

+static irqreturn_t geni_spi_isr(int irq, void *data)
+{
+   struct spi_master *spi = data;
+   struct spi_geni_master *mas = spi_master_get_devdata(spi);
+   struct geni_se *se = >se;
+   u32 m_irq;
+   unsigned long flags;
+   irqreturn_t ret = IRQ_HANDLED;
+
+   if (mas->cur_mcmd == CMD_NONE)
+   return IRQ_NONE;
+
+   spin_lock_irqsave(>lock, flags);
+   m_irq = readl(se->base + SE_GENI_M_IRQ_STATUS);
+
+   if ((m_irq & M_RX_FIFO_WATERMARK_EN) || (m_irq & 
M_RX_FIFO_LAST_EN))

+   geni_spi_handle_rx(mas);
+
+   if (m_irq & M_TX_FIFO_WATERMARK_EN)
+   geni_spi_handle_tx(mas);
+
+   if (m_irq & M_CMD_DONE_EN) {
+   if (mas->cur_mcmd == CMD_XFER)
+   spi_finalize_current_transfer(spi);
+   else if (mas->cur_mcmd == CMD_CS)
+   complete(>xfer_done);
+   mas->cur_mcmd = CMD_NONE;
+   /*
+* If this happens, then a CMD_DONE came before all 
the Tx
+* buffer bytes were sent out. This is unusual, log 
this
+* condition and disable the WM interrupt to prevent 
the

+* system from stalling due an interrupt storm.
+* If this happens when all Rx bytes haven't been 
received, log

+* the condition.
+* The only known time this can happen is if 
bits_per_word != 8
+* and some registers that expect xfer lengths in num 
spi_words

+* weren't written correctly.
+*/
+   if (mas->tx_rem_bytes) {
+   writel(0, se->base + 
SE_GENI_TX_WATERMARK_REG);
+   dev_err(mas->dev, "Premature done. tx_rem = %d 
bpw%d\n",
+   mas->tx_rem_bytes, 
mas->cur_bits_per_word);

+   }
+   if (mas->rx_rem_bytes)
+   dev_err(mas->dev, "Premature done. rx_rem = %d 
bpw%d\n",
+   mas->rx_rem_bytes, 
mas->cur_bits_per_word);

+   }
+
+   if ((m_irq & M_CMD_CANCEL_EN) || (m_irq & M_CMD_ABORT_EN)) {
+   mas->cur_mcmd = CMD_NONE;
+   complete(>xfer_done);
+   }
+
+   writel(m_irq, se->base + SE_GENI_M_IRQ_CLEAR);
+   spin_unlock_irqrestore(>lock, flags);
+   return ret;


Nitpick: Now this always returns IRQ_HANDLED, and we assign ret just to
do that. Perhaps only return IRQ_HANDLED if one of the above if
conditions is taken?


Not always. If ISR get triggered without setting proper cur_mcmd then it 
will return IRQ_NONE.


Re: [PATCH v3 3/3] i2c: i2c-qcom-geni: Simplify irq handler

2018-10-04 Thread alokc

On 2018-09-26 03:19, Doug Anderson wrote:

Hi,

On Mon, Sep 24, 2018 at 4:52 PM Stephen Boyd  
wrote:


We don't need to use goto here, we can just collapse the if statement
and goto chain into multiple branches and then combine some duplicate
completion calls into one big if statement. Let's do it to clean up 
code

some more.

Cc: Karthikeyan Ramasubramanian 
Cc: Sagar Dharia 
Cc: Girish Mahadevan 
Cc: Doug Anderson 
Signed-off-by: Stephen Boyd 
---
 drivers/i2c/busses/i2c-qcom-geni.c | 70 
+-

 1 file changed, 29 insertions(+), 41 deletions(-)


It doesn't gleam as powerfully the cleanups in patch 2/3 but this does
have a few nice readability improvements.

Reviewed-by: Douglas Anderson 


agree.

Reviewed-by: Alok Chauhan 

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


Re: [PATCH v3 3/3] i2c: i2c-qcom-geni: Simplify irq handler

2018-10-04 Thread alokc

On 2018-09-26 03:19, Doug Anderson wrote:

Hi,

On Mon, Sep 24, 2018 at 4:52 PM Stephen Boyd  
wrote:


We don't need to use goto here, we can just collapse the if statement
and goto chain into multiple branches and then combine some duplicate
completion calls into one big if statement. Let's do it to clean up 
code

some more.

Cc: Karthikeyan Ramasubramanian 
Cc: Sagar Dharia 
Cc: Girish Mahadevan 
Cc: Doug Anderson 
Signed-off-by: Stephen Boyd 
---
 drivers/i2c/busses/i2c-qcom-geni.c | 70 
+-

 1 file changed, 29 insertions(+), 41 deletions(-)


It doesn't gleam as powerfully the cleanups in patch 2/3 but this does
have a few nice readability improvements.

Reviewed-by: Douglas Anderson 


agree.

Reviewed-by: Alok Chauhan 

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


Re: [PATCH v3 2/3] i2c: i2c-qcom-geni: Simplify tx/rx functions

2018-10-04 Thread alokc

On 2018-09-25 05:22, Stephen Boyd wrote:

We never really look at the 'ret' local variable in these functions, so
let's remove it to make way for shorter and simpler code. Furthermore,
we can shorten some lines by adding two local variables for the SE and
the message length so that everything fits in 80 columns and testing 
the

'dma_buf' local variable in lieu of the 'mode' local variable.  And
kernel style is to leave the return statement by itself, detached from
the rest of the function.

Cc: Karthikeyan Ramasubramanian 
Cc: Sagar Dharia 
Cc: Girish Mahadevan 
Cc: Doug Anderson 
Signed-off-by: Stephen Boyd 
---


changes looks more clean now.

Reviewed-by: Alok Chauhan 


 drivers/i2c/busses/i2c-qcom-geni.c | 79 ++
 1 file changed, 36 insertions(+), 43 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c
b/drivers/i2c/busses/i2c-qcom-geni.c
index 9f2eb02481d3..0b466835cf40 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -365,29 +365,24 @@ static int geni_i2c_rx_one_msg(struct
geni_i2c_dev *gi2c, struct i2c_msg *msg,
u32 m_param)
 {
dma_addr_t rx_dma;
-   enum geni_se_xfer_mode mode;
-   unsigned long time_left = XFER_TIMEOUT;
+   unsigned long time_left;
void *dma_buf;
+   struct geni_se *se = >se;
+   size_t len = msg->len;

-   gi2c->cur = msg;
-   mode = GENI_SE_FIFO;
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
if (dma_buf)
-   mode = GENI_SE_DMA;
-
-   geni_se_select_mode(>se, mode);
-   writel_relaxed(msg->len, gi2c->se.base + SE_I2C_RX_TRANS_LEN);
-   geni_se_setup_m_cmd(>se, I2C_READ, m_param);
-   if (mode == GENI_SE_DMA) {
-   int ret;
-
-   ret = geni_se_rx_dma_prep(>se, dma_buf, msg->len,
-   _dma);
-   if (ret) {
-   mode = GENI_SE_FIFO;
-   geni_se_select_mode(>se, mode);
-   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-   }
+   geni_se_select_mode(se, GENI_SE_DMA);
+   else
+   geni_se_select_mode(se, GENI_SE_FIFO);
+
+   writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
+   geni_se_setup_m_cmd(se, I2C_READ, m_param);
+
+   if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, _dma)) {
+   geni_se_select_mode(se, GENI_SE_FIFO);
+   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+   dma_buf = NULL;
}

time_left = wait_for_completion_timeout(>done, XFER_TIMEOUT);
@@ -395,12 +390,13 @@ static int geni_i2c_rx_one_msg(struct
geni_i2c_dev *gi2c, struct i2c_msg *msg,
geni_i2c_abort_xfer(gi2c);

gi2c->cur_rd = 0;
-   if (mode == GENI_SE_DMA) {
+   if (dma_buf) {
if (gi2c->err)
geni_i2c_rx_fsm_rst(gi2c);
-   geni_se_rx_dma_unprep(>se, rx_dma, msg->len);
+   geni_se_rx_dma_unprep(se, rx_dma, len);
i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
}
+
return gi2c->err;
 }

@@ -408,45 +404,41 @@ static int geni_i2c_tx_one_msg(struct
geni_i2c_dev *gi2c, struct i2c_msg *msg,
u32 m_param)
 {
dma_addr_t tx_dma;
-   enum geni_se_xfer_mode mode;
unsigned long time_left;
void *dma_buf;
+   struct geni_se *se = >se;
+   size_t len = msg->len;

-   gi2c->cur = msg;
-   mode = GENI_SE_FIFO;
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
if (dma_buf)
-   mode = GENI_SE_DMA;
-
-   geni_se_select_mode(>se, mode);
-   writel_relaxed(msg->len, gi2c->se.base + SE_I2C_TX_TRANS_LEN);
-   geni_se_setup_m_cmd(>se, I2C_WRITE, m_param);
-   if (mode == GENI_SE_DMA) {
-   int ret;
-
-   ret = geni_se_tx_dma_prep(>se, dma_buf, msg->len,
-   _dma);
-   if (ret) {
-   mode = GENI_SE_FIFO;
-   geni_se_select_mode(>se, mode);
-   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-   }
+   geni_se_select_mode(se, GENI_SE_DMA);
+   else
+   geni_se_select_mode(se, GENI_SE_FIFO);
+
+   writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
+   geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
+
+   if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, _dma)) {
+   geni_se_select_mode(se, GENI_SE_FIFO);
+   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+   dma_buf = NULL;
}

-   if (mode == GENI_SE_FIFO) /* Get FIFO IRQ */
-   writel_relaxed(1, gi2c->se.base + SE_GENI_TX_WATERMARK_REG);
+   if (!dma_buf) /* Get FIFO IRQ */
+   writel_relaxed(1, se->base + 

Re: [PATCH v3 2/3] i2c: i2c-qcom-geni: Simplify tx/rx functions

2018-10-04 Thread alokc

On 2018-09-25 05:22, Stephen Boyd wrote:

We never really look at the 'ret' local variable in these functions, so
let's remove it to make way for shorter and simpler code. Furthermore,
we can shorten some lines by adding two local variables for the SE and
the message length so that everything fits in 80 columns and testing 
the

'dma_buf' local variable in lieu of the 'mode' local variable.  And
kernel style is to leave the return statement by itself, detached from
the rest of the function.

Cc: Karthikeyan Ramasubramanian 
Cc: Sagar Dharia 
Cc: Girish Mahadevan 
Cc: Doug Anderson 
Signed-off-by: Stephen Boyd 
---


changes looks more clean now.

Reviewed-by: Alok Chauhan 


 drivers/i2c/busses/i2c-qcom-geni.c | 79 ++
 1 file changed, 36 insertions(+), 43 deletions(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c
b/drivers/i2c/busses/i2c-qcom-geni.c
index 9f2eb02481d3..0b466835cf40 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -365,29 +365,24 @@ static int geni_i2c_rx_one_msg(struct
geni_i2c_dev *gi2c, struct i2c_msg *msg,
u32 m_param)
 {
dma_addr_t rx_dma;
-   enum geni_se_xfer_mode mode;
-   unsigned long time_left = XFER_TIMEOUT;
+   unsigned long time_left;
void *dma_buf;
+   struct geni_se *se = >se;
+   size_t len = msg->len;

-   gi2c->cur = msg;
-   mode = GENI_SE_FIFO;
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
if (dma_buf)
-   mode = GENI_SE_DMA;
-
-   geni_se_select_mode(>se, mode);
-   writel_relaxed(msg->len, gi2c->se.base + SE_I2C_RX_TRANS_LEN);
-   geni_se_setup_m_cmd(>se, I2C_READ, m_param);
-   if (mode == GENI_SE_DMA) {
-   int ret;
-
-   ret = geni_se_rx_dma_prep(>se, dma_buf, msg->len,
-   _dma);
-   if (ret) {
-   mode = GENI_SE_FIFO;
-   geni_se_select_mode(>se, mode);
-   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-   }
+   geni_se_select_mode(se, GENI_SE_DMA);
+   else
+   geni_se_select_mode(se, GENI_SE_FIFO);
+
+   writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN);
+   geni_se_setup_m_cmd(se, I2C_READ, m_param);
+
+   if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, _dma)) {
+   geni_se_select_mode(se, GENI_SE_FIFO);
+   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+   dma_buf = NULL;
}

time_left = wait_for_completion_timeout(>done, XFER_TIMEOUT);
@@ -395,12 +390,13 @@ static int geni_i2c_rx_one_msg(struct
geni_i2c_dev *gi2c, struct i2c_msg *msg,
geni_i2c_abort_xfer(gi2c);

gi2c->cur_rd = 0;
-   if (mode == GENI_SE_DMA) {
+   if (dma_buf) {
if (gi2c->err)
geni_i2c_rx_fsm_rst(gi2c);
-   geni_se_rx_dma_unprep(>se, rx_dma, msg->len);
+   geni_se_rx_dma_unprep(se, rx_dma, len);
i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err);
}
+
return gi2c->err;
 }

@@ -408,45 +404,41 @@ static int geni_i2c_tx_one_msg(struct
geni_i2c_dev *gi2c, struct i2c_msg *msg,
u32 m_param)
 {
dma_addr_t tx_dma;
-   enum geni_se_xfer_mode mode;
unsigned long time_left;
void *dma_buf;
+   struct geni_se *se = >se;
+   size_t len = msg->len;

-   gi2c->cur = msg;
-   mode = GENI_SE_FIFO;
dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
if (dma_buf)
-   mode = GENI_SE_DMA;
-
-   geni_se_select_mode(>se, mode);
-   writel_relaxed(msg->len, gi2c->se.base + SE_I2C_TX_TRANS_LEN);
-   geni_se_setup_m_cmd(>se, I2C_WRITE, m_param);
-   if (mode == GENI_SE_DMA) {
-   int ret;
-
-   ret = geni_se_tx_dma_prep(>se, dma_buf, msg->len,
-   _dma);
-   if (ret) {
-   mode = GENI_SE_FIFO;
-   geni_se_select_mode(>se, mode);
-   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
-   }
+   geni_se_select_mode(se, GENI_SE_DMA);
+   else
+   geni_se_select_mode(se, GENI_SE_FIFO);
+
+   writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN);
+   geni_se_setup_m_cmd(se, I2C_WRITE, m_param);
+
+   if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, _dma)) {
+   geni_se_select_mode(se, GENI_SE_FIFO);
+   i2c_put_dma_safe_msg_buf(dma_buf, msg, false);
+   dma_buf = NULL;
}

-   if (mode == GENI_SE_FIFO) /* Get FIFO IRQ */
-   writel_relaxed(1, gi2c->se.base + SE_GENI_TX_WATERMARK_REG);
+   if (!dma_buf) /* Get FIFO IRQ */
+   writel_relaxed(1, se->base +