[PATCH 2/4] arm64: dts: ls1012a: Fix incorrect I2C clock divider

2019-08-06 Thread Chuanhua Han
Ls1012a platform, the i2c input clock is actually platform pll CLK / 4
(this is the hardware connection), other clock divider can not get the
correct i2c clock, resulting in the output of SCL pin clock is not
accurate.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
index ec6257a..124a7e2 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
@@ -323,7 +323,7 @@
#size-cells = <0>;
reg = <0x0 0x218 0x0 0x1>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
-   clocks = < 4 0>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -333,7 +333,7 @@
#size-cells = <0>;
reg = <0x0 0x219 0x0 0x1>;
interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
-   clocks = < 4 0>;
+   clocks = < 4 3>;
status = "disabled";
};
 
-- 
2.9.5



[PATCH 3/4] arm64: dts: ls1028a: Fix incorrect I2C clock divider

2019-08-06 Thread Chuanhua Han
Ls1028a platform, the i2c input clock is actually platform pll CLK / 4
(this is the hardware connection), other clock divider can not get the
correct i2c clock, resulting in the output of SCL pin clock is not
accurate.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index aef5b06..cca7bfdb 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -171,7 +171,7 @@
#size-cells = <0>;
reg = <0x0 0x200 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -181,7 +181,7 @@
#size-cells = <0>;
reg = <0x0 0x201 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -191,7 +191,7 @@
#size-cells = <0>;
reg = <0x0 0x202 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -201,7 +201,7 @@
#size-cells = <0>;
reg = <0x0 0x203 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -211,7 +211,7 @@
#size-cells = <0>;
reg = <0x0 0x204 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -221,7 +221,7 @@
#size-cells = <0>;
reg = <0x0 0x205 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -231,7 +231,7 @@
#size-cells = <0>;
reg = <0x0 0x206 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
@@ -241,7 +241,7 @@
#size-cells = <0>;
reg = <0x0 0x207 0x0 0x1>;
interrupts = ;
-   clocks = < 4 1>;
+   clocks = < 4 3>;
status = "disabled";
};
 
-- 
2.9.5



[PATCH 1/4] arm64: dts: ls1088a: Fix incorrect I2C clock divider

2019-08-06 Thread Chuanhua Han
Ls1088a platform, the i2c input clock is actually platform pll CLK / 8
(this is the hardware connection), other clock divider can not get the
correct i2c clock, resulting in the output of SCL pin clock is not
accurate.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 20f5ebd..30b760e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -324,7 +324,7 @@
#size-cells = <0>;
reg = <0x0 0x200 0x0 0x1>;
interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
-   clocks = < 4 3>;
+   clocks = < 4 7>;
status = "disabled";
};
 
@@ -334,7 +334,7 @@
#size-cells = <0>;
reg = <0x0 0x201 0x0 0x1>;
interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
-   clocks = < 4 3>;
+   clocks = < 4 7>;
status = "disabled";
};
 
@@ -344,7 +344,7 @@
#size-cells = <0>;
reg = <0x0 0x202 0x0 0x1>;
interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
-   clocks = < 4 3>;
+   clocks = < 4 7>;
status = "disabled";
};
 
@@ -354,7 +354,7 @@
#size-cells = <0>;
reg = <0x0 0x203 0x0 0x1>;
interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
-   clocks = < 4 3>;
+   clocks = < 4 7>;
status = "disabled";
};
 
-- 
2.9.5



[PATCH 4/4] arm64: dts: lx2160a: Fix incorrect I2C clock divider

2019-08-06 Thread Chuanhua Han
Lx2160a platform, the i2c input clock is actually platform pll CLK / 16
(this is the hardware connection), other clock divider can not get the
correct i2c clock, resulting in the output of SCL pin clock is not
accurate.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 4720a8e..408e0ec 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -485,7 +485,7 @@
reg = <0x0 0x200 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
scl-gpio = < 15 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
@@ -497,7 +497,7 @@
reg = <0x0 0x201 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
status = "disabled";
};
 
@@ -508,7 +508,7 @@
reg = <0x0 0x202 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
status = "disabled";
};
 
@@ -519,7 +519,7 @@
reg = <0x0 0x203 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
status = "disabled";
};
 
@@ -530,7 +530,7 @@
reg = <0x0 0x204 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
scl-gpio = < 16 GPIO_ACTIVE_HIGH>;
status = "disabled";
};
@@ -542,7 +542,7 @@
reg = <0x0 0x205 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
status = "disabled";
};
 
@@ -553,7 +553,7 @@
reg = <0x0 0x206 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
status = "disabled";
};
 
@@ -564,7 +564,7 @@
reg = <0x0 0x207 0x0 0x1>;
interrupts = ;
clock-names = "i2c";
-   clocks = < 4 7>;
+   clocks = < 4 15>;
status = "disabled";
};
 
-- 
2.9.5



[PATCH 3/3] arm64: dts: ls1088a-qds: Add the spi-flash nodes under the DSPI controller

2019-08-01 Thread Chuanhua Han
This patch adds the spi-flash nodes under the DSPI controller for
ls1088a-qds boards.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts | 33 +++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts 
b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
index 6f48d21..120e62d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
@@ -17,6 +17,39 @@
compatible = "fsl,ls1088a-qds", "fsl,ls1088a";
 };
 
+ {
+   bus-num = <0>;
+   status = "okay";
+
+   flash@0 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "jedec,spi-nor";
+   reg = <0>;
+   spi-max-frequency = <100>;
+   };
+
+   flash@1 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "jedec,spi-nor";
+   spi-cpol;
+   spi-cpha;
+   spi-max-frequency = <350>;
+   reg = <1>;
+   };
+
+   flash@2 {
+   #address-cells = <1>;
+   #size-cells = <1>;
+   compatible = "jedec,spi-nor";
+   spi-cpol;
+   spi-cpha;
+   spi-max-frequency = <350>;
+   reg = <2>;
+   };
+};
+
  {
status = "okay";
 
-- 
2.9.5



[PATCH 2/3] arm64: dts: ls1088a: Add the DSPI controller node

2019-08-01 Thread Chuanhua Han
This patch adds the DSPI controller node for ls1088a boards.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index dacd8cf..fe8f1bd 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -252,6 +252,19 @@
#thermal-sensor-cells = <1>;
};
 
+   dspi: spi@210 {
+   compatible = "fsl,ls1088a-dspi",
+   "fsl,ls1021a-v1.0-dspi";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <0x0 0x210 0x0 0x1>;
+   interrupts = ;
+   clock-names = "dspi";
+   clocks = < 4 1>;
+   spi-num-chipselects = <6>;
+   status = "disabled";
+   };
+
duart0: serial@21c0500 {
compatible = "fsl,ns16550", "ns16550a";
reg = <0x0 0x21c0500 0x0 0x100>;
-- 
2.9.5



[PATCH 1/3] dt-bindings: fsl: dspi: Add fsl,ls1088a-dspi compatible string

2019-08-01 Thread Chuanhua Han
new compatible string: "fsl,ls1088a-dspi".

Signed-off-by: Chuanhua Han 
---
 Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt 
b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
index dcc7eaa..162e024 100644
--- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
+++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
@@ -6,6 +6,7 @@ Required properties:
or
"fsl,ls2080a-dspi" followed by "fsl,ls2085a-dspi"
"fsl,ls1012a-dspi" followed by "fsl,ls1021a-v1.0-dspi"
+   "fsl,ls1088a-dspi" followed by "fsl,ls1021a-v1.0-dspi"
 - reg : Offset and length of the register set for the device
 - interrupts : Should contain SPI controller interrupt
 - clocks: from common clock binding: handle to dspi clock.
-- 
2.9.5



RE: [EXT] Re: [PATCH] ACPI: support for NXP i2c controller

2019-07-18 Thread Chuanhua Han
Hi, Rafael J. Wysocki

> -Original Message-
> From: Rafael J. Wysocki 
> Sent: 2019年7月18日 16:45
> To: Chuanhua Han 
> Cc: l...@kernel.org; shawn...@kernel.org; s.ha...@pengutronix.de;
> linux-a...@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; Leo Li
> ; Meenakshi Aggarwal ;
> Udit Kumar 
> Subject: [EXT] Re: [PATCH] ACPI: support for NXP i2c controller
> 
> Caution: EXT Email
> 
> On Thursday, July 11, 2019 12:26:01 PM CEST Chuanhua Han wrote:
> > Enable NXP i2c controller to boot with ACPI
> >
> > Signed-off-by: Meenakshi Aggarwal 
> > Signed-off-by: Udit Kumar 
> > Signed-off-by: Chuanhua Han 
> 
> In case you want this to go in through the i2c tree:
> 
> Acked-by: Rafael J. Wysocki 
> 
> or in case you want me to take it, please let me know, but I will need an ACK
> from the i2c side then.
I'm sorry, I don't quite understand
> 
> > ---
> >  drivers/acpi/acpi_apd.c  |  6 ++
> >  drivers/i2c/busses/i2c-imx.c | 15 +++
> >  2 files changed, 21 insertions(+)
> >
> > diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index
> > ff47317..cf8566c 100644
> > --- a/drivers/acpi/acpi_apd.c
> > +++ b/drivers/acpi/acpi_apd.c
> > @@ -165,6 +165,11 @@ static const struct apd_device_desc
> thunderx2_i2c_desc = {
> >   .fixed_clk_rate = 12500,
> >  };
> >
> > +static const struct apd_device_desc nxp_i2c_desc = {
> > + .setup = acpi_apd_setup,
> > + .fixed_clk_rate = 35000,
> > +};
> > +
> >  static const struct apd_device_desc hip08_spi_desc = {
> >   .setup = acpi_apd_setup,
> >   .fixed_clk_rate = 25000,
> > @@ -238,6 +243,7 @@ static const struct acpi_device_id
> acpi_apd_device_ids[] = {
> >   { "HISI02A1", APD_ADDR(hip07_i2c_desc) },
> >   { "HISI02A2", APD_ADDR(hip08_i2c_desc) },
> >   { "HISI0173", APD_ADDR(hip08_spi_desc) },
> > + { "NXP0001", APD_ADDR(nxp_i2c_desc) },
> >  #endif
> >   { }
> >  };
> > diff --git a/drivers/i2c/busses/i2c-imx.c
> > b/drivers/i2c/busses/i2c-imx.c index b1b8b93..99f9b96 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -44,6 +44,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  /* This will be the driver name the kernel reports */  #define
> > DRIVER_NAME "imx-i2c"
> > @@ -255,6 +256,12 @@ static const struct of_device_id i2c_imx_dt_ids[]
> > = {  };  MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
> >
> > +static const struct acpi_device_id i2c_imx_acpi_ids[] = {
> > + {"NXP0001", .driver_data = (kernel_ulong_t)_i2c_hwdata},
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(acpi, i2c_imx_acpi_ids);
> > +
> >  static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)  {
> >   return i2c_imx->hwdata->devtype == IMX1_I2C; @@ -1052,6 +1059,9
> > @@ static int i2c_imx_probe(struct platform_device *pdev)  {
> >   const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
> >
> >dev);
> > + const struct acpi_device_id *acpi_id =
> > + acpi_match_device(i2c_imx_acpi_ids,
> > +   >dev);
> >   struct imx_i2c_struct *i2c_imx;
> >   struct resource *res;
> >   struct imxi2c_platform_data *pdata =
> > dev_get_platdata(>dev); @@ -1079,6 +1089,9 @@ static int
> > i2c_imx_probe(struct platform_device *pdev)
> >
> >   if (of_id)
> >   i2c_imx->hwdata = of_id->data;
> > + else if (acpi_id)
> > + i2c_imx->hwdata = (struct imx_i2c_hwdata *)
> > + acpi_id->driver_data;
> >   else
> >   i2c_imx->hwdata = (struct imx_i2c_hwdata *)
> >
> > platform_get_device_id(pdev)->driver_data;
> > @@ -1091,6 +1104,7 @@ static int i2c_imx_probe(struct platform_device
> *pdev)
> >   i2c_imx->adapter.nr = pdev->id;
> >   i2c_imx->adapter.dev.of_node= pdev->dev.of_node;
> >   i2c_imx->base   = base;
> > + ACPI_COMPANION_SET(_imx->adapter.dev,
> > + ACPI_COMPANION(>dev));
> >
> >   /* Get I2C clock */
> >   i2c_imx->clk = devm_clk_get(>dev, NULL); @@ -1253,6
> > +1267,7 @@ static struct platform_driver i2c_imx_driver = {
> >   .name = DRIVER_NAME,
> >   .pm = _imx_pm_ops,
> >   .of_match_table = i2c_imx_dt_ids,
> > + .acpi_match_table = ACPI_PTR(i2c_imx_acpi_ids),
> >   },
> >   .id_table = imx_i2c_devtype,
> >  };
> >
> 
> 
> 



[PATCH] ACPI: support for NXP i2c controller

2019-07-11 Thread Chuanhua Han
Enable NXP i2c controller to boot with ACPI

Signed-off-by: Meenakshi Aggarwal 
Signed-off-by: Udit Kumar 
Signed-off-by: Chuanhua Han 
---
 drivers/acpi/acpi_apd.c  |  6 ++
 drivers/i2c/busses/i2c-imx.c | 15 +++
 2 files changed, 21 insertions(+)

diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index ff47317..cf8566c 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -165,6 +165,11 @@ static const struct apd_device_desc thunderx2_i2c_desc = {
.fixed_clk_rate = 12500,
 };
 
+static const struct apd_device_desc nxp_i2c_desc = {
+   .setup = acpi_apd_setup,
+   .fixed_clk_rate = 35000,
+};
+
 static const struct apd_device_desc hip08_spi_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 25000,
@@ -238,6 +243,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "HISI02A1", APD_ADDR(hip07_i2c_desc) },
{ "HISI02A2", APD_ADDR(hip08_i2c_desc) },
{ "HISI0173", APD_ADDR(hip08_spi_desc) },
+   { "NXP0001", APD_ADDR(nxp_i2c_desc) },
 #endif
{ }
 };
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index b1b8b93..99f9b96 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -44,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* This will be the driver name the kernel reports */
 #define DRIVER_NAME "imx-i2c"
@@ -255,6 +256,12 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
 
+static const struct acpi_device_id i2c_imx_acpi_ids[] = {
+   {"NXP0001", .driver_data = (kernel_ulong_t)_i2c_hwdata},
+   { }
+};
+MODULE_DEVICE_TABLE(acpi, i2c_imx_acpi_ids);
+
 static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
 {
return i2c_imx->hwdata->devtype == IMX1_I2C;
@@ -1052,6 +1059,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
 {
const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
   >dev);
+   const struct acpi_device_id *acpi_id =
+   acpi_match_device(i2c_imx_acpi_ids,
+ >dev);
struct imx_i2c_struct *i2c_imx;
struct resource *res;
struct imxi2c_platform_data *pdata = dev_get_platdata(>dev);
@@ -1079,6 +1089,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
 
if (of_id)
i2c_imx->hwdata = of_id->data;
+   else if (acpi_id)
+   i2c_imx->hwdata = (struct imx_i2c_hwdata *)
+   acpi_id->driver_data;
else
i2c_imx->hwdata = (struct imx_i2c_hwdata *)
platform_get_device_id(pdev)->driver_data;
@@ -1091,6 +1104,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx->adapter.nr = pdev->id;
i2c_imx->adapter.dev.of_node= pdev->dev.of_node;
i2c_imx->base   = base;
+   ACPI_COMPANION_SET(_imx->adapter.dev, ACPI_COMPANION(>dev));
 
/* Get I2C clock */
i2c_imx->clk = devm_clk_get(>dev, NULL);
@@ -1253,6 +1267,7 @@ static struct platform_driver i2c_imx_driver = {
.name = DRIVER_NAME,
.pm = _imx_pm_ops,
.of_match_table = i2c_imx_dt_ids,
+   .acpi_match_table = ACPI_PTR(i2c_imx_acpi_ids),
},
.id_table = imx_i2c_devtype,
 };
-- 
2.9.5



RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node

2019-05-29 Thread Chuanhua Han


> -Original Message-
> From: Rob Herring 
> Sent: 2019年5月24日 20:29
> To: Chuanhua Han 
> Cc: Leo Li ; Shawn Guo ;
> mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> 
> Subject: Re: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node
> 
> Caution: EXT Email
> 
> On Fri, May 24, 2019 at 4:48 AM Chuanhua Han 
> wrote:
> >
> > Hi, Rob Herring
> >
> > > -Original Message-
> > > From: Leo Li
> > > Sent: 2019年5月22日 14:50
> 
> 
> > > > > > > > > > - wdog0: watchdog@23c {
> > > > > > > > > > - compatible = "fsl,ls1028a-wdt",
> > > > > "fsl,imx21-wdt";
> > > > > > > > > > - reg = <0x0 0x23c 0x0 0x1>;
> > > > > > > > > > - interrupts =  > > > > > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > > > > > > - clocks = < 4 1>;
> > > > > > > > > > - big-endian;
> > > > > > > > > > - status = "disabled";
> > > > > > > > > > + cluster1_core0_watchdog: wdt@c00 {
> > > > > > > > >
> > > > > > > > > Keep 'watchdog' as the node name,
> > > > > > > > Thanks for your replay
> > > > > > > > Do you mean replace the ‘wdt’ with ‘watchdog’?
> > > > > > > > and keep nodes sort in unit-address.
> > > > > > > > What does this mean?
> > > > > > >
> > > > > > > That means order the nodes by the addresses (e.g. c00,
> > > > > > > c01)
> > > > > > The current order is correct(The first is c00, then c00).
> > > > >
> > > > > But they are added after gpio@232 and before sata@320.
> > > > I changed and made the second version of the patch, but I found
> > > > the following error when I executed ./scripts/checkpatch.pl
> > > > xxx.patch to check the patch:
> > > >
> > > > WARNING: DT compatible string vendor "arm" appears un-documented
> > > > -- check ./Documentation/devicetree/bindings/vendor-prefixes.txt
> > > > #43: FILE: arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi:351:
> > > > + compatible = "arm,sp805", "arm,primecell";
> > > >
> > > > However, there is no vendor-prefixes.txt file in the
> > > > ./Documentation/devicetree/bindings/ directory, only vendor-
> > > > prefixes.yaml.
> > > > Moreover, there are ‘arm’ vendors in vendor-prefixes.yaml.
> > >
> > > Added Rob Herring to the thread.
> > >
> > > > Request help,thanks
> > How can I solve this patch check error? Ask for help, thank you!
> 
> Ignore it. A fix to checkpatch.pl is pending.
OK, the second version has been sent. Checking with checkpatch.pl is no problem.
> 
> Rob


[PATCH 3/3] arm64: dts: ls1088a: Revise gpio registers to little-endian

2019-05-29 Thread Chuanhua Han
Since fsl-ls1088a Soc GPIO registers are used as little endian,
the patch adds the little-endian attribute to each gpio node.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 661137ffa319..3e6d20d065bd 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -272,6 +272,7 @@
compatible = "fsl,qoriq-gpio";
reg = <0x0 0x230 0x0 0x1>;
interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+   little-endian;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -282,6 +283,7 @@
compatible = "fsl,qoriq-gpio";
reg = <0x0 0x231 0x0 0x1>;
interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+   little-endian;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -292,6 +294,7 @@
compatible = "fsl,qoriq-gpio";
reg = <0x0 0x232 0x0 0x1>;
interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+   little-endian;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -302,6 +305,7 @@
compatible = "fsl,qoriq-gpio";
reg = <0x0 0x233 0x0 0x1>;
interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+   little-endian;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
-- 
2.17.1



[PATCH 1/3] gpio: mpc8xxx: Enable port input and interrupt

2019-05-29 Thread Chuanhua Han
The GPIO Input Buffer Enable register is used to control the input
enable of each individual GPIO port. When an individual GPIO port's
direction is set to input (GPIO_GPDIR[DRn=0]), the associated
input enable must be set (GPIOxGPIE[IEn]=1) to propagate the port
value to the GPIO Data Register.

This patch enable port input and interrupt.

Signed-off-by: Zhang Ying-22455 
Signed-off-by: Chuanhua Han 
---
 drivers/gpio/gpio-mpc8xxx.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index c8673a5d9412..555e0e7957d9 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -373,9 +373,10 @@ static int mpc8xxx_probe(struct platform_device *pdev)
if (!mpc8xxx_gc->irq)
return 0;
 
-   /* ack and mask all irqs */
+   /* ack and enable irqs */
gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0x);
-   gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0);
+   gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0x);
+   gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR2, 0x);
 
irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
 mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
-- 
2.17.1



[PATCH 2/3] gpio: mpc8xxx: Use IRQF_SHARED mode to request IRQ

2019-05-29 Thread Chuanhua Han
GPIO3 and GPIO4 controllers share one irq number on Layerscape
platform. In the current implementation, only one GPIO controller
can register successfully.

This patch is to allow two controllers to share a single interrupt
number.

Signed-off-by: Zhang Ying-22455 
Signed-off-by: Chuanhua Han 
---
 drivers/gpio/gpio-mpc8xxx.c | 43 ++---
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 555e0e7957d9..63c8586fe5c8 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -105,10 +106,9 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, 
unsigned offset)
return -ENXIO;
 }
 
-static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
+static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *dev_id)
 {
-   struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
-   struct irq_chip *chip = irq_desc_get_chip(desc);
+   struct mpc8xxx_gpio_chip *mpc8xxx_gc = dev_id;
struct gpio_chip *gc = _gc->gc;
unsigned int mask;
 
@@ -117,8 +117,7 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
if (mask)
generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
 32 - ffs(mask)));
-   if (chip->irq_eoi)
-   chip->irq_eoi(>irq_data);
+   return IRQ_HANDLED;
 }
 
 static void mpc8xxx_irq_unmask(struct irq_data *d)
@@ -129,6 +128,9 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
 
raw_spin_lock_irqsave(_gc->lock, flags);
 
+   gc->write_reg(mpc8xxx_gc->regs + GPIO_IER,
+ gc->pin2mask(gc, irqd_to_hwirq(d)));
+
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
| mpc_pin2mask(irqd_to_hwirq(d)));
@@ -302,21 +304,31 @@ static int mpc8xxx_probe(struct platform_device *pdev)
struct gpio_chip*gc;
const struct mpc8xxx_gpio_devtype *devtype =
of_device_get_match_data(>dev);
-   int ret;
+   int ret, irq;
 
mpc8xxx_gc = devm_kzalloc(>dev, sizeof(*mpc8xxx_gc), GFP_KERNEL);
if (!mpc8xxx_gc)
return -ENOMEM;
 
-   platform_set_drvdata(pdev, mpc8xxx_gc);
-
-   raw_spin_lock_init(_gc->lock);
-
mpc8xxx_gc->regs = of_iomap(np, 0);
if (!mpc8xxx_gc->regs)
return -ENOMEM;
 
gc = _gc->gc;
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
+   dev_err(>dev, "can't get irq number\n");
+   return irq;
+   }
+
+   mpc8xxx_gc->gc.label = pdev->name;
+   mpc8xxx_gc->gc.owner = THIS_MODULE;
+   mpc8xxx_gc->gc.base = -1;
+   mpc8xxx_gc->gc.ngpio = MPC8XXX_GPIO_PINS;
+
+   platform_set_drvdata(pdev, mpc8xxx_gc);
+
+   raw_spin_lock_init(_gc->lock);
 
if (of_property_read_bool(np, "little-endian")) {
ret = bgpio_init(gc, >dev, 4,
@@ -364,7 +376,7 @@ static int mpc8xxx_probe(struct platform_device *pdev)
goto err;
}
 
-   mpc8xxx_gc->irqn = irq_of_parse_and_map(np, 0);
+   mpc8xxx_gc->irqn = platform_get_irq(pdev, 0);
if (!mpc8xxx_gc->irqn)
return 0;
 
@@ -378,8 +390,13 @@ static int mpc8xxx_probe(struct platform_device *pdev)
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0x);
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR2, 0x);
 
-   irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
-mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
+   /* Request IRQ */
+   ret = devm_request_irq(>dev, irq, mpc8xxx_gpio_irq_cascade,
+  IRQF_SHARED, pdev->name, mpc8xxx_gc);
+   if (ret) {
+   dev_err(>dev, "can't claim irq %d\n", mpc8xxx_gc->irqn);
+   goto err;
+   }
return 0;
 err:
iounmap(mpc8xxx_gc->regs);
-- 
2.17.1



[PATCH v2] arm64: dts: ls1028a: fix watchdog device node

2019-05-28 Thread Chuanhua Han
ls1028a platform uses sp805 watchdog, and use 1/16 platform clock as
timer clock, this patch fix device tree node.

Signed-off-by: Chuanhua Han 
---
Changes in v2: 
- Replace 'wdt' with 'watchdog' as the node name.
- Keep nodes sort in unit-address.

 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 23 +++
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index ceb608d0e622..bb386dd1d1b1 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -306,15 +306,6 @@
#interrupt-cells = <2>;
};
 
-   wdog0: watchdog@23c {
-   compatible = "fsl,ls1028a-wdt", "fsl,imx21-wdt";
-   reg = <0x0 0x23c 0x0 0x1>;
-   interrupts = ;
-   clocks = < 4 1>;
-   big-endian;
-   status = "disabled";
-   };
-
usb0: usb@310 {
compatible = "fsl,ls1028a-dwc3", "snps,dwc3";
reg = <0x0 0x310 0x0 0x1>;
@@ -397,6 +388,20 @@
 , 
;
};
 
