[PATCH AUTOSEL 5.1 42/51] platform/x86: mlx-platform: Fix parent device in i2c-mux-reg device registration

Sasha Levin
2019-06-26T03:50:09Z

From: Vadim Pasternak <vadimp@mellanox.com>

[ Upstream commit 160da20b254dd4bfc5828f12c208fa831ad4be6c ]

Fix the issue found while running kernel with the option
CONFIG_DEBUG_TEST_DRIVER_REMOVE.
Driver 'mlx-platform' registers 'i2c_mlxcpld' device and then registers
few underlying 'i2c-mux-reg' devices:
priv->pdev_i2c = platform_device_register_simple("i2c_mlxcpld", nr,
NULL, 0);
...
for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
priv->pdev_mux[i] = platform_device_register_resndata(
&mlxplat_dev->dev,
"i2c-mux-reg", i, NULL,
0, &mlxplat_mux_data[i],
sizeof(mlxplat_mux_data[i]));

But actual parent of "i2c-mux-reg" device is priv->pdev_i2c->dev and
not mlxplat_dev->dev.
Patch fixes parent device parameter in a call to
platform_device_register_resndata() for "i2c-mux-reg".

It solves the race during initialization flow while 'i2c_mlxcpld.1' is
removing after probe, while 'i2c-mux-reg.0' is still in probing flow:
'i2c_mlxcpld.1' flow: probe -> remove -> probe.
'i2c-mux-reg.0' flow: probe -> ...

