diff options
Diffstat (limited to 'drivers/char/ipmi/ipmi_si_intf.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 90 |
1 files changed, 33 insertions, 57 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b6ae6e9a9c5..c86d43b88e1 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -66,13 +66,10 @@ #include <linux/string.h> #include <linux/ctype.h> #include <linux/pnp.h> - -#ifdef CONFIG_PPC_OF #include <linux/of_device.h> #include <linux/of_platform.h> #include <linux/of_address.h> #include <linux/of_irq.h> -#endif #define PFX "ipmi_si: " @@ -116,13 +113,7 @@ static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI", #define DEVICE_NAME "ipmi_si" -static struct platform_driver ipmi_driver = { - .driver = { - .name = DEVICE_NAME, - .bus = &platform_bus_type - } -}; - +static struct platform_driver ipmi_driver; /* * Indexes into stats[] in smi_info below. @@ -308,9 +299,6 @@ static int pci_registered; #ifdef CONFIG_ACPI static int pnp_registered; #endif -#ifdef CONFIG_PPC_OF -static int of_registered; -#endif static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; static int num_max_busy_us; @@ -320,6 +308,7 @@ static int unload_when_empty = 1; static int add_smi(struct smi_info *smi); static int try_smi_init(struct smi_info *smi); static void cleanup_one_si(struct smi_info *to_clean); +static void cleanup_ipmi_si(void); static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); static int register_xaction_notifier(struct notifier_block *nb) @@ -899,6 +888,14 @@ static void sender(void *send_info, printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif + /* + * last_timeout_jiffies is updated here to avoid + * smi_timeout() handler passing very large time_diff + * value to smi_event_handler() that causes + * the send command to abort. + */ + smi_info->last_timeout_jiffies = jiffies; + mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); if (smi_info->thread) @@ -1859,8 +1856,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) return rv; } -static void __devinit hardcode_find_bmc(void) +static int __devinit hardcode_find_bmc(void) { + int ret = -ENODEV; int i; struct smi_info *info; @@ -1870,7 +1868,7 @@ static void __devinit hardcode_find_bmc(void) info = smi_info_alloc(); if (!info) - return; + return -ENOMEM; info->addr_source = SI_HARDCODED; printk(KERN_INFO PFX "probing via hardcoded address\n"); @@ -1923,10 +1921,12 @@ static void __devinit hardcode_find_bmc(void) if (!add_smi(info)) { if (try_smi_init(info)) cleanup_one_si(info); + ret = 0; } else { kfree(info); } } + return ret; } #ifdef CONFIG_ACPI @@ -2554,11 +2554,9 @@ static struct pci_driver ipmi_pci_driver = { }; #endif /* CONFIG_PCI */ - -#ifdef CONFIG_PPC_OF -static int __devinit ipmi_of_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit ipmi_probe(struct platform_device *dev) { +#ifdef CONFIG_OF struct smi_info *info; struct resource resource; const __be32 *regsize, *regspacing, *regshift; @@ -2568,6 +2566,9 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, dev_info(&dev->dev, "probing via device tree\n"); + if (!dev->dev.of_match) + return -EINVAL; + ret = of_address_to_resource(np, 0, &resource); if (ret) { dev_warn(&dev->dev, PFX "invalid address from OF\n"); @@ -2600,7 +2601,7 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, return -ENOMEM; } - info->si_type = (enum si_type) match->data; + info->si_type = (enum si_type) dev->dev.of_match->data; info->addr_source = SI_DEVICETREE; info->irq_setup = std_irq_setup; @@ -2631,13 +2632,15 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, kfree(info); return -EBUSY; } - +#endif return 0; } -static int __devexit ipmi_of_remove(struct platform_device *dev) +static int __devexit ipmi_remove(struct platform_device *dev) { +#ifdef CONFIG_OF cleanup_one_si(dev_get_drvdata(&dev->dev)); +#endif return 0; } @@ -2652,16 +2655,15 @@ static struct of_device_id ipmi_match[] = {}, }; -static struct of_platform_driver ipmi_of_platform_driver = { +static struct platform_driver ipmi_driver = { .driver = { - .name = "ipmi", + .name = DEVICE_NAME, .owner = THIS_MODULE, .of_match_table = ipmi_match, }, - .probe = ipmi_of_probe, - .remove = __devexit_p(ipmi_of_remove), + .probe = ipmi_probe, + .remove = __devexit_p(ipmi_remove), }; -#endif /* CONFIG_PPC_OF */ static int wait_for_msg_done(struct smi_info *smi_info) { @@ -3339,8 +3341,7 @@ static int __devinit init_ipmi_si(void) return 0; initialized = 1; - /* Register the device drivers. */ - rv = driver_register(&ipmi_driver.driver); + rv = platform_driver_register(&ipmi_driver); if (rv) { printk(KERN_ERR PFX "Unable to register driver: %d\n", rv); return rv; @@ -3364,15 +3365,9 @@ static int __devinit init_ipmi_si(void) printk(KERN_INFO "IPMI System Interface driver.\n"); - hardcode_find_bmc(); - /* If the user gave us a device, they presumably want us to use it */ - mutex_lock(&smi_infos_lock); - if (!list_empty(&smi_infos)) { - mutex_unlock(&smi_infos_lock); + if (!hardcode_find_bmc()) return 0; - } - mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI rv = pci_register_driver(&ipmi_pci_driver); @@ -3395,11 +3390,6 @@ static int __devinit init_ipmi_si(void) spmi_find_bmc(); #endif -#ifdef CONFIG_PPC_OF - of_register_platform_driver(&ipmi_of_platform_driver); - of_registered = 1; -#endif - /* We prefer devices with interrupts, but in the case of a machine with multiple BMCs we assume that there will be several instances of a given type so if we succeed in registering a type then also @@ -3450,16 +3440,7 @@ static int __devinit init_ipmi_si(void) mutex_lock(&smi_infos_lock); if (unload_when_empty && list_empty(&smi_infos)) { mutex_unlock(&smi_infos_lock); -#ifdef CONFIG_PCI - if (pci_registered) - pci_unregister_driver(&ipmi_pci_driver); -#endif - -#ifdef CONFIG_PPC_OF - if (of_registered) - of_unregister_platform_driver(&ipmi_of_platform_driver); -#endif - driver_unregister(&ipmi_driver.driver); + cleanup_ipmi_si(); printk(KERN_WARNING PFX "Unable to find any System Interface(s)\n"); return -ENODEV; @@ -3556,17 +3537,12 @@ static void __exit cleanup_ipmi_si(void) pnp_unregister_driver(&ipmi_pnp_driver); #endif -#ifdef CONFIG_PPC_OF - if (of_registered) - of_unregister_platform_driver(&ipmi_of_platform_driver); -#endif + platform_driver_unregister(&ipmi_driver); mutex_lock(&smi_infos_lock); list_for_each_entry_safe(e, tmp_e, &smi_infos, link) cleanup_one_si(e); mutex_unlock(&smi_infos_lock); - - driver_unregister(&ipmi_driver.driver); } module_exit(cleanup_ipmi_si); |