+   cluster1_core0_watchdog: watchdog@c00 {
+   compatible = "arm,sp805", "arm,primecell";
+   reg = <0x0 0xc00 0x0 0x1000>;
+   clocks = < 4 15>, < 4 15>;
+   clock-names = "apb_pclk", "wdog_clk";
+   };
+
+   cluster1_core1_watchdog: watchdog@c01 {
+   compatible = "arm,sp805", "arm,primecell";
+   reg = <0x0 0xc01 0x0 0x1000>;
+   clocks = < 4 15>, < 4 15>;
+   clock-names = "apb_pclk", "wdog_clk";
+   };
+
sai1: audio-controller@f10 {
#sound-dai-cells = <0>;
compatible = "fsl,vf610-sai";
-- 
2.17.1



RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node

2019-05-24 Thread Chuanhua Han
Hi, Rob Herring

> -Original Message-
> From: Leo Li
> Sent: 2019年5月22日 14:50
> To: Chuanhua Han ; Shawn Guo
> ; Rob Herring 
> Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> 
> Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node
> 
> 
> 
> > -----Original Message-
> > From: Chuanhua Han
> > Sent: Wednesday, May 22, 2019 1:26 AM
> > To: Leo Li ; Shawn Guo 
> > Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> > 
> > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > device node
> >
> >
> >
> > > -Original Message-
> > > From: Leo Li
> > > Sent: 2019年5月22日 4:15
> > > To: Chuanhua Han ; Shawn Guo
> > > 
> > > Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> > > 
> > > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > device node
> > >
> > >
> > >
> > > > -Original Message-
> > > > From: Chuanhua Han
> > > > Sent: Tuesday, May 21, 2019 8:00 AM
> > > > To: Leo Li ; Shawn Guo 
> > > > Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> > > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying
> > > > Zhang 
> > > > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > > device node
> > > >
> > > >
> > > >
> > > > > -Original Message-
> > > > > From: Leo Li
> > > > > Sent: 2019年5月18日 6:01
> > > > > To: Chuanhua Han ; Shawn Guo
> > > > > 
> > > > > Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> > > > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying
> > > > > Zhang 
> > > > > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > > > device node
> > > > >
> > > > >
> > > > >
> > > > > > -Original Message-
> > > > > > From: Chuanhua Han
> > > > > > Sent: Friday, May 17, 2019 1:11 AM
> > > > > > To: Shawn Guo 
> > > > > > Cc: Leo Li ; mark.rutl...@arm.com;
> > > > > > linux-arm- ker...@lists.infradead.org;
> > > > > > devicet...@vger.kernel.org; linux- ker...@vger.kernel.org;
> > > > > > Ying Zhang 
> > > > > > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix
> > > > > > watchdog device node
> > > > > >
> > > > > >
> > > > > >
> > > > > > > -Original Message-
> > > > > > > From: Shawn Guo 
> > > > > > > Sent: 2019年5月17日 10:38
> > > > > > > To: Chuanhua Han 
> > > > > > > Cc: Leo Li ; mark.rutl...@arm.com;
> > > > > > > linux-arm-ker...@lists.infradead.org;
> > > > > > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > > > > Ying Zhang 
> > > > > > > Subject: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > > > > > device node
> > > > > > >
> > > > > > > Caution: EXT Email
> > > > > > >
> > > > > > > On Thu, May 09, 2019 at 03:06:57PM +0800, Chuanhua Han wrote:
> > > > > > > > ls1028a platform uses sp805 watchdog, and use 1/16
> > > > > > > > platform clock as timer clock, this patch fix device tree node.
> > > > > > > >
> > > > > > > > Signed-off-by: Zhang Ying-22455 
> > > > > > > > Signed-off-by: Chuanhua Han 
> > > > > > > > ---
> > > > > > > >  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 19
> > > > > > > > ---
> > > > > > > >  1 file changed, 12 insertions(+), 7 deletions(-)
> > > > > > > >
> > > > > > > > diff --git
> > > > > > > > a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > > > > > b/arch/arm64/bo

RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node

2019-05-22 Thread Chuanhua Han


> -Original Message-
> From: Leo Li
> Sent: 2019年5月22日 4:15
> To: Chuanhua Han ; Shawn Guo
> 
> Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> 
> Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node
> 
> 
> 
> > -----Original Message-
> > From: Chuanhua Han
> > Sent: Tuesday, May 21, 2019 8:00 AM
> > To: Leo Li ; Shawn Guo 
> > Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> > 
> > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > device node
> >
> >
> >
> > > -Original Message-
> > > From: Leo Li
> > > Sent: 2019年5月18日 6:01
> > > To: Chuanhua Han ; Shawn Guo
> > > 
> > > Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> > > 
> > > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > device node
> > >
> > >
> > >
> > > > -Original Message-
> > > > From: Chuanhua Han
> > > > Sent: Friday, May 17, 2019 1:11 AM
> > > > To: Shawn Guo 
> > > > Cc: Leo Li ; mark.rutl...@arm.com; linux-arm-
> > > > ker...@lists.infradead.org; devicet...@vger.kernel.org; linux-
> > > > ker...@vger.kernel.org; Ying Zhang 
> > > > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > > device node
> > > >
> > > >
> > > >
> > > > > -Original Message-
> > > > > From: Shawn Guo 
> > > > > Sent: 2019年5月17日 10:38
> > > > > To: Chuanhua Han 
> > > > > Cc: Leo Li ; mark.rutl...@arm.com;
> > > > > linux-arm-ker...@lists.infradead.org;
> > > > > devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying
> > > > > Zhang 
> > > > > Subject: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > > > > device node
> > > > >
> > > > > Caution: EXT Email
> > > > >
> > > > > On Thu, May 09, 2019 at 03:06:57PM +0800, Chuanhua Han wrote:
> > > > > > ls1028a platform uses sp805 watchdog, and use 1/16 platform
> > > > > > clock as timer clock, this patch fix device tree node.
> > > > > >
> > > > > > Signed-off-by: Zhang Ying-22455 
> > > > > > Signed-off-by: Chuanhua Han 
> > > > > > ---
> > > > > >  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 19
> > > > > > ---
> > > > > >  1 file changed, 12 insertions(+), 7 deletions(-)
> > > > > >
> > > > > > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > > > b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > > > index b04581249f0b..1510b1858246 100644
> > > > > > --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > > > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > > > @@ -285,13 +285,18 @@
> > > > > >   #interrupt-cells = <2>;
> > > > > >   };
> > > > > >
> > > > > > - wdog0: watchdog@23c {
> > > > > > - compatible = "fsl,ls1028a-wdt",
> "fsl,imx21-wdt";
> > > > > > - reg = <0x0 0x23c 0x0 0x1>;
> > > > > > - interrupts =  > > IRQ_TYPE_LEVEL_HIGH>;
> > > > > > - clocks = < 4 1>;
> > > > > > - big-endian;
> > > > > > - status = "disabled";
> > > > > > + cluster1_core0_watchdog: wdt@c00 {
> > > > >
> > > > > Keep 'watchdog' as the node name,
> > > > Thanks for your replay
> > > > Do you mean replace the ‘wdt’ with ‘watchdog’?
> > > > and keep nodes sort in unit-address.
> > > > What does this mean?
> > >
> > > That means order the nodes by the addresses (e.g. c00, c01)
> > The current order is correct(The first is c00, then c00).
> 
> But they a

RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node

2019-05-21 Thread Chuanhua Han


> -Original Message-
> From: Leo Li
> Sent: 2019年5月18日 6:01
> To: Chuanhua Han ; Shawn Guo
> 
> Cc: mark.rutl...@arm.com; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; Ying Zhang
> 
> Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node
> 
> 
> 
> > -----Original Message-
> > From: Chuanhua Han
> > Sent: Friday, May 17, 2019 1:11 AM
> > To: Shawn Guo 
> > Cc: Leo Li ; mark.rutl...@arm.com; linux-arm-
> > ker...@lists.infradead.org; devicet...@vger.kernel.org; linux-
> > ker...@vger.kernel.org; Ying Zhang 
> > Subject: RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog
> > device node
> >
> >
> >
> > > -Original Message-
> > > From: Shawn Guo 
> > > Sent: 2019年5月17日 10:38
> > > To: Chuanhua Han 
> > > Cc: Leo Li ; mark.rutl...@arm.com;
> > > linux-arm-ker...@lists.infradead.org; devicet...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; Ying Zhang 
> > > Subject: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device
> > > node
> > >
> > > Caution: EXT Email
> > >
> > > On Thu, May 09, 2019 at 03:06:57PM +0800, Chuanhua Han wrote:
> > > > ls1028a platform uses sp805 watchdog, and use 1/16 platform clock
> > > > as timer clock, this patch fix device tree node.
> > > >
> > > > Signed-off-by: Zhang Ying-22455 
> > > > Signed-off-by: Chuanhua Han 
> > > > ---
> > > >  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 19
> > > > ---
> > > >  1 file changed, 12 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > index b04581249f0b..1510b1858246 100644
> > > > --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > > > @@ -285,13 +285,18 @@
> > > >   #interrupt-cells = <2>;
> > > >   };
> > > >
> > > > - wdog0: watchdog@23c {
> > > > - compatible = "fsl,ls1028a-wdt", "fsl,imx21-wdt";
> > > > - reg = <0x0 0x23c 0x0 0x1>;
> > > > - interrupts =  IRQ_TYPE_LEVEL_HIGH>;
> > > > - clocks = < 4 1>;
> > > > - big-endian;
> > > > - status = "disabled";
> > > > + cluster1_core0_watchdog: wdt@c00 {
> > >
> > > Keep 'watchdog' as the node name,
> > Thanks for your replay
> > Do you mean replace the ‘wdt’ with ‘watchdog’?
> > and keep nodes sort in unit-address.
> > What does this mean?
> 
> That means order the nodes by the addresses (e.g. c00, c01)
The current order is correct(The first is c00, then c00).
> 
> > >
> > > Shawn
> > >
> > > > + compatible = "arm,sp805", "arm,primecell";
> > > > + reg = <0x0 0xc00 0x0 0x1000>;
> > > > + clocks = < 4 15>, < 4 15>;
> > > > + clock-names = "apb_pclk", "wdog_clk";
> > > > + };
> > > > +
> > > > + cluster1_core1_watchdog: wdt@c01 {
> > > > + compatible = "arm,sp805", "arm,primecell";
> > > > + reg = <0x0 0xc01 0x0 0x1000>;
> > > > + clocks = < 4 15>, < 4 15>;
> > > > + clock-names = "apb_pclk", "wdog_clk";
> > > >   };
> > > >
> > > >   sata: sata@320 {
> > > > --
> > > > 2.17.1
> > > >


RE: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node

2019-05-17 Thread Chuanhua Han


> -Original Message-
> From: Shawn Guo 
> Sent: 2019年5月17日 10:38
> To: Chuanhua Han 
> Cc: Leo Li ; mark.rutl...@arm.com;
> linux-arm-ker...@lists.infradead.org; devicet...@vger.kernel.org;
> linux-kernel@vger.kernel.org; Ying Zhang 
> Subject: [EXT] Re: [PATCH] arm64: dts: ls1028a: fix watchdog device node
> 
> Caution: EXT Email
> 
> On Thu, May 09, 2019 at 03:06:57PM +0800, Chuanhua Han wrote:
> > ls1028a platform uses sp805 watchdog, and use 1/16 platform clock as
> > timer clock, this patch fix device tree node.
> >
> > Signed-off-by: Zhang Ying-22455 
> > Signed-off-by: Chuanhua Han 
> > ---
> >  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 19
> > ---
> >  1 file changed, 12 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > index b04581249f0b..1510b1858246 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > @@ -285,13 +285,18 @@
> >   #interrupt-cells = <2>;
> >   };
> >
> > - wdog0: watchdog@23c {
> > - compatible = "fsl,ls1028a-wdt", "fsl,imx21-wdt";
> > - reg = <0x0 0x23c 0x0 0x1>;
> > - interrupts = ;
> > - clocks = < 4 1>;
> > - big-endian;
> > - status = "disabled";
> > + cluster1_core0_watchdog: wdt@c00 {
> 
> Keep 'watchdog' as the node name,
Thanks for your replay
Do you mean replace the ‘wdt’ with ‘watchdog’?
and keep nodes sort in unit-address.
What does this mean?
> 
> Shawn
> 
> > + compatible = "arm,sp805", "arm,primecell";
> > + reg = <0x0 0xc00 0x0 0x1000>;
> > + clocks = < 4 15>, < 4 15>;
> > + clock-names = "apb_pclk", "wdog_clk";
> > + };
> > +
> > + cluster1_core1_watchdog: wdt@c01 {
> > + compatible = "arm,sp805", "arm,primecell";
> > + reg = <0x0 0xc01 0x0 0x1000>;
> > + clocks = < 4 15>, < 4 15>;
> > + clock-names = "apb_pclk", "wdog_clk";
> >   };
> >
> >   sata: sata@320 {
> > --
> > 2.17.1
> >


[PATCH] arm64: dts: ls1028a: fix watchdog device node

2019-05-09 Thread Chuanhua Han
ls1028a platform uses sp805 watchdog, and use 1/16 platform clock as
timer clock, this patch fix device tree node.

Signed-off-by: Zhang Ying-22455 
Signed-off-by: Chuanhua Han 
---
 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index b04581249f0b..1510b1858246 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -285,13 +285,18 @@
#interrupt-cells = <2>;
};
 
-   wdog0: watchdog@23c {
-   compatible = "fsl,ls1028a-wdt", "fsl,imx21-wdt";
-   reg = <0x0 0x23c 0x0 0x1>;
-   interrupts = ;
-   clocks = < 4 1>;
-   big-endian;
-   status = "disabled";
+   cluster1_core0_watchdog: wdt@c00 {
+   compatible = "arm,sp805", "arm,primecell";
+   reg = <0x0 0xc00 0x0 0x1000>;
+   clocks = < 4 15>, < 4 15>;
+   clock-names = "apb_pclk", "wdog_clk";
+   };
+
+   cluster1_core1_watchdog: wdt@c01 {
+   compatible = "arm,sp805", "arm,primecell";
+   reg = <0x0 0xc01 0x0 0x1000>;
+   clocks = < 4 15>, < 4 15>;
+   clock-names = "apb_pclk", "wdog_clk";
};
 
sata: sata@320 {
-- 
2.17.1



RE: [EXT] Re: [PATCH 1/3] dt-bindings: i2c: add optional mul-value property to binding

2019-05-08 Thread Chuanhua Han


> -Original Message-
> From: Rob Herring 
> Sent: 2019年5月3日 4:59
> To: Chuanhua Han 
> Cc: mark.rutl...@arm.com; shawn...@kernel.org; s.ha...@pengutronix.de;
> Leo Li ; linux-kernel@vger.kernel.org;
> devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> linux-...@vger.kernel.org; ker...@pengutronix.de; dl-linux-imx
> ; feste...@gmail.com;
> wsa+rene...@sang-engineering.com; u.kleine-koe...@pengutronix.de;
> e...@deif.com; li...@rempel-privat.de; Sumit Batra ;
> l.st...@pengutronix.de; p...@axentia.se
> Subject: [EXT] Re: [PATCH 1/3] dt-bindings: i2c: add optional mul-value
> property to binding
> 
> Caution: EXT Email
> 
> On Tue, Apr 30, 2019 at 12:32:40PM +0800, Chuanhua Han wrote:
> > NXP Layerscape SoC have up to three MUL options available for all
> > divider values, we choice of MUL determines the internal monitor rate
> > of the I2C bus (SCL and SDA signals):
> > A lower MUL value results in a higher sampling rate of the I2C signals.
> > A higher MUL value results in a lower sampling rate of the I2C signals.
> >
> > So in Optional properties we added our custom mul-value property in
> > the binding to select which mul option for the device tree i2c
> > controller node.
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> >  Documentation/devicetree/bindings/i2c/i2c-imx.txt | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > index b967544590e8..ba8e7b7b3fa8 100644
> > --- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > @@ -18,6 +18,9 @@ Optional properties:
> >  - sda-gpios: specify the gpio related to SDA pin
> >  - pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c
> >bus recovery, call it "gpio" state
> > +- mul-value: NXP Layerscape SoC have up to three MUL options
> > +available for all I2C divider values, it describes which MUL we
> > +choose to use for the driver, the values should be 1,2,4.
> 
> Needs a vendor prefix. I don't find 'value' to add anything nor do I 
> understand
> what MUL is.
Yes,you are right!
> 
> If it is determined by SoC rather than board, then it should perhaps be 
> implied
> by compatible.
This is determined by the SOC, but it has three options to choose from, 
so I think it's better to use the optional option instead of compatible

> 
> Rob


RE: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider I2C_IPGCLK_SEL RCW bit when using ls1046a SoC

2019-05-08 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年5月6日 15:48
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> 
> Caution: EXT Email
> 
> Hi,
> 
> In case we end up with the handling of this issue in the i2c driver, here are 
> the
> things to consider for v2.
> 
> On Tue, Apr 30, 2019 at 12:47:18PM +0800, Chuanhua Han wrote:
> > The current kernel driver does not consider I2C_IPGCLK_SEL (424 bit of
> > RCW) in deciding  i2c_clk_rate in function i2c_imx_set_clk() { 0
> > Platform clock/4, 1 Platform clock/2}.
> >
> > When using ls1046a SoC, this populates incorrect value in IBFD
> > register if I2C_IPGCLK_SEL = 0, which generates half of the desired Clock.
> >
> > Therefore, if ls1046a SoC is used, we need to set the i2c clock
> > according to the corresponding RCW.
> >
> > Signed-off-by: Sumit Batra 
> > Signed-off-by: Chuanhua Han 
> > ---
> >  drivers/i2c/busses/i2c-imx.c | 64
> > 
> >  1 file changed, 64 insertions(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-imx.c
> > b/drivers/i2c/busses/i2c-imx.c index 422f1a445b55..7186cf3c7d24 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -45,6 +45,8 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >
> >  /* This will be the driver name the kernel reports */  #define
> > DRIVER_NAME "imx-i2c"
> > @@ -109,6 +111,21 @@
> >
> >  #define I2C_PM_TIMEOUT   10 /* ms */
> >
> > +/* 14-1 Since array index starts from 0 */ #define
> > +RCW_I2C_IPGCLK_WORD (14 - 1)
> > +/*
> > + * Set mask for RCW 424th bit, reading from DCFG_CCSR RCW Status
> > +Registers
> > + * Since this register in RM depicted as big endian,
> > + * so consider 31st bit as LSB for creating the mask.
> > + */
> > +#define RCW_I2C_IPGCLK_MASK0x80
> > +int i2c_ipgclk_sel = 1;
> 
> should be static.
> 
> > +
> > +static const struct soc_device_attribute ls1046a_soc[] = {
> > +{.family = "QorIQ LS1046A"},
> > +{ /* sentinel */ }
> > +};
> > +
> >  /*
> >   * sorted list of clock divider, register value pairs
> >   * taken from table 26-5, p.26-9, Freescale i.MX @@ -304,6 +321,11 @@
> > static const struct platform_device_id imx_i2c_devtype[] = {  };
> > MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
> >
> > +static const struct of_device_id guts_device_ids[] = {
> > + { .compatible = "fsl,qoriq-device-config", },
> > + {}
> > +};
> > +
> >  static const struct of_device_id i2c_imx_dt_ids[] = {
> >   { .compatible = "fsl,imx1-i2c", .data = _i2c_hwdata, },
> >   { .compatible = "fsl,imx21-i2c", .data = _i2c_hwdata, },
> > @@ -533,6 +555,9 @@ static void i2c_imx_set_clk(struct imx_i2c_struct
> *i2c_imx,
> >   unsigned int div;
> >   int i;
> >
> > + if (!i2c_ipgclk_sel)
> > + i2c_clk_rate = i2c_clk_rate / 2;
> 
> It would be nice to have the variable inverted. You wouldn't have to 
> initialize a
> global variable with something else but 0 then.
> 
> > +
> >   /* Divider value calculation */
> >   if (i2c_imx->cur_clk == i2c_clk_rate)
> >   return;
> > @@ -551,6 +576,10 @@ static void i2c_imx_set_clk(struct imx_i2c_struct
> *i2c_imx,
> >   /* Store divider value */
> >   i2c_imx->ifdr = i2c_clk_div[i].val;
> >
> > + pr_alert("[%s] CLK Rate=%u Bitrate =%u Div =%u Value =%d\n",
> > +  __func__, i2c_clk_rate, i2c_imx->bitrate,
> > +  div, i2c_clk_div[i].val);
> 
> Please drop your debugging aids, for sure they shouldn't be pr_alert.
> 
> > +
> >   /*
> >* There dummy delay is calculated.
> >* It should be about one I2C clock period long.
> > @@ -1116,6 +1145,9 @@ static int i2c_imx_probe(struct platform_device
> *pdev)
> >

RE: [EXT] Re: [PATCH 2/2] arm64: dts: fsl: ls1046a: Add the guts node in dts

2019-05-08 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年5月6日 15:41
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: [EXT] Re: [PATCH 2/2] arm64: dts: fsl: ls1046a: Add the guts node in
> dts
> 
> Caution: EXT Email
> 
> On Tue, Apr 30, 2019 at 12:47:19PM +0800, Chuanhua Han wrote:
> > For NXP ls1046a SoC, the i2c clock needs to be configured with the
> > appropriate bit of RCW, so we add the guts node (GUTS/DCFG global
> > utilities block) for the driver to read.
> >
> > Signed-off-by: Sumit Batra 
> > Signed-off-by: Chuanhua Han 
> > ---
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > index 373310e4c0ea..f88599df18bb 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > @@ -205,6 +205,11 @@
> >   status = "disabled";
> >   };
> >
> > + guts: global-utilities@1ee {
> > + compatible = "fsl,qoriq-device-config";
> > + reg = <0x0 0x1ee 0x0 0x1000>;
> > + };
> 
> According to Documentation/devicetree/bindings/soc/fsl/guts.txt we have the
> following compatibles:
> 
> "fsl,qoriq-device-config-1.0"
> "fsl,qoriq-device-config-2.0"
> "fsl,-device-config"
> "fsl,-guts"
> 
> "fsl,qoriq-device-config" is none of them and I don't think you should give 
> this
> SoC specific thing a generic compatible.
> "fsl,ls1046a-device-config" would be better.
> 
Yes, you should be right
> Sascha
> 
> 
> --
> Pengutronix e.K.   |
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2Fdata=02%7C01%7Cchuanhua.han%40nxp.com%7C139
> 23fe17a1d46dad7e708d6d1f63f41%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C636927252885458344sdata=RLeDiCtLJRYzOZQ4P8CN8g
> hTUGNF%2FKA%2FT%2FtLSCrgEaE%3Dreserved=0  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686   | Fax:
> +49-5121-206917- |


RE: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider I2C_IPGCLK_SEL RCW bit when using ls1046a SoC

2019-05-08 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年5月6日 15:38
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: Re: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> 
> Caution: EXT Email
> 
> On Sat, May 04, 2019 at 09:28:48AM +, Chuanhua Han wrote:
> >
> >
> > > -Original Message-
> > > From: Sascha Hauer 
> > > Sent: 2019年4月30日 20:51
> > > To: Chuanhua Han 
> > > Cc: shawn...@kernel.org; Leo Li ;
> > > robh...@kernel.org; mark.rutl...@arm.com;
> > > linux-kernel@vger.kernel.org; linux-...@vger.kernel.org;
> > > linux-arm-ker...@lists.infradead.org;
> > > devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> > > ; wsa+rene...@sang-engineering.com;
> > > u.kleine-koe...@pengutronix.de; e...@deif.com;
> > > li...@rempel-privat.de; l.st...@pengutronix.de; p...@axentia.se;
> > > Sumit Batra 
> > > Subject: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> > > I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> > >
> > > Caution: EXT Email
> > >
> > > On Tue, Apr 30, 2019 at 12:47:18PM +0800, Chuanhua Han wrote:
> > > > The current kernel driver does not consider I2C_IPGCLK_SEL (424
> > > > bit of
> > > > RCW) in deciding  i2c_clk_rate in function i2c_imx_set_clk() { 0
> > > > Platform clock/4, 1 Platform clock/2}.
> > > >
> > > > When using ls1046a SoC, this populates incorrect value in IBFD
> > > > register if I2C_IPGCLK_SEL = 0, which generates half of the desired 
> > > > Clock.
> > > >
> > > > Therefore, if ls1046a SoC is used, we need to set the i2c clock
> > > > according to the corresponding RCW.
> > >
> > > So the clock driver reports the wrong clock. Please fix the clock driver 
> > > then.
> > No, this is a problem with the i2c driver. It is not a problem with
> > the clock driver, so the i2c driver needs to be modified.
> 
> So how does this RCW bit get evaluated? 
According to the reference manual
> only one clock goes to the i2c module (described as 1/2 Platform
> Clock) and the i2c module only takes one clock. So it seems there must be a /2
> divider somewhere, either in each i2c module or somewhere outside. Can your
> IC guys tell you where it is?
I need to confirm this with the IC team
> 
> One reason I suggested the clock driver is that the clock driver contains SoC
> specific code already, so it should be easier to integrate there.
It seems inappropriate to put the clock frequency division modification of i2c 
in the clock driver,
because the clock driver is for all IP and is a universal code, so I think it 
is better to modify the clock in the IP driver.
> 
> Sascha
> 
> 
> --
> Pengutronix e.K.   |
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2Fdata=02%7C01%7Cchuanhua.han%40nxp.com%7Cb2d
> 4680699c448e8514308d6d1f5bf82%7C686ea1d3bc2b4c6fa92cd99c5c30163
> 5%7C0%7C0%7C636927250743516563sdata=pFdCbiDXE%2FDll01X9Nj
> Hg3SCDpECzgrr8MLtYBdKH5c%3Dreserved=0  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686   | Fax:
> +49-5121-206917- |


RE: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider I2C_IPGCLK_SEL RCW bit when using ls1046a SoC

2019-05-06 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年5月6日 15:48
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> 
> Caution: EXT Email
> 
> Hi,
> 
> In case we end up with the handling of this issue in the i2c driver, here are 
> the
> things to consider for v2.
Ok,thank you for your advice!
> 
> On Tue, Apr 30, 2019 at 12:47:18PM +0800, Chuanhua Han wrote:
> > The current kernel driver does not consider I2C_IPGCLK_SEL (424 bit of
> > RCW) in deciding  i2c_clk_rate in function i2c_imx_set_clk() { 0
> > Platform clock/4, 1 Platform clock/2}.
> >
> > When using ls1046a SoC, this populates incorrect value in IBFD
> > register if I2C_IPGCLK_SEL = 0, which generates half of the desired Clock.
> >
> > Therefore, if ls1046a SoC is used, we need to set the i2c clock
> > according to the corresponding RCW.
> >
> > Signed-off-by: Sumit Batra 
> > Signed-off-by: Chuanhua Han 
> > ---
> >  drivers/i2c/busses/i2c-imx.c | 64
> > 
> >  1 file changed, 64 insertions(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-imx.c
> > b/drivers/i2c/busses/i2c-imx.c index 422f1a445b55..7186cf3c7d24 100644
> > --- a/drivers/i2c/busses/i2c-imx.c
> > +++ b/drivers/i2c/busses/i2c-imx.c
> > @@ -45,6 +45,8 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >
> >  /* This will be the driver name the kernel reports */  #define
> > DRIVER_NAME "imx-i2c"
> > @@ -109,6 +111,21 @@
> >
> >  #define I2C_PM_TIMEOUT   10 /* ms */
> >
> > +/* 14-1 Since array index starts from 0 */ #define
> > +RCW_I2C_IPGCLK_WORD (14 - 1)
> > +/*
> > + * Set mask for RCW 424th bit, reading from DCFG_CCSR RCW Status
> > +Registers
> > + * Since this register in RM depicted as big endian,
> > + * so consider 31st bit as LSB for creating the mask.
> > + */
> > +#define RCW_I2C_IPGCLK_MASK0x80
> > +int i2c_ipgclk_sel = 1;
> 
> should be static.
> 
> > +
> > +static const struct soc_device_attribute ls1046a_soc[] = {
> > +{.family = "QorIQ LS1046A"},
> > +{ /* sentinel */ }
> > +};
> > +
> >  /*
> >   * sorted list of clock divider, register value pairs
> >   * taken from table 26-5, p.26-9, Freescale i.MX @@ -304,6 +321,11 @@
> > static const struct platform_device_id imx_i2c_devtype[] = {  };
> > MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
> >
> > +static const struct of_device_id guts_device_ids[] = {
> > + { .compatible = "fsl,qoriq-device-config", },
> > + {}
> > +};
> > +
> >  static const struct of_device_id i2c_imx_dt_ids[] = {
> >   { .compatible = "fsl,imx1-i2c", .data = _i2c_hwdata, },
> >   { .compatible = "fsl,imx21-i2c", .data = _i2c_hwdata, },
> > @@ -533,6 +555,9 @@ static void i2c_imx_set_clk(struct imx_i2c_struct
> *i2c_imx,
> >   unsigned int div;
> >   int i;
> >
> > + if (!i2c_ipgclk_sel)
> > + i2c_clk_rate = i2c_clk_rate / 2;
> 
> It would be nice to have the variable inverted. You wouldn't have to 
> initialize a
> global variable with something else but 0 then.
> 
> > +
> >   /* Divider value calculation */
> >   if (i2c_imx->cur_clk == i2c_clk_rate)
> >   return;
> > @@ -551,6 +576,10 @@ static void i2c_imx_set_clk(struct imx_i2c_struct
> *i2c_imx,
> >   /* Store divider value */
> >   i2c_imx->ifdr = i2c_clk_div[i].val;
> >
> > + pr_alert("[%s] CLK Rate=%u Bitrate =%u Div =%u Value =%d\n",
> > +  __func__, i2c_clk_rate, i2c_imx->bitrate,
> > +  div, i2c_clk_div[i].val);
> 
> Please drop your debugging aids, for sure they shouldn't be pr_alert.
> 
> > +
> >   /*
> >* There dummy delay is calculated.
> >* It should be about one I2C clock period long.
> > @@ -1116,6 +1145,9 @@ static int i2c_imx_probe(struct pl

RE: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider I2C_IPGCLK_SEL RCW bit when using ls1046a SoC

2019-05-06 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年5月6日 15:38
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: Re: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> 
> Caution: EXT Email
> 
> On Sat, May 04, 2019 at 09:28:48AM +, Chuanhua Han wrote:
> >
> >
> > > -Original Message-
> > > From: Sascha Hauer 
> > > Sent: 2019年4月30日 20:51
> > > To: Chuanhua Han 
> > > Cc: shawn...@kernel.org; Leo Li ;
> > > robh...@kernel.org; mark.rutl...@arm.com;
> > > linux-kernel@vger.kernel.org; linux-...@vger.kernel.org;
> > > linux-arm-ker...@lists.infradead.org;
> > > devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> > > ; wsa+rene...@sang-engineering.com;
> > > u.kleine-koe...@pengutronix.de; e...@deif.com;
> > > li...@rempel-privat.de; l.st...@pengutronix.de; p...@axentia.se;
> > > Sumit Batra 
> > > Subject: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> > > I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> > >
> > > Caution: EXT Email
> > >
> > > On Tue, Apr 30, 2019 at 12:47:18PM +0800, Chuanhua Han wrote:
> > > > The current kernel driver does not consider I2C_IPGCLK_SEL (424
> > > > bit of
> > > > RCW) in deciding  i2c_clk_rate in function i2c_imx_set_clk() { 0
> > > > Platform clock/4, 1 Platform clock/2}.
> > > >
> > > > When using ls1046a SoC, this populates incorrect value in IBFD
> > > > register if I2C_IPGCLK_SEL = 0, which generates half of the desired 
> > > > Clock.
> > > >
> > > > Therefore, if ls1046a SoC is used, we need to set the i2c clock
> > > > according to the corresponding RCW.
> > >
> > > So the clock driver reports the wrong clock. Please fix the clock driver 
> > > then.
> > No, this is a problem with the i2c driver. It is not a problem with
> > the clock driver, so the i2c driver needs to be modified.
> 
> So how does this RCW bit get evaluated? According to the reference manual
> only one clock goes to the i2c module (described as 1/2 Platform
> Clock) and the i2c module only takes one clock. So it seems there must be a /2
> divider somewhere, either in each i2c module or somewhere outside. Can your
> IC guys tell you where it is?
> 
> One reason I suggested the clock driver is that the clock driver contains SoC
> specific code already, so it should be easier to integrate there.
OK, I will see that it can be qualified in the clock driver.
> 
> Sascha
> 
> 
> --
> Pengutronix e.K.   |
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2Fdata=02%7C01%7Cchuanhua.han%40nxp.com%7Cb2d
> 4680699c448e8514308d6d1f5bf82%7C686ea1d3bc2b4c6fa92cd99c5c30163
> 5%7C0%7C0%7C636927250743516563sdata=pFdCbiDXE%2FDll01X9Nj
> Hg3SCDpECzgrr8MLtYBdKH5c%3Dreserved=0  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686   | Fax:
> +49-5121-206917- |


RE: [EXT] Re: [PATCH 2/2] arm64: dts: fsl: ls1046a: Add the guts node in dts

2019-05-06 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年5月6日 15:41
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: [EXT] Re: [PATCH 2/2] arm64: dts: fsl: ls1046a: Add the guts node in
> dts
> 
> Caution: EXT Email
> 
> On Tue, Apr 30, 2019 at 12:47:19PM +0800, Chuanhua Han wrote:
> > For NXP ls1046a SoC, the i2c clock needs to be configured with the
> > appropriate bit of RCW, so we add the guts node (GUTS/DCFG global
> > utilities block) for the driver to read.
> >
> > Signed-off-by: Sumit Batra 
> > Signed-off-by: Chuanhua Han 
> > ---
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 5 +
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > index 373310e4c0ea..f88599df18bb 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
> > @@ -205,6 +205,11 @@
> >   status = "disabled";
> >   };
> >
> > + guts: global-utilities@1ee {
> > + compatible = "fsl,qoriq-device-config";
> > + reg = <0x0 0x1ee 0x0 0x1000>;
> > + };
> 
> According to Documentation/devicetree/bindings/soc/fsl/guts.txt we have the
> following compatibles:
> 
> "fsl,qoriq-device-config-1.0"
> "fsl,qoriq-device-config-2.0"
> "fsl,-device-config"
> "fsl,-guts"
> 
> "fsl,qoriq-device-config" is none of them and I don't think you should give 
> this
> SoC specific thing a generic compatible.
> "fsl,ls1046a-device-config" would be better.
yes, you are right,I will modify it 
> 
> Sascha
> 
> 
> --
> Pengutronix e.K.   |
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2Fdata=02%7C01%7Cchuanhua.han%40nxp.com%7C139
> 23fe17a1d46dad7e708d6d1f63f41%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C636927252885458344sdata=RLeDiCtLJRYzOZQ4P8CN8g
> hTUGNF%2FKA%2FT%2FtLSCrgEaE%3Dreserved=0  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686   | Fax:
> +49-5121-206917- |


RE: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider I2C_IPGCLK_SEL RCW bit when using ls1046a SoC

2019-05-04 Thread Chuanhua Han


> -Original Message-
> From: Sascha Hauer 
> Sent: 2019年4月30日 20:51
> To: Chuanhua Han 
> Cc: shawn...@kernel.org; Leo Li ; robh...@kernel.org;
> mark.rutl...@arm.com; linux-kernel@vger.kernel.org;
> linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> devicet...@vger.kernel.org; feste...@gmail.com; dl-linux-imx
> ; wsa+rene...@sang-engineering.com;
> u.kleine-koe...@pengutronix.de; e...@deif.com; li...@rempel-privat.de;
> l.st...@pengutronix.de; p...@axentia.se; Sumit Batra
> 
> Subject: [EXT] Re: [PATCH 1/2] i2c: imx: I2C Driver doesn't consider
> I2C_IPGCLK_SEL RCW bit when using ls1046a SoC
> 
> Caution: EXT Email
> 
> On Tue, Apr 30, 2019 at 12:47:18PM +0800, Chuanhua Han wrote:
> > The current kernel driver does not consider I2C_IPGCLK_SEL (424 bit of
> > RCW) in deciding  i2c_clk_rate in function i2c_imx_set_clk() { 0
> > Platform clock/4, 1 Platform clock/2}.
> >
> > When using ls1046a SoC, this populates incorrect value in IBFD
> > register if I2C_IPGCLK_SEL = 0, which generates half of the desired Clock.
> >
> > Therefore, if ls1046a SoC is used, we need to set the i2c clock
> > according to the corresponding RCW.
> 
> So the clock driver reports the wrong clock. Please fix the clock driver then.
No, this is a problem with the i2c driver. It is not a problem with the clock 
driver, so the i2c driver needs to be modified.
> 
> Sascha
> 
> --
> Pengutronix e.K.   |
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2Fdata=02%7C01%7Cchuanhua.han%40nxp.com%7C2bb
> a89c908fb4bd37b6708d6cd6a7ff7%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C636922254625472037sdata=eC4bGDNAOhEu24xt9F0h
> kxE%2B1ffooCZ4CUr4o0gQGD4%3Dreserved=0  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686   | Fax:
> +49-5121-206917- |


RE: [EXT] Re: [PATCH 1/3] dt-bindings: i2c: add optional mul-value property to binding

2019-04-30 Thread Chuanhua Han


> -Original Message-
> From: Uwe Kleine-König 
> Sent: 2019年4月30日 14:38
> To: Chuanhua Han 
> Cc: robh...@kernel.org; mark.rutl...@arm.com; shawn...@kernel.org;
> s.ha...@pengutronix.de; Leo Li ;
> linux-kernel@vger.kernel.org; devicet...@vger.kernel.org;
> linux-arm-ker...@lists.infradead.org; linux-...@vger.kernel.org;
> ker...@pengutronix.de; dl-linux-imx ;
> feste...@gmail.com; wsa+rene...@sang-engineering.com; e...@deif.com;
> li...@rempel-privat.de; Sumit Batra ;
> l.st...@pengutronix.de; p...@axentia.se
> Subject: [EXT] Re: [PATCH 1/3] dt-bindings: i2c: add optional mul-value
> property to binding
> 
> Caution: EXT Email
> 
> On Tue, Apr 30, 2019 at 12:32:40PM +0800, Chuanhua Han wrote:
> > NXP Layerscape SoC have up to three MUL options available for all
> > divider values, we choice of MUL determines the internal monitor rate
> > of the I2C bus (SCL and SDA signals):
> > A lower MUL value results in a higher sampling rate of the I2C signals.
> > A higher MUL value results in a lower sampling rate of the I2C signals.
> >
> > So in Optional properties we added our custom mul-value property in
> > the binding to select which mul option for the device tree i2c
> > controller node.
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> >  Documentation/devicetree/bindings/i2c/i2c-imx.txt | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > index b967544590e8..ba8e7b7b3fa8 100644
> > --- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
> > @@ -18,6 +18,9 @@ Optional properties:
> >  - sda-gpios: specify the gpio related to SDA pin
> >  - pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c
> >bus recovery, call it "gpio" state
> > +- mul-value: NXP Layerscape SoC have up to three MUL options
> > +available for all I2C divider values, it describes which MUL we
> > +choose to use for the driver, the values should be 1,2,4.
> 
> Indention is broken.
Yes, I also found this problem, next version I will fix the indent problem
> 
> I wonder why this needs to be configurable on a per-machine/device level.
> What is the trade-off?
According to NXP Layerscape SoC Reference Manual, there are three MUL 
options for i2c controller to configure i2c Bus Frequency Divider Register 
(IBFD)
to determine the clock Frequency of i2c. 
Some socs (such as ls1046a) have the best performance when MUL=4, 
and the default is MUL=1. 
This option is optional and can be configured by device tree
> 
> Best regards
> Uwe
> 
> --
> Pengutronix e.K.   | Uwe Kleine-König
> |
> Industrial Linux Solutions |
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pe
> ngutronix.de%2Fdata=02%7C01%7Cchuanhua.han%40nxp.com%7C158
> 21c9cf4c449f2d5ea08d6cd367aaa%7C686ea1d3bc2b4c6fa92cd99c5c301635
> %7C0%7C0%7C636922031201957736sdata=8jKPN%2FSJghgOF890NTr
> %2FC%2B9PsFpEr64%2B%2FXHLSX5Cipo%3Dreserved=0  |


[PATCH 1/2] i2c: imx: I2C Driver doesn't consider I2C_IPGCLK_SEL RCW bit when using ls1046a SoC

2019-04-29 Thread Chuanhua Han
The current kernel driver does not consider I2C_IPGCLK_SEL (424 bit
of RCW) in deciding  i2c_clk_rate in function i2c_imx_set_clk()
{ 0 Platform clock/4, 1 Platform clock/2}.

When using ls1046a SoC, this populates incorrect value in IBFD register
if I2C_IPGCLK_SEL = 0, which generates half of the desired Clock.

Therefore, if ls1046a SoC is used, we need to set the i2c clock
according to the corresponding RCW.

Signed-off-by: Sumit Batra 
Signed-off-by: Chuanhua Han 
---
 drivers/i2c/busses/i2c-imx.c | 64 
 1 file changed, 64 insertions(+)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 422f1a445b55..7186cf3c7d24 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -45,6 +45,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /* This will be the driver name the kernel reports */
 #define DRIVER_NAME "imx-i2c"
@@ -109,6 +111,21 @@
 
 #define I2C_PM_TIMEOUT 10 /* ms */
 
+/* 14-1 Since array index starts from 0 */
+#define RCW_I2C_IPGCLK_WORD (14 - 1)
+/*
+ * Set mask for RCW 424th bit, reading from DCFG_CCSR RCW Status Registers
+ * Since this register in RM depicted as big endian,
+ * so consider 31st bit as LSB for creating the mask.
+ */
+#define RCW_I2C_IPGCLK_MASK0x80
+int i2c_ipgclk_sel = 1;
+
+static const struct soc_device_attribute ls1046a_soc[] = {
+  {.family = "QorIQ LS1046A"},
+  { /* sentinel */ }
+};
+
 /*
  * sorted list of clock divider, register value pairs
  * taken from table 26-5, p.26-9, Freescale i.MX
@@ -304,6 +321,11 @@ static const struct platform_device_id imx_i2c_devtype[] = 
{
 };
 MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
 
+static const struct of_device_id guts_device_ids[] = {
+   { .compatible = "fsl,qoriq-device-config", },
+   {}
+};
+
 static const struct of_device_id i2c_imx_dt_ids[] = {
{ .compatible = "fsl,imx1-i2c", .data = _i2c_hwdata, },
{ .compatible = "fsl,imx21-i2c", .data = _i2c_hwdata, },
@@ -533,6 +555,9 @@ static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
unsigned int div;
int i;
 
+   if (!i2c_ipgclk_sel)
+   i2c_clk_rate = i2c_clk_rate / 2;
+
/* Divider value calculation */
if (i2c_imx->cur_clk == i2c_clk_rate)
return;
@@ -551,6 +576,10 @@ static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
/* Store divider value */
i2c_imx->ifdr = i2c_clk_div[i].val;
 
+   pr_alert("[%s] CLK Rate=%u Bitrate =%u Div =%u Value =%d\n",
+__func__, i2c_clk_rate, i2c_imx->bitrate,
+div, i2c_clk_div[i].val);
+
/*
 * There dummy delay is calculated.
 * It should be about one I2C clock period long.
@@ -1116,6 +1145,9 @@ static int i2c_imx_probe(struct platform_device *pdev)
int irq, ret;
dma_addr_t phy_addr;
u32 mul_value;
+   struct device_node *guts_node;
+   static struct ccsr_guts __iomem *guts_regs;
+   u32 rcw_reg;
 
dev_dbg(>dev, "<%s>\n", __func__);
 
@@ -1135,6 +1167,38 @@ static int i2c_imx_probe(struct platform_device *pdev)
if (!i2c_imx)
return -ENOMEM;
 
+   if (soc_device_match(ls1046a_soc)) {
+   /*
+* Make device node for GUTS/DCFG (global utilities block)
+* to read RCW.
+*/
+   guts_node = of_find_matching_node(NULL, guts_device_ids);
+   if (!guts_node) {
+   dev_err(>dev, "Could not find GUTS node\n");
+   return -ENODEV;
+   }
+   /*
+* Memory (IO)  MAP the DCFG registers(for RCW) to
+* be used in kernel virtual address space.
+*/
+   guts_regs = of_iomap(guts_node, 0);
+   of_node_put(guts_node);
+   if (!guts_regs) {
+   dev_err(>dev, "IOREMAP of GUTS node failed\n");
+   return -ENOMEM;
+   }
+   /* Read rcw bit 424 (starting from 0) */
+   rcw_reg = ioread32be(_regs->rcwsr[RCW_I2C_IPGCLK_WORD]);
+   pr_alert("RCW REG[%d]=0x%x\n", RCW_I2C_IPGCLK_WORD, rcw_reg);
+   if (rcw_reg & RCW_I2C_IPGCLK_MASK) {
+   pr_alert("Div by 2 Case Detected in RCW\n");
+   i2c_ipgclk_sel = 1;
+   } else {
+   pr_alert("Div by 4 Case Detected in RCW\n");
+   i2c_ipgclk_sel = 0;
+   }
+   }
+
if (of_id) {
i2c_imx->hwdata = of_id->data;
ret = of_property_read_u32(pdev->dev.of_node,
-- 
2.17.1



[PATCH 2/2] arm64: dts: fsl: ls1046a: Add the guts node in dts

2019-04-29 Thread Chuanhua Han
For NXP ls1046a SoC, the i2c clock needs to be configured with the
appropriate bit of RCW, so we add the guts node (GUTS/DCFG global
utilities block) for the driver to read.

Signed-off-by: Sumit Batra 
Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 373310e4c0ea..f88599df18bb 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -205,6 +205,11 @@
status = "disabled";
};
 
+   guts: global-utilities@1ee {
+   compatible = "fsl,qoriq-device-config";
+   reg = <0x0 0x1ee 0x0 0x1000>;
+   };
+
qspi: spi@155 {
compatible = "fsl,ls1021a-qspi";
#address-cells = <1>;
-- 
2.17.1



[PATCH 1/3] dt-bindings: i2c: add optional mul-value property to binding

2019-04-29 Thread Chuanhua Han
NXP Layerscape SoC have up to three MUL options available for all
divider values, we choice of MUL determines the internal monitor rate
of the I2C bus (SCL and SDA signals):
A lower MUL value results in a higher sampling rate of the I2C signals.
A higher MUL value results in a lower sampling rate of the I2C signals.

So in Optional properties we added our custom mul-value property in the
binding to select which mul option for the device tree i2c controller
node.

Signed-off-by: Chuanhua Han 
---
 Documentation/devicetree/bindings/i2c/i2c-imx.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt 
b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
index b967544590e8..ba8e7b7b3fa8 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt
@@ -18,6 +18,9 @@ Optional properties:
 - sda-gpios: specify the gpio related to SDA pin
 - pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c
   bus recovery, call it "gpio" state
+- mul-value: NXP Layerscape SoC have up to three MUL options available for
+all I2C divider values, it describes which MUL we choose to use for the driver,
+the values should be 1,2,4.
 
 Examples:
 
-- 
2.17.1



[PATCH 2/3] i2c: imx: I2C Driver IBC and SCL Divider for MUL=2 and MUL=4

2019-04-29 Thread Chuanhua Han
NXP Layerscape SoC have up to three MUL options available for all
divider values,we choice of MUL determines the internal monitor rate
of the I2C bus (SCL and SDA signals).

The current kernel driver supports MUL=1 by default ,but doesn't have
the IBC and SCL Divider entries in vf610_i2c_clk_div for MUL=2  and
MUL=4,so we need to add the corresponding support.

Signed-off-by: Sumit Batra 
Signed-off-by: Chuanhua Han 
---
 drivers/i2c/busses/i2c-imx.c | 71 +++-
 1 file changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 42fed40198a0..ac5a334b7339 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -156,6 +157,44 @@ static struct imx_i2c_clk_pair vf610_i2c_clk_div[] = {
{ 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E },
 };
 
+static struct imx_i2c_clk_pair mul2_i2c_clk_div[] = {
+   { 40,   0x40 }, { 44,   0x41 }, { 48,   0x42 }, { 52,   0x43 },
+   { 56,   0x44 }, { 60,   0x45 }, { 68,   0x46 }, { 80,   0x47 },
+   { 56,   0x48 }, { 64,   0x49 }, { 72,   0x4A }, { 80,   0x4B },
+   { 88,   0x4C }, { 96,   0x4D }, { 112,  0x4E }, { 136,  0x4F },
+   { 96,   0x50 }, { 112,  0x51 }, { 128,  0x52 }, { 144,  0x53 },
+   { 160,  0x54 }, { 176,  0x55 }, { 208,  0x56 }, { 256,  0x57 },
+   { 160,  0x58 }, { 192,  0x59 }, { 224,  0x5A }, { 256,  0x5B },
+   { 288,  0x5C }, { 320,  0x5D }, { 384,  0x5E }, { 480,  0x5F },
+   { 320,  0x60 }, { 384,  0x61 }, { 448,  0x62 }, { 512,  0x63 },
+   { 576,  0x64 }, { 640,  0x65 }, { 768,  0x66 }, { 960,  0x67 },
+   { 640,  0x68 }, { 768,  0x69 }, { 896,  0x6A }, { 1024, 0x6B },
+   { 1152, 0x6C }, { 1280, 0x6D }, { 1536, 0x6E }, { 1920, 0x6F },
+   { 1280, 0x70 }, { 1536, 0x71 }, { 1792, 0x72 }, { 2048, 0x73 },
+   { 2304, 0x74 }, { 2560, 0x75 }, { 3072, 0x76 }, { 3840, 0x77 },
+   { 2560, 0x78 }, { 3072, 0x79 }, { 3584, 0x7A }, { 4096, 0x7B },
+   { 4608, 0x7C }, { 5120, 0x7D }, { 6144, 0x7E }, { 7680, 0x7F },
+};
+
+static struct imx_i2c_clk_pair mul4_i2c_clk_div[] = {
+   { 80,0x80 }, { 88,0x81 }, { 96,0x82 }, { 104,   0x83 },
+   { 112,   0x84 }, { 120,   0x85 }, { 136,   0x86 }, { 160,   0x87 },
+   { 112,   0x88 }, { 128,   0x89 }, { 144,   0x8A }, { 160,   0x8B },
+   { 176,   0x8C }, { 192,   0x8D }, { 224,   0x8E }, { 272,   0x8F },
+   { 192,   0x90 }, { 224,   0x91 }, { 256,   0x92 }, { 288,   0x93 },
+   { 320,   0x94 }, { 352,   0x95 }, { 416,   0x96 }, { 512,   0x97 },
+   { 320,   0x98 }, { 384,   0x99 }, { 448,   0x9A }, { 512,   0x9B },
+   { 576,   0x9C }, { 640,   0x9D }, { 768,   0x9E }, { 960,   0x9F },
+   { 640,   0xA0 }, { 768,   0xA1 }, { 896,   0xA2 }, { 1024,  0xA3 },
+   { 1152,  0xA4 }, { 1280,  0xA5 }, { 1536,  0xA6 }, { 1792,  0xAA },
+   { 1280,  0xA8 }, { 1536,  0xA9 }, { 1920,  0xA7 }, { 2048,  0xAB },
+   { 2304,  0xAC }, { 2560,  0xAD }, { 3072,  0xAE }, { 3584,  0xB2 },
+   { 2560,  0xB0 }, { 3072,  0xB1 }, { 3820,  0xAF }, { 4096,  0xB3 },
+   { 4608,  0xB4 }, { 5120,  0xB5 }, { 6144,  0xB6 }, { 7680,  0xB7 },
+   { 5120,  0xB8 }, { 6144,  0xB9 }, { 7168,  0xBA }, { 8192,  0xBB },
+   { 9216,  0xBC }, { 10240, 0xBD }, { 12288, 0xBE }, { 15360, 0xBF },
+};
+
 enum imx_i2c_type {
IMX1_I2C,
IMX21_I2C,
@@ -234,6 +273,24 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
 
 };
 
+static struct imx_i2c_hwdata mul2_i2c_hwdata = {
+   .devtype= VF610_I2C,
+   .regshift   = VF610_I2C_REGSHIFT,
+   .clk_div= mul2_i2c_clk_div,
+   .ndivs  = ARRAY_SIZE(mul2_i2c_clk_div),
+   .i2sr_clr_opcode= I2SR_CLR_OPCODE_W1C,
+   .i2cr_ien_opcode= I2CR_IEN_OPCODE_0,
+};
+
+static struct imx_i2c_hwdata mul4_i2c_hwdata = {
+   .devtype= VF610_I2C,
+   .regshift   = VF610_I2C_REGSHIFT,
+   .clk_div= mul4_i2c_clk_div,
+   .ndivs  = ARRAY_SIZE(mul4_i2c_clk_div),
+   .i2sr_clr_opcode= I2SR_CLR_OPCODE_W1C,
+   .i2cr_ien_opcode= I2CR_IEN_OPCODE_0,
+};
+
 static const struct platform_device_id imx_i2c_devtype[] = {
{
.name = "imx1-i2c",
@@ -1058,6 +1115,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
void __iomem *base;
int irq, ret;
dma_addr_t phy_addr;
+   u32 mul_value;
 
dev_dbg(>dev, "<%s>\n", __func__);
 
@@ -1077,11 +1135,20 @@ static int i2c_imx_probe(struct platform_device *pdev)
if (!i2c_imx)
return -ENOMEM;
 
-   if (of_id)
+   if (of_id) {
i2c_imx->hwdata = of_id->data;
-   else
+   ret = of_

[PATCH 3/3] arm64: dts: fsl: ls1046a: Add mul-value property of the i2c controller nodes

2019-04-29 Thread Chuanhua Han
According to LS1046A Reference Manual, for the i2c controller, you have
up to three MUL options available for all divider values. Therefore, we
need to determine which MUL to use in the device tree for driver use.

The "mul-value" property provides which mul is used in our driver.

Signed-off-by: Chuanhua Han 
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index b0ef08b090dd..373310e4c0ea 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -385,6 +385,7 @@
dmas = < 1 39>,
   < 1 38>;
dma-names = "tx", "rx";
+   mul-value = <4>;
status = "disabled";
};
 
@@ -395,6 +396,7 @@
reg = <0x0 0x219 0x0 0x1>;
interrupts = ;
clocks = < 4 1>;
+   mul-value = <4>;
status = "disabled";
};
 
@@ -405,6 +407,7 @@
reg = <0x0 0x21a 0x0 0x1>;
interrupts = ;
clocks = < 4 1>;
+   mul-value = <4>;
status = "disabled";
};
 
@@ -415,6 +418,7 @@
reg = <0x0 0x21b 0x0 0x1>;
interrupts = ;
clocks = < 4 1>;
+   mul-value = <4>;
status = "disabled";
};
 
-- 
2.17.1



[PATCH RESEND] spi: spi-fsl-dspi: use IRQF_SHARED mode to request IRQ

2018-10-28 Thread Chuanhua Han
Some SoC share one irq number between DSPI controllers.
For example, on the LX2160 board, DSPI0 and DSPI1 share one irq number.
In this case, only one DSPI controller can register successfully,
and others will fail.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-dspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..5e10dc5c93a5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1090,8 +1090,8 @@ static int dspi_probe(struct platform_device *pdev)
goto out_clk_put;
}
 
-   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt, 0,
-   pdev->name, dspi);
+   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt,
+  IRQF_SHARED, pdev->name, dspi);
if (ret < 0) {
dev_err(>dev, "Unable to attach DSPI interrupt\n");
goto out_clk_put;
-- 
2.17.1



[PATCH RESEND] spi: spi-fsl-dspi: use IRQF_SHARED mode to request IRQ

2018-10-28 Thread Chuanhua Han
Some SoC share one irq number between DSPI controllers.
For example, on the LX2160 board, DSPI0 and DSPI1 share one irq number.
In this case, only one DSPI controller can register successfully,
and others will fail.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-dspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..5e10dc5c93a5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1090,8 +1090,8 @@ static int dspi_probe(struct platform_device *pdev)
goto out_clk_put;
}
 
-   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt, 0,
-   pdev->name, dspi);
+   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt,
+  IRQF_SHARED, pdev->name, dspi);
if (ret < 0) {
dev_err(>dev, "Unable to attach DSPI interrupt\n");
goto out_clk_put;
-- 
2.17.1



[PATCH 1/3] dspi: lx2160a: use IRQF_SHARED mode to request IRQ

2018-10-25 Thread Chuanhua Han
Some SoC share one irq number between DSPI controllers.
For example, on the LX2160 board, DSPI0 and DSPI1 share one irq number.
In this case, only one DSPI controller can register successfully,
and others will fail.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-dspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..5e10dc5c93a5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1090,8 +1090,8 @@ static int dspi_probe(struct platform_device *pdev)
goto out_clk_put;
}
 
-   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt, 0,
-   pdev->name, dspi);
+   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt,
+  IRQF_SHARED, pdev->name, dspi);
if (ret < 0) {
dev_err(>dev, "Unable to attach DSPI interrupt\n");
goto out_clk_put;
-- 
2.17.1



[PATCH 1/3] dspi: lx2160a: use IRQF_SHARED mode to request IRQ

2018-10-25 Thread Chuanhua Han
Some SoC share one irq number between DSPI controllers.
For example, on the LX2160 board, DSPI0 and DSPI1 share one irq number.
In this case, only one DSPI controller can register successfully,
and others will fail.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-dspi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..5e10dc5c93a5 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1090,8 +1090,8 @@ static int dspi_probe(struct platform_device *pdev)
goto out_clk_put;
}
 
-   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt, 0,
-   pdev->name, dspi);
+   ret = devm_request_irq(>dev, dspi->irq, dspi_interrupt,
+  IRQF_SHARED, pdev->name, dspi);
if (ret < 0) {
dev_err(>dev, "Unable to attach DSPI interrupt\n");
goto out_clk_put;
-- 
2.17.1



RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-10-09 Thread Chuanhua Han


> -Original Message-
> From: Esben Haabendal  On Behalf Of Esben
> Haabendal
> Sent: 2018年10月9日 19:21
> To: Chuanhua Han 
> Cc: Boris Brezillon ; broo...@kernel.org;
> linux-...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Chuanhua Han  writes:
> 
> >> -Original Message-
> >> From: Boris Brezillon 
> >> Sent: 2018年10月9日 18:05
> >> To: Chuanhua Han 
> >> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> >> linux-kernel@vger.kernel.org; e...@deif.com
> >> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw
> >> function
> >>
> >> On Tue, 9 Oct 2018 09:52:23 +
> >> Chuanhua Han  wrote:
> >>
> >> > 1. In the dspi driver (spi controller), bits_per_word
> >> > (dspi->bits_per_word = transfer->bits_per_word) passed from the
> >> > upper layer (spi-mem.c) is used. In this way, I can only assign the
> >> > appropriate value of transfer->bits_per_word before passing to the
> >> > controller, that is, the controller driver does not know the value
> >> > of bits_per_word, and it will use this value when the upper level
> >> > sets what value is passed.
> >>
> >> I think you're missing my point: ->bits_per_word is not what you're
> >> looking for if what you're trying to do is use 32-bits accesses when
> >> things are properly aligned.
> >>
> > In the dspi driver (spi controller driver), it is based on whether
> > ->bits_per_word is
> > larger than 16 to decide whether to use the XSPI mode (32bit) to transfer
> data.
> 
> Not completely true.  XSPI mode is enabled, also for words smaller than or
> equal to 16 bits.  But TX FIFO and CMD FIFO is written together, just as for
> non-XSPI mode.
> 
> > If ->bits_per_word is not set and the default bits_per_word =8 is
> > passed to the dspi driver, the XSPI mode (32bit) is not used for data
> > transfer in the dspi driver
> 
> Not true.  XSPI mode is unconditionally enabled in dspi_init().  But XSPI
> mode does not overrule the value of transfer->bits_per_word.
> The meaning of XSPI mode is the following:
> 
> 1. Frame (word) size is max 32 bits (with normal SPI mode, max is 16 bits).
> 2. For frames (words) with more than 16 bits per frame (word), each frame
> transfer results in 2 TX FIFO pop operations.
> 3. Command cycling is possible, enabled when SPI_CTARE[DTCP] > 1.
> 
> Command cycling is currently not implemented.  If implemented, it would be
> possible to send multiple frames (words) by writing one time to CMD FIFO and
> multiple times to TX FIFO.  This could possibly improve performance
> 
> Another possibility would be to use EOQ mode, if supported by the DSPI
> controller in the CPU.  It allows for filling TX FIFO, and getting IRQ only 
> after
> last TX FIFO entry is sent.  This is also a likely performance improvement.
> 
> >> > 2. As I understand, bits_per_word does not exist for non-byte
> >> > alignment, but for the need to reserve non-byte transmission mode
> >> > that meets the controller.
> >>
> >> Exactly. It's an optimization you have to take care of inside your
> >> driver. The core cannot help you with that.
> >>
> > The core layer is the upper layer. If you don't set ->bits_per_word,
> > bits_per_word will use the default value of 8, so that the
> > controller's specific mode for transferring data cannot be used (eg:
> > XSPI mode).
> 
> XSPI mode is independent of bits_per_word.  In XSPI mode, you can send
> frames as small as 4 bits, and up to 32 bits.  In normal SPI mode, you can
> send frames from 4 to 16 bits.
> 
> >> > 3. In addition, now the
> >> > XSPI of dspi cannot transfer data normally, so this problem needs
> >> > to be solved.
> >>
> >> I still don't understand what the problem is.
> >>
> > The problem is that I tested the XSPI mode and could not work, that
> > is, the data could not be transmitted normally.
> 
> What does "could not be transmitted normally" mean?
> 
> I am using XSPI mode on LS1021A, talking to a lot of different SPI devices.
> And they all work, and I believe everything is quite "normal".
> 
Since I don't have the board of LS1021, I can't test it. I use other boards 
with DSPI (such as LS1043, LS2088, etc.), 
and I test sp-flash connected on DSPI. If XSPI mode is used at this time, data 
cannot be transmitted normally.
> /Esben


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-10-09 Thread Chuanhua Han


