Skip to content

Commit 38b9ab8

Browse files
kuu-rtij-intel
authored andcommitted
platform/x86: thinkpad_acpi: Move subdriver initialization to tpacpi_pdriver's probe.
It was reported that if subdrivers assigned devres resources inside ibm_init_struct's .init callbacks, driver binding would fail with the following error message: platform thinkpad_acpi: Resources present before probing Let the driver core manage the lifetimes of the subdrivers and children devices, by initializing them inside tpacpi_driver's .probe callback. This is appropriate because these subdrivers usually expose sysfs groups and the driver core manages this automatically to avoid races. One immediate benefit of this, is that we are now able to use devres inside .init subdriver callbacks. platform_create_bundle is specifically used because it makes the driver's probe type synchronous and returns an ERR_PTR if attachment failed. Additionally, to make error handling simpler, allocate the input device using devm_input_allocate_device(). Reported-by: Mark Pearson <[email protected]> Closes: https://lore.kernel.org/platform-driver-x86/[email protected]/#t Reviewed-by: Mark Pearson <[email protected]> Tested-by: Mark Pearson <[email protected]> Signed-off-by: Kurt Borja <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent c5855d2 commit 38b9ab8

File tree

1 file changed

+62
-74
lines changed

1 file changed

+62
-74
lines changed

drivers/platform/x86/thinkpad_acpi.c

Lines changed: 62 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,6 @@ static struct {
367367
u32 beep_needs_two_args:1;
368368
u32 mixer_no_level_control:1;
369369
u32 battery_force_primary:1;
370-
u32 input_device_registered:1;
371-
u32 platform_drv_registered:1;
372370
u32 sensors_pdrv_registered:1;
373371
u32 hotkey_poll_active:1;
374372
u32 has_adaptive_kbd:1;
@@ -11815,36 +11813,20 @@ MODULE_PARM_DESC(profile_force, "Force profile mode. -1=off, 1=MMC, 2=PSC");
1181511813

1181611814
static void thinkpad_acpi_module_exit(void)
1181711815
{
11818-
struct ibm_struct *ibm, *itmp;
11819-
1182011816
tpacpi_lifecycle = TPACPI_LIFE_EXITING;
1182111817

1182211818
if (tpacpi_hwmon)
1182311819
hwmon_device_unregister(tpacpi_hwmon);
1182411820
if (tp_features.sensors_pdrv_registered)
1182511821
platform_driver_unregister(&tpacpi_hwmon_pdriver);
11826-
if (tp_features.platform_drv_registered)
11827-
platform_driver_unregister(&tpacpi_pdriver);
11828-
11829-
list_for_each_entry_safe_reverse(ibm, itmp,
11830-
&tpacpi_all_drivers,
11831-
all_drivers) {
11832-
ibm_exit(ibm);
11833-
}
11834-
11835-
dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
11836-
11837-
if (tpacpi_inputdev) {
11838-
if (tp_features.input_device_registered)
11839-
input_unregister_device(tpacpi_inputdev);
11840-
else
11841-
input_free_device(tpacpi_inputdev);
11842-
}
11843-
1184411822
if (tpacpi_sensors_pdev)
1184511823
platform_device_unregister(tpacpi_sensors_pdev);
11846-
if (tpacpi_pdev)
11824+
11825+
if (tpacpi_pdev) {
11826+
platform_driver_unregister(&tpacpi_pdriver);
1184711827
platform_device_unregister(tpacpi_pdev);
11828+
}
11829+
1184811830
if (proc_dir)
1184911831
remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
1185011832
if (tpacpi_wq)
@@ -11856,11 +11838,63 @@ static void thinkpad_acpi_module_exit(void)
1185611838
kfree(thinkpad_id.nummodel_str);
1185711839
}
1185811840

11841+
static void tpacpi_subdrivers_release(void *data)
11842+
{
11843+
struct ibm_struct *ibm, *itmp;
11844+
11845+
list_for_each_entry_safe_reverse(ibm, itmp, &tpacpi_all_drivers, all_drivers)
11846+
ibm_exit(ibm);
11847+
11848+
dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
11849+
}
11850+
11851+
static int __init tpacpi_pdriver_probe(struct platform_device *pdev)
11852+
{
11853+
int ret;
11854+
11855+
devm_mutex_init(&pdev->dev, &tpacpi_inputdev_send_mutex);
11856+
11857+
tpacpi_inputdev = devm_input_allocate_device(&pdev->dev);
11858+
if (!tpacpi_inputdev)
11859+
return -ENOMEM;
11860+
11861+
tpacpi_inputdev->name = "ThinkPad Extra Buttons";
11862+
tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
11863+
tpacpi_inputdev->id.bustype = BUS_HOST;
11864+
tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
11865+
tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
11866+
tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
11867+
tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
11868+
11869+
/* Init subdriver dependencies */
11870+
tpacpi_detect_brightness_capabilities();
11871+
11872+
/* Init subdrivers */
11873+
for (unsigned int i = 0; i < ARRAY_SIZE(ibms_init); i++) {
11874+
ret = ibm_init(&ibms_init[i]);
11875+
if (ret >= 0 && *ibms_init[i].param)
11876+
ret = ibms_init[i].data->write(ibms_init[i].param);
11877+
if (ret < 0) {
11878+
tpacpi_subdrivers_release(NULL);
11879+
return ret;
11880+
}
11881+
}
11882+
11883+
ret = devm_add_action_or_reset(&pdev->dev, tpacpi_subdrivers_release, NULL);
11884+
if (ret)
11885+
return ret;
11886+
11887+
ret = input_register_device(tpacpi_inputdev);
11888+
if (ret < 0)
11889+
pr_err("unable to register input device\n");
11890+
11891+
return ret;
11892+
}
1185911893

1186011894
static int __init thinkpad_acpi_module_init(void)
1186111895
{
1186211896
const struct dmi_system_id *dmi_id;
11863-
int ret, i;
11897+
int ret;
1186411898
acpi_object_type obj_type;
1186511899

1186611900
tpacpi_lifecycle = TPACPI_LIFE_INIT;
@@ -11920,15 +11954,16 @@ static int __init thinkpad_acpi_module_init(void)
1192011954
tp_features.quirks = dmi_id->driver_data;
1192111955

1192211956
/* Device initialization */
11923-
tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, PLATFORM_DEVID_NONE,
11924-
NULL, 0);
11957+
tpacpi_pdev = platform_create_bundle(&tpacpi_pdriver, tpacpi_pdriver_probe,
11958+
NULL, 0, NULL, 0);
1192511959
if (IS_ERR(tpacpi_pdev)) {
1192611960
ret = PTR_ERR(tpacpi_pdev);
1192711961
tpacpi_pdev = NULL;
11928-
pr_err("unable to register platform device\n");
11962+
pr_err("unable to register platform device/driver bundle\n");
1192911963
thinkpad_acpi_module_exit();
1193011964
return ret;
1193111965
}
11966+
1193211967
tpacpi_sensors_pdev = platform_device_register_simple(
1193311968
TPACPI_HWMON_DRVR_NAME,
1193411969
PLATFORM_DEVID_NONE, NULL, 0);
@@ -11940,46 +11975,8 @@ static int __init thinkpad_acpi_module_init(void)
1194011975
return ret;
1194111976
}
1194211977

