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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
Get the interconnect paths for SPI based Serial Engine device
and vote accordingly based on maximum supported SPI frequency.

Signed-off-by: Alok Chauhan 
---
 drivers/spi/spi-geni-qcom.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index fdb7cb88..7bbbe9d 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* SPI SE specific registers and respective register fields */
 #define SE_SPI_CPHA0x224
@@ -589,6 +590,15 @@ static int spi_geni_probe(struct platform_device *pdev)
spin_lock_init(>lock);
pm_runtime_enable(>dev);
 
+   /* Set the bus quota to a reasonable value */
+   mas->se.avg_bw = Bps_to_icc(2500);
+   mas->se.peak_bw = Bps_to_icc(2);
+   ret = geni_interconnect_init(>se);
+   if (ret) {
+   dev_err(>dev, "interconnect_init failed %d\n", ret);
+   return ret;
+   }
+
ret = spi_geni_init(mas);
if (ret)
goto spi_geni_probe_runtime_disable;
@@ -628,8 +638,15 @@ static int __maybe_unused spi_geni_runtime_suspend(struct 
device *dev)
 {
struct spi_master *spi = dev_get_drvdata(dev);
struct spi_geni_master *mas = spi_master_get_devdata(spi);
+   int ret;
 
-   return geni_se_resources_off(>se);
+   ret = geni_se_resources_off(>se);
+   if (ret)
+   return ret;
+
+   geni_icc_update_bw(>se, false);
+
+   return 0;
 }
 
 static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
@@ -637,6 +654,7 @@ static int __maybe_unused spi_geni_runtime_resume(struct 
device *dev)
struct spi_master *spi = dev_get_drvdata(dev);
struct spi_geni_master *mas = spi_master_get_devdata(spi);
 
+   geni_icc_update_bw(>se, true);
return geni_se_resources_on(>se);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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))

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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
Get the interconnect paths for SPI based Serial Engine device
and vote accordingly based on maximum supported SPI frequency.

Signed-off-by: Alok Chauhan 
---
 drivers/spi/spi-geni-qcom.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index fdb7cb88..7bbbe9d 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* SPI SE specific registers and respective register fields */
 #define SE_SPI_CPHA0x224
@@ -589,6 +590,15 @@ static int spi_geni_probe(struct platform_device *pdev)
spin_lock_init(>lock);
pm_runtime_enable(>dev);
 
+   /* Set the bus quota to a reasonable value */
+   mas->se.avg_bw = Bps_to_icc(2500);
+   mas->se.peak_bw = Bps_to_icc(2);
+   ret = geni_interconnect_init(>se);
+   if (ret) {
+   dev_err(>dev, "interconnect_init failed %d\n", ret);
+   return ret;
+   }
+
ret = spi_geni_init(mas);
if (ret)
goto spi_geni_probe_runtime_disable;
@@ -628,8 +638,15 @@ static int __maybe_unused spi_geni_runtime_suspend(struct 
device *dev)
 {
struct spi_master *spi = dev_get_drvdata(dev);
struct spi_geni_master *mas = spi_master_get_devdata(spi);
+   int ret;
 
-   return geni_se_resources_off(>se);
+   ret = geni_se_resources_off(>se);
+   if (ret)
+   return ret;
+
+   geni_icc_update_bw(>se, false);
+
+   return 0;
 }
 
 static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
@@ -637,6 +654,7 @@ static int __maybe_unused spi_geni_runtime_resume(struct 
device *dev)
struct spi_master *spi = dev_get_drvdata(dev);
struct spi_geni_master *mas = spi_master_get_devdata(spi);
 
+   geni_icc_update_bw(>se, true);
return geni_se_resources_on(>se);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



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

2019-01-21 Thread Alok Chauhan
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



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

2019-01-21 Thread Alok Chauhan
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))

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

2019-01-21 Thread Alok Chauhan
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



[PATCH 1/2] spi: spi-geni-qcom: fix nitpicks

2018-10-25 Thread Alok Chauhan
fixed the nitpicks.

Signed-off-by: Alok Chauhan 
---
 drivers/spi/spi-geni-qcom.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 6432ecc..d1830fb 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -64,15 +64,13 @@
 #define TIMESTAMP_AFTERBIT(3)
 #define POST_CMD_DELAY BIT(4)
 
-/* SPI M_COMMAND OPCODE */
-enum spi_mcmd_code {
+enum spi_m_cmd_opcode {
CMD_NONE,
CMD_XFER,
CMD_CS,
CMD_CANCEL,
 };
 
-
 struct spi_geni_master {
struct geni_se se;
struct device *dev;
@@ -87,7 +85,7 @@ struct spi_geni_master {
struct completion xfer_done;
unsigned int oversampling;
spinlock_t lock;
-   unsigned int cur_mcmd;
+   enum spi_m_cmd_opcode cur_mcmd;
int irq;
 };
 
@@ -129,7 +127,7 @@ static void spi_geni_set_cs(struct spi_device *slv, bool 
set_flag)
struct spi_geni_master *mas = spi_master_get_devdata(slv->master);
struct spi_master *spi = dev_get_drvdata(mas->dev);
struct geni_se *se = >se;
-   unsigned long timeout;
+   unsigned long time_left;
 
reinit_completion(>xfer_done);
pm_runtime_get_sync(mas->dev);
@@ -142,8 +140,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool 
set_flag)
else
geni_se_setup_m_cmd(se, SPI_CS_DEASSERT, 0);
 
-   timeout = wait_for_completion_timeout(>xfer_done, HZ);
-   if (!timeout)
+   time_left = wait_for_completion_timeout(>xfer_done, HZ);
+   if (!time_left)
handle_fifo_timeout(spi, NULL);
 
pm_runtime_put(mas->dev);
@@ -485,7 +483,6 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
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;
@@ -533,7 +530,7 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
 
writel(m_irq, se->base + SE_GENI_M_IRQ_CLEAR);
spin_unlock_irqrestore(>lock, flags);
-   return ret;
+   return IRQ_HANDLED;
 }
 
 static int spi_geni_probe(struct platform_device *pdev)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 2/2] spi: spi-geni-qcom: Simplify probe function