> -Original Message-
> From: Esben Haabendal  On Behalf Of Esben
> Haabendal
> Sent: 2018年10月9日 19:21
> To: Chuanhua Han 
> Cc: Boris Brezillon ; broo...@kernel.org;
> linux-...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Chuanhua Han  writes:
> 
> >> -Original Message-
> >> From: Boris Brezillon 
> >> Sent: 2018年10月9日 18:05
> >> To: Chuanhua Han 
> >> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> >> linux-kernel@vger.kernel.org; e...@deif.com
> >> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw
> >> function
> >>
> >> On Tue, 9 Oct 2018 09:52:23 +
> >> Chuanhua Han  wrote:
> >>
> >> > 1. In the dspi driver (spi controller), bits_per_word
> >> > (dspi->bits_per_word = transfer->bits_per_word) passed from the
> >> > upper layer (spi-mem.c) is used. In this way, I can only assign the
> >> > appropriate value of transfer->bits_per_word before passing to the
> >> > controller, that is, the controller driver does not know the value
> >> > of bits_per_word, and it will use this value when the upper level
> >> > sets what value is passed.
> >>
> >> I think you're missing my point: ->bits_per_word is not what you're
> >> looking for if what you're trying to do is use 32-bits accesses when
> >> things are properly aligned.
> >>
> > In the dspi driver (spi controller driver), it is based on whether
> > ->bits_per_word is
> > larger than 16 to decide whether to use the XSPI mode (32bit) to transfer
> data.
> 
> Not completely true.  XSPI mode is enabled, also for words smaller than or
> equal to 16 bits.  But TX FIFO and CMD FIFO is written together, just as for
> non-XSPI mode.
> 
> > If ->bits_per_word is not set and the default bits_per_word =8 is
> > passed to the dspi driver, the XSPI mode (32bit) is not used for data
> > transfer in the dspi driver
> 
> Not true.  XSPI mode is unconditionally enabled in dspi_init().  But XSPI
> mode does not overrule the value of transfer->bits_per_word.
> The meaning of XSPI mode is the following:
> 
> 1. Frame (word) size is max 32 bits (with normal SPI mode, max is 16 bits).
> 2. For frames (words) with more than 16 bits per frame (word), each frame
> transfer results in 2 TX FIFO pop operations.
> 3. Command cycling is possible, enabled when SPI_CTARE[DTCP] > 1.
> 
> Command cycling is currently not implemented.  If implemented, it would be
> possible to send multiple frames (words) by writing one time to CMD FIFO and
> multiple times to TX FIFO.  This could possibly improve performance
> 
> Another possibility would be to use EOQ mode, if supported by the DSPI
> controller in the CPU.  It allows for filling TX FIFO, and getting IRQ only 
> after
> last TX FIFO entry is sent.  This is also a likely performance improvement.
> 
> >> > 2. As I understand, bits_per_word does not exist for non-byte
> >> > alignment, but for the need to reserve non-byte transmission mode
> >> > that meets the controller.
> >>
> >> Exactly. It's an optimization you have to take care of inside your
> >> driver. The core cannot help you with that.
> >>
> > The core layer is the upper layer. If you don't set ->bits_per_word,
> > bits_per_word will use the default value of 8, so that the
> > controller's specific mode for transferring data cannot be used (eg:
> > XSPI mode).
> 
> XSPI mode is independent of bits_per_word.  In XSPI mode, you can send
> frames as small as 4 bits, and up to 32 bits.  In normal SPI mode, you can
> send frames from 4 to 16 bits.
> 
> >> > 3. In addition, now the
> >> > XSPI of dspi cannot transfer data normally, so this problem needs
> >> > to be solved.
> >>
> >> I still don't understand what the problem is.
> >>
> > The problem is that I tested the XSPI mode and could not work, that
> > is, the data could not be transmitted normally.
> 
> What does "could not be transmitted normally" mean?
> 
> I am using XSPI mode on LS1021A, talking to a lot of different SPI devices.
> And they all work, and I believe everything is quite "normal".
> 
Since I don't have the board of LS1021, I can't test it. I use other boards 
with DSPI (such as LS1043, LS2088, etc.), 
and I test sp-flash connected on DSPI. If XSPI mode is used at this time, data 
cannot be transmitted normally.
> /Esben


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-10-09 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年10月9日 18:05
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Tue, 9 Oct 2018 09:52:23 +
> Chuanhua Han  wrote:
> 
> > 1. In the dspi driver (spi controller), bits_per_word
> > (dspi->bits_per_word = transfer->bits_per_word) passed from the upper
> > layer (spi-mem.c) is used. In this way, I can only assign the
> > appropriate value of transfer->bits_per_word before passing to the
> > controller, that is, the controller driver does not know the value of
> > bits_per_word, and it will use this value when the upper level sets
> > what value is passed.
> 
> I think you're missing my point: ->bits_per_word is not what you're looking 
> for
> if what you're trying to do is use 32-bits accesses when things are properly
> aligned.
> 
In the dspi driver (spi controller driver), it is based on whether 
->bits_per_word is 
larger than 16 to decide whether to use the XSPI mode (32bit) to transfer data.
If ->bits_per_word is not set and the default bits_per_word =8 is passed to the 
dspi driver, the XSPI mode (32bit) is not used for data transfer in the dspi 
driver
> > 2. As I understand, bits_per_word does not exist for non-byte
> > alignment, but for the need to reserve non-byte transmission mode that
> > meets the controller.
> 
> Exactly. It's an optimization you have to take care of inside your driver. 
> The core
> cannot help you with that.
> 
The core layer is the upper layer. If you don't set ->bits_per_word, 
bits_per_word
 will use the default value of 8, so that the controller's specific mode for 
transferring
 data cannot be used (eg: XSPI mode).
> > 3. In addition, now the
> > XSPI of dspi cannot transfer data normally, so this problem needs to
> > be solved.
> 
> I still don't understand what the problem is.
> 
The problem is that I tested the XSPI mode and could not work, that is, the 
data could
not be transmitted normally. I used spi flash connected on dspi to conduct the 
test. 
In any case, the controller is independent of connected slave devices, and the 
data should
be transmitted by spi-flash devices and other spi devices.

> > As for the DMA transfer mode, some colleagues will study it.



RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-10-09 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年10月9日 18:05
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Tue, 9 Oct 2018 09:52:23 +
> Chuanhua Han  wrote:
> 
> > 1. In the dspi driver (spi controller), bits_per_word
> > (dspi->bits_per_word = transfer->bits_per_word) passed from the upper
> > layer (spi-mem.c) is used. In this way, I can only assign the
> > appropriate value of transfer->bits_per_word before passing to the
> > controller, that is, the controller driver does not know the value of
> > bits_per_word, and it will use this value when the upper level sets
> > what value is passed.
> 
> I think you're missing my point: ->bits_per_word is not what you're looking 
> for
> if what you're trying to do is use 32-bits accesses when things are properly
> aligned.
> 
In the dspi driver (spi controller driver), it is based on whether 
->bits_per_word is 
larger than 16 to decide whether to use the XSPI mode (32bit) to transfer data.
If ->bits_per_word is not set and the default bits_per_word =8 is passed to the 
dspi driver, the XSPI mode (32bit) is not used for data transfer in the dspi 
driver
> > 2. As I understand, bits_per_word does not exist for non-byte
> > alignment, but for the need to reserve non-byte transmission mode that
> > meets the controller.
> 
> Exactly. It's an optimization you have to take care of inside your driver. 
> The core
> cannot help you with that.
> 
The core layer is the upper layer. If you don't set ->bits_per_word, 
bits_per_word
 will use the default value of 8, so that the controller's specific mode for 
transferring
 data cannot be used (eg: XSPI mode).
> > 3. In addition, now the
> > XSPI of dspi cannot transfer data normally, so this problem needs to
> > be solved.
> 
> I still don't understand what the problem is.
> 
The problem is that I tested the XSPI mode and could not work, that is, the 
data could
not be transmitted normally. I used spi flash connected on dspi to conduct the 
test. 
In any case, the controller is independent of connected slave devices, and the 
data should
be transmitted by spi-flash devices and other spi devices.

> > As for the DMA transfer mode, some colleagues will study it.



RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-10-09 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月28日 15:19
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Fri, 28 Sep 2018 06:59:58 +
> Chuanhua Han  wrote:
> 
> > >
> > > It's still unclear why you need to specify a bits_per_word value,
> > > but if this is needed, it's probably something you want to add to
> > > spi.c, when a message is queued.
> > To specify a specific bits_per_word to be able to use the xspi
> > (32bit) mode of the fsl_dspi module to transfer data, you can look at
> > my PATCH 2/2. Do not add a value in spis.c that takes into account
> > that the value assigned to bits_per_word is decided before the
> > transfer. Thanks for your check and reply!
> 
> I might be wrong, but that's not my understanding of ->bits_per_word.
> To me, it's something that you can use when your *device* (not
> controller) expects non-byte aligned words [1]. The spi-mem protocol is
> definitely designed to work with 1byte large words, so, as I said, I suspect
> you're abusing xfer->bits_per_word to address a controller driver issue.
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Flatest%2Fsource%2Finclude%2Flinux%2Fspi%2Fspi
> .h%23L114data=02%7C01%7Cchuanhua.han%40nxp.com%7C7ec61d6d
> 7ef741aba84408d62512a9e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0
> %7C0%7C636737159420820050sdata=iwFgXG3yFvH7Ruac7MGCoaP8h
> l2M916m9%2BZeV7nksTg%3Dreserved=0
1. In the dspi driver (spi controller), bits_per_word (dspi->bits_per_word = 
transfer->bits_per_word) passed from the upper layer (spi-mem.c) is used. 
In this way, I can only assign the appropriate value of transfer->bits_per_word 
before passing to the controller, that is, the controller driver does not
know the value of bits_per_word, and it will use this value when the upper 
level sets what value is passed.
2. As I understand, bits_per_word does not exist for non-byte alignment, but 
for the need to reserve non-byte transmission mode that meets the controller.
3. In addition, now the XSPI of dspi cannot transfer data normally, so this 
problem needs to be solved. As for the DMA transfer mode, some colleagues will 
study it.


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-10-09 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月28日 15:19
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Fri, 28 Sep 2018 06:59:58 +
> Chuanhua Han  wrote:
> 
> > >
> > > It's still unclear why you need to specify a bits_per_word value,
> > > but if this is needed, it's probably something you want to add to
> > > spi.c, when a message is queued.
> > To specify a specific bits_per_word to be able to use the xspi
> > (32bit) mode of the fsl_dspi module to transfer data, you can look at
> > my PATCH 2/2. Do not add a value in spis.c that takes into account
> > that the value assigned to bits_per_word is decided before the
> > transfer. Thanks for your check and reply!
> 
> I might be wrong, but that's not my understanding of ->bits_per_word.
> To me, it's something that you can use when your *device* (not
> controller) expects non-byte aligned words [1]. The spi-mem protocol is
> definitely designed to work with 1byte large words, so, as I said, I suspect
> you're abusing xfer->bits_per_word to address a controller driver issue.
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Flatest%2Fsource%2Finclude%2Flinux%2Fspi%2Fspi
> .h%23L114data=02%7C01%7Cchuanhua.han%40nxp.com%7C7ec61d6d
> 7ef741aba84408d62512a9e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0
> %7C0%7C636737159420820050sdata=iwFgXG3yFvH7Ruac7MGCoaP8h
> l2M916m9%2BZeV7nksTg%3Dreserved=0
1. In the dspi driver (spi controller), bits_per_word (dspi->bits_per_word = 
transfer->bits_per_word) passed from the upper layer (spi-mem.c) is used. 
In this way, I can only assign the appropriate value of transfer->bits_per_word 
before passing to the controller, that is, the controller driver does not
know the value of bits_per_word, and it will use this value when the upper 
level sets what value is passed.
2. As I understand, bits_per_word does not exist for non-byte alignment, but 
for the need to reserve non-byte transmission mode that meets the controller.
3. In addition, now the XSPI of dspi cannot transfer data normally, so this 
problem needs to be solved. As for the DMA transfer mode, some colleagues will 
study it.


RE: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:40
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Sun, 30 Sep 2018 10:18:18 +
> Chuanhua Han  wrote:
> 
> > > -Original Message-
> > > From: Boris Brezillon 
> > > Sent: 2018年9月30日 18:04
> > > To: Chuanhua Han 
> > > Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; e...@deif.com
> > > Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw
> > > function
> > >
> > > Hi Chuanhua,
> > >
> > > On Sun, 30 Sep 2018 17:25:32 +0800
> > > Chuanhua Han  wrote:
> > >
> > > > Before we add this spi_transfer to the spi_message chain table, we
> > > > need bits_per_word_mask based on spi_control to set the
> > > > bits_per_word of this spi_transfer.
> > >
> > > Let's make it clearer: this is wrong. The spi-mem protocol is just
> > > using bytes, not custom size words. Fix the fsl-dspi driver if
> > > needed, but don't try to adjust
> > > xfer->bits_per_word in spi-mem.c, because this is inappropriate.
> > The value of bits_per_word is only known before the
> > spi_message_add_tail function is called,
> 
> No, it's not. It's known from the beginning, and spi_setup() defaults to 8 
> when
> spidev->bits_per_word is 0, which is exactly what we want. Then, when you
> send a message through, spi_sync(), spi_validate() makes sure that each
> transfer in the message has a
> xfer->bits_per_word != 0 and when that's not the case, it sets it to
> spi->bits_per_word [2].
> 
> Really, there's nothing to fix in spi-mem.c, because it's already doing the 
> right
> thing (leaving ->bits_per_word to 0 so that it's set to
> spi->bits_per_word, which should be 8). Maybe we have a bug somewhere
> else though.
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Fv4.19-rc5%2Fsource%2Fdrivers%2Fspi%2Fspi.c%23
> L2803data=02%7C01%7Cchuanhua.han%40nxp.com%7C48694d5d7cd
> a460b3e0b08d626c11e3f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C636739008212287814sdata=5wYyFaZjk9kkbZtR0w0uS2YFlfNjC
> Gz3SN80Ws599j0%3Dreserved=0
> [2]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Fv4.19-rc5%2Fsource%2Fdrivers%2Fspi%2Fspi.c%23
> L2869data=02%7C01%7Cchuanhua.han%40nxp.com%7C48694d5d7cd
> a460b3e0b08d626c11e3f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C636739008212287814sdata=ibwl%2BZuk%2FMLagsudNetwgda
> hR1VVKBqI2ByL6225H50%3Dreserved=0
I'll take the time to study this.
October 1 to October 7 is the National Day of our country. I need to take a 
vacation.
I may not reply to the email in time during this period. 
Thank you very much for your valuable advice!!!