11943-
mutex_init(&tpacpi_inputdev_send_mutex);
11944-
tpacpi_inputdev = input_allocate_device();
11945-
if (!tpacpi_inputdev) {
11946-
thinkpad_acpi_module_exit();
11947-
return -ENOMEM;
11948-
} else {
11949-
/* Prepare input device, but don't register */
11950-
tpacpi_inputdev->name = "ThinkPad Extra Buttons";
11951-
tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
11952-
tpacpi_inputdev->id.bustype = BUS_HOST;
11953-
tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
11954-
tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
11955-
tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
11956-
tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
11957-
}
11958-
11959-
/* Init subdriver dependencies */
11960-
tpacpi_detect_brightness_capabilities();
11961-
11962-
/* Init subdrivers */
11963-
for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
11964-
ret = ibm_init(&ibms_init[i]);
11965-
if (ret >= 0 && *ibms_init[i].param)
11966-
ret = ibms_init[i].data->write(ibms_init[i].param);
11967-
if (ret < 0) {
11968-
thinkpad_acpi_module_exit();
11969-
return ret;
11970-
}
11971-
}
11972-
1197311978
tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
1197411979

11975-
ret = platform_driver_register(&tpacpi_pdriver);
11976-
if (ret) {
11977-
pr_err("unable to register main platform driver\n");
11978-
thinkpad_acpi_module_exit();
11979-
return ret;
11980-
}
11981-
tp_features.platform_drv_registered = 1;
11982-
1198311980
ret = platform_driver_register(&tpacpi_hwmon_pdriver);
1198411981
if (ret) {
1198511982
pr_err("unable to register hwmon platform driver\n");
@@ -11998,15 +11995,6 @@ static int __init thinkpad_acpi_module_init(void)
1199811995
return ret;
1199911996
}
1200011997

12001-
ret = input_register_device(tpacpi_inputdev);
12002-
if (ret < 0) {
12003-
pr_err("unable to register input device\n");
12004-
thinkpad_acpi_module_exit();
12005-
return ret;
12006-
} else {
12007-
tp_features.input_device_registered = 1;
12008-
}
12009-
1201011998
return 0;
1201111999
}
1201212000

0 commit comments

Comments
 (0)