[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200714075251.12777-4-xiaoning.wang@nxp.com>
Date: Tue, 14 Jul 2020 15:52:49 +0800
From: Clark Wang <xiaoning.wang@....com>
To: broonie@...nel.org
Cc: linux-spi@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 3/5] spi: lpspi: fix kernel warning dump when probe fail after calling spi_register
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.wang@....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
Powered by blists - more mailing lists