RE: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:40
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Sun, 30 Sep 2018 10:18:18 +
> Chuanhua Han  wrote:
> 
> > > -Original Message-
> > > From: Boris Brezillon 
> > > Sent: 2018年9月30日 18:04
> > > To: Chuanhua Han 
> > > Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; e...@deif.com
> > > Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw
> > > function
> > >
> > > Hi Chuanhua,
> > >
> > > On Sun, 30 Sep 2018 17:25:32 +0800
> > > Chuanhua Han  wrote:
> > >
> > > > Before we add this spi_transfer to the spi_message chain table, we
> > > > need bits_per_word_mask based on spi_control to set the
> > > > bits_per_word of this spi_transfer.
> > >
> > > Let's make it clearer: this is wrong. The spi-mem protocol is just
> > > using bytes, not custom size words. Fix the fsl-dspi driver if
> > > needed, but don't try to adjust
> > > xfer->bits_per_word in spi-mem.c, because this is inappropriate.
> > The value of bits_per_word is only known before the
> > spi_message_add_tail function is called,
> 
> No, it's not. It's known from the beginning, and spi_setup() defaults to 8 
> when
> spidev->bits_per_word is 0, which is exactly what we want. Then, when you
> send a message through, spi_sync(), spi_validate() makes sure that each
> transfer in the message has a
> xfer->bits_per_word != 0 and when that's not the case, it sets it to
> spi->bits_per_word [2].
> 
> Really, there's nothing to fix in spi-mem.c, because it's already doing the 
> right
> thing (leaving ->bits_per_word to 0 so that it's set to
> spi->bits_per_word, which should be 8). Maybe we have a bug somewhere
> else though.
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Fv4.19-rc5%2Fsource%2Fdrivers%2Fspi%2Fspi.c%23
> L2803data=02%7C01%7Cchuanhua.han%40nxp.com%7C48694d5d7cd
> a460b3e0b08d626c11e3f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C636739008212287814sdata=5wYyFaZjk9kkbZtR0w0uS2YFlfNjC
> Gz3SN80Ws599j0%3Dreserved=0
> [2]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Fv4.19-rc5%2Fsource%2Fdrivers%2Fspi%2Fspi.c%23
> L2869data=02%7C01%7Cchuanhua.han%40nxp.com%7C48694d5d7cd
> a460b3e0b08d626c11e3f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C636739008212287814sdata=ibwl%2BZuk%2FMLagsudNetwgda
> hR1VVKBqI2ByL6225H50%3Dreserved=0
I'll take the time to study this.
October 1 to October 7 is the National Day of our country. I need to take a 
vacation.
I may not reply to the email in time during this period. 
Thank you very much for your valuable advice!!!


RE: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Esben Haabendal  On Behalf Of Esben
> Haabendal
> Sent: 2018年9月30日 18:18
> To: Boris Brezillon 
> Cc: Chuanhua Han ; broo...@kernel.org;
> linux-...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Boris Brezillon  writes:
> 
> > Hi Chuanhua,
> >
> > On Sun, 30 Sep 2018 17:25:32 +0800
> > Chuanhua Han  wrote:
> >
> >> Before we add this spi_transfer to the spi_message chain table, we
> >> need bits_per_word_mask based on spi_control to set the bits_per_word
> >> of this spi_transfer.
> >
> > Let's make it clearer: this is wrong. The spi-mem protocol is just
> > using bytes, not custom size words. Fix the fsl-dspi driver if needed,
> > but don't try to adjust xfer->bits_per_word in spi-mem.c, because this
> > is inappropriate.
> 
> I don't think there is a "fix" needed in fsl-dspi driver for this.
> 
> I am not sure, but I think that what Han is trying to achieve here is better
> performance.
> And wile the XSPI mode does provide better performance for sending one
> 32 bit word, than normal mode providees for sending 4 x 8 bit words.
> But as you say, this is wrong.
> 
> To improve performance, the fsl-dspi driver should be fixed to work in DMA
> mode.  Implementation of erratum A-011218 is necessary in order to use
> DSPI DMA mode on LS1021A.
> I was planning to work on that, but haven't had the time for it.
> So if you want better performance for spi-mem on LS1021A DSPI, please work
> on this.
> 
> /Esben
Hi,
Another colleague is responsible for the DMA transmission of dspi.
I am not clear about it. I just fix the transmission of XSPI mode with several 
patches. 
Thank you for your comments.


RE: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Esben Haabendal  On Behalf Of Esben
> Haabendal
> Sent: 2018年9月30日 18:18
> To: Boris Brezillon 
> Cc: Chuanhua Han ; broo...@kernel.org;
> linux-...@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Boris Brezillon  writes:
> 
> > Hi Chuanhua,
> >
> > On Sun, 30 Sep 2018 17:25:32 +0800
> > Chuanhua Han  wrote:
> >
> >> Before we add this spi_transfer to the spi_message chain table, we
> >> need bits_per_word_mask based on spi_control to set the bits_per_word
> >> of this spi_transfer.
> >
> > Let's make it clearer: this is wrong. The spi-mem protocol is just
> > using bytes, not custom size words. Fix the fsl-dspi driver if needed,
> > but don't try to adjust xfer->bits_per_word in spi-mem.c, because this
> > is inappropriate.
> 
> I don't think there is a "fix" needed in fsl-dspi driver for this.
> 
> I am not sure, but I think that what Han is trying to achieve here is better
> performance.
> And wile the XSPI mode does provide better performance for sending one
> 32 bit word, than normal mode providees for sending 4 x 8 bit words.
> But as you say, this is wrong.
> 
> To improve performance, the fsl-dspi driver should be fixed to work in DMA
> mode.  Implementation of erratum A-011218 is necessary in order to use
> DSPI DMA mode on LS1021A.
> I was planning to work on that, but haven't had the time for it.
> So if you want better performance for spi-mem on LS1021A DSPI, please work
> on this.
> 
> /Esben
Hi,
Another colleague is responsible for the DMA transmission of dspi.
I am not clear about it. I just fix the transmission of XSPI mode with several 
patches. 
Thank you for your comments.