2018-10-25 Thread Alok Chauhan
Re-arrange existing APIs in probe function to
avoid using goto and remove redundant variables.

Signed-off-by: Alok Chauhan 
---
 drivers/spi/spi-geni-qcom.c | 49 ++---
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index d1830fb..fdb7cb88 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -535,11 +535,30 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
 
 static int spi_geni_probe(struct platform_device *pdev)
 {
-   int ret;
+   int ret, irq;
struct spi_master *spi;
struct spi_geni_master *mas;
struct resource *res;
-   struct geni_se *se;
+   void __iomem *base;
+   struct clk *clk;
+
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
+   dev_err(>dev, "Err getting IRQ %d\n", irq);
+   return irq;
+   }
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(base))
+   return PTR_ERR(base);
+
+   clk = devm_clk_get(>dev, "se");
+   if (IS_ERR(clk)) {
+   dev_err(>dev, "Err getting SE Core clk %ld\n",
+   PTR_ERR(clk));
+   return PTR_ERR(clk);
+   }
 
spi = spi_alloc_master(>dev, sizeof(*mas));
if (!spi)
@@ -547,27 +566,15 @@ static int spi_geni_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, spi);
mas = spi_master_get_devdata(spi);
+   mas->irq = irq;
mas->dev = >dev;
mas->se.dev = >dev;
mas->se.wrapper = dev_get_drvdata(pdev->dev.parent);
-   se = >se;
+   mas->se.base = base;
+   mas->se.clk = clk;
 
spi->bus_num = -1;
spi->dev.of_node = pdev->dev.of_node;
-   mas->se.clk = devm_clk_get(>dev, "se");
-   if (IS_ERR(mas->se.clk)) {
-   ret = PTR_ERR(mas->se.clk);
-   dev_err(>dev, "Err getting SE Core clk %d\n", ret);
-   goto spi_geni_probe_err;
-   }
-
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   se->base = devm_ioremap_resource(>dev, res);
-   if (IS_ERR(se->base)) {
-   ret = PTR_ERR(se->base);
-   goto spi_geni_probe_err;
-   }
-
spi->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH;
spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
spi->num_chipselect = 4;
@@ -586,13 +593,6 @@ static int spi_geni_probe(struct platform_device *pdev)
if (ret)
goto spi_geni_probe_runtime_disable;
 
-   mas->irq = platform_get_irq(pdev, 0);
-   if (mas->irq < 0) {
-   ret = mas->irq;
-   dev_err(>dev, "Err getting IRQ %d\n", ret);
-   goto spi_geni_probe_runtime_disable;
-   }
-
ret = request_irq(mas->irq, geni_spi_isr,
IRQF_TRIGGER_HIGH, "spi_geni", spi);
if (ret)
@@ -607,7 +607,6 @@ static int spi_geni_probe(struct platform_device *pdev)
free_irq(mas->irq, spi);
 spi_geni_probe_runtime_disable:
pm_runtime_disable(>dev);
-spi_geni_probe_err:
spi_master_put(spi);
return ret;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 1/2] spi: spi-geni-qcom: fix nitpicks

2018-10-25 Thread Alok Chauhan
fixed the nitpicks.

Signed-off-by: Alok Chauhan 
---
 drivers/spi/spi-geni-qcom.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 6432ecc..d1830fb 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -64,15 +64,13 @@
 #define TIMESTAMP_AFTERBIT(3)
 #define POST_CMD_DELAY BIT(4)
 
-/* SPI M_COMMAND OPCODE */
-enum spi_mcmd_code {
+enum spi_m_cmd_opcode {
CMD_NONE,
CMD_XFER,
CMD_CS,
CMD_CANCEL,
 };
 
-
 struct spi_geni_master {
struct geni_se se;
struct device *dev;
@@ -87,7 +85,7 @@ struct spi_geni_master {
struct completion xfer_done;
unsigned int oversampling;
spinlock_t lock;
-   unsigned int cur_mcmd;
+   enum spi_m_cmd_opcode cur_mcmd;
int irq;
 };
 
@@ -129,7 +127,7 @@ static void spi_geni_set_cs(struct spi_device *slv, bool 
set_flag)
struct spi_geni_master *mas = spi_master_get_devdata(slv->master);
struct spi_master *spi = dev_get_drvdata(mas->dev);
struct geni_se *se = >se;
-   unsigned long timeout;
+   unsigned long time_left;
 
reinit_completion(>xfer_done);
pm_runtime_get_sync(mas->dev);
@@ -142,8 +140,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool 
set_flag)
else
geni_se_setup_m_cmd(se, SPI_CS_DEASSERT, 0);
 
-   timeout = wait_for_completion_timeout(>xfer_done, HZ);
-   if (!timeout)
+   time_left = wait_for_completion_timeout(>xfer_done, HZ);
+   if (!time_left)
handle_fifo_timeout(spi, NULL);
 
pm_runtime_put(mas->dev);
@@ -485,7 +483,6 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
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;
@@ -533,7 +530,7 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
 
writel(m_irq, se->base + SE_GENI_M_IRQ_CLEAR);
spin_unlock_irqrestore(>lock, flags);
-   return ret;
+   return IRQ_HANDLED;
 }
 
 static int spi_geni_probe(struct platform_device *pdev)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH 2/2] spi: spi-geni-qcom: Simplify probe function

