Skip to contentSkip to conversation

spi/imx: Fix spi-imx when the hardware SPI chipselects are used

PATCH Superseded Fabio Estevam 4 participants 6 messages Sep 15, 2011

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 spi/imx: Fix spi-imx when the hardware SPI chipselects are used

commit 22a85e4cd51 (spi/imx: add device tree probe support) broke spi-imx usage when the SPI chipselect is the one internal to the controller.

On a mx31pdk board the following error is seen:

Registering mxc_nand as whole device

------------[ cut here ]------------
WARNING: at drivers/gpio/gpiolib.c:101 gpio_ensure_requested+0x4c/0xf4()
autorequest GPIO-0
Modules linked in:
[<c0014410>] (unwind_backtrace+0x0/0xf4) from [<c0025754>] (warn_slowpath_common+0x4c/0x64)
[<c0025754>] (warn_slowpath_common+0x4c/0x64) from [<c0025800>] (warn_slowpath_fmt+0x30/0x40)
[<c0025800>] (warn_slowpath_fmt+0x30/0x40) from [<c0198688>] (gpio_ensure_requested+0x4c/0xf4)
[<c0198688>] (gpio_ensure_requested+0x4c/0xf4) from [<c01988c8>] (gpio_direction_output+0xa0/0x138)
[<c01988c8>] (gpio_direction_output+0xa0/0x138) from [<c01ed198>] (spi_imx_setup+0x38/0x4c)
[<c01ed198>] (spi_imx_setup+0x38/0x4c) from [<c01eb5d0>] (spi_setup+0x38/0x50)
[<c01eb5d0>] (spi_setup+0x38/0x50) from [<c01eb85c>] (spi_add_device+0x94/0x124)
[<c01eb85c>] (spi_add_device+0x94/0x124) from [<c01eb960>] (spi_new_device+0x74/0xac)
[<c01eb960>] (spi_new_device+0x74/0xac) from [<c01eb9b8>] (spi_match_master_to_boardinfo+0x20/0x40)
[<c01eb9b8>] (spi_match_master_to_boardinfo+0x20/0x40) from [<c01eba88>] (spi_register_master+0xb0/0x104)
[<c01eba88>] (spi_register_master+0xb0/0x104) from [<c01ec0b4>] (spi_bitbang_start+0x104/0x17c)
[<c01ec0b4>] (spi_bitbang_start+0x104/0x17c) from [<c02c2c4c>] (spi_imx_probe+0x2fc/0x404)
[<c02c2c4c>] (spi_imx_probe+0x2fc/0x404) from [<c01c2498>] (platform_drv_probe+0x18/0x1c)
[<c01c2498>] (platform_drv_probe+0x18/0x1c) from [<c01c1058>] (driver_probe_device+0x78/0x174)
[<c01c1058>] (driver_probe_device+0x78/0x174) from [<c01c11e0>] (__driver_attach+0x8c/0x90)
[<c01c11e0>] (__driver_attach+0x8c/0x90) from [<c01c0860>] (bus_for_each_dev+0x60/0x8c)
[<c01c0860>] (bus_for_each_dev+0x60/0x8c) from [<c01c0088>] (bus_add_driver+0xa0/0x288)
[<c01c0088>] (bus_add_driver+0xa0/0x288) from [<c01c179c>] (driver_register+0x78/0x18c)
[<c01c179c>] (driver_register+0x78/0x18c) from [<c0008490>] (do_one_initcall+0x34/0x178)
[<c0008490>] (do_one_initcall+0x34/0x178) from [<c03a5204>] (kernel_init+0x74/0x118)
[<c03a5204>] (kernel_init+0x74/0x118) from [<c000f65c>] (kernel_thread_exit+0x0/0x8)
---[ end trace 759f924b30fd5a44 ]---

Fix this issue by using the original chip select logic and make spi-imx to work again.

Tested on a mx31pdk that uses the hardware SPI chipselect pins and also on a mx27pdk that uses GPIO as SPI chipselect.

---
Changes since v1:
- Fix the logic for the internal chip select case and keep the usage of of_get_named_gpio for getting the cs_gpio

 drivers/spi/spi-imx.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/spi/spi-imx.c +4 -2