RE: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of undefined bitmask for rxdata

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:17
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of
> undefined bitmask for rxdata
> 
> On Sun, 30 Sep 2018 10:10:14 +
> Chuanhua Han  wrote:
> 
> > > -Original Message-
> > > From: Boris Brezillon 
> > > Sent: 2018年9月30日 18:07
> > > To: Chuanhua Han 
> > > Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; e...@deif.com
> > > Subject: Re: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the
> > > processing of undefined bitmask for rxdata
> > >
> > > On Sun, 30 Sep 2018 17:25:33 +0800
> > > Chuanhua Han  wrote:
> > >
> > > > This patch fixes the problem of rxdata being equal to 0 during the
> > > > XSPI mode transfer of the dspi controller.
> > > > In XSPI mode, If it is not deleted, the value of rxdata will be
> > > > equal to 0, and the data received will not be received correctly,
> > > > causing the receiving transfer of the spi to fail.
> > > >
> > > > Signed-off-by: Chuanhua Han 
> > > > ---
> > > > Changes in v2:
> > > >  -The original patch is divided into multiple patches(the original
> > > > patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
> > > > mode"),one of which is segmented.
> > > >
> > > >  drivers/spi/spi-fsl-dspi.c | 3 ---
> > > >  1 file changed, 3 deletions(-)
> > > >
> > > > diff --git a/drivers/spi/spi-fsl-dspi.c
> > > > b/drivers/spi/spi-fsl-dspi.c index 3082e72e4f6c..4dc1064bf408
> > > > 100644
> > > > --- a/drivers/spi/spi-fsl-dspi.c
> > > > +++ b/drivers/spi/spi-fsl-dspi.c
> > > > @@ -243,9 +243,6 @@ static void dspi_push_rx(struct fsl_dspi
> > > > *dspi, u32
> > > rxdata)
> > > > if (!dspi->rx)
> > > > return;
> > > >
> > > > -   /* Mask of undefined bits */
> > > > -   rxdata &= (1 << dspi->bits_per_word) - 1;
> > > > -
> > >
> > > Why not
> > In xspi mode, the value of rxdata after the statement is processed is equal 
> > to
> 0 no matter what data is received.
> 
> Only if dspi->bits_per_word is 0.
> 
> Actually, I just had a look, and xfer->bits_per_word should never be 0 because
> spi_validate() makes sure it's initialized [1]. Don't know where
> dpsi->bits_per_word comes from, but maybe you have a problem there
> (dpsi->bits_per_word and xfer->bits_per_word not in sync).
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Fv4.19-rc5%2Fsource%2Fdrivers%2Fspi%2Fspi.c%23
> L2869data=02%7C01%7Cchuanhua.han%40nxp.com%7Cd92a3b54ccf0
> 4d1c1f3208d626bde775%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C
> 0%7C636738994411369491sdata=piLwfBc0kzMhOnI5uubHYJ9tbe%2BR
> KENKbYiLrkY1c30%3Dreserved=0
OK, Let me analyze it again,Thanks!


RE: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of undefined bitmask for rxdata

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:17
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of
> undefined bitmask for rxdata
> 
> On Sun, 30 Sep 2018 10:10:14 +
> Chuanhua Han  wrote:
> 
> > > -Original Message-
> > > From: Boris Brezillon 
> > > Sent: 2018年9月30日 18:07
> > > To: Chuanhua Han 
> > > Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; e...@deif.com
> > > Subject: Re: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the
> > > processing of undefined bitmask for rxdata
> > >
> > > On Sun, 30 Sep 2018 17:25:33 +0800
> > > Chuanhua Han  wrote:
> > >
> > > > This patch fixes the problem of rxdata being equal to 0 during the
> > > > XSPI mode transfer of the dspi controller.
> > > > In XSPI mode, If it is not deleted, the value of rxdata will be
> > > > equal to 0, and the data received will not be received correctly,
> > > > causing the receiving transfer of the spi to fail.
> > > >
> > > > Signed-off-by: Chuanhua Han 
> > > > ---
> > > > Changes in v2:
> > > >  -The original patch is divided into multiple patches(the original
> > > > patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
> > > > mode"),one of which is segmented.
> > > >
> > > >  drivers/spi/spi-fsl-dspi.c | 3 ---
> > > >  1 file changed, 3 deletions(-)
> > > >
> > > > diff --git a/drivers/spi/spi-fsl-dspi.c
> > > > b/drivers/spi/spi-fsl-dspi.c index 3082e72e4f6c..4dc1064bf408
> > > > 100644
> > > > --- a/drivers/spi/spi-fsl-dspi.c
> > > > +++ b/drivers/spi/spi-fsl-dspi.c
> > > > @@ -243,9 +243,6 @@ static void dspi_push_rx(struct fsl_dspi
> > > > *dspi, u32
> > > rxdata)
> > > > if (!dspi->rx)
> > > > return;
> > > >
> > > > -   /* Mask of undefined bits */
> > > > -   rxdata &= (1 << dspi->bits_per_word) - 1;
> > > > -
> > >
> > > Why not
> > In xspi mode, the value of rxdata after the statement is processed is equal 
> > to
> 0 no matter what data is received.
> 
> Only if dspi->bits_per_word is 0.
> 
> Actually, I just had a look, and xfer->bits_per_word should never be 0 because
> spi_validate() makes sure it's initialized [1]. Don't know where
> dpsi->bits_per_word comes from, but maybe you have a problem there
> (dpsi->bits_per_word and xfer->bits_per_word not in sync).
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Fv4.19-rc5%2Fsource%2Fdrivers%2Fspi%2Fspi.c%23
> L2869data=02%7C01%7Cchuanhua.han%40nxp.com%7Cd92a3b54ccf0
> 4d1c1f3208d626bde775%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C
> 0%7C636738994411369491sdata=piLwfBc0kzMhOnI5uubHYJ9tbe%2BR
> KENKbYiLrkY1c30%3Dreserved=0
OK, Let me analyze it again,Thanks!


RE: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:04
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Hi Chuanhua,
> 
> On Sun, 30 Sep 2018 17:25:32 +0800
> Chuanhua Han  wrote:
> 
> > Before we add this spi_transfer to the spi_message chain table, we
> > need bits_per_word_mask based on spi_control to set the bits_per_word
> > of this spi_transfer.
> 
> Let's make it clearer: this is wrong. The spi-mem protocol is just using 
> bytes,
> not custom size words. Fix the fsl-dspi driver if needed, but don't try to 
> adjust
> xfer->bits_per_word in spi-mem.c, because this is inappropriate.
The value of bits_per_word is only known before the spi_message_add_tail 
function is called, 
and dspi controllers only decide which mode (8bit, 16bit, or 32bit) to use for 
data
transfer based on the value of the transfer->bits_per_word.

> 
> Regards,
> 
> Boris
> 
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> > Changes in v2:
> >  -The original patch is divided into multiple patches(the original
> > patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
> > mode"),one of which is segmented.
> >
> >  drivers/spi/spi-mem.c | 39
> +++
> >  1 file changed, 39 insertions(+)
> >
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > eb72dba71d83..717e711c0952 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem
> *mem,
> > const struct spi_mem_op *op)  }
> > EXPORT_SYMBOL_GPL(spi_mem_supports_op);
> >
> > +/**
> > + * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
> > + * the bits_per_word_mask of the spi controller
> > + * @ctrl: the spi controller
> > + * @xfer: the spi transfer
> > + *
> > + * This function sets the bits_per_word for each transfer based on
> > +the spi
> > + * controller's bits_per_word_mask to improve the efficiency of spi
> transport.
> > + *
> > + * Return: 0 in case of success, a negative error code otherwise.
> > + */
> > +int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer
> > +*xfer) {
> > +   if (!ctlr || !xfer) {
> > +   dev_err(>dev,
> > +   "Fail to set bits_per_word for spi transfer\n");
> > +   return -EINVAL;
> > +   }
> > +
> > +   if (ctlr->bits_per_word_mask) {
> > +   if (!(xfer->len % 4)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
> > +   xfer->bits_per_word = 32;
> > +   } else if (!(xfer->len % 2)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
> > +   xfer->bits_per_word = 16;
> > +   } else {
> > +   xfer->bits_per_word = 8;
> > +   }
> > +   }
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
> > +
> >  /**
> >   * spi_mem_exec_op() - Execute a memory operation
> >   * @mem: the SPI memory
> > @@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf;
> > xfers[xferpos].len = sizeof(op->cmd.opcode);
> > xfers[xferpos].tx_nbits = op->cmd.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen++;
> > @@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + 1;
> > xfers[xferpos].len = op->addr.nbytes;
> > xfers[xferpos].tx_nbits = op->addr.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->addr.nbytes;
> > @@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> > xfers[xferpos].len = op->dummy.nbytes;
> > xfers[xferpos].tx_nbits = op->dummy.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->dummy.nbytes;
> > @@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > }
> >
> > xfers[xferpos].len = op->data.nbytes;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->data.nbytes;



RE: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:04
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Hi Chuanhua,
> 
> On Sun, 30 Sep 2018 17:25:32 +0800
> Chuanhua Han  wrote:
> 
> > Before we add this spi_transfer to the spi_message chain table, we
> > need bits_per_word_mask based on spi_control to set the bits_per_word
> > of this spi_transfer.
> 
> Let's make it clearer: this is wrong. The spi-mem protocol is just using 
> bytes,
> not custom size words. Fix the fsl-dspi driver if needed, but don't try to 
> adjust
> xfer->bits_per_word in spi-mem.c, because this is inappropriate.
The value of bits_per_word is only known before the spi_message_add_tail 
function is called, 
and dspi controllers only decide which mode (8bit, 16bit, or 32bit) to use for 
data
transfer based on the value of the transfer->bits_per_word.

> 
> Regards,
> 
> Boris
> 
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> > Changes in v2:
> >  -The original patch is divided into multiple patches(the original
> > patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
> > mode"),one of which is segmented.
> >
> >  drivers/spi/spi-mem.c | 39
> +++
> >  1 file changed, 39 insertions(+)
> >
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > eb72dba71d83..717e711c0952 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem
> *mem,
> > const struct spi_mem_op *op)  }
> > EXPORT_SYMBOL_GPL(spi_mem_supports_op);
> >
> > +/**
> > + * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
> > + * the bits_per_word_mask of the spi controller
> > + * @ctrl: the spi controller
> > + * @xfer: the spi transfer
> > + *
> > + * This function sets the bits_per_word for each transfer based on
> > +the spi
> > + * controller's bits_per_word_mask to improve the efficiency of spi
> transport.
> > + *
> > + * Return: 0 in case of success, a negative error code otherwise.
> > + */
> > +int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer
> > +*xfer) {
> > +   if (!ctlr || !xfer) {
> > +   dev_err(>dev,
> > +   "Fail to set bits_per_word for spi transfer\n");
> > +   return -EINVAL;
> > +   }
> > +
> > +   if (ctlr->bits_per_word_mask) {
> > +   if (!(xfer->len % 4)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
> > +   xfer->bits_per_word = 32;
> > +   } else if (!(xfer->len % 2)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
> > +   xfer->bits_per_word = 16;
> > +   } else {
> > +   xfer->bits_per_word = 8;
> > +   }
> > +   }
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
> > +
> >  /**
> >   * spi_mem_exec_op() - Execute a memory operation
> >   * @mem: the SPI memory
> > @@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf;
> > xfers[xferpos].len = sizeof(op->cmd.opcode);
> > xfers[xferpos].tx_nbits = op->cmd.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen++;
> > @@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + 1;
> > xfers[xferpos].len = op->addr.nbytes;
> > xfers[xferpos].tx_nbits = op->addr.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->addr.nbytes;
> > @@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
> > xfers[xferpos].len = op->dummy.nbytes;
> > xfers[xferpos].tx_nbits = op->dummy.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->dummy.nbytes;
> > @@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > }
> >
> > xfers[xferpos].len = op->data.nbytes;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->data.nbytes;



RE: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of undefined bitmask for rxdata

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:07
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of
> undefined bitmask for rxdata
> 
> On Sun, 30 Sep 2018 17:25:33 +0800
> Chuanhua Han  wrote:
> 
> > This patch fixes the problem of rxdata being equal to 0 during the
> > XSPI mode transfer of the dspi controller.
> > In XSPI mode, If it is not deleted, the value of rxdata will be equal
> > to 0, and the data received will not be received correctly, causing
> > the receiving transfer of the spi to fail.
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> > Changes in v2:
> >  -The original patch is divided into multiple patches(the original
> > patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
> > mode"),one of which is segmented.
> >
> >  drivers/spi/spi-fsl-dspi.c | 3 ---
> >  1 file changed, 3 deletions(-)
> >
> > diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
> > index 3082e72e4f6c..4dc1064bf408 100644
> > --- a/drivers/spi/spi-fsl-dspi.c
> > +++ b/drivers/spi/spi-fsl-dspi.c
> > @@ -243,9 +243,6 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32
> rxdata)
> > if (!dspi->rx)
> > return;
> >
> > -   /* Mask of undefined bits */
> > -   rxdata &= (1 << dspi->bits_per_word) - 1;
> > -
> 
> Why not
In xspi mode, the value of rxdata after the statement is processed is equal to 
0 no matter what data is received.
> 
>   if (dspi->bits_per_word)
>   rxdata &= (1 << dspi->bits_per_word) - 1;
> 
> > if (dspi->bytes_per_word == 1)
> > *(u8 *)dspi->rx = rxdata;
> > else if (dspi->bytes_per_word == 2)



RE: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of undefined bitmask for rxdata

2018-09-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月30日 18:07
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of
> undefined bitmask for rxdata
> 
> On Sun, 30 Sep 2018 17:25:33 +0800
> Chuanhua Han  wrote:
> 
> > This patch fixes the problem of rxdata being equal to 0 during the
> > XSPI mode transfer of the dspi controller.
> > In XSPI mode, If it is not deleted, the value of rxdata will be equal
> > to 0, and the data received will not be received correctly, causing
> > the receiving transfer of the spi to fail.
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> > Changes in v2:
> >  -The original patch is divided into multiple patches(the original
> > patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
> > mode"),one of which is segmented.
> >
> >  drivers/spi/spi-fsl-dspi.c | 3 ---
> >  1 file changed, 3 deletions(-)
> >
> > diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
> > index 3082e72e4f6c..4dc1064bf408 100644
> > --- a/drivers/spi/spi-fsl-dspi.c
> > +++ b/drivers/spi/spi-fsl-dspi.c
> > @@ -243,9 +243,6 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32
> rxdata)
> > if (!dspi->rx)
> > return;
> >
> > -   /* Mask of undefined bits */
> > -   rxdata &= (1 << dspi->bits_per_word) - 1;
> > -
> 
> Why not
In xspi mode, the value of rxdata after the statement is processed is equal to 
0 no matter what data is received.
> 
>   if (dspi->bits_per_word)
>   rxdata &= (1 << dspi->bits_per_word) - 1;
> 
> > if (dspi->bytes_per_word == 1)
> > *(u8 *)dspi->rx = rxdata;
> > else if (dspi->bytes_per_word == 2)



[PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han
Before we add this spi_transfer to the spi_message chain table, we need
bits_per_word_mask based on spi_control to set the bits_per_word of
this spi_transfer.

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-mem.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index eb72dba71d83..717e711c0952 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_supports_op);
 
+/**
+ * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
+ * the bits_per_word_mask of the spi controller
+ * @ctrl: the spi controller
+ * @xfer: the spi transfer
+ *
+ * This function sets the bits_per_word for each transfer based on the spi
+ * controller's bits_per_word_mask to improve the efficiency of spi transport.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer *xfer)
+{
+   if (!ctlr || !xfer) {
+   dev_err(>dev,
+   "Fail to set bits_per_word for spi transfer\n");
+   return -EINVAL;
+   }
+
+   if (ctlr->bits_per_word_mask) {
+   if (!(xfer->len % 4)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
+   xfer->bits_per_word = 32;
+   } else if (!(xfer->len % 2)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
+   xfer->bits_per_word = 16;
+   } else {
+   xfer->bits_per_word = 8;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
+
 /**
  * spi_mem_exec_op() - Execute a memory operation
  * @mem: the SPI memory
@@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf;
xfers[xferpos].len = sizeof(op->cmd.opcode);
xfers[xferpos].tx_nbits = op->cmd.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen++;
@@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + 1;
xfers[xferpos].len = op->addr.nbytes;
xfers[xferpos].tx_nbits = op->addr.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->addr.nbytes;
@@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
@@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
 
xfers[xferpos].len = op->data.nbytes;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->data.nbytes;
-- 
2.17.1



[PATCH v2 3/4] spi: spi-fsl-dspi: Fix cmd_fifo is written before tx_fifo

2018-09-30 Thread Chuanhua Han
This patch fixes the problem of invalid data writing during the XSPI
mode transfer of the dspi controller.
In XSPI mode,When I executed TX FIFO first and then CMD FIFO for XSPI
transmission, I found that SPIx_SR[TFIWF]=1(Invalid Data present in TX
FIFO since CMD FIFO is empty).
This is the time when no data can be read or written (all the data
obtained is equal to 0).

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-fsl-dspi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 4dc1064bf408..96e790e90997 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -590,6 +590,7 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
 */
u32 data = dspi_pop_tx(dspi);
 
+   cmd_fifo_write(dspi);
if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
/* LSB */
tx_fifo_write(dspi, data & 0x);
@@ -599,7 +600,6 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
tx_fifo_write(dspi, data >> 16);
tx_fifo_write(dspi, data & 0x);
}
-   cmd_fifo_write(dspi);
} else {
/* Write one entry to both TX FIFO and CMD FIFO
 * simultaneously.
-- 
2.17.1



[PATCH v2 4/4] spi: spi-fsl-dspi: Fix adjust the byte order when sending and receiving data

2018-09-30 Thread Chuanhua Han
This patch fixes the byte order inversion problem in the XSPI mode of
the dspi controller during data transfer.
In XSPI mode,When I read and write data without converting the byte
order of the data, and read and write the data directly, I tested spi
flash connected by the dspi controller and found that the byte
order of the data was reversed by the correct byte order.
When I changed the byte order according to the SPIx_CTARn[LSBFE] flag,
the correct data was obtained.

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-fsl-dspi.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 96e790e90997..44cc2bd0120e 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -220,9 +220,15 @@ static u32 dspi_pop_tx(struct fsl_dspi *dspi)
if (dspi->bytes_per_word == 1)
txdata = *(u8 *)dspi->tx;
else if (dspi->bytes_per_word == 2)
-   txdata = *(u16 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata =  cpu_to_le16(*(u16 *)dspi->tx);
+   else
+   txdata =  cpu_to_be16(*(u16 *)dspi->tx);
else  /* dspi->bytes_per_word == 4 */
-   txdata = *(u32 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata = cpu_to_le32(*(u32 *)dspi->tx);
+   else
+   txdata = cpu_to_be32(*(u32 *)dspi->tx);
dspi->tx += dspi->bytes_per_word;
}
dspi->len -= dspi->bytes_per_word;
@@ -246,9 +252,15 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
if (dspi->bytes_per_word == 1)
*(u8 *)dspi->rx = rxdata;
else if (dspi->bytes_per_word == 2)
-   *(u16 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
+   else
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
else /* dspi->bytes_per_word == 4 */
-   *(u32 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u32 *)dspi->rx = le32_to_cpu(rxdata);
+   else
+   *(u32 *)dspi->rx = be32_to_cpu(rxdata);
dspi->rx += dspi->bytes_per_word;
 }
 
@@ -593,12 +605,12 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
cmd_fifo_write(dspi);
if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
/* LSB */
-   tx_fifo_write(dspi, data & 0x);
tx_fifo_write(dspi, data >> 16);
+   tx_fifo_write(dspi, data & 0x);
} else {
/* MSB */
-   tx_fifo_write(dspi, data >> 16);
tx_fifo_write(dspi, data & 0x);
+   tx_fifo_write(dspi, data >> 16);
}
} else {
/* Write one entry to both TX FIFO and CMD FIFO
-- 
2.17.1



[PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of undefined bitmask for rxdata

2018-09-30 Thread Chuanhua Han
This patch fixes the problem of rxdata being equal to 0 during the XSPI
mode transfer of the dspi controller.
In XSPI mode, If it is not deleted, the value of rxdata will be equal
to 0, and the data received will not be received correctly, causing the
receiving transfer of the spi to fail.

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-fsl-dspi.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..4dc1064bf408 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -243,9 +243,6 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
if (!dspi->rx)
return;
 
-   /* Mask of undefined bits */
-   rxdata &= (1 << dspi->bits_per_word) - 1;
-
if (dspi->bytes_per_word == 1)
*(u8 *)dspi->rx = rxdata;
else if (dspi->bytes_per_word == 2)
-- 
2.17.1



[PATCH v2 3/4] spi: spi-fsl-dspi: Fix cmd_fifo is written before tx_fifo

2018-09-30 Thread Chuanhua Han
This patch fixes the problem of invalid data writing during the XSPI
mode transfer of the dspi controller.
In XSPI mode,When I executed TX FIFO first and then CMD FIFO for XSPI
transmission, I found that SPIx_SR[TFIWF]=1(Invalid Data present in TX
FIFO since CMD FIFO is empty).
This is the time when no data can be read or written (all the data
obtained is equal to 0).

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-fsl-dspi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 4dc1064bf408..96e790e90997 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -590,6 +590,7 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
 */
u32 data = dspi_pop_tx(dspi);
 
+   cmd_fifo_write(dspi);
if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
/* LSB */
tx_fifo_write(dspi, data & 0x);
@@ -599,7 +600,6 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
tx_fifo_write(dspi, data >> 16);
tx_fifo_write(dspi, data & 0x);
}
-   cmd_fifo_write(dspi);
} else {
/* Write one entry to both TX FIFO and CMD FIFO
 * simultaneously.
-- 
2.17.1



[PATCH v2 4/4] spi: spi-fsl-dspi: Fix adjust the byte order when sending and receiving data

2018-09-30 Thread Chuanhua Han
This patch fixes the byte order inversion problem in the XSPI mode of
the dspi controller during data transfer.
In XSPI mode,When I read and write data without converting the byte
order of the data, and read and write the data directly, I tested spi
flash connected by the dspi controller and found that the byte
order of the data was reversed by the correct byte order.
When I changed the byte order according to the SPIx_CTARn[LSBFE] flag,
the correct data was obtained.

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-fsl-dspi.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 96e790e90997..44cc2bd0120e 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -220,9 +220,15 @@ static u32 dspi_pop_tx(struct fsl_dspi *dspi)
if (dspi->bytes_per_word == 1)
txdata = *(u8 *)dspi->tx;
else if (dspi->bytes_per_word == 2)
-   txdata = *(u16 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata =  cpu_to_le16(*(u16 *)dspi->tx);
+   else
+   txdata =  cpu_to_be16(*(u16 *)dspi->tx);
else  /* dspi->bytes_per_word == 4 */
-   txdata = *(u32 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata = cpu_to_le32(*(u32 *)dspi->tx);
+   else
+   txdata = cpu_to_be32(*(u32 *)dspi->tx);
dspi->tx += dspi->bytes_per_word;
}
dspi->len -= dspi->bytes_per_word;
@@ -246,9 +252,15 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
if (dspi->bytes_per_word == 1)
*(u8 *)dspi->rx = rxdata;
else if (dspi->bytes_per_word == 2)
-   *(u16 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
+   else
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
else /* dspi->bytes_per_word == 4 */
-   *(u32 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u32 *)dspi->rx = le32_to_cpu(rxdata);
+   else
+   *(u32 *)dspi->rx = be32_to_cpu(rxdata);
dspi->rx += dspi->bytes_per_word;
 }
 
@@ -593,12 +605,12 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
cmd_fifo_write(dspi);
if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
/* LSB */
-   tx_fifo_write(dspi, data & 0x);
tx_fifo_write(dspi, data >> 16);
+   tx_fifo_write(dspi, data & 0x);
} else {
/* MSB */
-   tx_fifo_write(dspi, data >> 16);
tx_fifo_write(dspi, data & 0x);
+   tx_fifo_write(dspi, data >> 16);
}
} else {
/* Write one entry to both TX FIFO and CMD FIFO
-- 
2.17.1



[PATCH v2 2/4] spi: spi-fsl-dspi: Fix delete the processing of undefined bitmask for rxdata

2018-09-30 Thread Chuanhua Han
This patch fixes the problem of rxdata being equal to 0 during the XSPI
mode transfer of the dspi controller.
In XSPI mode, If it is not deleted, the value of rxdata will be equal
to 0, and the data received will not be received correctly, causing the
receiving transfer of the spi to fail.

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-fsl-dspi.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..4dc1064bf408 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -243,9 +243,6 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
if (!dspi->rx)
return;
 
-   /* Mask of undefined bits */
-   rxdata &= (1 << dspi->bits_per_word) - 1;
-
if (dspi->bytes_per_word == 1)
*(u8 *)dspi->rx = rxdata;
else if (dspi->bytes_per_word == 2)
-- 
2.17.1



[PATCH v2 1/4] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-30 Thread Chuanhua Han
Before we add this spi_transfer to the spi_message chain table, we need
bits_per_word_mask based on spi_control to set the bits_per_word of
this spi_transfer.

Signed-off-by: Chuanhua Han 
---
Changes in v2:
 -The original patch is divided into multiple patches(the original
patch theme is "spi: spi-fsl-dspi: Fix support for XSPI transport
mode"),one of which is segmented.

 drivers/spi/spi-mem.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index eb72dba71d83..717e711c0952 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_supports_op);
 
+/**
+ * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
+ * the bits_per_word_mask of the spi controller
+ * @ctrl: the spi controller
+ * @xfer: the spi transfer
+ *
+ * This function sets the bits_per_word for each transfer based on the spi
+ * controller's bits_per_word_mask to improve the efficiency of spi transport.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer *xfer)
+{
+   if (!ctlr || !xfer) {
+   dev_err(>dev,
+   "Fail to set bits_per_word for spi transfer\n");
+   return -EINVAL;
+   }
+
+   if (ctlr->bits_per_word_mask) {
+   if (!(xfer->len % 4)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
+   xfer->bits_per_word = 32;
+   } else if (!(xfer->len % 2)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
+   xfer->bits_per_word = 16;
+   } else {
+   xfer->bits_per_word = 8;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
+
 /**
  * spi_mem_exec_op() - Execute a memory operation
  * @mem: the SPI memory
@@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf;
xfers[xferpos].len = sizeof(op->cmd.opcode);
xfers[xferpos].tx_nbits = op->cmd.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen++;
@@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + 1;
xfers[xferpos].len = op->addr.nbytes;
xfers[xferpos].tx_nbits = op->addr.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->addr.nbytes;
@@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
@@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
 
xfers[xferpos].len = op->data.nbytes;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->data.nbytes;
-- 
2.17.1



RE: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode

2018-09-29 Thread Chuanhua Han


> -Original Message-
> From: Esben Haabendal  On Behalf Of Esben
> Haabendal
> Sent: 2018年9月29日 22:56
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; boris.brezil...@bootlin.com
> Subject: Re: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport 
> mode
> 
> Chuanhua Han  writes:
> 
> > This patch fixes the problem that the XSPI mode of the dspi controller
> > cannot transfer data properly.
> > In XSPI mode, cmd_fifo is written before tx_fifo, which transforms the
> > byte order of sending and receiving data.
> 
> Did you find documentation on proper ordering of writes to related TX FIFO
> and CMD FIFO entries?
> 
> I have failed to find such information, and thus opted for what I believed 
> would
> be the safe approach, writing to TX FIFO first, so that when CMD FIFO is
> written, it will already have data in place.  And it seems to work.
> 
> But, I now see that SPIx_SR[TFIWF] hints that it should be done the other way
> around.
> 
> Tranmit FIFO Invalid Write Flag - Indicates Data Write on TX FIFO
> while CMD FIFO is empty. Without a Command, the Data entries present
> in TXFIFO are invalid.
> 
> But I fail to see how that should be related to byte ordering.
> 
> So I believe this patch is doing two things.
> 
> 1. Changing write ordering of TX FIFO and CMD FIFO.
> 2. Handling byte ordering based on SPIx_CTARn[LSBFE] flag.
> 
> It would be nice if we could get clarification from NXP on what is the right 
> way
> to do the TX FIFO and CMD FIFO write ordering.
> 
> But as for the byte ordering changes, I don't think it looks write.  The 
> meaning
> of SPIx_CTARn[LSBFE] is according to the documentaiton the bit ordering on
> the wire, and should not be related to register byte ordering.
> 
> You should probably split this patch in two, so they can be reviewed and
> merged independently.
> 
> /Esben
Hi, Esben
First of all, thank you for your valuable advice. I'm going to do two things:
1. Divide this patch into multiple patches.
2. Verify (if you can) from the relevant NXP documentation.

Second, let me mention the issues I found on fixing fsl_dspi's XSPI pattern not 
working:
1. When I executed TX FIFO first and then CMD FIFO for XSPI transmission, I 
found that SPIx_SR[TFIWF]=1 (Invalid Data present in TX FIFO since CMD FIFO is 
empty).
 This is the time when no Data can be read or written (all the Data obtained is 
equal to 0).
2. When I read and write data without converting data byte order, and read and 
write data directly,
 I tested spi-flash connected by fsl_dspi controller, and found that data byte 
order was reversed with the correct byte order. 
When I changed the byte order according to the SPIx_CTARn[LSBFE] flag, the 
correct data was obtained (not explained in this data manual).
3. In the dspi_push_rx function, if you add your "rxdata &= (1 << 
dspi->bits_per_word) -1" statement, the rxdata=0 is obtained when xspi is 
transmitted, 
and the correct data cannot be transmitted at this time (I don't quite 
understand why you added this statement).
Thanks,
Chuanhua


RE: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode

2018-09-29 Thread Chuanhua Han


> -Original Message-
> From: Esben Haabendal  On Behalf Of Esben
> Haabendal
> Sent: 2018年9月29日 22:56
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; boris.brezil...@bootlin.com
> Subject: Re: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport 
> mode
> 
> Chuanhua Han  writes:
> 
> > This patch fixes the problem that the XSPI mode of the dspi controller
> > cannot transfer data properly.
> > In XSPI mode, cmd_fifo is written before tx_fifo, which transforms the
> > byte order of sending and receiving data.
> 
> Did you find documentation on proper ordering of writes to related TX FIFO
> and CMD FIFO entries?
> 
> I have failed to find such information, and thus opted for what I believed 
> would
> be the safe approach, writing to TX FIFO first, so that when CMD FIFO is
> written, it will already have data in place.  And it seems to work.
> 
> But, I now see that SPIx_SR[TFIWF] hints that it should be done the other way
> around.
> 
> Tranmit FIFO Invalid Write Flag - Indicates Data Write on TX FIFO
> while CMD FIFO is empty. Without a Command, the Data entries present
> in TXFIFO are invalid.
> 
> But I fail to see how that should be related to byte ordering.
> 
> So I believe this patch is doing two things.
> 
> 1. Changing write ordering of TX FIFO and CMD FIFO.
> 2. Handling byte ordering based on SPIx_CTARn[LSBFE] flag.
> 
> It would be nice if we could get clarification from NXP on what is the right 
> way
> to do the TX FIFO and CMD FIFO write ordering.
> 
> But as for the byte ordering changes, I don't think it looks write.  The 
> meaning
> of SPIx_CTARn[LSBFE] is according to the documentaiton the bit ordering on
> the wire, and should not be related to register byte ordering.
> 
> You should probably split this patch in two, so they can be reviewed and
> merged independently.
> 
> /Esben
Hi, Esben
First of all, thank you for your valuable advice. I'm going to do two things:
1. Divide this patch into multiple patches.
2. Verify (if you can) from the relevant NXP documentation.

Second, let me mention the issues I found on fixing fsl_dspi's XSPI pattern not 
working:
1. When I executed TX FIFO first and then CMD FIFO for XSPI transmission, I 
found that SPIx_SR[TFIWF]=1 (Invalid Data present in TX FIFO since CMD FIFO is 
empty).
 This is the time when no Data can be read or written (all the Data obtained is 
equal to 0).
2. When I read and write data without converting data byte order, and read and 
write data directly,
 I tested spi-flash connected by fsl_dspi controller, and found that data byte 
order was reversed with the correct byte order. 
When I changed the byte order according to the SPIx_CTARn[LSBFE] flag, the 
correct data was obtained (not explained in this data manual).
3. In the dspi_push_rx function, if you add your "rxdata &= (1 << 
dspi->bits_per_word) -1" statement, the rxdata=0 is obtained when xspi is 
transmitted, 
and the correct data cannot be transmitted at this time (I don't quite 
understand why you added this statement).
Thanks,
Chuanhua


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-28 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月28日 15:19
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Fri, 28 Sep 2018 06:59:58 +
> Chuanhua Han  wrote:
> 
> > >
> > > It's still unclear why you need to specify a bits_per_word value,
> > > but if this is needed, it's probably something you want to add to
> > > spi.c, when a message is queued.
> > To specify a specific bits_per_word to be able to use the xspi
> > (32bit) mode of the fsl_dspi module to transfer data, you can look at
> > my PATCH 2/2. Do not add a value in spis.c that takes into account
> > that the value assigned to bits_per_word is decided before the
> > transfer. Thanks for your check and reply!
> 
> I might be wrong, but that's not my understanding of ->bits_per_word.
> To me, it's something that you can use when your *device* (not
> controller) expects non-byte aligned words [1]. The spi-mem protocol is
> definitely designed to work with 1byte large words, so, as I said, I suspect
> you're abusing xfer->bits_per_word to address a controller driver issue.
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Flatest%2Fsource%2Finclude%2Flinux%2Fspi%2Fspi
> .h%23L114data=02%7C01%7Cchuanhua.han%40nxp.com%7C7ec61d6d
> 7ef741aba84408d62512a9e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0
> %7C0%7C636737159420820050sdata=iwFgXG3yFvH7Ruac7MGCoaP8h
> l2M916m9%2BZeV7nksTg%3Dreserved=0
Ah, I'll study it. Thank you!


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-28 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月28日 15:19
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> On Fri, 28 Sep 2018 06:59:58 +
> Chuanhua Han  wrote:
> 
> > >
> > > It's still unclear why you need to specify a bits_per_word value,
> > > but if this is needed, it's probably something you want to add to
> > > spi.c, when a message is queued.
> > To specify a specific bits_per_word to be able to use the xspi
> > (32bit) mode of the fsl_dspi module to transfer data, you can look at
> > my PATCH 2/2. Do not add a value in spis.c that takes into account
> > that the value assigned to bits_per_word is decided before the
> > transfer. Thanks for your check and reply!
> 
> I might be wrong, but that's not my understanding of ->bits_per_word.
> To me, it's something that you can use when your *device* (not
> controller) expects non-byte aligned words [1]. The spi-mem protocol is
> definitely designed to work with 1byte large words, so, as I said, I suspect
> you're abusing xfer->bits_per_word to address a controller driver issue.
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Feli
> xir.bootlin.com%2Flinux%2Flatest%2Fsource%2Finclude%2Flinux%2Fspi%2Fspi
> .h%23L114data=02%7C01%7Cchuanhua.han%40nxp.com%7C7ec61d6d
> 7ef741aba84408d62512a9e1%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0
> %7C0%7C636737159420820050sdata=iwFgXG3yFvH7Ruac7MGCoaP8h
> l2M916m9%2BZeV7nksTg%3Dreserved=0
Ah, I'll study it. Thank you!


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-28 Thread Chuanhua Han
HI,Boris,

> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月28日 14:45
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Hi Chuanhua,
> 
> On Fri, 21 Sep 2018 15:06:26 +0800
> Chuanhua Han  wrote:
> 
> > Before we add this spi_transfer to the spi_message chain table, we
> > need bits_per_word_mask based on spi_control to set the bits_per_word
> > of this spi_transfer.
> 
> It's not clear to me what you're trying to fix/improve. Can you give more
> details on what the problem is?
> 
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> >  drivers/spi/spi-mem.c | 39
> +++
> >  1 file changed, 39 insertions(+)
> >
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > eb72dba71d83..717e711c0952 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem
> *mem,
> > const struct spi_mem_op *op)  }
> > EXPORT_SYMBOL_GPL(spi_mem_supports_op);
> >
> > +/**
> > + * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
> > + * the bits_per_word_mask of the spi controller
> > + * @ctrl: the spi controller
> > + * @xfer: the spi transfer
> > + *
> > + * This function sets the bits_per_word for each transfer based on
> > +the spi
> > + * controller's bits_per_word_mask to improve the efficiency of spi
> transport.
> > + *
> > + * Return: 0 in case of success, a negative error code otherwise.
> > + */
> > +int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer
> > +*xfer) {
> > +   if (!ctlr || !xfer) {
> > +   dev_err(>dev,
> > +   "Fail to set bits_per_word for spi transfer\n");
> > +   return -EINVAL;
> > +   }
> > +
> > +   if (ctlr->bits_per_word_mask) {
> > +   if (!(xfer->len % 4)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
> > +   xfer->bits_per_word = 32;
> > +   } else if (!(xfer->len % 2)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
> > +   xfer->bits_per_word = 16;
> > +   } else {
> > +   xfer->bits_per_word = 8;
> > +   }
> > +   }
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
> 
> Why is this function placed in spi-mem.c, and more importantly, why is it
> exported?
Since bits_per_word is not judged by spi every time it is transmitted, the code 
defaults to bits_per_word=8 so that bits_per_word cannot be implemented if it 
wants to transfer a specific spi controller, so it is flexible to assign 
bits_per_word according to the spi controller's bits_per_word_mask before each 
transfer spi. Ah, for which export, there is really no need to deliberately 
remove.
> 
> > +
> >  /**
> >   * spi_mem_exec_op() - Execute a memory operation
> >   * @mem: the SPI memory
> > @@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf;
> > xfers[xferpos].len = sizeof(op->cmd.opcode);
> > xfers[xferpos].tx_nbits = op->cmd.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> 
> It's still unclear why you need to specify a bits_per_word value, but if this 
> is
> needed, it's probably something you want to add to spi.c, when a message is
> queued.
To specify a specific bits_per_word to be able to use the xspi (32bit) mode of 
the fsl_dspi module to transfer data, you can look at my PATCH 2/2.
 Do not add a value in spis.c that takes into account that the value assigned 
to bits_per_word is decided before the transfer. Thanks for your check and 
reply!
> 
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen++;
> > @@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + 1;
> > xfers[xferpos].len = op->addr.nbytes;
> > xfers[xferpos].tx_nbits = op->addr.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->addr.nbytes;
> > @@ -276,6 +313,7 @@ int spi_mem_ex

RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-28 Thread Chuanhua Han
HI,Boris,

> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年9月28日 14:45
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; e...@deif.com
> Subject: Re: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Hi Chuanhua,
> 
> On Fri, 21 Sep 2018 15:06:26 +0800
> Chuanhua Han  wrote:
> 
> > Before we add this spi_transfer to the spi_message chain table, we
> > need bits_per_word_mask based on spi_control to set the bits_per_word
> > of this spi_transfer.
> 
> It's not clear to me what you're trying to fix/improve. Can you give more
> details on what the problem is?
> 
> >
> > Signed-off-by: Chuanhua Han 
> > ---
> >  drivers/spi/spi-mem.c | 39
> +++
> >  1 file changed, 39 insertions(+)
> >
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > eb72dba71d83..717e711c0952 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem
> *mem,
> > const struct spi_mem_op *op)  }
> > EXPORT_SYMBOL_GPL(spi_mem_supports_op);
> >
> > +/**
> > + * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
> > + * the bits_per_word_mask of the spi controller
> > + * @ctrl: the spi controller
> > + * @xfer: the spi transfer
> > + *
> > + * This function sets the bits_per_word for each transfer based on
> > +the spi
> > + * controller's bits_per_word_mask to improve the efficiency of spi
> transport.
> > + *
> > + * Return: 0 in case of success, a negative error code otherwise.
> > + */
> > +int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer
> > +*xfer) {
> > +   if (!ctlr || !xfer) {
> > +   dev_err(>dev,
> > +   "Fail to set bits_per_word for spi transfer\n");
> > +   return -EINVAL;
> > +   }
> > +
> > +   if (ctlr->bits_per_word_mask) {
> > +   if (!(xfer->len % 4)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
> > +   xfer->bits_per_word = 32;
> > +   } else if (!(xfer->len % 2)) {
> > +   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
> > +   xfer->bits_per_word = 16;
> > +   } else {
> > +   xfer->bits_per_word = 8;
> > +   }
> > +   }
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
> 
> Why is this function placed in spi-mem.c, and more importantly, why is it
> exported?
Since bits_per_word is not judged by spi every time it is transmitted, the code 
defaults to bits_per_word=8 so that bits_per_word cannot be implemented if it 
wants to transfer a specific spi controller, so it is flexible to assign 
bits_per_word according to the spi controller's bits_per_word_mask before each 
transfer spi. Ah, for which export, there is really no need to deliberately 
remove.
> 
> > +
> >  /**
> >   * spi_mem_exec_op() - Execute a memory operation
> >   * @mem: the SPI memory
> > @@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf;
> > xfers[xferpos].len = sizeof(op->cmd.opcode);
> > xfers[xferpos].tx_nbits = op->cmd.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> 
> It's still unclear why you need to specify a bits_per_word value, but if this 
> is
> needed, it's probably something you want to add to spi.c, when a message is
> queued.
To specify a specific bits_per_word to be able to use the xspi (32bit) mode of 
the fsl_dspi module to transfer data, you can look at my PATCH 2/2.
 Do not add a value in spis.c that takes into account that the value assigned 
to bits_per_word is decided before the transfer. Thanks for your check and 
reply!
> 
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen++;
> > @@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
> > xfers[xferpos].tx_buf = tmpbuf + 1;
> > xfers[xferpos].len = op->addr.nbytes;
> > xfers[xferpos].tx_nbits = op->addr.buswidth;
> > +   spi_set_xfer_bpw(ctlr, [xferpos]);
> > spi_message_add_tail([xferpos], );
> > xferpos++;
> > totalxferlen += op->addr.nbytes;
> > @@ -276,6 +313,7 @@ int spi_mem_ex

RE: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode

2018-09-28 Thread Chuanhua Han


> -Original Message-
> From: Chuanhua Han 
> Sent: 2018年9月21日 15:06
> To: broo...@kernel.org
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; e...@deif.com;
> boris.brezil...@bootlin.com; Chuanhua Han 
> Subject: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode
> 
> This patch fixes the problem that the XSPI mode of the dspi controller cannot
> transfer data properly.
> In XSPI mode, cmd_fifo is written before tx_fifo, which transforms the byte
> order of sending and receiving data.
> 
> Signed-off-by: Chuanhua Han 
> ---
>  drivers/spi/spi-fsl-dspi.c | 29 +++--
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index
> 3082e72e4f6c..44cc2bd0120e 100644
> --- a/drivers/spi/spi-fsl-dspi.c
> +++ b/drivers/spi/spi-fsl-dspi.c
> @@ -220,9 +220,15 @@ static u32 dspi_pop_tx(struct fsl_dspi *dspi)
>   if (dspi->bytes_per_word == 1)
>   txdata = *(u8 *)dspi->tx;
>   else if (dspi->bytes_per_word == 2)
> - txdata = *(u16 *)dspi->tx;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + txdata =  cpu_to_le16(*(u16 *)dspi->tx);
> + else
> + txdata =  cpu_to_be16(*(u16 *)dspi->tx);
>   else  /* dspi->bytes_per_word == 4 */
> - txdata = *(u32 *)dspi->tx;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + txdata = cpu_to_le32(*(u32 *)dspi->tx);
> + else
> + txdata = cpu_to_be32(*(u32 *)dspi->tx);
>   dspi->tx += dspi->bytes_per_word;
>   }
>   dspi->len -= dspi->bytes_per_word;
> @@ -243,15 +249,18 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32
> rxdata)
>   if (!dspi->rx)
>   return;
> 
> - /* Mask of undefined bits */
> - rxdata &= (1 << dspi->bits_per_word) - 1;
> -
>   if (dspi->bytes_per_word == 1)
>   *(u8 *)dspi->rx = rxdata;
>   else if (dspi->bytes_per_word == 2)
> - *(u16 *)dspi->rx = rxdata;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + *(u16 *)dspi->rx = be16_to_cpu(rxdata);
> + else
> + *(u16 *)dspi->rx = be16_to_cpu(rxdata);
>   else /* dspi->bytes_per_word == 4 */
> - *(u32 *)dspi->rx = rxdata;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + *(u32 *)dspi->rx = le32_to_cpu(rxdata);
> + else
> + *(u32 *)dspi->rx = be32_to_cpu(rxdata);
>   dspi->rx += dspi->bytes_per_word;
>  }
> 
> @@ -593,16 +602,16 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
>*/
>   u32 data = dspi_pop_tx(dspi);
> 
> + cmd_fifo_write(dspi);
>   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
>   /* LSB */
> - tx_fifo_write(dspi, data & 0x);
>   tx_fifo_write(dspi, data >> 16);
> + tx_fifo_write(dspi, data & 0x);
>   } else {
>   /* MSB */
> - tx_fifo_write(dspi, data >> 16);
>   tx_fifo_write(dspi, data & 0x);
> + tx_fifo_write(dspi, data >> 16);
>   }
> - cmd_fifo_write(dspi);
>   } else {
>   /* Write one entry to both TX FIFO and CMD FIFO
>* simultaneously.
> --
> 2.17.1
Hi,all
Could you please help me to see the fix of this patch? What changes need to be 
made? 
Looking forward to your valuable comments and criticism, thank you very much!!!
Thanks,
Chuanhua


RE: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode

2018-09-28 Thread Chuanhua Han


> -Original Message-
> From: Chuanhua Han 
> Sent: 2018年9月21日 15:06
> To: broo...@kernel.org
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; e...@deif.com;
> boris.brezil...@bootlin.com; Chuanhua Han 
> Subject: [PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode
> 
> This patch fixes the problem that the XSPI mode of the dspi controller cannot
> transfer data properly.
> In XSPI mode, cmd_fifo is written before tx_fifo, which transforms the byte
> order of sending and receiving data.
> 
> Signed-off-by: Chuanhua Han 
> ---
>  drivers/spi/spi-fsl-dspi.c | 29 +++--
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index
> 3082e72e4f6c..44cc2bd0120e 100644
> --- a/drivers/spi/spi-fsl-dspi.c
> +++ b/drivers/spi/spi-fsl-dspi.c
> @@ -220,9 +220,15 @@ static u32 dspi_pop_tx(struct fsl_dspi *dspi)
>   if (dspi->bytes_per_word == 1)
>   txdata = *(u8 *)dspi->tx;
>   else if (dspi->bytes_per_word == 2)
> - txdata = *(u16 *)dspi->tx;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + txdata =  cpu_to_le16(*(u16 *)dspi->tx);
> + else
> + txdata =  cpu_to_be16(*(u16 *)dspi->tx);
>   else  /* dspi->bytes_per_word == 4 */
> - txdata = *(u32 *)dspi->tx;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + txdata = cpu_to_le32(*(u32 *)dspi->tx);
> + else
> + txdata = cpu_to_be32(*(u32 *)dspi->tx);
>   dspi->tx += dspi->bytes_per_word;
>   }
>   dspi->len -= dspi->bytes_per_word;
> @@ -243,15 +249,18 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32
> rxdata)
>   if (!dspi->rx)
>   return;
> 
> - /* Mask of undefined bits */
> - rxdata &= (1 << dspi->bits_per_word) - 1;
> -
>   if (dspi->bytes_per_word == 1)
>   *(u8 *)dspi->rx = rxdata;
>   else if (dspi->bytes_per_word == 2)
> - *(u16 *)dspi->rx = rxdata;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + *(u16 *)dspi->rx = be16_to_cpu(rxdata);
> + else
> + *(u16 *)dspi->rx = be16_to_cpu(rxdata);
>   else /* dspi->bytes_per_word == 4 */
> - *(u32 *)dspi->rx = rxdata;
> + if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
> + *(u32 *)dspi->rx = le32_to_cpu(rxdata);
> + else
> + *(u32 *)dspi->rx = be32_to_cpu(rxdata);
>   dspi->rx += dspi->bytes_per_word;
>  }
> 
> @@ -593,16 +602,16 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
>*/
>   u32 data = dspi_pop_tx(dspi);
> 
> + cmd_fifo_write(dspi);
>   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
>   /* LSB */
> - tx_fifo_write(dspi, data & 0x);
>   tx_fifo_write(dspi, data >> 16);
> + tx_fifo_write(dspi, data & 0x);
>   } else {
>   /* MSB */
> - tx_fifo_write(dspi, data >> 16);
>   tx_fifo_write(dspi, data & 0x);
> + tx_fifo_write(dspi, data >> 16);
>   }
> - cmd_fifo_write(dspi);
>   } else {
>   /* Write one entry to both TX FIFO and CMD FIFO
>* simultaneously.
> --
> 2.17.1
Hi,all
Could you please help me to see the fix of this patch? What changes need to be 
made? 
Looking forward to your valuable comments and criticism, thank you very much!!!
Thanks,
Chuanhua


RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-28 Thread Chuanhua Han


> -Original Message-
> From: Chuanhua Han 
> Sent: 2018年9月21日 15:06
> To: broo...@kernel.org
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; e...@deif.com;
> boris.brezil...@bootlin.com; Chuanhua Han 
> Subject: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Before we add this spi_transfer to the spi_message chain table, we need
> bits_per_word_mask based on spi_control to set the bits_per_word of this
> spi_transfer.
> 
> Signed-off-by: Chuanhua Han 
> ---
>  drivers/spi/spi-mem.c | 39 +++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> eb72dba71d83..717e711c0952 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem *mem,
> const struct spi_mem_op *op)  }
> EXPORT_SYMBOL_GPL(spi_mem_supports_op);
> 
> +/**
> + * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
> + *   the bits_per_word_mask of the spi controller
> + * @ctrl: the spi controller
> + * @xfer: the spi transfer
> + *
> + * This function sets the bits_per_word for each transfer based on the
> +spi
> + * controller's bits_per_word_mask to improve the efficiency of spi 
> transport.
> + *
> + * Return: 0 in case of success, a negative error code otherwise.
> + */
> +int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer
> +*xfer) {
> + if (!ctlr || !xfer) {
> + dev_err(>dev,
> + "Fail to set bits_per_word for spi transfer\n");
> + return -EINVAL;
> + }
> +
> + if (ctlr->bits_per_word_mask) {
> + if (!(xfer->len % 4)) {
> + if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
> + xfer->bits_per_word = 32;
> + } else if (!(xfer->len % 2)) {
> + if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
> + xfer->bits_per_word = 16;
> + } else {
> + xfer->bits_per_word = 8;
> + }
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
> +
>  /**
>   * spi_mem_exec_op() - Execute a memory operation
>   * @mem: the SPI memory
> @@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   xfers[xferpos].tx_buf = tmpbuf;
>   xfers[xferpos].len = sizeof(op->cmd.opcode);
>   xfers[xferpos].tx_nbits = op->cmd.buswidth;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen++;
> @@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   xfers[xferpos].tx_buf = tmpbuf + 1;
>   xfers[xferpos].len = op->addr.nbytes;
>   xfers[xferpos].tx_nbits = op->addr.buswidth;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen += op->addr.nbytes;
> @@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
>   xfers[xferpos].len = op->dummy.nbytes;
>   xfers[xferpos].tx_nbits = op->dummy.buswidth;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen += op->dummy.nbytes;
> @@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   }
> 
>   xfers[xferpos].len = op->data.nbytes;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen += op->data.nbytes;
> --
> 2.17.1
Hi,all
Could you please help me to see the fix of this patch? What changes need to be 
made? 
Looking forward to your valuable comments and criticism, thank you very much!!!
Thanks,
Chuanhua



RE: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-28 Thread Chuanhua Han


> -Original Message-
> From: Chuanhua Han 
> Sent: 2018年9月21日 15:06
> To: broo...@kernel.org
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; e...@deif.com;
> boris.brezil...@bootlin.com; Chuanhua Han 
> Subject: [PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function
> 
> Before we add this spi_transfer to the spi_message chain table, we need
> bits_per_word_mask based on spi_control to set the bits_per_word of this
> spi_transfer.
> 
> Signed-off-by: Chuanhua Han 
> ---
>  drivers/spi/spi-mem.c | 39 +++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> eb72dba71d83..717e711c0952 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem *mem,
> const struct spi_mem_op *op)  }
> EXPORT_SYMBOL_GPL(spi_mem_supports_op);
> 
> +/**
> + * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
> + *   the bits_per_word_mask of the spi controller
> + * @ctrl: the spi controller
> + * @xfer: the spi transfer
> + *
> + * This function sets the bits_per_word for each transfer based on the
> +spi
> + * controller's bits_per_word_mask to improve the efficiency of spi 
> transport.
> + *
> + * Return: 0 in case of success, a negative error code otherwise.
> + */
> +int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer
> +*xfer) {
> + if (!ctlr || !xfer) {
> + dev_err(>dev,
> + "Fail to set bits_per_word for spi transfer\n");
> + return -EINVAL;
> + }
> +
> + if (ctlr->bits_per_word_mask) {
> + if (!(xfer->len % 4)) {
> + if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
> + xfer->bits_per_word = 32;
> + } else if (!(xfer->len % 2)) {
> + if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
> + xfer->bits_per_word = 16;
> + } else {
> + xfer->bits_per_word = 8;
> + }
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
> +
>  /**
>   * spi_mem_exec_op() - Execute a memory operation
>   * @mem: the SPI memory
> @@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   xfers[xferpos].tx_buf = tmpbuf;
>   xfers[xferpos].len = sizeof(op->cmd.opcode);
>   xfers[xferpos].tx_nbits = op->cmd.buswidth;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen++;
> @@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   xfers[xferpos].tx_buf = tmpbuf + 1;
>   xfers[xferpos].len = op->addr.nbytes;
>   xfers[xferpos].tx_nbits = op->addr.buswidth;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen += op->addr.nbytes;
> @@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
>   xfers[xferpos].len = op->dummy.nbytes;
>   xfers[xferpos].tx_nbits = op->dummy.buswidth;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen += op->dummy.nbytes;
> @@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const
> struct spi_mem_op *op)
>   }
> 
>   xfers[xferpos].len = op->data.nbytes;
> + spi_set_xfer_bpw(ctlr, [xferpos]);
>   spi_message_add_tail([xferpos], );
>   xferpos++;
>   totalxferlen += op->data.nbytes;
> --
> 2.17.1
Hi,all
Could you please help me to see the fix of this patch? What changes need to be 
made? 
Looking forward to your valuable comments and criticism, thank you very much!!!
Thanks,
Chuanhua



RE: [PATCH] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-09-21 Thread Chuanhua Han


> -Original Message-
> From: Chuanhua Han 
> Sent: 2018年9月21日 15:06
> To: broo...@kernel.org
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; e...@deif.com;
> boris.brezil...@bootlin.com; Chuanhua Han ;
> sta...@vger.kernel.org
> Subject: [PATCH] spi: spi-mem: Adjust op len based on message/transfer size
> limitations
> 
> We need that to adjust the len of the 2nd transfer (called data in
> spi-mem) if it's too long to fit in a SPI message or SPI transfer.
> 
> Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory
> controllers")
> Cc: 
> Signed-off-by: Chuanhua Han 
> Reviewed-by: Boris Brezillon 
> Signed-off-by: Mark Brown 
> ---
>  drivers/spi/spi-mem.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> 990770dfa5cf..ec0c24e873cd 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -328,10 +328,25 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
>  int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
> {
>   struct spi_controller *ctlr = mem->spi->controller;
> + size_t len;
> +
> + len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
> 
>   if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
>   return ctlr->mem_ops->adjust_op_size(mem, op);
> 
> + if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
> + if (len > spi_max_transfer_size(mem->spi))
> + return -EINVAL;
> +
> + op->data.nbytes = min3((size_t)op->data.nbytes,
> +spi_max_transfer_size(mem->spi),
> +spi_max_message_size(mem->spi) -
> +len);
> + if (!op->data.nbytes)
> + return -EINVAL;
> + }
> +
>   return 0;
>  }
>  EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
> --
> 2.17.1
I'm really sorry for my error in operation, this has been applied to the latest 
kernel, please ignore this patch in email!!!


RE: [PATCH] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-09-21 Thread Chuanhua Han


> -Original Message-
> From: Chuanhua Han 
> Sent: 2018年9月21日 15:06
> To: broo...@kernel.org
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; e...@deif.com;
> boris.brezil...@bootlin.com; Chuanhua Han ;
> sta...@vger.kernel.org
> Subject: [PATCH] spi: spi-mem: Adjust op len based on message/transfer size
> limitations
> 
> We need that to adjust the len of the 2nd transfer (called data in
> spi-mem) if it's too long to fit in a SPI message or SPI transfer.
> 
> Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory
> controllers")
> Cc: 
> Signed-off-by: Chuanhua Han 
> Reviewed-by: Boris Brezillon 
> Signed-off-by: Mark Brown 
> ---
>  drivers/spi/spi-mem.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> 990770dfa5cf..ec0c24e873cd 100644
> --- a/drivers/spi/spi-mem.c
> +++ b/drivers/spi/spi-mem.c
> @@ -328,10 +328,25 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
>  int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
> {
>   struct spi_controller *ctlr = mem->spi->controller;
> + size_t len;
> +
> + len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
> 
>   if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
>   return ctlr->mem_ops->adjust_op_size(mem, op);
> 
> + if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
> + if (len > spi_max_transfer_size(mem->spi))
> + return -EINVAL;
> +
> + op->data.nbytes = min3((size_t)op->data.nbytes,
> +spi_max_transfer_size(mem->spi),
> +spi_max_message_size(mem->spi) -
> +len);
> + if (!op->data.nbytes)
> + return -EINVAL;
> + }
> +
>   return 0;
>  }
>  EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
> --
> 2.17.1
I'm really sorry for my error in operation, this has been applied to the latest 
kernel, please ignore this patch in email!!!


[PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-21 Thread Chuanhua Han
Before we add this spi_transfer to the spi_message chain table, we need
bits_per_word_mask based on spi_control to set the bits_per_word of
this spi_transfer.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-mem.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index eb72dba71d83..717e711c0952 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_supports_op);
 
+/**
+ * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
+ * the bits_per_word_mask of the spi controller
+ * @ctrl: the spi controller
+ * @xfer: the spi transfer
+ *
+ * This function sets the bits_per_word for each transfer based on the spi
+ * controller's bits_per_word_mask to improve the efficiency of spi transport.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer *xfer)
+{
+   if (!ctlr || !xfer) {
+   dev_err(>dev,
+   "Fail to set bits_per_word for spi transfer\n");
+   return -EINVAL;
+   }
+
+   if (ctlr->bits_per_word_mask) {
+   if (!(xfer->len % 4)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
+   xfer->bits_per_word = 32;
+   } else if (!(xfer->len % 2)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
+   xfer->bits_per_word = 16;
+   } else {
+   xfer->bits_per_word = 8;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
+
 /**
  * spi_mem_exec_op() - Execute a memory operation
  * @mem: the SPI memory
@@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf;
xfers[xferpos].len = sizeof(op->cmd.opcode);
xfers[xferpos].tx_nbits = op->cmd.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen++;
@@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + 1;
xfers[xferpos].len = op->addr.nbytes;
xfers[xferpos].tx_nbits = op->addr.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->addr.nbytes;
@@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
@@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
 
xfers[xferpos].len = op->data.nbytes;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->data.nbytes;
-- 
2.17.1



[PATCH] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-09-21 Thread Chuanhua Han
We need that to adjust the len of the 2nd transfer (called data in
spi-mem) if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
Cc: 
Signed-off-by: Chuanhua Han 
Reviewed-by: Boris Brezillon 
Signed-off-by: Mark Brown 
---
 drivers/spi/spi-mem.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770dfa5cf..ec0c24e873cd 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,25 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   size_t len;
+
+   len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (len > spi_max_transfer_size(mem->spi))
+   return -EINVAL;
+
+   op->data.nbytes = min3((size_t)op->data.nbytes,
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  len);
+   if (!op->data.nbytes)
+   return -EINVAL;
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.17.1



[PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode

2018-09-21 Thread Chuanhua Han
This patch fixes the problem that the XSPI mode of the dspi controller
cannot transfer data properly.
In XSPI mode, cmd_fifo is written before tx_fifo, which transforms the
byte order of sending and receiving data.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-dspi.c | 29 +++--
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..44cc2bd0120e 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -220,9 +220,15 @@ static u32 dspi_pop_tx(struct fsl_dspi *dspi)
if (dspi->bytes_per_word == 1)
txdata = *(u8 *)dspi->tx;
else if (dspi->bytes_per_word == 2)
-   txdata = *(u16 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata =  cpu_to_le16(*(u16 *)dspi->tx);
+   else
+   txdata =  cpu_to_be16(*(u16 *)dspi->tx);
else  /* dspi->bytes_per_word == 4 */
-   txdata = *(u32 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata = cpu_to_le32(*(u32 *)dspi->tx);
+   else
+   txdata = cpu_to_be32(*(u32 *)dspi->tx);
dspi->tx += dspi->bytes_per_word;
}
dspi->len -= dspi->bytes_per_word;
@@ -243,15 +249,18 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 
rxdata)
if (!dspi->rx)
return;
 
-   /* Mask of undefined bits */
-   rxdata &= (1 << dspi->bits_per_word) - 1;
-
if (dspi->bytes_per_word == 1)
*(u8 *)dspi->rx = rxdata;
else if (dspi->bytes_per_word == 2)
-   *(u16 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
+   else
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
else /* dspi->bytes_per_word == 4 */
-   *(u32 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u32 *)dspi->rx = le32_to_cpu(rxdata);
+   else
+   *(u32 *)dspi->rx = be32_to_cpu(rxdata);
dspi->rx += dspi->bytes_per_word;
 }
 
@@ -593,16 +602,16 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
 */
u32 data = dspi_pop_tx(dspi);
 
+   cmd_fifo_write(dspi);
if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
/* LSB */
-   tx_fifo_write(dspi, data & 0x);
tx_fifo_write(dspi, data >> 16);
+   tx_fifo_write(dspi, data & 0x);
} else {
/* MSB */
-   tx_fifo_write(dspi, data >> 16);
tx_fifo_write(dspi, data & 0x);
+   tx_fifo_write(dspi, data >> 16);
}
-   cmd_fifo_write(dspi);
} else {
/* Write one entry to both TX FIFO and CMD FIFO
 * simultaneously.
-- 
2.17.1



[PATCH 1/2] spi: spi-mem: Add the spi_set_xfer_bpw function

2018-09-21 Thread Chuanhua Han
Before we add this spi_transfer to the spi_message chain table, we need
bits_per_word_mask based on spi_control to set the bits_per_word of
this spi_transfer.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-mem.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index eb72dba71d83..717e711c0952 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -175,6 +175,41 @@ bool spi_mem_supports_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_supports_op);
 
+/**
+ * spi_set_xfer_bpw() - Set the bits_per_word for each transfer based on
+ * the bits_per_word_mask of the spi controller
+ * @ctrl: the spi controller
+ * @xfer: the spi transfer
+ *
+ * This function sets the bits_per_word for each transfer based on the spi
+ * controller's bits_per_word_mask to improve the efficiency of spi transport.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_set_xfer_bpw(struct spi_controller *ctlr, struct spi_transfer *xfer)
+{
+   if (!ctlr || !xfer) {
+   dev_err(>dev,
+   "Fail to set bits_per_word for spi transfer\n");
+   return -EINVAL;
+   }
+
+   if (ctlr->bits_per_word_mask) {
+   if (!(xfer->len % 4)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(32))
+   xfer->bits_per_word = 32;
+   } else if (!(xfer->len % 2)) {
+   if (ctlr->bits_per_word_mask & SPI_BPW_MASK(16))
+   xfer->bits_per_word = 16;
+   } else {
+   xfer->bits_per_word = 8;
+   }
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(spi_set_xfer_bpw);
+
 /**
  * spi_mem_exec_op() - Execute a memory operation
  * @mem: the SPI memory
@@ -252,6 +287,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf;
xfers[xferpos].len = sizeof(op->cmd.opcode);
xfers[xferpos].tx_nbits = op->cmd.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen++;
@@ -266,6 +302,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + 1;
xfers[xferpos].len = op->addr.nbytes;
xfers[xferpos].tx_nbits = op->addr.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->addr.nbytes;
@@ -276,6 +313,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
xfers[xferpos].len = op->dummy.nbytes;
xfers[xferpos].tx_nbits = op->dummy.buswidth;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->dummy.nbytes;
@@ -291,6 +329,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct 
spi_mem_op *op)
}
 
xfers[xferpos].len = op->data.nbytes;
+   spi_set_xfer_bpw(ctlr, [xferpos]);
spi_message_add_tail([xferpos], );
xferpos++;
totalxferlen += op->data.nbytes;
-- 
2.17.1



[PATCH] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-09-21 Thread Chuanhua Han
We need that to adjust the len of the 2nd transfer (called data in
spi-mem) if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
Cc: 
Signed-off-by: Chuanhua Han 
Reviewed-by: Boris Brezillon 
Signed-off-by: Mark Brown 
---
 drivers/spi/spi-mem.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770dfa5cf..ec0c24e873cd 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,25 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   size_t len;
+
+   len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (len > spi_max_transfer_size(mem->spi))
+   return -EINVAL;
+
+   op->data.nbytes = min3((size_t)op->data.nbytes,
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  len);
+   if (!op->data.nbytes)
+   return -EINVAL;
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.17.1



[PATCH 2/2] spi: spi-fsl-dspi: Fix support for XSPI transport mode

2018-09-21 Thread Chuanhua Han
This patch fixes the problem that the XSPI mode of the dspi controller
cannot transfer data properly.
In XSPI mode, cmd_fifo is written before tx_fifo, which transforms the
byte order of sending and receiving data.

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-dspi.c | 29 +++--
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3082e72e4f6c..44cc2bd0120e 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -220,9 +220,15 @@ static u32 dspi_pop_tx(struct fsl_dspi *dspi)
if (dspi->bytes_per_word == 1)
txdata = *(u8 *)dspi->tx;
else if (dspi->bytes_per_word == 2)
-   txdata = *(u16 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata =  cpu_to_le16(*(u16 *)dspi->tx);
+   else
+   txdata =  cpu_to_be16(*(u16 *)dspi->tx);
else  /* dspi->bytes_per_word == 4 */
-   txdata = *(u32 *)dspi->tx;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   txdata = cpu_to_le32(*(u32 *)dspi->tx);
+   else
+   txdata = cpu_to_be32(*(u32 *)dspi->tx);
dspi->tx += dspi->bytes_per_word;
}
dspi->len -= dspi->bytes_per_word;
@@ -243,15 +249,18 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 
rxdata)
if (!dspi->rx)
return;
 