2018-10-25 Thread Alok Chauhan
Re-arrange existing APIs in probe function to
avoid using goto and remove redundant variables.

Signed-off-by: Alok Chauhan 
---
 drivers/spi/spi-geni-qcom.c | 49 ++---
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index d1830fb..fdb7cb88 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -535,11 +535,30 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
 
 static int spi_geni_probe(struct platform_device *pdev)
 {
-   int ret;
+   int ret, irq;
struct spi_master *spi;
struct spi_geni_master *mas;
struct resource *res;
-   struct geni_se *se;
+   void __iomem *base;
+   struct clk *clk;
+
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
+   dev_err(>dev, "Err getting IRQ %d\n", irq);
+   return irq;
+   }
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(base))
+   return PTR_ERR(base);
+
+   clk = devm_clk_get(>dev, "se");
+   if (IS_ERR(clk)) {
+   dev_err(>dev, "Err getting SE Core clk %ld\n",
+   PTR_ERR(clk));
+   return PTR_ERR(clk);
+   }
 
spi = spi_alloc_master(>dev, sizeof(*mas));
if (!spi)
@@ -547,27 +566,15 @@ static int spi_geni_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, spi);
mas = spi_master_get_devdata(spi);
+   mas->irq = irq;
mas->dev = >dev;
mas->se.dev = >dev;
mas->se.wrapper = dev_get_drvdata(pdev->dev.parent);
-   se = >se;
+   mas->se.base = base;
+   mas->se.clk = clk;
 
spi->bus_num = -1;
spi->dev.of_node = pdev->dev.of_node;
-   mas->se.clk = devm_clk_get(>dev, "se");
-   if (IS_ERR(mas->se.clk)) {
-   ret = PTR_ERR(mas->se.clk);
-   dev_err(>dev, "Err getting SE Core clk %d\n", ret);
-   goto spi_geni_probe_err;
-   }
-
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   se->base = devm_ioremap_resource(>dev, res);
-   if (IS_ERR(se->base)) {
-   ret = PTR_ERR(se->base);
-   goto spi_geni_probe_err;
-   }
-
spi->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH;
spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
spi->num_chipselect = 4;
@@ -586,13 +593,6 @@ static int spi_geni_probe(struct platform_device *pdev)
if (ret)
goto spi_geni_probe_runtime_disable;
 
-   mas->irq = platform_get_irq(pdev, 0);
-   if (mas->irq < 0) {
-   ret = mas->irq;
-   dev_err(>dev, "Err getting IRQ %d\n", ret);
-   goto spi_geni_probe_runtime_disable;
-   }
-
ret = request_irq(mas->irq, geni_spi_isr,
IRQF_TRIGGER_HIGH, "spi_geni", spi);
if (ret)
@@ -607,7 +607,6 @@ static int spi_geni_probe(struct platform_device *pdev)
free_irq(mas->irq, spi);
 spi_geni_probe_runtime_disable:
pm_runtime_disable(>dev);
-spi_geni_probe_err:
spi_master_put(spi);
return ret;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



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

2018-10-03 Thread Alok Chauhan
From: Girish Mahadevan 

This driver supports GENI based SPI Controller in the Qualcomm SOCs. The
Qualcomm Generic Interface (GENI) is a programmable module supporting a
wide range of serial interfaces including SPI. This driver supports SPI
operations using FIFO mode of transfer.

Signed-off-by: Girish Mahadevan 
Signed-off-by: Dilip Kota 
Signed-off-by: Alok Chauhan 
---
 drivers/spi/Kconfig |  12 +
 drivers/spi/Makefile|   1 +
 drivers/spi/spi-geni-qcom.c | 703 
 3 files changed, 716 insertions(+)
 create mode 100644 drivers/spi/spi-geni-qcom.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 671d078..51edc76 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -533,6 +533,18 @@ config SPI_QUP
  This driver can also be built as a module.  If so, the module
  will be called spi_qup.
 
+config SPI_QCOM_GENI
+   tristate "Qualcomm GENI based SPI controller"
+   depends on QCOM_GENI_SE
+   help
+ This driver supports GENI serial engine based SPI controller in
+ master mode on the Qualcomm Technologies Inc.'s SoCs. If you say
+ yes to this option, support will be included for the built-in SPI
+ interface on the Qualcomm Technologies Inc.'s SoCs.
+
+ This driver can also be built as a module.  If so, the module
+ will be called spi-geni-qcom.
+
 config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on ARCH_S3C24XX
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index a90d559..b057c9c 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_SPI_PPC4xx)  += spi-ppc4xx.o
 spi-pxa2xx-platform-objs   := spi-pxa2xx.o spi-pxa2xx-dma.o
 obj-$(CONFIG_SPI_PXA2XX)   += spi-pxa2xx-platform.o
 obj-$(CONFIG_SPI_PXA2XX_PCI)   += spi-pxa2xx-pci.o
