Commit fe2d5ffc authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Linus Torvalds

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: default avatarDarrick J. Wong <djwong@us.ibm.com>
Acked-by: default avatarCorey 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 722faccc
...@@ -422,9 +422,11 @@ struct ipmi_smi { ...@@ -422,9 +422,11 @@ struct ipmi_smi {
/** /**
* The driver model view of the IPMI messaging driver. * The driver model view of the IPMI messaging driver.
*/ */
static struct device_driver ipmidriver = { static struct platform_driver ipmidriver = {
.driver = {
.name = "ipmi", .name = "ipmi",
.bus = &platform_bus_type .bus = &platform_bus_type
}
}; };
static DEFINE_MUTEX(ipmidriver_mutex); static DEFINE_MUTEX(ipmidriver_mutex);
...@@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, ...@@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
* representing the interfaced BMC already * representing the interfaced BMC already
*/ */
if (bmc->guid_set) if (bmc->guid_set)
old_bmc = ipmi_find_bmc_guid(&ipmidriver, bmc->guid); old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid);
else else
old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver, old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
bmc->id.product_id, bmc->id.product_id,
bmc->id.device_id); bmc->id.device_id);
...@@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, ...@@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
snprintf(name, sizeof(name), snprintf(name, sizeof(name),
"ipmi_bmc.%4.4x", bmc->id.product_id); "ipmi_bmc.%4.4x", bmc->id.product_id);
while (ipmi_find_bmc_prod_dev_id(&ipmidriver, while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
bmc->id.product_id, bmc->id.product_id,
bmc->id.device_id)) { bmc->id.device_id)) {
if (!warn_printed) { if (!warn_printed) {
...@@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, ...@@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
" Unable to allocate platform device\n"); " Unable to allocate platform device\n");
return -ENOMEM; return -ENOMEM;
} }
bmc->dev->dev.driver = &ipmidriver; bmc->dev->dev.driver = &ipmidriver.driver;
dev_set_drvdata(&bmc->dev->dev, bmc); dev_set_drvdata(&bmc->dev->dev, bmc);
kref_init(&bmc->refcount); kref_init(&bmc->refcount);
...@@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void) ...@@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void)
if (initialized) if (initialized)
return 0; return 0;
rv = driver_register(&ipmidriver); rv = driver_register(&ipmidriver.driver);
if (rv) { if (rv) {
printk(KERN_ERR PFX "Could not register IPMI driver\n"); printk(KERN_ERR PFX "Could not register IPMI driver\n");
return rv; return rv;
...@@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void) ...@@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void)
remove_proc_entry(proc_ipmi_root->name, NULL); remove_proc_entry(proc_ipmi_root->name, NULL);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
driver_unregister(&ipmidriver); driver_unregister(&ipmidriver.driver);
initialized = 0; initialized = 0;
......
...@@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" }; ...@@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" };
#define DEVICE_NAME "ipmi_si" #define DEVICE_NAME "ipmi_si"
static struct device_driver ipmi_driver = { static struct platform_driver ipmi_driver = {
.driver = {
.name = DEVICE_NAME, .name = DEVICE_NAME,
.bus = &platform_bus_type .bus = &platform_bus_type
}
}; };
...@@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi) ...@@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi)
goto out_err; goto out_err;
} }
new_smi->dev = &new_smi->pdev->dev; new_smi->dev = &new_smi->pdev->dev;
new_smi->dev->driver = &ipmi_driver; new_smi->dev->driver = &ipmi_driver.driver;
rv = platform_device_add(new_smi->pdev); rv = platform_device_add(new_smi->pdev);
if (rv) { if (rv) {
...@@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void) ...@@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void)
initialized = 1; initialized = 1;
/* Register the device drivers. */ /* Register the device drivers. */
rv = driver_register(&ipmi_driver); rv = driver_register(&ipmi_driver.driver);
if (rv) { if (rv) {
printk(KERN_ERR printk(KERN_ERR
"init_ipmi_si: Unable to register driver: %d\n", "init_ipmi_si: Unable to register driver: %d\n",
...@@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void) ...@@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void)
#ifdef CONFIG_PPC_OF #ifdef CONFIG_PPC_OF
of_unregister_platform_driver(&ipmi_of_platform_driver); of_unregister_platform_driver(&ipmi_of_platform_driver);
#endif #endif
driver_unregister(&ipmi_driver); driver_unregister(&ipmi_driver.driver);
printk(KERN_WARNING printk(KERN_WARNING
"ipmi_si: Unable to find any System Interface(s)\n"); "ipmi_si: Unable to find any System Interface(s)\n");
return -ENODEV; return -ENODEV;
...@@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void) ...@@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void)
cleanup_one_si(e); cleanup_one_si(e);
mutex_unlock(&smi_infos_lock); mutex_unlock(&smi_infos_lock);
driver_unregister(&ipmi_driver); driver_unregister(&ipmi_driver.driver);
} }
module_exit(cleanup_ipmi_si); module_exit(cleanup_ipmi_si);
......
...@@ -88,9 +88,11 @@ ...@@ -88,9 +88,11 @@
static DEFINE_IDR(aem_idr); static DEFINE_IDR(aem_idr);
static DEFINE_SPINLOCK(aem_idr_lock); static DEFINE_SPINLOCK(aem_idr_lock);
static struct device_driver aem_driver = { static struct platform_driver aem_driver = {
.driver = {
.name = DRVNAME, .name = DRVNAME,
.bus = &platform_bus_type, .bus = &platform_bus_type,
}
}; };
struct aem_ipmi_data { struct aem_ipmi_data {
...@@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) ...@@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
data->pdev = platform_device_alloc(DRVNAME, data->id); data->pdev = platform_device_alloc(DRVNAME, data->id);
if (!data->pdev) if (!data->pdev)
goto dev_err; goto dev_err;
data->pdev->dev.driver = &aem_driver; data->pdev->dev.driver = &aem_driver.driver;
res = platform_device_add(data->pdev); res = platform_device_add(data->pdev);
if (res) if (res)
...@@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, ...@@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
data->pdev = platform_device_alloc(DRVNAME, data->id); data->pdev = platform_device_alloc(DRVNAME, data->id);
if (!data->pdev) if (!data->pdev)
goto dev_err; goto dev_err;
data->pdev->dev.driver = &aem_driver; data->pdev->dev.driver = &aem_driver.driver;
res = platform_device_add(data->pdev); res = platform_device_add(data->pdev);
if (res) if (res)
...@@ -1085,7 +1087,7 @@ static int __init aem_init(void) ...@@ -1085,7 +1087,7 @@ static int __init aem_init(void)
{ {
int res; int res;
res = driver_register(&aem_driver); res = driver_register(&aem_driver.driver);
if (res) { if (res) {
printk(KERN_ERR "Can't register aem driver\n"); printk(KERN_ERR "Can't register aem driver\n");
return res; return res;
...@@ -1097,7 +1099,7 @@ static int __init aem_init(void) ...@@ -1097,7 +1099,7 @@ static int __init aem_init(void)
return 0; return 0;
ipmi_reg_err: ipmi_reg_err:
driver_unregister(&aem_driver); driver_unregister(&aem_driver.driver);
return res; return res;
} }
...@@ -1107,7 +1109,7 @@ static void __exit aem_exit(void) ...@@ -1107,7 +1109,7 @@ static void __exit aem_exit(void)
struct aem_data *p1, *next1; struct aem_data *p1, *next1;
ipmi_smi_watcher_unregister(&driver_data.bmc_events); ipmi_smi_watcher_unregister(&driver_data.bmc_events);
driver_unregister(&aem_driver); driver_unregister(&aem_driver.driver);
list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list)
aem_delete(p1); aem_delete(p1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment