Calling devm_spi_register_controller() too early will cause problem.
When probe failed occurs after calling devm_spi_register_controller(),
the call of spi_controller_put() will trigger the following warning dump.

[    2.092138] ------------[ cut here ]------------
[    2.096876] kernfs: can not remove 'uevent', no directory
[    2.102440] WARNING: CPU: 0 PID: 181 at fs/kernfs/dir.c:1503 
kernfs_remove_by_name_ns+0xa0/0xb0
[    2.111142] Modules linked in:
[    2.114207] CPU: 0 PID: 181 Comm: kworker/0:7 Not tainted 
5.4.24-05024-g775c6e8a738c-dirty #1314
[    2.122991] Hardware name: Freescale i.MX8DXL EVK (DT)
[    2.128141] Workqueue: events deferred_probe_work_func
[    2.133281] pstate: 60000005 (nZCv daif -PAN -UAO)
[    2.138076] pc : kernfs_remove_by_name_ns+0xa0/0xb0
[    2.142958] lr : kernfs_remove_by_name_ns+0xa0/0xb0
[    2.147837] sp : ffff8000122bba70
[    2.151145] x29: ffff8000122bba70 x28: ffff8000119d6000
[    2.156462] x27: 0000000000000000 x26: ffff800011edbce8
[    2.161779] x25: 0000000000000000 x24: ffff00003ae4f700
[    2.167096] x23: ffff000010184c10 x22: ffff00003a3d6200
[    2.172412] x21: ffff800011a464a8 x20: ffff000010126a68
[    2.177729] x19: ffff00003ae5c800 x18: 000000000000000e
[    2.183046] x17: 0000000000000001 x16: 0000000000000019
[    2.188362] x15: 0000000000000004 x14: 000000000000004c
[    2.193679] x13: 0000000000000000 x12: 0000000000000001
[    2.198996] x11: 0000000000000000 x10: 00000000000009c0
[    2.204313] x9 : ffff8000122bb7a0 x8 : ffff00003a3d6c20
[    2.209630] x7 : ffff00003a3d6380 x6 : 0000000000000001
[    2.214946] x5 : 0000000000000001 x4 : ffff00003a05eb18
[    2.220263] x3 : 0000000000000005 x2 : ffff8000119f1c48
[    2.225580] x1 : 2bcbda323bf5a800 x0 : 0000000000000000
[    2.230898] Call trace:
[    2.233345]  kernfs_remove_by_name_ns+0xa0/0xb0
[    2.237879]  sysfs_remove_file_ns+0x14/0x20
[    2.242065]  device_del+0x12c/0x348
[    2.245555]  device_unregister+0x14/0x30
[    2.249492]  spi_unregister_controller+0xac/0x120
[    2.254201]  devm_spi_unregister+0x10/0x18
[    2.258304]  release_nodes+0x1a8/0x220
[    2.262055]  devres_release_all+0x34/0x58
[    2.266069]  really_probe+0x1b8/0x318
[    2.269733]  driver_probe_device+0x54/0xe8
[    2.273833]  __device_attach_driver+0x80/0xb8
[    2.278194]  bus_for_each_drv+0x74/0xc0
[    2.282034]  __device_attach+0xdc/0x138
[    2.285876]  device_initial_probe+0x10/0x18
[    2.290063]  bus_probe_device+0x90/0x98
[    2.293901]  deferred_probe_work_func+0x64/0x98
[    2.298442]  process_one_work+0x198/0x320
[    2.302451]  worker_thread+0x1f0/0x420
[    2.306208]  kthread+0xf0/0x120
[    2.309352]  ret_from_fork+0x10/0x18
[    2.312927] ---[ end trace 58abcdfae01bd3c7 ]---

So put this function at the end of the probe sequence.

Meanwhile, in order to keep the multi-CS working, add
"fsl,spi-num-chipselects" check.

Signed-off-by: Clark Wang <xiaoning.w...@nxp.com>
---
 drivers/spi/spi-fsl-lpspi.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index ca43d93adf30..6fb77f0f657a 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -837,7 +837,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
        struct spi_imx_master *lpspi_platform_info =
                dev_get_platdata(&pdev->dev);
        struct resource *res;
-       int i, ret, irq;
+       int i, ret, irq, num_cs;
        u32 temp;
        bool is_slave;
 
@@ -859,6 +859,16 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, controller);
 
+       ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs);
+       if (ret < 0) {
+               if (lpspi_platform_info) {
+                       num_cs = lpspi_platform_info->num_chipselect;
+                       controller->num_chipselect = num_cs;
+               }
+       } else {
+               controller->num_chipselect = num_cs;
+       }
+
        fsl_lpspi = spi_controller_get_devdata(controller);
        fsl_lpspi->dev = &pdev->dev;
        fsl_lpspi->is_slave = is_slave;
@@ -873,12 +883,6 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
        controller->bus_num = pdev->id;
        controller->slave_abort = fsl_lpspi_slave_abort;
 
-       ret = devm_spi_register_controller(&pdev->dev, controller);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "spi_register_controller error.\n");
-               goto out_controller_put;
-       }
-
        if (!fsl_lpspi->is_slave) {
                for (i = 0; i < controller->num_chipselect; i++) {
                        int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
@@ -959,6 +963,12 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
        if (ret < 0)
                dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
 
+       ret = devm_spi_register_controller(&pdev->dev, controller);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "spi_register_controller error.\n");
+               goto out_pm_get;
+       }
+
        pm_runtime_mark_last_busy(fsl_lpspi->dev);
        pm_runtime_put_autosuspend(fsl_lpspi->dev);
 
-- 
2.17.1

Reply via email to