diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2008-11-12 16:25:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-12 20:17:16 -0500 |
commit | fe2d5ffc74a1de6a31e9fd65b65cce72d881edf7 (patch) | |
tree | f867318d9831cfa347e1374d6f723564f235399c /drivers | |
parent | 722faccc7eb0a9b248fba3e7020b1c3770c41aef (diff) |
Fix platform drivers that crash on suspend/resume
It turns out that if one registers a struct platform_device, the
platform device code expects that platform_device.device->driver points
to a struct driver inside a struct platform_driver.
This is not the case with the ipmi-si, ipmi-msghandler and ibmaem
drivers, which causes the suspend/resume hook functions to jump off into
nowhere, causing a crash. Make this assumption hold true for these
three drivers.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Greg KH <greg@kroah.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 20 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 16 | ||||
-rw-r--r-- | drivers/hwmon/ibmaem.c | 18 |
3 files changed, 30 insertions, 24 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 8a59aaa21be5..7a88dfd4427b 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -422,9 +422,11 @@ struct ipmi_smi { | |||
422 | /** | 422 | /** |
423 | * The driver model view of the IPMI messaging driver. | 423 | * The driver model view of the IPMI messaging driver. |
424 | */ | 424 | */ |
425 | static struct device_driver ipmidriver = { | 425 | static struct platform_driver ipmidriver = { |
426 | .name = "ipmi", | 426 | .driver = { |
427 | .bus = &platform_bus_type | 427 | .name = "ipmi", |
428 | .bus = &platform_bus_type | ||
429 | } | ||
428 | }; | 430 | }; |
429 | static DEFINE_MUTEX(ipmidriver_mutex); | 431 | static DEFINE_MUTEX(ipmidriver_mutex); |
430 | 432 | ||
@@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2384 | * representing the interfaced BMC already | 2386 | * representing the interfaced BMC already |
2385 | */ | 2387 | */ |
2386 | if (bmc->guid_set) | 2388 | if (bmc->guid_set) |
2387 | old_bmc = ipmi_find_bmc_guid(&ipmidriver, bmc->guid); | 2389 | old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid); |
2388 | else | 2390 | else |
2389 | old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver, | 2391 | old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, |
2390 | bmc->id.product_id, | 2392 | bmc->id.product_id, |
2391 | bmc->id.device_id); | 2393 | bmc->id.device_id); |
2392 | 2394 | ||
@@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2416 | snprintf(name, sizeof(name), | 2418 | snprintf(name, sizeof(name), |
2417 | "ipmi_bmc.%4.4x", bmc->id.product_id); | 2419 | "ipmi_bmc.%4.4x", bmc->id.product_id); |
2418 | 2420 | ||
2419 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver, | 2421 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, |
2420 | bmc->id.product_id, | 2422 | bmc->id.product_id, |
2421 | bmc->id.device_id)) { | 2423 | bmc->id.device_id)) { |
2422 | if (!warn_printed) { | 2424 | if (!warn_printed) { |
@@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2446 | " Unable to allocate platform device\n"); | 2448 | " Unable to allocate platform device\n"); |
2447 | return -ENOMEM; | 2449 | return -ENOMEM; |
2448 | } | 2450 | } |
2449 | bmc->dev->dev.driver = &ipmidriver; | 2451 | bmc->dev->dev.driver = &ipmidriver.driver; |
2450 | dev_set_drvdata(&bmc->dev->dev, bmc); | 2452 | dev_set_drvdata(&bmc->dev->dev, bmc); |
2451 | kref_init(&bmc->refcount); | 2453 | kref_init(&bmc->refcount); |
2452 | 2454 | ||
@@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void) | |||
4247 | if (initialized) | 4249 | if (initialized) |
4248 | return 0; | 4250 | return 0; |
4249 | 4251 | ||
4250 | rv = driver_register(&ipmidriver); | 4252 | rv = driver_register(&ipmidriver.driver); |
4251 | if (rv) { | 4253 | if (rv) { |
4252 | printk(KERN_ERR PFX "Could not register IPMI driver\n"); | 4254 | printk(KERN_ERR PFX "Could not register IPMI driver\n"); |
4253 | return rv; | 4255 | return rv; |
@@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void) | |||
4308 | remove_proc_entry(proc_ipmi_root->name, NULL); | 4310 | remove_proc_entry(proc_ipmi_root->name, NULL); |
4309 | #endif /* CONFIG_PROC_FS */ | 4311 | #endif /* CONFIG_PROC_FS */ |
4310 | 4312 | ||
4311 | driver_unregister(&ipmidriver); | 4313 | driver_unregister(&ipmidriver.driver); |
4312 | 4314 | ||
4313 | initialized = 0; | 4315 | initialized = 0; |
4314 | 4316 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 3123bf57ad91..3000135f2ead 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" }; | |||
114 | 114 | ||
115 | #define DEVICE_NAME "ipmi_si" | 115 | #define DEVICE_NAME "ipmi_si" |
116 | 116 | ||
117 | static struct device_driver ipmi_driver = { | 117 | static struct platform_driver ipmi_driver = { |
118 | .name = DEVICE_NAME, | 118 | .driver = { |
119 | .bus = &platform_bus_type | 119 | .name = DEVICE_NAME, |
120 | .bus = &platform_bus_type | ||
121 | } | ||
120 | }; | 122 | }; |
121 | 123 | ||
122 | 124 | ||
@@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2868 | goto out_err; | 2870 | goto out_err; |
2869 | } | 2871 | } |
2870 | new_smi->dev = &new_smi->pdev->dev; | 2872 | new_smi->dev = &new_smi->pdev->dev; |
2871 | new_smi->dev->driver = &ipmi_driver; | 2873 | new_smi->dev->driver = &ipmi_driver.driver; |
2872 | 2874 | ||
2873 | rv = platform_device_add(new_smi->pdev); | 2875 | rv = platform_device_add(new_smi->pdev); |
2874 | if (rv) { | 2876 | if (rv) { |
@@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void) | |||
2983 | initialized = 1; | 2985 | initialized = 1; |
2984 | 2986 | ||
2985 | /* Register the device drivers. */ | 2987 | /* Register the device drivers. */ |
2986 | rv = driver_register(&ipmi_driver); | 2988 | rv = driver_register(&ipmi_driver.driver); |
2987 | if (rv) { | 2989 | if (rv) { |
2988 | printk(KERN_ERR | 2990 | printk(KERN_ERR |
2989 | "init_ipmi_si: Unable to register driver: %d\n", | 2991 | "init_ipmi_si: Unable to register driver: %d\n", |
@@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void) | |||
3052 | #ifdef CONFIG_PPC_OF | 3054 | #ifdef CONFIG_PPC_OF |
3053 | of_unregister_platform_driver(&ipmi_of_platform_driver); | 3055 | of_unregister_platform_driver(&ipmi_of_platform_driver); |
3054 | #endif | 3056 | #endif |
3055 | driver_unregister(&ipmi_driver); | 3057 | driver_unregister(&ipmi_driver.driver); |
3056 | printk(KERN_WARNING | 3058 | printk(KERN_WARNING |
3057 | "ipmi_si: Unable to find any System Interface(s)\n"); | 3059 | "ipmi_si: Unable to find any System Interface(s)\n"); |
3058 | return -ENODEV; | 3060 | return -ENODEV; |
@@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void) | |||
3151 | cleanup_one_si(e); | 3153 | cleanup_one_si(e); |
3152 | mutex_unlock(&smi_infos_lock); | 3154 | mutex_unlock(&smi_infos_lock); |
3153 | 3155 | ||
3154 | driver_unregister(&ipmi_driver); | 3156 | driver_unregister(&ipmi_driver.driver); |
3155 | } | 3157 | } |
3156 | module_exit(cleanup_ipmi_si); | 3158 | module_exit(cleanup_ipmi_si); |
3157 | 3159 | ||
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 7b0ed5dea399..fe74609a7feb 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
@@ -88,9 +88,11 @@ | |||
88 | static DEFINE_IDR(aem_idr); | 88 | static DEFINE_IDR(aem_idr); |
89 | static DEFINE_SPINLOCK(aem_idr_lock); | 89 | static DEFINE_SPINLOCK(aem_idr_lock); |
90 | 90 | ||
91 | static struct device_driver aem_driver = { | 91 | static struct platform_driver aem_driver = { |
92 | .name = DRVNAME, | 92 | .driver = { |
93 | .bus = &platform_bus_type, | 93 | .name = DRVNAME, |
94 | .bus = &platform_bus_type, | ||
95 | } | ||
94 | }; | 96 | }; |
95 | 97 | ||
96 | struct aem_ipmi_data { | 98 | struct aem_ipmi_data { |
@@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
583 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 585 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
584 | if (!data->pdev) | 586 | if (!data->pdev) |
585 | goto dev_err; | 587 | goto dev_err; |
586 | data->pdev->dev.driver = &aem_driver; | 588 | data->pdev->dev.driver = &aem_driver.driver; |
587 | 589 | ||
588 | res = platform_device_add(data->pdev); | 590 | res = platform_device_add(data->pdev); |
589 | if (res) | 591 | if (res) |
@@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
716 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 718 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
717 | if (!data->pdev) | 719 | if (!data->pdev) |
718 | goto dev_err; | 720 | goto dev_err; |
719 | data->pdev->dev.driver = &aem_driver; | 721 | data->pdev->dev.driver = &aem_driver.driver; |
720 | 722 | ||
721 | res = platform_device_add(data->pdev); | 723 | res = platform_device_add(data->pdev); |
722 | if (res) | 724 | if (res) |
@@ -1085,7 +1087,7 @@ static int __init aem_init(void) | |||
1085 | { | 1087 | { |
1086 | int res; | 1088 | int res; |
1087 | 1089 | ||
1088 | res = driver_register(&aem_driver); | 1090 | res = driver_register(&aem_driver.driver); |
1089 | if (res) { | 1091 | if (res) { |
1090 | printk(KERN_ERR "Can't register aem driver\n"); | 1092 | printk(KERN_ERR "Can't register aem driver\n"); |
1091 | return res; | 1093 | return res; |
@@ -1097,7 +1099,7 @@ static int __init aem_init(void) | |||
1097 | return 0; | 1099 | return 0; |
1098 | 1100 | ||
1099 | ipmi_reg_err: | 1101 | ipmi_reg_err: |
1100 | driver_unregister(&aem_driver); | 1102 | driver_unregister(&aem_driver.driver); |
1101 | return res; | 1103 | return res; |
1102 | 1104 | ||
1103 | } | 1105 | } |
@@ -1107,7 +1109,7 @@ static void __exit aem_exit(void) | |||
1107 | struct aem_data *p1, *next1; | 1109 | struct aem_data *p1, *next1; |
1108 | 1110 | ||
1109 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | 1111 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); |
1110 | driver_unregister(&aem_driver); | 1112 | driver_unregister(&aem_driver.driver); |
1111 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | 1113 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) |
1112 | aem_delete(p1); | 1114 | aem_delete(p1); |
1113 | } | 1115 | } |