-   /* Mask of undefined bits */
-   rxdata &= (1 << dspi->bits_per_word) - 1;
-
if (dspi->bytes_per_word == 1)
*(u8 *)dspi->rx = rxdata;
else if (dspi->bytes_per_word == 2)
-   *(u16 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
+   else
+   *(u16 *)dspi->rx = be16_to_cpu(rxdata);
else /* dspi->bytes_per_word == 4 */
-   *(u32 *)dspi->rx = rxdata;
+   if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1))
+   *(u32 *)dspi->rx = le32_to_cpu(rxdata);
+   else
+   *(u32 *)dspi->rx = be32_to_cpu(rxdata);
dspi->rx += dspi->bytes_per_word;
 }
 
@@ -593,16 +602,16 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
 */
u32 data = dspi_pop_tx(dspi);
 
+   cmd_fifo_write(dspi);
if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
/* LSB */
-   tx_fifo_write(dspi, data & 0x);
tx_fifo_write(dspi, data >> 16);
+   tx_fifo_write(dspi, data & 0x);
} else {
/* MSB */
-   tx_fifo_write(dspi, data >> 16);
tx_fifo_write(dspi, data & 0x);
+   tx_fifo_write(dspi, data >> 16);
}
-   cmd_fifo_write(dspi);
} else {
/* Write one entry to both TX FIFO and CMD FIFO
 * simultaneously.
-- 
2.17.1



RE: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-08-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年8月30日 17:17
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; sta...@vger.kernel.org
> Subject: Re: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer
> size limitations
> 
> On Thu, 30 Aug 2018 09:13:03 +
> Chuanhua Han  wrote:
> 
> > > -Original Message-
> > > From: Boris Brezillon 
> > > Sent: 2018年8月30日 16:47
> > > To: Chuanhua Han 
> > > Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; sta...@vger.kernel.org
> > > Subject: Re: [PATCH v5] spi: spi-mem: Adjust op len based on
> > > message/transfer size limitations
> > >
> > > Hi Chuanhua,
> > >
> > > On Thu, 30 Aug 2018 16:43:24 +0800
> > > Chuanhua Han  wrote:
> > >
> > > > We need that to adjust the len of the 2nd transfer (called data in
> > > > spi-mem) if it's too long to fit in a SPI message or SPI transfer.
> > >
> > > You already sent this email a few days back. Please wait a bit
> > > before sending it again. And when you do so and nothing changed in
> > > the patch please use the [PATCH RESEND vX] prefix and explain why you
> resend it.
> > I have modified the patch for the comment you mentioned last time. Do
> > you need any other modification?
> 
> Oops, sorry. Looks like the previous one was only sent to me, not the ML and
> the SPI maintainer.
It doesn't matter,thank you for your valuable advice!


RE: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-08-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年8月30日 17:17
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; sta...@vger.kernel.org
> Subject: Re: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer
> size limitations
> 
> On Thu, 30 Aug 2018 09:13:03 +
> Chuanhua Han  wrote:
> 
> > > -Original Message-
> > > From: Boris Brezillon 
> > > Sent: 2018年8月30日 16:47
> > > To: Chuanhua Han 
> > > Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> > > linux-kernel@vger.kernel.org; sta...@vger.kernel.org
> > > Subject: Re: [PATCH v5] spi: spi-mem: Adjust op len based on
> > > message/transfer size limitations
> > >
> > > Hi Chuanhua,
> > >
> > > On Thu, 30 Aug 2018 16:43:24 +0800
> > > Chuanhua Han  wrote:
> > >
> > > > We need that to adjust the len of the 2nd transfer (called data in
> > > > spi-mem) if it's too long to fit in a SPI message or SPI transfer.
> > >
> > > You already sent this email a few days back. Please wait a bit
> > > before sending it again. And when you do so and nothing changed in
> > > the patch please use the [PATCH RESEND vX] prefix and explain why you
> resend it.
> > I have modified the patch for the comment you mentioned last time. Do
> > you need any other modification?
> 
> Oops, sorry. Looks like the previous one was only sent to me, not the ML and
> the SPI maintainer.
It doesn't matter,thank you for your valuable advice!


RE: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-08-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年8月30日 16:47
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; sta...@vger.kernel.org
> Subject: Re: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer
> size limitations
> 
> Hi Chuanhua,
> 
> On Thu, 30 Aug 2018 16:43:24 +0800
> Chuanhua Han  wrote:
> 
> > We need that to adjust the len of the 2nd transfer (called data in
> > spi-mem) if it's too long to fit in a SPI message or SPI transfer.
> 
> You already sent this email a few days back. Please wait a bit before sending 
> it
> again. And when you do so and nothing changed in the patch please use the
> [PATCH RESEND vX] prefix and explain why you resend it.
I have modified the patch for the comment you mentioned last time. Do you need 
any other modification?
> 
> Thanks,
> 
> Boris
> 
> >
> > Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI
> > memory controllers")
> > Cc: 
> > Signed-off-by: Chuanhua Han 
> > Reviewed-by: Boris Brezillon 
> > ---
> > Changes in v5:
> >   -Add the validation check after the op->data.nbytes assignment
> >   -Assign the "len" variable after defining it
> >   -Remove the brackets on both sides of "opt-> data.nbytes"
> > Changes in v4:
> >   -Rename variable name "opcode_addr_dummy_sum" to "len"
> >   -The comparison of "spi_max_message_size(mem->spi)" and "len" was
> removed
> >   -Adjust their order when comparing the sizes of
> "spi_max_message_size(mem->spi)" and "len"
> >   -Changing the "unsigned long" type in the code to "size_t"
> > Changes in v3:
> >   -Rename variable name "val" to "opcode_addr_dummy_sum"
> >   -Place the legitimacy of the transfer size(i.e.,
> > "spi_max_message_size(mem->spi)" and
> > "opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr->
> mem_ops->exec_op) {"
> > structure and add "spi_max_transfer_size(mem->spi) and
> opcode_addr_dummy_sum"
> >   -Adjust the formatting alignment of the code
> >   -"(unsigned long)op->data.nbytes" was modified to "(unsigned
> long)(op->data.nbytes)"
> > Changes in v2:
> >   -Place the adjusted transfer bytes code in spi_mem_adjust_op_size()
> > and  check
> > spi_max_message_size(mem->spi) value before subtracting opcode, addr and
> dummy bytes
> >   -Change the code from fsl-espi controller to generic code(The
> > adjustment of spi transmission length was originally modified in the
> > "drivers/spi/spi-fsl-espi.c" file, and now the adjustment of transfer
> > length is made in the "drivers/spi/spi-mem.c" file)
> >
> >  drivers/spi/spi-mem.c | 15 +++
> >  1 file changed, 15 insertions(+)
> >
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > e43842c..eb72dba 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
> >  int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op
> > *op)  {
> > struct spi_controller *ctlr = mem->spi->controller;
> > +   size_t len;
> > +
> > +   len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
> >
> > if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
> > return ctlr->mem_ops->adjust_op_size(mem, op);
> >
> > +   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
> > +   if (len > spi_max_transfer_size(mem->spi))
> > +   return -EINVAL;
> > +
> > +   op->data.nbytes = min3((size_t)op->data.nbytes,
> > +  spi_max_transfer_size(mem->spi),
> > +  spi_max_message_size(mem->spi) -
> > +  len);
> > +   if (!op->data.nbytes)
> > +   return -EINVAL;
> > +   }
> > +
> > return 0;
> >  }
> >  EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);



RE: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-08-30 Thread Chuanhua Han


> -Original Message-
> From: Boris Brezillon 
> Sent: 2018年8月30日 16:47
> To: Chuanhua Han 
> Cc: broo...@kernel.org; linux-...@vger.kernel.org;
> linux-kernel@vger.kernel.org; sta...@vger.kernel.org
> Subject: Re: [PATCH v5] spi: spi-mem: Adjust op len based on message/transfer
> size limitations
> 
> Hi Chuanhua,
> 
> On Thu, 30 Aug 2018 16:43:24 +0800
> Chuanhua Han  wrote:
> 
> > We need that to adjust the len of the 2nd transfer (called data in
> > spi-mem) if it's too long to fit in a SPI message or SPI transfer.
> 
> You already sent this email a few days back. Please wait a bit before sending 
> it
> again. And when you do so and nothing changed in the patch please use the
> [PATCH RESEND vX] prefix and explain why you resend it.
I have modified the patch for the comment you mentioned last time. Do you need 
any other modification?
> 
> Thanks,
> 
> Boris
> 
> >
> > Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI
> > memory controllers")
> > Cc: 
> > Signed-off-by: Chuanhua Han 
> > Reviewed-by: Boris Brezillon 
> > ---
> > Changes in v5:
> >   -Add the validation check after the op->data.nbytes assignment
> >   -Assign the "len" variable after defining it
> >   -Remove the brackets on both sides of "opt-> data.nbytes"
> > Changes in v4:
> >   -Rename variable name "opcode_addr_dummy_sum" to "len"
> >   -The comparison of "spi_max_message_size(mem->spi)" and "len" was
> removed
> >   -Adjust their order when comparing the sizes of
> "spi_max_message_size(mem->spi)" and "len"
> >   -Changing the "unsigned long" type in the code to "size_t"
> > Changes in v3:
> >   -Rename variable name "val" to "opcode_addr_dummy_sum"
> >   -Place the legitimacy of the transfer size(i.e.,
> > "spi_max_message_size(mem->spi)" and
> > "opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr->
> mem_ops->exec_op) {"
> > structure and add "spi_max_transfer_size(mem->spi) and
> opcode_addr_dummy_sum"
> >   -Adjust the formatting alignment of the code
> >   -"(unsigned long)op->data.nbytes" was modified to "(unsigned
> long)(op->data.nbytes)"
> > Changes in v2:
> >   -Place the adjusted transfer bytes code in spi_mem_adjust_op_size()
> > and  check
> > spi_max_message_size(mem->spi) value before subtracting opcode, addr and
> dummy bytes
> >   -Change the code from fsl-espi controller to generic code(The
> > adjustment of spi transmission length was originally modified in the
> > "drivers/spi/spi-fsl-espi.c" file, and now the adjustment of transfer
> > length is made in the "drivers/spi/spi-mem.c" file)
> >
> >  drivers/spi/spi-mem.c | 15 +++
> >  1 file changed, 15 insertions(+)
> >
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > e43842c..eb72dba 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
> >  int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op
> > *op)  {
> > struct spi_controller *ctlr = mem->spi->controller;
> > +   size_t len;
> > +
> > +   len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
> >
> > if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
> > return ctlr->mem_ops->adjust_op_size(mem, op);
> >
> > +   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
> > +   if (len > spi_max_transfer_size(mem->spi))
> > +   return -EINVAL;
> > +
> > +   op->data.nbytes = min3((size_t)op->data.nbytes,
> > +  spi_max_transfer_size(mem->spi),
> > +  spi_max_message_size(mem->spi) -
> > +  len);
> > +   if (!op->data.nbytes)
> > +   return -EINVAL;
> > +   }
> > +
> > return 0;
> >  }
> >  EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);



[PATCH v5] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-08-30 Thread Chuanhua Han
We need that to adjust the len of the 2nd transfer (called data in
spi-mem) if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
Cc: 
Signed-off-by: Chuanhua Han 
Reviewed-by: Boris Brezillon 
---
Changes in v5:
  -Add the validation check after the op->data.nbytes assignment
  -Assign the "len" variable after defining it
  -Remove the brackets on both sides of "opt-> data.nbytes"
Changes in v4:
  -Rename variable name "opcode_addr_dummy_sum" to "len"
  -The comparison of "spi_max_message_size(mem->spi)" and "len" was removed
  -Adjust their order when comparing the sizes of 
"spi_max_message_size(mem->spi)" and "len"
  -Changing the "unsigned long" type in the code to "size_t"
Changes in v3:
  -Rename variable name "val" to "opcode_addr_dummy_sum"
  -Place the legitimacy of the transfer size(i.e., 
"spi_max_message_size(mem->spi)" and
"opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr-> 
mem_ops->exec_op) {"
structure and add "spi_max_transfer_size(mem->spi) and opcode_addr_dummy_sum"
  -Adjust the formatting alignment of the code
  -"(unsigned long)op->data.nbytes" was modified to "(unsigned 
long)(op->data.nbytes)"
Changes in v2:
  -Place the adjusted transfer bytes code in spi_mem_adjust_op_size() and  check
spi_max_message_size(mem->spi) value before subtracting opcode, addr and dummy 
bytes
  -Change the code from fsl-espi controller to generic code(The adjustment of 
spi transmission
length was originally modified in the "drivers/spi/spi-fsl-espi.c" file, and 
now the adjustment
of transfer length is made in the "drivers/spi/spi-mem.c" file)

 drivers/spi/spi-mem.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index e43842c..eb72dba 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   size_t len;
+
+   len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (len > spi_max_transfer_size(mem->spi))
+   return -EINVAL;
+
+   op->data.nbytes = min3((size_t)op->data.nbytes,
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  len);
+   if (!op->data.nbytes)
+   return -EINVAL;
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH v5] spi: spi-mem: Adjust op len based on message/transfer size limitations

2018-08-30 Thread Chuanhua Han
We need that to adjust the len of the 2nd transfer (called data in
spi-mem) if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
Cc: 
Signed-off-by: Chuanhua Han 
Reviewed-by: Boris Brezillon 
---
Changes in v5:
  -Add the validation check after the op->data.nbytes assignment
  -Assign the "len" variable after defining it
  -Remove the brackets on both sides of "opt-> data.nbytes"
Changes in v4:
  -Rename variable name "opcode_addr_dummy_sum" to "len"
  -The comparison of "spi_max_message_size(mem->spi)" and "len" was removed
  -Adjust their order when comparing the sizes of 
"spi_max_message_size(mem->spi)" and "len"
  -Changing the "unsigned long" type in the code to "size_t"
Changes in v3:
  -Rename variable name "val" to "opcode_addr_dummy_sum"
  -Place the legitimacy of the transfer size(i.e., 
"spi_max_message_size(mem->spi)" and
"opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr-> 
mem_ops->exec_op) {"
structure and add "spi_max_transfer_size(mem->spi) and opcode_addr_dummy_sum"
  -Adjust the formatting alignment of the code
  -"(unsigned long)op->data.nbytes" was modified to "(unsigned 
long)(op->data.nbytes)"
Changes in v2:
  -Place the adjusted transfer bytes code in spi_mem_adjust_op_size() and  check
spi_max_message_size(mem->spi) value before subtracting opcode, addr and dummy 
bytes
  -Change the code from fsl-espi controller to generic code(The adjustment of 
spi transmission
length was originally modified in the "drivers/spi/spi-fsl-espi.c" file, and 
now the adjustment
of transfer length is made in the "drivers/spi/spi-mem.c" file)

 drivers/spi/spi-mem.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index e43842c..eb72dba 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   size_t len;
+
+   len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (len > spi_max_transfer_size(mem->spi))
+   return -EINVAL;
+
+   op->data.nbytes = min3((size_t)op->data.nbytes,
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  len);
+   if (!op->data.nbytes)
+   return -EINVAL;
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH v4] mtd: spi-mem: Add the default transfer length adjustments

2018-08-21 Thread Chuanhua Han
We need that to adjust the len of the 2nd transfer (called data in spi-mem)
if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
Cc: 

Signed-off-by: Boris Brezillon 
Signed-off-by: Chuanhua Han 
---
Changes in v4:
  -Rename variable name "opcode_addr_dummy_sum" to "len".
  -The comparison of "spi_max_message_size(mem->spi)" and "len" was removed.
  -Adjust their order when comparing the sizes of 
"spi_max_message_size(mem->spi)" and "len".
  -Changing the "unsigned long" type in the code to "size_t".
Changes in v3:
  -Rename variable name "val" to "opcode_addr_dummy_sum".
  -Place the legitimacy of the transfer size(i.e., 
"spi_max_message_size(mem->spi)" and
  -"opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr-> 
mem_ops->exec_op) {"
structure and add "spi_max_transfer_size(mem->spi) and opcode_addr_dummy_sum".
  -Adjust the formatting alignment of the code.
  -"(unsigned long)op->data.nbytes" was modified to "(unsigned 
long)(op->data.nbytes)".
Changes in v2:
  -Place the adjusted transfer bytes code in spi_mem_adjust_op_size() and  
check 
spi_max_message_size(mem->spi) value before subtracting opcode, addr and dummy 
bytes.
  -Change the code from fsl-espi controller to generic code(The adjustment of 
spi transmission
length was originally modified in the "drivers/spi/spi-fsl-espi.c" file, and 
now the adjustment
of transfer length is made in the "drivers/spi/spi-mem.c" file).

 drivers/spi/spi-mem.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770d..5374606 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,23 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   size_t len = sizeof(op->cmd.opcode) +
+   op->addr.nbytes +
+   op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (len > spi_max_transfer_size(mem->spi))
+   return -EINVAL;
+
+   op->data.nbytes = min3((size_t)(op->data.nbytes),
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  len);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH v4] mtd: spi-mem: Add the default transfer length adjustments

2018-08-21 Thread Chuanhua Han
We need that to adjust the len of the 2nd transfer (called data in spi-mem)
if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
Cc: 

Signed-off-by: Boris Brezillon 
Signed-off-by: Chuanhua Han 
---
Changes in v4:
  -Rename variable name "opcode_addr_dummy_sum" to "len".
  -The comparison of "spi_max_message_size(mem->spi)" and "len" was removed.
  -Adjust their order when comparing the sizes of 
"spi_max_message_size(mem->spi)" and "len".
  -Changing the "unsigned long" type in the code to "size_t".
Changes in v3:
  -Rename variable name "val" to "opcode_addr_dummy_sum".
  -Place the legitimacy of the transfer size(i.e., 
"spi_max_message_size(mem->spi)" and
  -"opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr-> 
mem_ops->exec_op) {"
structure and add "spi_max_transfer_size(mem->spi) and opcode_addr_dummy_sum".
  -Adjust the formatting alignment of the code.
  -"(unsigned long)op->data.nbytes" was modified to "(unsigned 
long)(op->data.nbytes)".
Changes in v2:
  -Place the adjusted transfer bytes code in spi_mem_adjust_op_size() and  
check 
spi_max_message_size(mem->spi) value before subtracting opcode, addr and dummy 
bytes.
  -Change the code from fsl-espi controller to generic code(The adjustment of 
spi transmission
length was originally modified in the "drivers/spi/spi-fsl-espi.c" file, and 
now the adjustment
of transfer length is made in the "drivers/spi/spi-mem.c" file).

 drivers/spi/spi-mem.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770d..5374606 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,23 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   size_t len = sizeof(op->cmd.opcode) +
+   op->addr.nbytes +
+   op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (len > spi_max_transfer_size(mem->spi))
+   return -EINVAL;
+
+   op->data.nbytes = min3((size_t)(op->data.nbytes),
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  len);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH] mtd: m25p80: consider max message size when use the spi_mem_xx() API

2018-08-20 Thread Chuanhua Han
Signed-off-by: Chuanhua Han 
---
Changes in v3:
Rename variable name "val" to "opcode_addr_dummy_sum".
Place the legitimacy of the transfer size(i.e., 
"pi_max_message_size(mem->spi)" and
"opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr-> 
mem_ops->exec_op) {"
structure and add "spi_max_transfer_size(mem->spi) and opcode_addr_dummy_sum".
Adjust the formatting alignment of your code.
"(unsigned long)op->data.nbytes" was modified to "(unsigned 
long)(op->data.nbytes)".

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
---
 drivers/spi/spi-mem.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770d..5ec2bc9 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,24 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   unsigned long opcode_addr_dummy_sum = sizeof(op->cmd.opcode) +
+ op->addr.nbytes +
+ op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (spi_max_message_size(mem->spi) < opcode_addr_dummy_sum ||
+   spi_max_transfer_size(mem->spi) < opcode_addr_dummy_sum)
+   return -EINVAL;
+
+   op->data.nbytes = min3((unsigned long)(op->data.nbytes),
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  opcode_addr_dummy_sum);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH] mtd: m25p80: consider max message size when use the spi_mem_xx() API

2018-08-20 Thread Chuanhua Han
Signed-off-by: Chuanhua Han 
---
Changes in v3:
Rename variable name "val" to "opcode_addr_dummy_sum".
Place the legitimacy of the transfer size(i.e., 
"pi_max_message_size(mem->spi)" and
"opcode_addr_dummy_sum") into "if (! ctlr - > mem_ops | |! ctlr-> 
mem_ops->exec_op) {"
structure and add "spi_max_transfer_size(mem->spi) and opcode_addr_dummy_sum".
Adjust the formatting alignment of your code.
"(unsigned long)op->data.nbytes" was modified to "(unsigned 
long)(op->data.nbytes)".

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory 
controllers")
---
 drivers/spi/spi-mem.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770d..5ec2bc9 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,24 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   unsigned long opcode_addr_dummy_sum = sizeof(op->cmd.opcode) +
+ op->addr.nbytes +
+ op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+   if (spi_max_message_size(mem->spi) < opcode_addr_dummy_sum ||
+   spi_max_transfer_size(mem->spi) < opcode_addr_dummy_sum)
+   return -EINVAL;
+
+   op->data.nbytes = min3((unsigned long)(op->data.nbytes),
+  spi_max_transfer_size(mem->spi),
+  spi_max_message_size(mem->spi) -
+  opcode_addr_dummy_sum);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH] mtd: m25p80: consider max message size when use the spi_mem_xx() API

2018-08-20 Thread Chuanhua Han
Signed-off-by: Chuanhua Han 
---
Changes in v2:
- Place the adjusted transfer bytes code in spi_mem_adjust_op_size()
and  check spi_max_message_size(mem->spi) value before subtracting 
opcode, addr and dummy bytes.
*fixes:
spi: Extend the core to ease integration of SPI memory controllers
---
 drivers/spi/spi-mem.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770d..f5e75d1 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,21 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   unsigned long val = sizeof(op->cmd.opcode) +
+ op->addr.nbytes +
+ op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (spi_max_message_size(mem->spi) < val)
+   return -EINVAL;
+
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op)
+   op->data.nbytes = min3((unsigned long)op->data.nbytes,
+   spi_max_transfer_size(mem->spi),
+   spi_max_message_size(mem->spi) - val);
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH] mtd: m25p80: consider max message size when use the spi_mem_xx() API

2018-08-20 Thread Chuanhua Han
Signed-off-by: Chuanhua Han 
---
Changes in v2:
- Place the adjusted transfer bytes code in spi_mem_adjust_op_size()
and  check spi_max_message_size(mem->spi) value before subtracting 
opcode, addr and dummy bytes.
*fixes:
spi: Extend the core to ease integration of SPI memory controllers
---
 drivers/spi/spi-mem.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 990770d..f5e75d1 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -328,10 +328,21 @@ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
struct spi_controller *ctlr = mem->spi->controller;
+   unsigned long val = sizeof(op->cmd.opcode) +
+ op->addr.nbytes +
+ op->dummy.nbytes;
 
if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
return ctlr->mem_ops->adjust_op_size(mem, op);
 
+   if (spi_max_message_size(mem->spi) < val)
+   return -EINVAL;
+
+   if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op)
+   op->data.nbytes = min3((unsigned long)op->data.nbytes,
+   spi_max_transfer_size(mem->spi),
+   spi_max_message_size(mem->spi) - val);
+
return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
-- 
2.7.4



[PATCH] spi: fsl-espi: master->mem_ops is implemented in the controller

2018-08-17 Thread Chuanhua Han
The length of the transmitted data needs to be adjusted due to the maximum 
length limit for espi transmission messages

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-espi.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 1d332e2..4724127 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* eSPI Controller registers */
 #define ESPI_SPMODE0x00/* eSPI mode register */
@@ -659,6 +660,29 @@ static void fsl_espi_init_regs(struct device *dev, bool 
initial)
fsl_espi_write_reg(espi, ESPI_SPMODE, SPMODE_INIT_VAL | SPMODE_ENABLE);
 }
 