+obj-$(CONFIG_SPI_QCOM_GENI)+= spi-geni-qcom.o
 obj-$(CONFIG_SPI_QUP)  += spi-qup.o
 obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
 obj-$(CONFIG_SPI_RB4XX)+= spi-rb4xx.o
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
new file mode 100644
index 000..6432ecc
--- /dev/null
+++ b/drivers/spi/spi-geni-qcom.c
@@ -0,0 +1,703 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* SPI SE specific registers and respective register fields */
+#define SE_SPI_CPHA0x224
+#define CPHA   BIT(0)
+
+#define SE_SPI_LOOPBACK0x22c
+#define LOOPBACK_ENABLE0x1
+#define NORMAL_MODE0x0
+#define LOOPBACK_MSK   GENMASK(1, 0)
+
+#define SE_SPI_CPOL0x230
+#define CPOL   BIT(2)
+
+#define SE_SPI_DEMUX_OUTPUT_INV0x24c
+#define CS_DEMUX_OUTPUT_INV_MSKGENMASK(3, 0)
+
+#define SE_SPI_DEMUX_SEL   0x250
+#define CS_DEMUX_OUTPUT_SELGENMASK(3, 0)
+
+#define SE_SPI_TRANS_CFG   0x25c
+#define CS_TOGGLE  BIT(0)
+
+#define SE_SPI_WORD_LEN0x268
+#define WORD_LEN_MSK   GENMASK(9, 0)
+#define MIN_WORD_LEN   4
+
+#define SE_SPI_TX_TRANS_LEN0x26c
+#define SE_SPI_RX_TRANS_LEN0x270
+#define TRANS_LEN_MSK  GENMASK(23, 0)
+
+#define SE_SPI_PRE_POST_CMD_DLY0x274
+
+#define SE_SPI_DELAY_COUNTERS  0x278
+#define SPI_INTER_WORDS_DELAY_MSK  GENMASK(9, 0)
+#define SPI_CS_CLK_DELAY_MSK   GENMASK(19, 10)
+#define SPI_CS_CLK_DELAY_SHFT  10
+
+/* M_CMD OP codes for SPI */
+#define SPI_TX_ONLY1
+#define SPI_RX_ONLY2
+#define SPI_FULL_DUPLEX3
+#define SPI_TX_RX  7
+#define SPI_CS_ASSERT  8
+#define SPI_CS_DEASSERT9
+#define SPI_SCK_ONLY   10
+/* M_CMD params for SPI */
+#define SPI_PRE_CMD_DELAY  BIT(0)
+#define TIMESTAMP_BEFORE   BIT(1)
+#define FRAGMENTATION  BIT(2)
+#define TIMESTAMP_AFTERBIT(3)
+#define POST_CMD_DELAY BIT(4)
+
+/* SPI M_COMMAND OPCODE */
+enum spi_mcmd_code {
+   CMD_NONE,
+   CMD_XFER,
+   CMD_CS,
+   CMD_CANCEL,
+};
+
+
+struct spi_geni_master {
+   struct geni_se se;
+   struct device *dev;
+   u32 tx_fifo_depth;
+   u32 fifo_width_bits;
+   u32 tx_wm;
+   unsigned long cur_speed_hz;
+   unsigned int cur_bits_per_word;
+   unsigned int tx_rem_bytes;
+   unsigned int rx_rem_bytes;
+   const struct spi_transfer *cur_xfer;
+   struct completion xfer_done;
+   unsigned int oversampling;
+   spinlock_t lock;
+   unsigned int cur_mcmd;
+   int irq;
+};
+
+static void handle_fifo_timeout(struct spi_master *spi,
+   str

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

2018-10-03 Thread Alok Chauhan
From: Girish Mahadevan 

This driver supports GENI based SPI Controller in the Qualcomm SOCs. The
Qualcomm Generic Interface (GENI) is a programmable module supporting a
wide range of serial interfaces including SPI. This driver supports SPI
operations using FIFO mode of transfer.

Signed-off-by: Girish Mahadevan 
Signed-off-by: Dilip Kota 
Signed-off-by: Alok Chauhan 
---
 drivers/spi/Kconfig |  12 +
 drivers/spi/Makefile|   1 +
 drivers/spi/spi-geni-qcom.c | 703 
 3 files changed, 716 insertions(+)
 create mode 100644 drivers/spi/spi-geni-qcom.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 671d078..51edc76 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -533,6 +533,18 @@ config SPI_QUP
  This driver can also be built as a module.  If so, the module
  will be called spi_qup.
 
+config SPI_QCOM_GENI
+   tristate "Qualcomm GENI based SPI controller"
+   depends on QCOM_GENI_SE
+   help
+ This driver supports GENI serial engine based SPI controller in
+ master mode on the Qualcomm Technologies Inc.'s SoCs. If you say
+ yes to this option, support will be included for the built-in SPI
+ interface on the Qualcomm Technologies Inc.'s SoCs.
+
+ This driver can also be built as a module.  If so, the module
+ will be called spi-geni-qcom.
+
 config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on ARCH_S3C24XX
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index a90d559..b057c9c 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_SPI_PPC4xx)  += spi-ppc4xx.o
 spi-pxa2xx-platform-objs   := spi-pxa2xx.o spi-pxa2xx-dma.o
 obj-$(CONFIG_SPI_PXA2XX)   += spi-pxa2xx-platform.o
 obj-$(CONFIG_SPI_PXA2XX_PCI)   += spi-pxa2xx-pci.o