index 8ac6542..d917fa3 100644
@@ -784,11 +784,13 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 
 	for (i = 0; i < master->num_chipselect; i++) {
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
-		if (cs_gpio < 0)
+		if (cs_gpio < 0) {
 			cs_gpio = mxc_platform_info->chipselect[i];
+			spi_imx->chipselect[i] = cs_gpio;
+		}
 		if (cs_gpio < 0)
 			continue;
-		spi_imx->chipselect[i] = cs_gpio;
+
 		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
 		if (ret) {
 			while (i > 0) {
Signature · 1 line
1.7.1
#1 lore raw

PATCH v2 1/1 spi/imx: Fix spi-imx when the hardware SPI chipselects are used

Hello Fabio,

Quoted 10 lines · Fabio Estevam
drivers/spi/spi-imx.c +1 -1
index 8ac6542..d917fa3 100644
@@ -784,11 +784,13 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 
 	for (i = 0; i < master->num_chipselect; i++) {
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
-		if (cs_gpio < 0)
+		if (cs_gpio < 0) {

drivers/spi/spi-imx.c static int __devinit spi_imx_probe(struct platform_device *pdev) · line 796

Quoted 10 lines
drivers/spi/spi-imx.c +3 -1
 			cs_gpio = mxc_platform_info->chipselect[i];
+			spi_imx->chipselect[i] = cs_gpio;
+		}
 		if (cs_gpio < 0)
 			continue;
-		spi_imx->chipselect[i] = cs_gpio;
+
 		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
 		if (ret) {
 			while (i > 0) {

I think this is wrong. In case of_get_named_gpio returns a gpio to use spi_imx->chipselect[i] is unassigned.

I think you just need

drivers/spi/spi-imx.c +3 -1
index 8ac6542..fa594d6 100644
@@ -786,9 +786,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
 		if (cs_gpio < 0)
 			cs_gpio = mxc_platform_info->chipselect[i];
+
+		spi_imx->chipselect[i] = cs_gpio;
 		if (cs_gpio < 0)
 			continue;
-		spi_imx->chipselect[i] = cs_gpio;
+
 		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
 		if (ret) {
 			while (i > 0) {
Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#2 lore raw

PATCH v2 1/1 spi/imx: Fix spi-imx when the hardware SPI chipselects are used

Hello again,

Quoted 7 lines · Uwe Kleine-K?nig
drivers/spi/spi-imx.c +0 -0
index 8ac6542..fa594d6 100644
@@ -786,9 +786,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
 		if (cs_gpio < 0)

drivers/spi/spi-imx.c static int __devinit spi_imx_probe(struct platform_device *pdev) · line 796

Quoted 10 lines
drivers/spi/spi-imx.c +3 -1
 			cs_gpio = mxc_platform_info->chipselect[i];
+
+		spi_imx->chipselect[i] = cs_gpio;
 		if (cs_gpio < 0)
 			continue;
-		spi_imx->chipselect[i] = cs_gpio;
+
 		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
 		if (ret) {
 			while (i > 0) {

Having said that I wonder how to specify to use an internal chipselect via DT?

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#3 lore raw

PATCH v2 1/1 spi/imx: Fix spi-imx when the hardware SPI chipselects are used

Quoted 14 lines · Uwe Kleine-K?nig

Hello again,

Quoted 11 lines · Uwe Kleine-K?nig
drivers/spi/spi-imx.c +2 -0
index 8ac6542..fa594d6 100644
@@ -786,9 +786,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
 		if (cs_gpio < 0)
 			cs_gpio = mxc_platform_info->chipselect[i];
+
+		spi_imx->chipselect[i] = cs_gpio;
 		if (cs_gpio < 0)
Quoted 8 lines

drivers/spi/spi-imx.c static int __devinit spi_imx_probe(struct platform_device *pdev) · line 796

Quoted 6 lines
drivers/spi/spi-imx.c +1 -1
 			continue;
-		spi_imx->chipselect[i] = cs_gpio;
+
 		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
 		if (ret) {
 			while (i > 0) {

Having said that I wonder how to specify to use an internal chipselect via DT?

It would be done with a blank gpio specifier which is supported by the GPIO binding.

g.

#4 lore raw

PATCH v2 1/1 spi/imx: Fix spi-imx when the hardware SPI chipselects are used

In reply to Fabio Estevam
Quoted 54 lines · Fabio Estevam

commit 22a85e4cd51 (spi/imx: add device tree probe support) broke spi-imx usage when the SPI chipselect is the one internal to the controller.

On a mx31pdk board the following error is seen:

Registering mxc_nand as whole device

------------[ cut here ]------------
WARNING: at drivers/gpio/gpiolib.c:101 gpio_ensure_requested+0x4c/0xf4()
autorequest GPIO-0
Modules linked in:
[<c0014410>] (unwind_backtrace+0x0/0xf4) from [<c0025754>] (warn_slowpath_common+0x4c/0x64)
[<c0025754>] (warn_slowpath_common+0x4c/0x64) from [<c0025800>] (warn_slowpath_fmt+0x30/0x40)
[<c0025800>] (warn_slowpath_fmt+0x30/0x40) from [<c0198688>] (gpio_ensure_requested+0x4c/0xf4)
[<c0198688>] (gpio_ensure_requested+0x4c/0xf4) from [<c01988c8>] (gpio_direction_output+0xa0/0x138)
[<c01988c8>] (gpio_direction_output+0xa0/0x138) from [<c01ed198>] (spi_imx_setup+0x38/0x4c)
[<c01ed198>] (spi_imx_setup+0x38/0x4c) from [<c01eb5d0>] (spi_setup+0x38/0x50)
[<c01eb5d0>] (spi_setup+0x38/0x50) from [<c01eb85c>] (spi_add_device+0x94/0x124)
[<c01eb85c>] (spi_add_device+0x94/0x124) from [<c01eb960>] (spi_new_device+0x74/0xac)
[<c01eb960>] (spi_new_device+0x74/0xac) from [<c01eb9b8>] (spi_match_master_to_boardinfo+0x20/0x40)
[<c01eb9b8>] (spi_match_master_to_boardinfo+0x20/0x40) from [<c01eba88>] (spi_register_master+0xb0/0x104)
[<c01eba88>] (spi_register_master+0xb0/0x104) from [<c01ec0b4>] (spi_bitbang_start+0x104/0x17c)
[<c01ec0b4>] (spi_bitbang_start+0x104/0x17c) from [<c02c2c4c>] (spi_imx_probe+0x2fc/0x404)
[<c02c2c4c>] (spi_imx_probe+0x2fc/0x404) from [<c01c2498>] (platform_drv_probe+0x18/0x1c)
[<c01c2498>] (platform_drv_probe+0x18/0x1c) from [<c01c1058>] (driver_probe_device+0x78/0x174)
[<c01c1058>] (driver_probe_device+0x78/0x174) from [<c01c11e0>] (__driver_attach+0x8c/0x90)
[<c01c11e0>] (__driver_attach+0x8c/0x90) from [<c01c0860>] (bus_for_each_dev+0x60/0x8c)
[<c01c0860>] (bus_for_each_dev+0x60/0x8c) from [<c01c0088>] (bus_add_driver+0xa0/0x288)
[<c01c0088>] (bus_add_driver+0xa0/0x288) from [<c01c179c>] (driver_register+0x78/0x18c)
[<c01c179c>] (driver_register+0x78/0x18c) from [<c0008490>] (do_one_initcall+0x34/0x178)
[<c0008490>] (do_one_initcall+0x34/0x178) from [<c03a5204>] (kernel_init+0x74/0x118)
[<c03a5204>] (kernel_init+0x74/0x118) from [<c000f65c>] (kernel_thread_exit+0x0/0x8)
---[ end trace 759f924b30fd5a44 ]---

Fix this issue by using the original chip select logic and make spi-imx to work again.

Tested on a mx31pdk that uses the hardware SPI chipselect pins and also on a mx27pdk that uses GPIO as SPI chipselect.

---
Changes since v1:
- Fix the logic for the internal chip select case and keep the usage of of_get_named_gpio for getting the cs_gpio

 drivers/spi/spi-imx.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/spi/spi-imx.c +0 -0
index 8ac6542..d917fa3 100644
@@ -784,11 +784,13 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
 
 	for (i = 0; i < master->num_chipselect; i++) {

drivers/spi/spi-imx.c static int __devinit spi_imx_probe(struct platform_device *pdev) · line 793

Quoted 10 lines
drivers/spi/spi-imx.c +4 -2
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
-		if (cs_gpio < 0)
+		if (cs_gpio < 0) {
 			cs_gpio = mxc_platform_info->chipselect[i];
+			spi_imx->chipselect[i] = cs_gpio;
+		}
 		if (cs_gpio < 0)
 			continue;
-		spi_imx->chipselect[i] = cs_gpio;
+

It looks like the removal of this line will break DT users. Perhaps the spi_imx->chipselect[i] line should just be moved before the 'if (cp_gpio < 0)' line.

g.

Quoted 7 lines
drivers/spi/spi-imx.c +0 -0
 		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
 		if (ret) {
 			while (i > 0) {
Signature · 1 line
1.7.1
reviewer
#5 lore raw

PATCH v2 1/1 spi/imx: Fix spi-imx when the hardware SPI chipselects are used

Grant,

On Thu, Sep 15, 2011 at 6:01 PM, Grant Likely <[email protected]> wrote:
...

Quoted 3 lines

It looks like the removal of this line will break DT users. ?Perhaps the spi_imx->chipselect[i] line should just be moved before the 'if (cp_gpio < 0)' line.

Yes, this is addressed in v3 now.

Thanks,

Fabio Estevam