+static int fsl_espi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
+   if (!mem || !op)
+   return -EINVAL;
+   op->data.nbytes = min3((unsigned long)op->data.nbytes,
+   spi_max_transfer_size(mem->spi),
+   spi_max_message_size(mem->spi) -
+   sizeof(op->cmd.opcode) -
+   op->addr.nbytes -
+   op->dummy.nbytes);
+   return 0;
+}
+
+static int fsl_espi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+   return -ENOTSUPP;
+}
+
+static const struct spi_controller_mem_ops fsl_espi_mem_ops = {
+   .adjust_op_size = fsl_espi_adjust_op_size,
+   .exec_op = fsl_espi_exec_op,
+};
+
 static int fsl_espi_probe(struct device *dev, struct resource *mem,
  unsigned int irq, unsigned int num_cs)
 {
@@ -682,6 +706,7 @@ static int fsl_espi_probe(struct device *dev, struct 
resource *mem,
master->auto_runtime_pm = true;
master->max_message_size = fsl_espi_max_message_size;
master->num_chipselect = num_cs;
+   master->mem_ops = _espi_mem_ops;
 
espi = spi_master_get_devdata(master);
spin_lock_init(>lock);
-- 
2.7.4



[PATCH] spi: fsl-espi: master->mem_ops is implemented in the controller

2018-08-17 Thread Chuanhua Han
The length of the transmitted data needs to be adjusted due to the maximum 
length limit for espi transmission messages

Signed-off-by: Chuanhua Han 
---
 drivers/spi/spi-fsl-espi.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 1d332e2..4724127 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* eSPI Controller registers */
 #define ESPI_SPMODE0x00/* eSPI mode register */
@@ -659,6 +660,29 @@ static void fsl_espi_init_regs(struct device *dev, bool 
initial)
fsl_espi_write_reg(espi, ESPI_SPMODE, SPMODE_INIT_VAL | SPMODE_ENABLE);
 }
 
+static int fsl_espi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
+   if (!mem || !op)
+   return -EINVAL;
+   op->data.nbytes = min3((unsigned long)op->data.nbytes,
+   spi_max_transfer_size(mem->spi),
+   spi_max_message_size(mem->spi) -
+   sizeof(op->cmd.opcode) -
+   op->addr.nbytes -
+   op->dummy.nbytes);
+   return 0;
+}
+
+static int fsl_espi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+   return -ENOTSUPP;
+}
+
+static const struct spi_controller_mem_ops fsl_espi_mem_ops = {
+   .adjust_op_size = fsl_espi_adjust_op_size,
+   .exec_op = fsl_espi_exec_op,
+};
+
 static int fsl_espi_probe(struct device *dev, struct resource *mem,
  unsigned int irq, unsigned int num_cs)
 {
@@ -682,6 +706,7 @@ static int fsl_espi_probe(struct device *dev, struct 
resource *mem,
master->auto_runtime_pm = true;
master->max_message_size = fsl_espi_max_message_size;
master->num_chipselect = num_cs;
+   master->mem_ops = _espi_mem_ops;
 
espi = spi_master_get_devdata(master);
spin_lock_init(>lock);
-- 
2.7.4



[PATCH] mtd: m25p80: consider max message size in m25p80_read when use the spi_mem_xx() API

2018-08-15 Thread Chuanhua Han
Consider a message size limit when calculating the maximum amount
of data that can be read.

Signed-off-by: Chuanhua Han 
---
 drivers/mtd/devices/m25p80.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index e84563d..87efa56 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -128,7 +128,12 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t 
from, size_t len,
op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
 
while (remaining) {
-   op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX;
+   op.data.nbytes = min3(remaining,
+   spi_max_transfer_size(flash->spimem->spi),
+   spi_max_message_size(flash->spimem->spi) -
+   sizeof(op.cmd.opcode) -
+   op.addr.nbytes -
+   op.dummy.nbytes);
ret = spi_mem_adjust_op_size(flash->spimem, );
if (ret)
return ret;
-- 
2.7.4



[PATCH] mtd: m25p80: consider max message size in m25p80_read when use the spi_mem_xx() API

2018-08-15 Thread Chuanhua Han
Consider a message size limit when calculating the maximum amount
of data that can be read.

Signed-off-by: Chuanhua Han 
---
 drivers/mtd/devices/m25p80.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index e84563d..87efa56 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -128,7 +128,12 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t 
from, size_t len,
op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
 
while (remaining) {
-   op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX;
+   op.data.nbytes = min3(remaining,
+   spi_max_transfer_size(flash->spimem->spi),
+   spi_max_message_size(flash->spimem->spi) -
+   sizeof(op.cmd.opcode) -
+   op.addr.nbytes -
+   op.dummy.nbytes);
ret = spi_mem_adjust_op_size(flash->spimem, );
if (ret)
return ret;
-- 
2.7.4