+obj-$(CONFIG_SPI_QCOM_GENI)+= spi-geni-qcom.o
 obj-$(CONFIG_SPI_QUP)  += spi-qup.o
 obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
 obj-$(CONFIG_SPI_RB4XX)+= spi-rb4xx.o
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
new file mode 100644
index 000..6432ecc
--- /dev/null
+++ b/drivers/spi/spi-geni-qcom.c
@@ -0,0 +1,703 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* SPI SE specific registers and respective register fields */
+#define SE_SPI_CPHA0x224
+#define CPHA   BIT(0)
+
+#define SE_SPI_LOOPBACK0x22c
+#define LOOPBACK_ENABLE0x1
+#define NORMAL_MODE0x0
+#define LOOPBACK_MSK   GENMASK(1, 0)
+
+#define SE_SPI_CPOL0x230
+#define CPOL   BIT(2)
+
+#define SE_SPI_DEMUX_OUTPUT_INV0x24c
+#define CS_DEMUX_OUTPUT_INV_MSKGENMASK(3, 0)
+
+#define SE_SPI_DEMUX_SEL   0x250
+#define CS_DEMUX_OUTPUT_SELGENMASK(3, 0)
+
+#define SE_SPI_TRANS_CFG   0x25c
+#define CS_TOGGLE  BIT(0)
+
+#define SE_SPI_WORD_LEN0x268
+#define WORD_LEN_MSK   GENMASK(9, 0)
+#define MIN_WORD_LEN   4
+
+#define SE_SPI_TX_TRANS_LEN0x26c
+#define SE_SPI_RX_TRANS_LEN0x270
+#define TRANS_LEN_MSK  GENMASK(23, 0)
+
+#define SE_SPI_PRE_POST_CMD_DLY0x274
+
+#define SE_SPI_DELAY_COUNTERS  0x278
+#define SPI_INTER_WORDS_DELAY_MSK  GENMASK(9, 0)
+#define SPI_CS_CLK_DELAY_MSK   GENMASK(19, 10)
+#define SPI_CS_CLK_DELAY_SHFT  10
+
+/* M_CMD OP codes for SPI */
+#define SPI_TX_ONLY1
+#define SPI_RX_ONLY2
+#define SPI_FULL_DUPLEX3
+#define SPI_TX_RX  7
+#define SPI_CS_ASSERT  8
+#define SPI_CS_DEASSERT9
+#define SPI_SCK_ONLY   10
+/* M_CMD params for SPI */
+#define SPI_PRE_CMD_DELAY  BIT(0)
+#define TIMESTAMP_BEFORE   BIT(1)
+#define FRAGMENTATION  BIT(2)
+#define TIMESTAMP_AFTERBIT(3)
+#define POST_CMD_DELAY BIT(4)
+
+/* SPI M_COMMAND OPCODE */
+enum spi_mcmd_code {
+   CMD_NONE,
+   CMD_XFER,
+   CMD_CS,
+   CMD_CANCEL,
+};
+
+
+struct spi_geni_master {
+   struct geni_se se;
+   struct device *dev;
+   u32 tx_fifo_depth;
+   u32 fifo_width_bits;
+   u32 tx_wm;
+   unsigned long cur_speed_hz;
+   unsigned int cur_bits_per_word;
+   unsigned int tx_rem_bytes;
+   unsigned int rx_rem_bytes;
+   const struct spi_transfer *cur_xfer;
+   struct completion xfer_done;
+   unsigned int oversampling;
+   spinlock_t lock;
+   unsigned int cur_mcmd;
+   int irq;
+};
+
+static void handle_fifo_timeout(struct spi_master *spi,
+   str

[PATCH V5 2/3] dt-bindings: soc: qcom: GENI SE SPI controller device tree binding

2018-10-03 Thread Alok Chauhan
From: Dilip Kota 

Move GENI SE SPI controller device-tree bindings
from devicetree/bindings/soc/qcom/qcom,geni-se.txt
to devicetree/bindings/spi/qcom,spi-geni-qcom.txt.

Signed-off-by: Dilip Kota 
Reviewed-by: Douglas Anderson 
Reviewed-by: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Alok Chauhan 
---
 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  | 27 ++-
 .../devicetree/bindings/spi/qcom,spi-geni-qcom.txt | 39 ++
 2 files changed, 41 insertions(+), 25 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
index b9d0c21..dab7ca9 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -53,19 +53,8 @@ Required properties:
 - clocks:  Serial engine core clock needed by the device.
 
 Qualcomm Technologies Inc. GENI Serial Engine based SPI Controller
-
-Required properties:
-- compatible:  Must contain "qcom,geni-spi".
-- reg: Must contain SPI register location and length.
-- interrupts:  Must contain SPI controller interrupts.
-- clock-names: Must contain "se".
-- clocks:  Serial engine core clock needed by the device.
-- #address-cells:  Must be <1> to define a chip select address on
-   the SPI bus.
-- #size-cells: Must be <0>.
-
-SPI slave nodes must be children of the SPI master node and conform to SPI bus
-binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt.
+node binding is described in
+Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt.
 
 Example:
geniqup@8c {
@@ -102,16 +91,4 @@ Example:
pinctrl-1 = <_1_uart_3_sleep>;
};
 
-   spi0: spi@a84000 {
-   compatible = "qcom,geni-spi";
-   reg = <0xa84000 0x4000>;
-   interrupts = ;
-   clock-names = "se";
-   clocks = <_gcc GCC_QUPV3_WRAP0_S0_CLK>;
-   pinctrl-names = "default", "sleep";
-   pinctrl-0 = <_1_spi_2_active>;
-   pinctrl-1 = <_1_spi_2_sleep>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   };
}
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt 
b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
new file mode 100644
index 000..790311a
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
@@ -0,0 +1,39 @@
+GENI based Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface 
(SPI)
+
+The QUP v3 core is a GENI based AHB slave that provides a common data path
+(an output FIFO and an input FIFO) for serial peripheral interface (SPI)
+mini-core.
+
+SPI in master mode supports up to 50MHz, up to four chip selects, programmable
+data path from 4 bits to 32 bits and numerous protocol variants.
+
+Required properties:
+- compatible:  Must contain "qcom,geni-spi".
+- reg: Must contain SPI register location and length.
+- interrupts:  Must contain SPI controller interrupts.
+- clock-names: Must contain "se".
+- clocks:  Serial engine core clock needed by the device.
+- #address-cells:  Must be <1> to define a chip select address on
+   the SPI bus.
+- #size-cells: Must be <0>.
+
+SPI Controller nodes must be child of GENI based Qualcomm Universal
+Peripharal. Please refer GENI based QUP wrapper controller node bindings
+described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt.
+
+SPI slave nodes must be children of the SPI master node and conform to SPI bus
+binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt.
+
+Example:
+   spi0: spi@a84000 {
+   compatible = "qcom,geni-spi";
+   reg = <0xa84000 0x4000>;
+   interrupts = ;
+   clock-names = "se";
+   clocks = <_gcc GCC_QUPV3_WRAP0_S0_CLK>;
+   pinctrl-names = "default", "sleep";
+   pinctrl-0 = <_1_spi_2_active>;
+   pinctrl-1 = <_1_spi_2_sleep>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH V5 2/3] dt-bindings: soc: qcom: GENI SE SPI controller device tree binding

