spi: new feature and fix for Marvell Orion driver
Subsystems (2)
cover spi: new feature and fix for Marvell Orion driver
From: Konstantin Porotchkin <[email protected]>
This patch set contains the following:
- support for switching CS for every transferred byte
- fix for the clock by enabling it for every call to spi_setup()
Konstantin Porotchkin (1):
dt-bindings: spi: add support for spi-1byte-cs
Marcin Wojtas (2):
spi: orion: enable clocks before spi_setup
spi: orion: enable support for switching CS every transferred byte
.../bindings/spi/spi-controller.yaml | 5 ++++ drivers/spi/spi-orion.c | 30 ++++++++++++++++++- drivers/spi/spi.c | 6 ++-- include/linux/spi/spi.h | 1 + 4 files changed, 39 insertions(+), 3 deletions(-)
Signature · 1 line
2.17.1
PATCH 1/3 spi: orion: enable clocks before spi_setup
From: Marcin Wojtas <[email protected]>
The spi-orion driver disables its clocks whenever it is not used. In usual case during boot (i.e. using SPI flash) it is not a problem, as the child device driver is present and probed along with spi_register_master() execution.
However in case the child device driver is not ready (e.g. when its type is module_spi_driver) the spi_setup() callback can be called after the spi-orion probe. It may happen, that as a result there will be an attempt to access controller's registers with the clocks disabled.
Prevent such situations and make sure the clocks are on, each time the spi_setup() is called.
--- drivers/spi/spi-orion.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/spi/spi-orion.c +10 -0
@@ -507,6 +507,16 @@ static int orion_spi_transfer_one(struct spi_master *master,static int orion_spi_setup (struct spi_device *spi) { +struct orion_spi *orion_spi =spi_master_get_devdata (spi->master); + +/* +* Make sure the clocks are enabled before +* configuring the SPI controller. +*/ +clk_prepare_enable (orion_spi->clk); +if (!IS_ERR (orion_spi->axi_clk)) +clk_prepare_enable (orion_spi->axi_clk); +return orion_spi_setup_transfer (spi,NULL ); }
Signature · 1 line
2.17.1
Mark Brown
maintainerRe: [PATCH 1/3] spi: orion: enable clocks before spi_setup
Quoted 5 lines · On Thu, Dec 17, 2020 at 01:27:06PM +0200, [email protected] wrote:
each time the
spi_setup()is called.Signed-off-by Marcin Wojtas <[email protected]>Reviewed-by Stefan Chulski <[email protected]>---
You've not provided a Signed-off-by for this so I can't do anything with it, please see Documentation/process/submitting-patches.rst for details on what this is and why it's important.
RE: [EXT] Re: [PATCH 1/3] spi: orion: enable clocks before spi_setup
Hello, Mark,
Quoted 9 lines
Quoted 5 lines
each time the
spi_setup()is called.Signed-off-by Marcin Wojtas <[email protected]>Reviewed-by Stefan Chulski <[email protected]>---
You've not provided a Signed-off-by for this so I can't do anything with it, please see
Documentation/process/submitting-patches.rstfor details on what this is and why it's important.
[KP] Sorry about it, will fix in the next version
Kosta
PATCH 2/3 spi: orion: enable support for switching CS every transferred byte
In reply to [email protected]From: Marcin Wojtas <[email protected]>
Some SPI devices, such as SLIC (Subscriber Line Interface Card) require toggling the CS every transferred byte. Enable such possibility by creating a new DT property and enabling SPI device mode update. Add according support in the spi-orion driver.
--- drivers/spi/spi-orion.c | 20 +++++++++++++++++++- drivers/spi/spi.c | 6 ++++-- include/linux/spi/spi.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-)
drivers/spi/spi-orion.c +19 -1
@@ -369,8 +369,15 @@ orion_spi_write_read_8bit(struct spi_device *spi, {void __iomem *tx_reg, *rx_reg, *int_reg;struct orion_spi *orion_spi; +bool cs_single_byte; + + cs_single_byte = spi->mode &SPI_1BYTE_CS ; orion_spi =spi_master_get_devdata (spi->master); + +if (cs_single_byte) +orion_spi_set_cs (spi,0 ); + tx_reg =spi_reg (orion_spi,ORION_SPI_DATA_OUT_REG ); rx_reg =spi_reg (orion_spi,ORION_SPI_DATA_IN_REG ); int_reg =spi_reg (orion_spi,ORION_SPI_INT_CAUSE_REG );
@@ -384,6 +391,11 @@ orion_spi_write_read_8bit(struct spi_device *spi,writel (0 , tx_reg);if (orion_spi_wait_till_ready (orion_spi) <0 ) { +if (cs_single_byte) { +orion_spi_set_cs (spi,1 ); +/* Satisfy some SLIC devices requirements */ +udelay (4 ); + }dev_err (&spi->dev,"TXS timed out\n" );return -1 ; }
@@ -391,6 +403,12 @@ orion_spi_write_read_8bit(struct spi_device *spi,if (rx_buf && *rx_buf) *(*rx_buf)++ =readl (rx_reg); +if (cs_single_byte) { +orion_spi_set_cs (spi,1 ); +/* Satisfy some SLIC devices requirements */ +udelay (4 ); + } +return 1 ; }
@@ -626,7 +644,7 @@ static int orion_spi_probe(struct platform_device *pdev) }/* we support all 4 SPI modes and LSB first option */ - master->mode_bits =SPI_CPHA |SPI_CPOL |SPI_LSB_FIRST ; + master->mode_bits =SPI_CPHA |SPI_CPOL |SPI_LSB_FIRST |SPI_1BYTE_CS ; master->set_cs = orion_spi_set_cs; master->transfer_one = orion_spi_transfer_one; master->num_chipselect =ORION_NUM_CHIPSELECTS ;
drivers/spi/spi.c +4 -2
@@ -1937,6 +1937,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, spi->mode |=SPI_LSB_FIRST ;if (of_property_read_bool (nc,"spi-cs-high" )) spi->mode |=SPI_CS_HIGH ; +if (of_find_property (nc,"spi-1byte-cs" ,NULL )) + spi->mode |=SPI_1BYTE_CS ;/* Device DUAL/QUAD mode */ if (!of_property_read_u32 (nc,"spi-tx-bus-width" , &value)) {
@@ -3419,15 +3421,15 @@ int spi_setup(struct spi_device *spi)spi_set_thread_rt (spi->controller); } -dev_dbg (&spi->dev,"setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n" , +dev_dbg (&spi->dev,"setup mode %d, %s%s%s%s%s%u bits/w, %u Hz max --> %d\n" , (int ) (spi->mode & (SPI_CPOL |SPI_CPHA )), (spi->mode &SPI_CS_HIGH ) ?"cs_high, " :"" , (spi->mode &SPI_LSB_FIRST ) ?"lsb, " :"" , (spi->mode &SPI_3WIRE ) ?"3wire, " :"" , (spi->mode &SPI_LOOP ) ?"loopback, " :"" , + (spi->mode &SPI_1BYTE_CS ) ?"single_cs_byte, " :"" , spi->bits_per_word, spi->max_speed_hz, status); -return status; }EXPORT_SYMBOL_GPL (spi_setup);
include/linux/spi/spi.h +1 -0
@@ -186,6 +186,7 @@ struct spi_device {#define SPI_TX_OCTAL 0x2000/* transmit with 8 wires */ #define SPI_RX_OCTAL 0x4000/* receive with 8 wires */ #define SPI_3WIRE_HIZ 0x8000/* high impedance turnaround */ +#define SPI_1BYTE_CS 0x10000/* toggle cs after each byte */ int irq;void *controller_state;void *controller_data;
Signature · 1 line
2.17.1
Re: [PATCH 2/3] spi: orion: enable support for switching CS every transferred byte
Hi Mark,
czw., 17 gru 2020 o 12:27 <[email protected]> napisał(a):
Quoted 75 lines
From: Marcin Wojtas <[email protected]>
Some SPI devices, such as SLIC (Subscriber Line Interface Card) require toggling the CS every transferred byte. Enable such possibility by creating a new DT property and enabling SPI device mode update. Add according support in the spi-orion driver.
Signed-off-by Marcin Wojtas <[email protected]>Signed-off-by Konstantin Porotchkin <[email protected]>--- drivers/spi/spi-orion.c | 20 +++++++++++++++++++- drivers/spi/spi.c | 6 ++++-- include/linux/spi/spi.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-)drivers/spi/spi-orion.c +19
-1@@ -369,8 +369,15 @@ orion_spi_write_read_8bit(struct spi_device *spi, {void __iomem *tx_reg, *rx_reg, *int_reg;struct orion_spi *orion_spi; +bool cs_single_byte; + + cs_single_byte = spi->mode &SPI_1BYTE_CS ; orion_spi =spi_master_get_devdata (spi->master); + +if (cs_single_byte) +orion_spi_set_cs (spi,0 ); + tx_reg =spi_reg (orion_spi,ORION_SPI_DATA_OUT_REG ); rx_reg =spi_reg (orion_spi,ORION_SPI_DATA_IN_REG ); int_reg =spi_reg (orion_spi,ORION_SPI_INT_CAUSE_REG );@@ -384,6 +391,11 @@ orion_spi_write_read_8bit(struct spi_device *spi,writel (0 , tx_reg);if (orion_spi_wait_till_ready (orion_spi) <0 ) { +if (cs_single_byte) { +orion_spi_set_cs (spi,1 ); +/* Satisfy some SLIC devices requirements */ +udelay (4 ); + }dev_err (&spi->dev,"TXS timed out\n" );return -1 ; }@@ -391,6 +403,12 @@ orion_spi_write_read_8bit(struct spi_device *spi,if (rx_buf && *rx_buf) *(*rx_buf)++ =readl (rx_reg); +if (cs_single_byte) { +orion_spi_set_cs (spi,1 ); +/* Satisfy some SLIC devices requirements */ +udelay (4 ); + } +return 1 ; }@@ -626,7 +644,7 @@ static int orion_spi_probe(struct platform_device *pdev) }/* we support all 4 SPI modes and LSB first option */ - master->mode_bits =SPI_CPHA |SPI_CPOL |SPI_LSB_FIRST ; + master->mode_bits =SPI_CPHA |SPI_CPOL |SPI_LSB_FIRST |SPI_1BYTE_CS ; master->set_cs = orion_spi_set_cs; master->transfer_one = orion_spi_transfer_one; master->num_chipselect =ORION_NUM_CHIPSELECTS ;drivers/spi/spi.c +0
-0
drivers/spi/spi.c static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, · line 1941
Quoted 5 lines
drivers/spi/spi.c +2
-0@@ -1937,6 +1937,8 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, spi->mode |=SPI_LSB_FIRST ;if (of_property_read_bool (nc,"spi-cs-high" )) spi->mode |=SPI_CS_HIGH ; +if (of_find_property (nc,"spi-1byte-cs" ,NULL )) + spi->mode |=SPI_1BYTE_CS ;
Regarding your comment from patch 3/3 that "spi-1byte-cs" should be replaced by handling based on the compatible string - do you mean dropping above parsing and updating SPI bus mode field with SPI_1BYTE_CS flag in the relevant SPI device driver?
Best regards,
Marcin
Quoted 36 lines
drivers/spi/spi.c +2
-2/* Device DUAL/QUAD mode */ if (!of_property_read_u32 (nc,"spi-tx-bus-width" , &value)) {@@ -3419,15 +3421,15 @@ int spi_setup(struct spi_device *spi)spi_set_thread_rt (spi->controller); } -dev_dbg (&spi->dev,"setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n" , +dev_dbg (&spi->dev,"setup mode %d, %s%s%s%s%s%u bits/w, %u Hz max --> %d\n" , (int ) (spi->mode & (SPI_CPOL |SPI_CPHA )), (spi->mode &SPI_CS_HIGH ) ?"cs_high, " :"" , (spi->mode &SPI_LSB_FIRST ) ?"lsb, " :"" , (spi->mode &SPI_3WIRE ) ?"3wire, " :"" , (spi->mode &SPI_LOOP ) ?"loopback, " :"" , + (spi->mode &SPI_1BYTE_CS ) ?"single_cs_byte, " :"" , spi->bits_per_word, spi->max_speed_hz, status); -return status; }EXPORT_SYMBOL_GPL (spi_setup);include/linux/spi/spi.h +1
-1@@ -186,6 +186,7 @@ struct spi_device {#define SPI_TX_OCTAL 0x2000/* transmit with 8 wires */ #define SPI_RX_OCTAL 0x4000/* receive with 8 wires */ #define SPI_3WIRE_HIZ 0x8000/* high impedance turnaround */ +#define SPI_1BYTE_CS 0x10000/* toggle cs after each byte */ int irq;void *controller_state;void *controller_data; --2.17.1
Mark Brown
maintainerRe: [PATCH 2/3] spi: orion: enable support for switching CS every transferred byte
Quoted 4 lines · Marcin Wojtas
Regarding your comment from patch 3/3 that "spi-1byte-cs" should be replaced by handling based on the compatible string - do you mean dropping above parsing and updating SPI bus mode field with
SPI_1BYTE_CSflag in the relevant SPI device driver?
There's more to it than that but like I said in reply to the patch AFAICT we already support this.
Please delete unneeded context from mails when replying. Doing this makes it much easier to find your reply in the message, helping ensure it won't be missed by people scrolling through the irrelevant quoted material.
Re: [PATCH 2/3] spi: orion: enable support for switching CS every transferred byte
czw., 17 gru 2020 o 15:21 Mark Brown <[email protected]> napisał(a):
Quoted 8 lines · Marcin Wojtas
Quoted 5 lines
Regarding your comment from patch 3/3 that "spi-1byte-cs" should be replaced by handling based on the compatible string - do you mean dropping above parsing and updating SPI bus mode field with
SPI_1BYTE_CSflag in the relevant SPI device driver?
Quoted 7 lines
There's more to it than that but like I said in reply to the patch AFAICT we already support this.
Please delete unneeded context from mails when replying. Doing this makes it much easier to find your reply in the message, helping ensure it won't be missed by people scrolling through the irrelevant quoted material.
Sure, thanks.
Marcin
Mark Brown
maintainerRe: [PATCH 2/3] spi: orion: enable support for switching CS every transferred byte
In reply to [email protected]Quoted 4 lines · On Thu, Dec 17, 2020 at 01:27:07PM +0200, [email protected] wrote:
Some SPI devices, such as SLIC (Subscriber Line Interface Card) require toggling the CS every transferred byte. Enable such possibility by creating a new DT property and enabling SPI device mode update. Add according support in the spi-orion driver.
I'm pretty sure we already support this - if the client driver sets the word length to 8 bits then SPI_CS_WORD ought to do what your change describes as far as I can see. What's missing there?
Quoted 5 lines
--- drivers/spi/spi-orion.c | 20 +++++++++++++++++++- drivers/spi/spi.c | 6 ++++-- include/linux/spi/spi.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-)
This is introducing something into the core and adding a user of it, it should be two separate patches.
Re: [PATCH 2/3] spi: orion: enable support for switching CS every transferred byte
czw., 17 gru 2020 o 15:15 Mark Brown <[email protected]> napisał(a):
Quoted 11 lines · On Thu, Dec 17, 2020 at 01:27:07PM +0200, [email protected] wrote:
Quoted 5 lines
Some SPI devices, such as SLIC (Subscriber Line Interface Card) require toggling the CS every transferred byte. Enable such possibility by creating a new DT property and enabling SPI device mode update. Add according support in the spi-orion driver.
I'm pretty sure we already support this - if the client driver sets the word length to 8 bits then
SPI_CS_WORDought to do what your change describes as far as I can see. What's missing there?
Sure, that needs to be confirmed on HW, but it looks like the required functionality can be handled with SPI_CS_WORD.
As for the justification, the new flag was developed on a kernel revision without it and applied easily, hence the possible oversight.
Quoted 9 lines
Quoted 6 lines
--- drivers/spi/spi-orion.c | 20 +++++++++++++++++++- drivers/spi/spi.c | 6 ++++-- include/linux/spi/spi.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-)This is introducing something into the core and adding a user of it, it should be two separate patches.
Agree.
Thanks,
Marcin
PATCH 3/3 dt-bindings: spi: add support for spi-1byte-cs
In reply to [email protected]From: Konstantin Porotchkin <[email protected]>
add support for enable switching CS every transferred byte
--- Documentation/devicetree/bindings/spi/spi-controller.yaml | 5 +++++ 1 file changed, 5 insertions(+)
Documentation/devicetree/bindings/spi/spi-controller.yaml +5 -0
@@ -171,6 +171,11 @@ patternProperties: description: Delay, in microseconds, after a write transfer. + spi-1byte-cs: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires toggling the CS for every 1 byte of data + required: - compatible - reg
Signature · 1 line
2.17.1
Mark Brown
maintainerRe: [PATCH 3/3] dt-bindings: spi: add support for spi-1byte-cs
Documentation/devicetree/bindings/spi/spi-controller.yaml patternProperties: · line 177
Quoted 4 lines · On Thu, Dec 17, 2020 at 01:27:08PM +0200, [email protected] wrote:
Documentation/devicetree/bindings/spi/spi-controller.yaml +4
-0+ spi-1byte-cs: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device requires toggling the CS for every 1 byte of data
This is absolutely not something that should be in the DT, if the device requires this we know that simply from the compatible string.