From: Barry Song <hidden> Date: 2014-09-02 09:01:00
From: Barry Song <redacted>
this patchset fixes the cs_gpio, cmd_mode, make DMA optional etc.
Qipan Li (8):
spi: sirf: correct spi gpio and hardware chipselect behaviour
spi: sirf: request and free cs gpio in setup and cleanup callbacks
spi: sirf: enable RX_IO_DMA_INT interrupt
spi: sirf: fix 'cmd_transfer' function typos
spi: sirf: add fifo reset/start for cmd transfer
spi: sirf: set default spi frequency if it is not set
spi: sirf: cleanup the indentation of marcos
spi: sirf: make DMA transfer mode optional
drivers/spi/Kconfig | 10 ++++
drivers/spi/spi-sirf.c | 148 ++++++++++++++++++++++++++-----------------------
2 files changed, 89 insertions(+), 69 deletions(-)
--
2.1.0
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
From: Barry Song <hidden> Date: 2014-09-02 09:01:01
From: Qipan Li <redacted>
the old codes check the cs-gpios, if the gpio number is 0 like:
<&gpio, 0, 0>, the driver will use the only hardware chipselect.
this is wrong because of_spi_register_master() can read property
cs-gpios from device node and set the spi master's cs number and
gpio cs automatically based on whether the cs-gpios is valid.
this patch fixes the beviour of CSR spi driver and move to a core
level supported way.
Signed-off-by: Qipan Li <redacted>
Signed-off-by: Barry Song <redacted>
---
drivers/spi/spi-sirf.c | 86 +++++++++++++++++++-------------------------------
1 file changed, 33 insertions(+), 53 deletions(-)
@@ -638,19 +644,10 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)structsirfsoc_spi*sspi;structspi_master*master;structresource*mem_res;-intnum_cs,cs_gpio,irq;-inti;-intret;--ret=of_property_read_u32(pdev->dev.of_node,-"sirf,spi-num-chipselects",&num_cs);-if(ret<0){-dev_err(&pdev->dev,"Unable to get chip select number\n");-gotoerr_cs;-}+intirq;+inti,ret;-master=spi_alloc_master(&pdev->dev,-sizeof(*sspi)+sizeof(int)*num_cs);+master=spi_alloc_master(&pdev->dev,sizeof(*sspi));if(!master){dev_err(&pdev->dev,"Unable to allocate SPI master\n");return-ENOMEM;
@@ -658,32 +655,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)platform_set_drvdata(pdev,master);sspi=spi_master_get_devdata(master);-master->num_chipselect=num_cs;--for(i=0;i<master->num_chipselect;i++){-cs_gpio=of_get_named_gpio(pdev->dev.of_node,"cs-gpios",i);-if(cs_gpio<0){-dev_err(&pdev->dev,"can't get cs gpio from DT\n");-ret=-ENODEV;-gotofree_master;-}--sspi->chipselect[i]=cs_gpio;-if(cs_gpio==0)-continue;/* use cs from spi controller */--ret=gpio_request(cs_gpio,DRIVER_NAME);-if(ret){-while(i>0){-i--;-if(sspi->chipselect[i]>0)-gpio_free(sspi->chipselect[i]);-}-dev_err(&pdev->dev,"fail to request cs gpios\n");-gotofree_master;-}-}-mem_res=platform_get_resource(pdev,IORESOURCE_MEM,0);sspi->base=devm_ioremap_resource(&pdev->dev,mem_res);if(IS_ERR(sspi->base)){
@@ -753,7 +724,21 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)ret=spi_bitbang_start(&sspi->bitbang);if(ret)gotofree_dummypage;-+for(i=0;master->cs_gpios&&i<master->num_chipselect;i++){+if(master->cs_gpios[i]==-ENOENT)+continue;+if(!gpio_is_valid(master->cs_gpios[i])){+dev_err(&pdev->dev,"no valid gpio\n");+ret=-EINVAL;+gotofree_dummypage;+}+ret=devm_gpio_request(&pdev->dev,+master->cs_gpios[i],DRIVER_NAME);+if(ret){+dev_err(&pdev->dev,"failed to request gpio\n");+gotofree_dummypage;+}+}dev_info(&pdev->dev,"registerred, bus number = %d\n",master->bus_num);return0;
@@ -776,16 +761,11 @@ static int spi_sirfsoc_remove(struct platform_device *pdev){structspi_master*master;structsirfsoc_spi*sspi;-inti;master=platform_get_drvdata(pdev);sspi=spi_master_get_devdata(master);spi_bitbang_stop(&sspi->bitbang);-for(i=0;i<master->num_chipselect;i++){-if(sspi->chipselect[i]>0)-gpio_free(sspi->chipselect[i]);-}kfree(sspi->dummypage);clk_disable_unprepare(sspi->clk);clk_put(sspi->clk);
--
2.1.0
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
On Tue, Sep 02, 2014 at 05:01:01PM +0800, Barry Song wrote:
From: Qipan Li <redacted>
the old codes check the cs-gpios, if the gpio number is 0 like:
<&gpio, 0, 0>, the driver will use the only hardware chipselect.
From: Barry Song <hidden> Date: 2014-09-02 09:01:02
From: Qipan Li <redacted>
move spi controller's gpio request work out from probe() to spi device
register stage, so after spi device register spi controller can deactive
device's gpio chipselect. old code can't do it because gpio request has
not be done until device register is finised in spi_bitbang_start.
and add cleanup function to free CS gpio.
Signed-off-by: Qipan Li <redacted>
Signed-off-by: Barry Song <redacted>
---
drivers/spi/spi-sirf.c | 58 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 38 insertions(+), 20 deletions(-)
@@ -634,9 +634,41 @@ static int spi_sirfsoc_setup(struct spi_device *spi)if(spi->cs_gpio==-ENOENT)sspi->hw_cs=true;-else+else{sspi->hw_cs=false;-returnspi_sirfsoc_setup_transfer(spi,NULL);+if(!spi_get_ctldata(spi)){+void*cs=kmalloc(sizeof(int),GFP_KERNEL);+if(!cs){+ret=-ENOMEM;+gotoexit;+}+ret=gpio_is_valid(spi->cs_gpio);+if(!ret){+dev_err(&spi->dev,"no valid gpio\n");+ret=-ENOENT;+gotoexit;+}+ret=gpio_request(spi->cs_gpio,DRIVER_NAME);+if(ret){+dev_err(&spi->dev,"failed to request gpio\n");+gotoexit;+}+spi_set_ctldata(spi,cs);+}+}+writel(readl(sspi->base+SIRFSOC_SPI_CTRL)|SIRFSOC_SPI_CS_IO_MODE,+sspi->base+SIRFSOC_SPI_CTRL);+spi_sirfsoc_chipselect(spi,BITBANG_CS_INACTIVE);+exit:+returnret;+}++staticvoidspi_sirfsoc_cleanup(structspi_device*spi)+{+if(spi_get_ctldata(spi)){+gpio_free(spi->cs_gpio);+kfree(spi_get_ctldata(spi));+}}staticintspi_sirfsoc_probe(structplatform_device*pdev)
@@ -645,7 +677,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)structspi_master*master;structresource*mem_res;intirq;-inti,ret;+intret;master=spi_alloc_master(&pdev->dev,sizeof(*sspi));if(!master){
@@ -677,6 +709,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)sspi->bitbang.setup_transfer=spi_sirfsoc_setup_transfer;sspi->bitbang.txrx_bufs=spi_sirfsoc_transfer;sspi->bitbang.master->setup=spi_sirfsoc_setup;+sspi->bitbang.master->cleanup=spi_sirfsoc_cleanup;master->bus_num=pdev->id;master->mode_bits=SPI_CPOL|SPI_CPHA|SPI_LSB_FIRST|SPI_CS_HIGH;master->bits_per_word_mask=SPI_BPW_MASK(8)|SPI_BPW_MASK(12)|
@@ -723,22 +756,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)ret=spi_bitbang_start(&sspi->bitbang);if(ret)-gotofree_dummypage;-for(i=0;master->cs_gpios&&i<master->num_chipselect;i++){-if(master->cs_gpios[i]==-ENOENT)-continue;-if(!gpio_is_valid(master->cs_gpios[i])){-dev_err(&pdev->dev,"no valid gpio\n");-ret=-EINVAL;-gotofree_dummypage;-}-ret=devm_gpio_request(&pdev->dev,-master->cs_gpios[i],DRIVER_NAME);-if(ret){-dev_err(&pdev->dev,"failed to request gpio\n");-gotofree_dummypage;-}-}+gotofree_clk;dev_info(&pdev->dev,"registerred, bus number = %d\n",master->bus_num);return0;
--
2.1.0
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
On Tue, Sep 02, 2014 at 05:01:02PM +0800, Barry Song wrote:
From: Qipan Li <redacted>
move spi controller's gpio request work out from probe() to spi device
register stage, so after spi device register spi controller can deactive
device's gpio chipselect. old code can't do it because gpio request has
not be done until device register is finised in spi_bitbang_start.
and add cleanup function to free CS gpio.
I'm not quite sure I understand the rationale here - as far as I can
tell this is making the GPIO request happen later not earlier so it's
not clear to me what the problem this is fixing in the existing code.
If the goal is to move the request around in the probe function why not
just move the existing code earlier in probe()?
This also won't interact well with deferred probe, though a better
solution here would be some kind of deferred device registration and
typically the link ordering will mean it won't be an issue when
everything is built in.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140904/2453b10c/attachment.sig>
2014-09-05 3:19 GMT+08:00 Mark Brown [off-list ref]:
On Tue, Sep 02, 2014 at 05:01:02PM +0800, Barry Song wrote:
quoted
From: Qipan Li <redacted>
move spi controller's gpio request work out from probe() to spi device
register stage, so after spi device register spi controller can deactive
device's gpio chipselect. old code can't do it because gpio request has
not be done until device register is finised in spi_bitbang_start.
and add cleanup function to free CS gpio.
I'm not quite sure I understand the rationale here - as far as I can
tell this is making the GPIO request happen later not earlier so it's
not clear to me what the problem this is fixing in the existing code.
If the goal is to move the request around in the probe function why not
just move the existing code earlier in probe()?
This also won't interact well with deferred probe, though a better
solution here would be some kind of deferred device registration and
typically the link ordering will mean it won't be an issue when
everything is built in.
As GPIO cs can be high or low validate and the used GPIO pin with
default value may high or low,
it is need do spi device's chipselect invalidation work in spi_setup,
the patch purpose for it.
master->cs_gpios only assigned after spi_bitbang_start and the
function call spi_setup,
if keep the existing code there will result gpio usage before gpio request.
just move gpio request code in spi_sirfsoc_setup before gpio use.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140905/4af903d9/attachment.sig>
On Fri, Sep 05, 2014 at 11:34:57AM +0800, swingboard wrote:
2014-09-05 3:19 GMT+08:00 Mark Brown [off-list ref]:
quoted
I'm not quite sure I understand the rationale here - as far as I can
tell this is making the GPIO request happen later not earlier so it's
not clear to me what the problem this is fixing in the existing code.
If the goal is to move the request around in the probe function why not
just move the existing code earlier in probe()?
As GPIO cs can be high or low validate and the used GPIO pin with
default value may high or low,
it is need do spi device's chipselect invalidation work in spi_setup,
the patch purpose for it.
master->cs_gpios only assigned after spi_bitbang_start and the
function call spi_setup,
if keep the existing code there will result gpio usage before gpio request.
just move gpio request code in spi_sirfsoc_setup before gpio use.
From: Barry Song <hidden> Date: 2014-09-07 00:50:19
On 14-9-6 ??9:57, "Mark Brown" [off-list ref] wrote:
On Fri, Sep 05, 2014 at 11:34:57AM +0800, swingboard wrote:
quoted
2014-09-05 3:19 GMT+08:00 Mark Brown [off-list ref]:
quoted
quoted
I'm not quite sure I understand the rationale here - as far as I can
tell this is making the GPIO request happen later not earlier so it's
not clear to me what the problem this is fixing in the existing code.
If the goal is to move the request around in the probe function why
not
quoted
just move the existing code earlier in probe()?
quoted
As GPIO cs can be high or low validate and the used GPIO pin with
default value may high or low,
it is need do spi device's chipselect invalidation work in spi_setup,
the patch purpose for it.
master->cs_gpios only assigned after spi_bitbang_start and the
function call spi_setup,
if keep the existing code there will result gpio usage before gpio
request.
just move gpio request code in spi_sirfsoc_setup before gpio use.
I'm still having a hard time understanding why pulling the code earlier
in probe isn't a better fix here.
Gpio is unknown before spi_bitbang_start(). Everything is done in the big
routine spi_bitbang_start(). It includes:
Get cs_gpios, extend spi devices, and setup cs to de-active.
-barry
From: Barry Song <hidden> Date: 2015-04-28 03:36:51
quoted
quoted
quoted
I'm not quite sure I understand the rationale here - as far as I can
tell this is making the GPIO request happen later not earlier so it's
not clear to me what the problem this is fixing in the existing code.
If the goal is to move the request around in the probe function why
not
quoted
just move the existing code earlier in probe()?
quoted
As GPIO cs can be high or low validate and the used GPIO pin with
default value may high or low,
it is need do spi device's chipselect invalidation work in spi_setup,
the patch purpose for it.
master->cs_gpios only assigned after spi_bitbang_start and the
function call spi_setup,
if keep the existing code there will result gpio usage before gpio
request.
just move gpio request code in spi_sirfsoc_setup before gpio use.
I'm still having a hard time understanding why pulling the code earlier
in probe isn't a better fix here.
Gpio is unknown before spi_bitbang_start(). Everything is done in the big
routine spi_bitbang_start(). It includes:
Get cs_gpios, extend spi devices, and setup cs to de-active.
Mark, i'd like to re-call this patch. "pulling the code earlier in
probe" is impossible based on current SPI core codes. because before
spi master is registerred,
cs_gpios is NULL. but once it is registered, cs_gpios are assigned in
spi_register_master:
1446 static int of_spi_register_master(struct spi_master *master)
1447 {
1448 int nb, i, *cs;
1449 struct device_node *np = master->dev.of_node;
1450
1451 if (!np)
1452 return 0;
1453
1454 nb = of_gpio_named_count(np, "cs-gpios");
1455 master->num_chipselect = max_t(int, nb, master->num_chipselect);
1456
1457 /* Return error only for an incorrectly formed cs-gpios property */
1458 if (nb == 0 || nb == -ENOENT)
1459 return 0;
1460 else if (nb < 0)
1461 return nb;
1462
1463 cs = devm_kzalloc(&master->dev,
1464 sizeof(int) * master->num_chipselect,
1465 GFP_KERNEL);
1466 master->cs_gpios = cs;
1467
1468 if (!master->cs_gpios)
1469 return -ENOMEM;
1470
1471 for (i = 0; i < master->num_chipselect; i++)
1472 cs[i] = -ENOENT;
1473
1474 for (i = 0; i < nb; i++)
1475 cs[i] = of_get_named_gpio(np, "cs-gpios", i);
we can get cs_gpios earlier in probe(), but this will definitely
reduplicated with SPI core.
and in the setup() stage, we need the CS to be de-active, so we need
the cs_gpio. that means we have to move gpio_request codes earlier,
but the current SPI core stop us from get ting gpio earlier than
spi_bitbang_start() being called. it looks the setup() itself is the
best place to get the cs.
drivers/spi/spi-clps711x.c is doing cs_gpios earlier in probe(), but
it is a non-OF driver, which will not have of_spi_register_master() to
set cs_gpios.
-barry
On Tue, Apr 28, 2015 at 11:36:51AM +0800, Barry Song wrote:
Mark, i'd like to re-call this patch. "pulling the code earlier in
probe" is impossible based on current SPI core codes. because before
spi master is registerred,
cs_gpios is NULL. but once it is registered, cs_gpios are assigned in
spi_register_master:
From: Barry Song <hidden> Date: 2014-09-02 09:01:03
From: Qipan Li <redacted>
in spi interrupt handler, we need check RX_IO_DMA status to ensure
rx fifo have received the specify count data.
if not set, the while statement in spi isr function will keep loop,
at last, make the kernel hang.
Signed-off-by: Qipan Li <redacted>
Signed-off-by: Barry Song <redacted>
---
drivers/spi/spi-sirf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--
2.1.0
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
...the change is actually just unmasking a bit in the interrupt mask
register and doesn't add anything to the interrupt handler? Looking at
the code it seems that the actual issue is that the mask register causes
the interrupt handler not to see the mask bit since the mask not only
disables the interrupt but also causes the bit not to report in the
status register.
That makes sense so I've applied this but please try to be clear about
things like this, it's hard to review code where the changelog doesn't
clearly match the code.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140904/9698c51a/attachment.sig>
From: Barry Song <hidden> Date: 2014-09-02 09:01:04
From: Qipan Li <redacted>
unify 'cmd_transfer' like 'pio_transfer' and 'dma_transfer' as void
function, and also change left_rx_word according to transfer result.
Signed-off-by: Qipan Li <redacted>
Signed-off-by: Barry Song <redacted>
---
drivers/spi/spi-sirf.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
@@ -325,10 +325,9 @@ static int spi_sirfsoc_cmd_transfer(struct spi_device *spi,sspi->base+SIRFSOC_SPI_TX_RX_EN);if(wait_for_completion_timeout(&sspi->tx_done,timeout)==0){dev_err(&spi->dev,"cmd transfer timeout\n");-return0;+return;}--returnt->len;+sspi->left_rx_word-=t->len;}staticvoidspi_sirfsoc_dma_transfer(structspi_device*spi,
--
2.1.0
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.
On Tue, Sep 02, 2014 at 05:01:04PM +0800, Barry Song wrote:
From: Qipan Li <redacted>
unify 'cmd_transfer' like 'pio_transfer' and 'dma_transfer' as void
function, and also change left_rx_word according to transfer result.