2018-10-03 Thread Alok Chauhan
From: Dilip Kota 

Move GENI SE SPI controller device-tree bindings
from devicetree/bindings/soc/qcom/qcom,geni-se.txt
to devicetree/bindings/spi/qcom,spi-geni-qcom.txt.

Signed-off-by: Dilip Kota 
Reviewed-by: Douglas Anderson 
Reviewed-by: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Alok Chauhan 
---
 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  | 27 ++-
 .../devicetree/bindings/spi/qcom,spi-geni-qcom.txt | 39 ++
 2 files changed, 41 insertions(+), 25 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
index b9d0c21..dab7ca9 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -53,19 +53,8 @@ Required properties:
 - clocks:  Serial engine core clock needed by the device.
 
 Qualcomm Technologies Inc. GENI Serial Engine based SPI Controller
-
-Required properties:
-- compatible:  Must contain "qcom,geni-spi".
-- reg: Must contain SPI register location and length.
-- interrupts:  Must contain SPI controller interrupts.
-- clock-names: Must contain "se".
-- clocks:  Serial engine core clock needed by the device.
-- #address-cells:  Must be <1> to define a chip select address on
-   the SPI bus.
-- #size-cells: Must be <0>.
-
-SPI slave nodes must be children of the SPI master node and conform to SPI bus
-binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt.
+node binding is described in
+Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt.
 
 Example:
geniqup@8c {
@@ -102,16 +91,4 @@ Example:
pinctrl-1 = <_1_uart_3_sleep>;
};
 
-   spi0: spi@a84000 {
-   compatible = "qcom,geni-spi";
-   reg = <0xa84000 0x4000>;
-   interrupts = ;
-   clock-names = "se";
-   clocks = <_gcc GCC_QUPV3_WRAP0_S0_CLK>;
-   pinctrl-names = "default", "sleep";
-   pinctrl-0 = <_1_spi_2_active>;
-   pinctrl-1 = <_1_spi_2_sleep>;
-   #address-cells = <1>;
-   #size-cells = <0>;
-   };
}
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt 
b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
new file mode 100644
index 000..790311a
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
@@ -0,0 +1,39 @@
+GENI based Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface 
(SPI)
+
+The QUP v3 core is a GENI based AHB slave that provides a common data path
+(an output FIFO and an input FIFO) for serial peripheral interface (SPI)
+mini-core.
+
+SPI in master mode supports up to 50MHz, up to four chip selects, programmable
+data path from 4 bits to 32 bits and numerous protocol variants.
+
+Required properties:
+- compatible:  Must contain "qcom,geni-spi".
+- reg: Must contain SPI register location and length.
+- interrupts:  Must contain SPI controller interrupts.
+- clock-names: Must contain "se".
+- clocks:  Serial engine core clock needed by the device.
+- #address-cells:  Must be <1> to define a chip select address on
+   the SPI bus.
+- #size-cells: Must be <0>.
+
+SPI Controller nodes must be child of GENI based Qualcomm Universal
+Peripharal. Please refer GENI based QUP wrapper controller node bindings
+described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt.
+
+SPI slave nodes must be children of the SPI master node and conform to SPI bus
+binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt.
+
+Example:
+   spi0: spi@a84000 {
+   compatible = "qcom,geni-spi";
+   reg = <0xa84000 0x4000>;
+   interrupts = ;
+   clock-names = "se";
+   clocks = <_gcc GCC_QUPV3_WRAP0_S0_CLK>;
+   pinctrl-names = "default", "sleep";
+   pinctrl-0 = <_1_spi_2_active>;
+   pinctrl-1 = <_1_spi_2_sleep>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+   };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH V5 1/3] dt-bindings: soc: qcom: Remove SPI controller maximum frequency binding

2018-10-03 Thread Alok Chauhan
From: Dilip Kota 

SPI controller driver should maintain the maximum frequency
of the controller instead of relying on device tree bindings.
Because maximum frequency is specific property of SPI
controller.

Signed-off-by: Dilip Kota 
Reviewed-by: Douglas Anderson 
Reviewed-by: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Alok Chauhan 
---
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
index ff92e5a..b9d0c21 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -60,7 +60,6 @@ Required properties:
 - interrupts:  Must contain SPI controller interrupts.
 - clock-names: Must contain "se".
 - clocks:  Serial engine core clock needed by the device.
-- spi-max-frequency:   Specifies maximum SPI clock frequency, units - Hz.
 - #address-cells:  Must be <1> to define a chip select address on
the SPI bus.
 - #size-cells: Must be <0>.
@@ -112,7 +111,6 @@ Example:
pinctrl-names = "default", "sleep";
pinctrl-0 = <_1_spi_2_active>;
pinctrl-1 = <_1_spi_2_sleep>;
-   spi-max-frequency = <1920>;
#address-cells = <1>;
#size-cells = <0>;
};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH V5 1/3] dt-bindings: soc: qcom: Remove SPI controller maximum frequency binding

2018-10-03 Thread Alok Chauhan
From: Dilip Kota 