[ 12:621096] Registering platform device 'i2c_mlxcpld.1'. Parent at platform
[ 12:621117] device: 'i2c_mlxcpld.1': device_add
[ 12:621155] bus: 'platform': add device i2c_mlxcpld.1
[ 12:621384] Registering platform device 'i2c-mux-reg.0'. Parent at mlxplat
[ 12:621395] device: 'i2c-mux-reg.0': device_add
[ 12:621425] bus: 'platform': add device i2c-mux-reg.0
[ 12:621806] Registering platform device 'i2c-mux-reg.1'. Parent at mlxplat
[ 12:621828] device: 'i2c-mux-reg.1': device_add
[ 12:621892] bus: 'platform': add device i2c-mux-reg.1
[ 12:621906] bus: 'platform': add driver i2c_mlxcpld
[ 12:621996] bus: 'platform': driver_probe_device: matched device i2c_mlxcpld.1 with driver i2c_mlxcpld
[ 12:622003] bus: 'platform': really_probe: probing driver i2c_mlxcpld with device i2c_mlxcpld.1
[ 12:622100] i2c_mlxcpld i2c_mlxcpld.1: no default pinctrl state
[ 12:622293] device: 'i2c-1': device_add
[ 12:627280] bus: 'i2c': add device i2c-1
[ 12:627692] device: 'i2c-1': device_add
[ 12.629639] bus: 'platform': add driver i2c-mux-reg
[ 12.629718] bus: 'platform': driver_probe_device: matched device i2c-mux-reg.0 with driver i2c-mux-reg
[ 12.629723] bus: 'platform': really_probe: probing driver i2c-mux-reg with device i2c-mux-reg.0
[ 12.629818] i2c-mux-reg i2c-mux-reg.0: no default pinctrl state
[ 12.629981] platform i2c-mux-reg.0: Driver i2c-mux-reg requests probe deferral
[ 12.629986] platform i2c-mux-reg.0: Added to deferred list
[ 12.629992] bus: 'platform': driver_probe_device: matched device i2c-mux-reg.1 with driver i2c-mux-reg
[ 12.629997] bus: 'platform': really_probe: probing driver i2c-mux-reg with device i2c-mux-reg.1
[ 12.630091] i2c-mux-reg i2c-mux-reg.1: no default pinctrl state
[ 12.630247] platform i2c-mux-reg.1: Driver i2c-mux-reg requests probe deferral
[ 12.630252] platform i2c-mux-reg.1: Added to deferred list
[ 12.640892] devices_kset: Moving i2c-mux-reg.0 to end of list
[ 12.640900] platform i2c-mux-reg.0: Retrying from deferred list
[ 12.640911] bus: 'platform': driver_probe_device: matched device i2c-mux-reg.0 with driver i2c-mux-reg
[ 12.640919] bus: 'platform': really_probe: probing driver i2c-mux-reg with device i2c-mux-reg.0
[ 12.640999] i2c-mux-reg i2c-mux-reg.0: no default pinctrl state
[ 12.641177] platform i2c-mux-reg.0: Driver i2c-mux-reg requests probe deferral
[ 12.641187] platform i2c-mux-reg.0: Added to deferred list
[ 12.641198] devices_kset: Moving i2c-mux-reg.1 to end of list
[ 12.641219] platform i2c-mux-reg.1: Retrying from deferred list
[ 12.641237] bus: 'platform': driver_probe_device: matched device i2c-mux-reg.1 with driver i2c-mux-reg
[ 12.641247] bus: 'platform': really_probe: probing driver i2c-mux-reg with device i2c-mux-reg.1
[ 12.641331] i2c-mux-reg i2c-mux-reg.1: no default pinctrl state
[ 12.641465] platform i2c-mux-reg.1: Driver i2c-mux-reg requests probe deferral
[ 12.641469] platform i2c-mux-reg.1: Added to deferred list
[ 12.646427] device: 'i2c-1': device_add
[ 12.646647] bus: 'i2c': add device i2c-1
[ 12.647104] device: 'i2c-1': device_add
[ 12.669231] devices_kset: Moving i2c-mux-reg.0 to end of list
[ 12.669240] platform i2c-mux-reg.0: Retrying from deferred list
[ 12.669258] bus: 'platform': driver_probe_device: matched device i2c-mux-reg.0 with driver i2c-mux-reg
[ 12.669263] bus: 'platform': really_probe: probing driver i2c-mux-reg with device i2c-mux-reg.0
[ 12.669343] i2c-mux-reg i2c-mux-reg.0: no default pinctrl state
[ 12.669585] device: 'i2c-2': device_add
[ 12.669795] bus: 'i2c': add device i2c-2
[ 12.670201] device: 'i2c-2': device_add
[ 12.671427] i2c i2c-1: Added multiplexed i2c bus 2
[ 12.671514] device: 'i2c-3': device_add
[ 12.671724] bus: 'i2c': add device i2c-3
[ 12.672136] device: 'i2c-3': device_add
[ 12.673378] i2c i2c-1: Added multiplexed i2c bus 3
[ 12.673472] device: 'i2c-4': device_add
[ 12.673676] bus: 'i2c': add device i2c-4
[ 12.674060] device: 'i2c-4': device_add
[ 12.675861] i2c i2c-1: Added multiplexed i2c bus 4
[ 12.675941] device: 'i2c-5': device_add
[ 12.676150] bus: 'i2c': add device i2c-5
[ 12.676550] device: 'i2c-5': device_add
[ 12.678103] i2c i2c-1: Added multiplexed i2c bus 5
[ 12.678193] device: 'i2c-6': device_add
[ 12.678395] bus: 'i2c': add device i2c-6
[ 12.678774] device: 'i2c-6': device_add
[ 12.679969] i2c i2c-1: Added multiplexed i2c bus 6
[ 12.680065] device: 'i2c-7': device_add
[ 12.680275] bus: 'i2c': add device i2c-7
[ 12.680913] device: 'i2c-7': device_add
[ 12.682506] i2c i2c-1: Added multiplexed i2c bus 7
[ 12.682600] device: 'i2c-8': device_add
[ 12.682808] bus: 'i2c': add device i2c-8
[ 12.683189] device: 'i2c-8': device_add
[ 12.683907] device: 'i2c-1': device_unregister
[ 12.683945] device: 'i2c-1': device_unregister
[ 12.684387] device: 'i2c-1': device_create_release
[ 12.684536] bus: 'i2c': remove device i2c-1
[ 12.686019] i2c i2c-8: Failed to create compatibility class link
[ 12.686086] ------------[ cut here ]------------
[ 12.686087] can't create symlink to mux device
[ 12.686224] Workqueue: events deferred_probe_work_func
[ 12.686135] WARNING: CPU: 7 PID: 436 at drivers/i2c/i2c-mux.c:416 i2c_mux_add_adapter+0x729/0x7d0 [i2c_mux]
[ 12.686232] RIP: 0010:i2c_mux_add_adapter+0x729/0x7d0 [i2c_mux]
[ 0x190/0x190 [i2c_mux]
[ 12.686300] ? i2c_mux_alloc+0xac/0x110 [i2c_mux]
[ 12.686306] ? i2c_mux_reg_set+0x200/0x200 [i2c_mux_reg]
[ 12.686313] i2c_mux_reg_probe+0x22c/0x731 [i2c_mux_reg]
[ 12.686322] ? i2c_mux_reg_deselect+0x60/0x60 [i2c_mux_reg]
[ 12.686346] platform_drv_probe+0xa8/0x110
[ 12.686351] really_probe+0x185/0x720
[ 12.686358] driver_probe_device+0xdf/0x1f0
...
[ 12.686522] i2c i2c-1: Added multiplexed i2c bus 8
[ 12.686621] device: 'i2c-9': device_add
[ 12.686626] kobject_add_internal failed for i2c-9 (error: -2 parent: i2c-1)
[ 12.694729] i2c-core: adapter 'i2c-1-mux (chan_id 8)': can't register device (-2)
[ 12.705726] i2c i2c-1: failed to add mux-adapter 8 as bus 9 (error=-2)
[ 12.714494] device: 'i2c-8': device_unregister
[ 12.714537] device: 'i2c-8': device_unregister

Fixes: 6613d18e9038 ("platform/x86: mlx-platform: Move module from arch/x86")
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/mlx-platform.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index 48fa7573e29b..0e5f073e51bc 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -1828,7 +1828,7 @@ static int __init mlxplat_init(void)

for (i = 0; i < ARRAY_SIZE(mlxplat_mux_data); i++) {
priv->pdev_mux[i] = platform_device_register_resndata(
- &mlxplat_dev->dev,
+ &priv->pdev_i2c->dev,
"i2c-mux-reg", i, NULL,
0, &mlxplat_mux_data[i],
sizeof(mlxplat_mux_data[i]));
--
2.20.1