Merge branch 'master' into for-next
[cascardo/linux.git] / drivers / char / ipmi / ipmi_si_intf.c
index 7855f9f..cc6c9b2 100644 (file)
 #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;
@@ -351,7 +339,7 @@ static void return_hosed_msg(struct smi_info *smi_info, int cCode)
                cCode = IPMI_ERR_UNSPECIFIED;
        /* else use it as is */
 
-       /* Make it a reponse */
+       /* Make it a response */
        msg->rsp[0] = msg->data[0] | 4;
        msg->rsp[1] = msg->data[1];
        msg->rsp[2] = cCode;
@@ -900,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)
@@ -1860,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;
 
@@ -1871,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");
@@ -1924,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
@@ -2555,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;
@@ -2569,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");
@@ -2601,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;
 
@@ -2632,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;
 }
 
@@ -2653,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)
 {
@@ -2926,7 +2927,7 @@ static void return_hosed_msg_badsize(struct smi_info *smi_info)
 {
        struct ipmi_smi_msg *msg = smi_info->curr_msg;
 
-       /* Make it a reponse */
+       /* Make it a response */
        msg->rsp[0] = msg->data[0] | 4;
        msg->rsp[1] = msg->data[1];
        msg->rsp[2] = CANNOT_RETURN_REQUESTED_LENGTH;
@@ -3340,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;
@@ -3365,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);
@@ -3396,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
@@ -3532,7 +3521,7 @@ static void cleanup_one_si(struct smi_info *to_clean)
        kfree(to_clean);
 }
 
-static void __exit cleanup_ipmi_si(void)
+static void cleanup_ipmi_si(void)
 {
        struct smi_info *e, *tmp_e;
 
@@ -3548,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);