SPI controller driver should maintain the maximum frequency
of the controller instead of relying on device tree bindings.
Because maximum frequency is specific property of SPI
controller.

Signed-off-by: Dilip Kota 
Reviewed-by: Douglas Anderson 
Reviewed-by: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Alok Chauhan 
---
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt 
b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
index ff92e5a..b9d0c21 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt
@@ -60,7 +60,6 @@ Required properties:
 - interrupts:  Must contain SPI controller interrupts.
 - clock-names: Must contain "se".
 - clocks:  Serial engine core clock needed by the device.
-- spi-max-frequency:   Specifies maximum SPI clock frequency, units - Hz.
 - #address-cells:  Must be <1> to define a chip select address on
the SPI bus.
 - #size-cells: Must be <0>.
@@ -112,7 +111,6 @@ Example:
pinctrl-names = "default", "sleep";
pinctrl-0 = <_1_spi_2_active>;
pinctrl-1 = <_1_spi_2_sleep>;
-   spi-max-frequency = <1920>;
#address-cells = <1>;
#size-cells = <0>;
};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH V5 0/3] spi-geni-qcom: QUP SPI GENI driver and SPI device tree bindings

2018-10-03 Thread Alok Chauhan
This patch series adds the driver for GENI based Qualcomm Universal
Peripheral (QUP) Serial Peripheral Interface (SPI) and SPI device tree
bindings.

An overview of the GENI SE SPI controller device tree components are in
patch 2 and 1. Patch 3 adds the SPI driver for GENI QUP HW.

changes from v4:
- Patch 1/3 and 2/3 are unchanged
- squashed patch 4/4 into 3/4 as suggested
- Patch 3/3 changes are follows:
* Add SPI M_COMMAND OPCODE to handle different geni command
  handling
* Remove forward declaration of ISR
* Remove unused variable rx_fifo_depth in spi_master structure
* Declare cur_speed_hz as unsigned long to match clock framework
* Declare cur_xfer as const pointer
* Newline in error print
* Correct consecutive spelling
* Rename trans_len to len and restructure the lines in
  setup_fifo_xfer()
* Rename timeout to time_left and restructure the
  handle_fifo_timeout()
* Add check for '0' bytes transfer as part of
  spi_geni_transfer_one()
* Correct if-else check in geni_byte_per_fifo_word()
* Remove NULL current transfer check in
  geni_spi_handle_tx()/geni_spi_handle_rx() and make these
  functions as void.
* Hoist rx_last_byte_valid variable into function scope
* Remove RT check in ISR and add cur_mcmd handling
* Correct the error prints in ISR
* In spi_alloc_master() pass 2nd arg as sizeof(*mas) for code
  clarity
* Use ret = PTR_ERR(se->base) for devm_ioremap_resource() err
  return
* Move request irq code to probe() and used request_irq() in place
  of devm_request_irq()
* Rewrite suspend/resume function
* Add MODULE_DEVICE_TABLE(of, spi_geni_dt_match);
* Remove include/linux/spi/spi-geni-qcom.h file


Dilip Kota (2):
  dt-bindings: soc: qcom: Remove SPI controller maximum frequency
binding
  dt-bindings: soc: qcom: GENI SE SPI controller device tree binding

Girish Mahadevan (1):
  spi: spi-geni-qcom: Add SPI driver support for GENI based QUP

 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  29 +-
 .../devicetree/bindings/spi/qcom,spi-geni-qcom.txt |  39 ++
 drivers/spi/Kconfig|  12 +
 drivers/spi/Makefile   |   1 +
 drivers/spi/spi-geni-qcom.c| 703 +
 5 files changed, 757 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
 create mode 100644 drivers/spi/spi-geni-qcom.c

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



[PATCH V5 0/3] spi-geni-qcom: QUP SPI GENI driver and SPI device tree bindings

2018-10-03 Thread Alok Chauhan
This patch series adds the driver for GENI based Qualcomm Universal
Peripheral (QUP) Serial Peripheral Interface (SPI) and SPI device tree
bindings.

An overview of the GENI SE SPI controller device tree components are in
patch 2 and 1. Patch 3 adds the SPI driver for GENI QUP HW.

changes from v4:
- Patch 1/3 and 2/3 are unchanged
- squashed patch 4/4 into 3/4 as suggested
- Patch 3/3 changes are follows:
* Add SPI M_COMMAND OPCODE to handle different geni command
  handling
* Remove forward declaration of ISR
* Remove unused variable rx_fifo_depth in spi_master structure
* Declare cur_speed_hz as unsigned long to match clock framework
* Declare cur_xfer as const pointer
* Newline in error print
* Correct consecutive spelling
* Rename trans_len to len and restructure the lines in
  setup_fifo_xfer()
* Rename timeout to time_left and restructure the
  handle_fifo_timeout()
* Add check for '0' bytes transfer as part of
  spi_geni_transfer_one()
* Correct if-else check in geni_byte_per_fifo_word()
* Remove NULL current transfer check in
  geni_spi_handle_tx()/geni_spi_handle_rx() and make these
  functions as void.
* Hoist rx_last_byte_valid variable into function scope
* Remove RT check in ISR and add cur_mcmd handling
* Correct the error prints in ISR
* In spi_alloc_master() pass 2nd arg as sizeof(*mas) for code
  clarity
* Use ret = PTR_ERR(se->base) for devm_ioremap_resource() err
  return
* Move request irq code to probe() and used request_irq() in place
  of devm_request_irq()
* Rewrite suspend/resume function
* Add MODULE_DEVICE_TABLE(of, spi_geni_dt_match);
* Remove include/linux/spi/spi-geni-qcom.h file


Dilip Kota (2):
  dt-bindings: soc: qcom: Remove SPI controller maximum frequency
binding
  dt-bindings: soc: qcom: GENI SE SPI controller device tree binding

Girish Mahadevan (1):
  spi: spi-geni-qcom: Add SPI driver support for GENI based QUP

 .../devicetree/bindings/soc/qcom/qcom,geni-se.txt  |  29 +-
 .../devicetree/bindings/spi/qcom,spi-geni-qcom.txt |  39 ++
 drivers/spi/Kconfig|  12 +
 drivers/spi/Makefile   |   1 +
 drivers/spi/spi-geni-qcom.c| 703 +
 5 files changed, 757 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
 create mode 100644 drivers/spi/spi-geni-qcom.c

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



[PATCH] soc: qcom: Add irq clear handling during SE init

2018-10-03 Thread Alok Chauhan
when the kernel inits a SE, its quite possible we have pending interrupts
from bootloaders which did not handle/clear them. So do this in kernel at
the SE init, to avoid some of it causing bad behavior, while at it also
club all the register writes needed to clear the se irqs into a function
to avoid repeating it over.

Signed-off-by: Alok Chauhan 
---
 drivers/soc/qcom/qcom-geni-se.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index feed3db2..1422fc5 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -215,6 +215,16 @@ static void geni_se_io_init(void __iomem *base)
writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
 }
 
+static void geni_se_irq_clear(struct geni_se *se)
+{
+   writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
+   writel_relaxed(0x, se->base + SE_GENI_M_IRQ_CLEAR);
+   writel_relaxed(0x, se->base + SE_GENI_S_IRQ_CLEAR);
+   writel_relaxed(0x, se->base + SE_DMA_TX_IRQ_CLR);
+   writel_relaxed(0x, se->base + SE_DMA_RX_IRQ_CLR);
+   writel_relaxed(0x, se->base + SE_IRQ_EN);
+}
+
 /**
  * geni_se_init() - Initialize the GENI serial engine
  * @se:Pointer to the concerned serial engine.
@@ -228,6 +238,7 @@ void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
 {
u32 val;
 
+   geni_se_irq_clear(se);
geni_se_io_init(se->base);
geni_se_io_set_mode(se->base);
 
@@ -249,12 +260,7 @@ static void geni_se_select_fifo_mode(struct geni_se *se)
u32 proto = geni_se_read_proto(se);
u32 val;
 
-   writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
-   writel_relaxed(0x, se->base + SE_GENI_M_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_GENI_S_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_DMA_TX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_DMA_RX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_IRQ_EN);
+   geni_se_irq_clear(se);
 
val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
if (proto != GENI_SE_UART) {
@@ -277,12 +283,7 @@ static void geni_se_select_dma_mode(struct geni_se *se)
 {
u32 val;
 
-   writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
-   writel_relaxed(0x, se->base + SE_GENI_M_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_GENI_S_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_DMA_TX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_DMA_RX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_IRQ_EN);
+   geni_se_irq_clear(se);
 
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
val |= GENI_DMA_MODE_EN;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] soc: qcom: Add irq clear handling during SE init

2018-10-03 Thread Alok Chauhan
when the kernel inits a SE, its quite possible we have pending interrupts
from bootloaders which did not handle/clear them. So do this in kernel at
the SE init, to avoid some of it causing bad behavior, while at it also
club all the register writes needed to clear the se irqs into a function
to avoid repeating it over.

Signed-off-by: Alok Chauhan 
---
 drivers/soc/qcom/qcom-geni-se.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index feed3db2..1422fc5 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -215,6 +215,16 @@ static void geni_se_io_init(void __iomem *base)
writel_relaxed(FORCE_DEFAULT, base + GENI_FORCE_DEFAULT_REG);
 }
 
+static void geni_se_irq_clear(struct geni_se *se)
+{
+   writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
+   writel_relaxed(0x, se->base + SE_GENI_M_IRQ_CLEAR);
+   writel_relaxed(0x, se->base + SE_GENI_S_IRQ_CLEAR);
+   writel_relaxed(0x, se->base + SE_DMA_TX_IRQ_CLR);
+   writel_relaxed(0x, se->base + SE_DMA_RX_IRQ_CLR);
+   writel_relaxed(0x, se->base + SE_IRQ_EN);
+}
+
 /**
  * geni_se_init() - Initialize the GENI serial engine
  * @se:Pointer to the concerned serial engine.
@@ -228,6 +238,7 @@ void geni_se_init(struct geni_se *se, u32 rx_wm, u32 rx_rfr)
 {
u32 val;
 
+   geni_se_irq_clear(se);
geni_se_io_init(se->base);
geni_se_io_set_mode(se->base);
 
@@ -249,12 +260,7 @@ static void geni_se_select_fifo_mode(struct geni_se *se)
u32 proto = geni_se_read_proto(se);
u32 val;
 
-   writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
-   writel_relaxed(0x, se->base + SE_GENI_M_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_GENI_S_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_DMA_TX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_DMA_RX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_IRQ_EN);
+   geni_se_irq_clear(se);
 
val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN);
if (proto != GENI_SE_UART) {
@@ -277,12 +283,7 @@ static void geni_se_select_dma_mode(struct geni_se *se)
 {
u32 val;
 
-   writel_relaxed(0, se->base + SE_GSI_EVENT_EN);
-   writel_relaxed(0x, se->base + SE_GENI_M_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_GENI_S_IRQ_CLEAR);
-   writel_relaxed(0x, se->base + SE_DMA_TX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_DMA_RX_IRQ_CLR);
-   writel_relaxed(0x, se->base + SE_IRQ_EN);
+   geni_se_irq_clear(se);
 
val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN);
val |= GENI_DMA_MODE_EN;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project