};
 
 static unsigned int pmi_frequency_limit = 0;
+
 /*
  * hardware specific functions
  */
 
-static struct of_device *pmi_dev;
+static bool cbe_cpufreq_has_pmi;
 
 #ifdef CONFIG_PPC_PMI
 static int set_pmode_pmi(int cpu, unsigned int pmode)
        time = (u64) get_cycles();
 #endif
 
-       pmi_send_message(pmi_dev, pmi_msg);
+       pmi_send_message(pmi_msg);
        ret = pmi_msg.data2;
 
        pr_debug("PMI returned slow mode %d\n", ret);
        return 0;
 }
 
-static int set_pmode(int cpu, unsigned int slow_mode) {
+static int set_pmode(int cpu, unsigned int slow_mode)
+{
 #ifdef CONFIG_PPC_PMI
-       if (pmi_dev)
+       if (cbe_cpufreq_has_pmi)
                return set_pmode_pmi(cpu, slow_mode);
-       else
 #endif
-               return set_pmode_reg(cpu, slow_mode);
+       return set_pmode_reg(cpu, slow_mode);
 }
 
-static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg)
+static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg)
 {
        u8 cpu;
        u8 cbe_pmode_new;
 
        cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
 
-       if (pmi_dev) {
+       if (cbe_cpufreq_has_pmi) {
                /* frequency might get limited later, initialize limit with max_freq */
                pmi_frequency_limit = max_freq;
                cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
 
 static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
-       if (pmi_dev)
+       if (cbe_cpufreq_has_pmi)
                cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
 
        cpufreq_frequency_table_put_attr(policy->cpu);
 
 static int __init cbe_cpufreq_init(void)
 {
-#ifdef CONFIG_PPC_PMI
-       struct device_node *np;
-#endif
        if (!machine_is(cell))
                return -ENODEV;
-#ifdef CONFIG_PPC_PMI
-       np = of_find_node_by_type(NULL, "ibm,pmi");
 
-       pmi_dev = of_find_device_by_node(np);
+       cbe_cpufreq_has_pmi = pmi_register_handler(&cbe_pmi_handler) == 0;
 
-       if (pmi_dev)
-               pmi_register_handler(pmi_dev, &cbe_pmi_handler);
-#endif
        return cpufreq_register_driver(&cbe_cpufreq_driver);
 }
 
 static void __exit cbe_cpufreq_exit(void)
 {
-#ifdef CONFIG_PPC_PMI
-       if (pmi_dev)
-               pmi_unregister_handler(pmi_dev, &cbe_pmi_handler);
-#endif
        cpufreq_unregister_driver(&cbe_cpufreq_driver);
+
+       if (cbe_cpufreq_has_pmi)
+               pmi_unregister_handler(&cbe_pmi_handler);
 }
 
 module_init(cbe_cpufreq_init);
 
        struct work_struct      work;
 };
 
+static struct pmi_data *data;
 
 static int pmi_irq_handler(int irq, void *dev_id)
 {
-       struct pmi_data *data;
        u8 type;
        int rc;
 
-       data = dev_id;
-
        spin_lock(&data->pmi_spinlock);
 
        type = ioread8(data->pmi_reg + PMI_READ_TYPE);
 
 static void pmi_notify_handlers(struct work_struct *work)
 {
-       struct pmi_data *data;
        struct pmi_handler *handler;
 
-       data = container_of(work, struct pmi_data, work);
-
        spin_lock(&data->handler_spinlock);
        list_for_each_entry(handler, &data->handler, node) {
                pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler);
                if (handler->type == data->msg.type)
-                       handler->handle_pmi_message(data->dev, data->msg);
+                       handler->handle_pmi_message(data->msg);
        }
        spin_unlock(&data->handler_spinlock);
 }
                        const struct of_device_id *match)
 {
        struct device_node *np = dev->node;
-       struct pmi_data *data;
        int rc;
 
+       if (data) {
+               printk(KERN_ERR "pmi: driver has already been initialized.\n");
+               rc = -EBUSY;
+               goto out;
+       }
+
        data = kzalloc(sizeof(struct pmi_data), GFP_KERNEL);
        if (!data) {
                printk(KERN_ERR "pmi: could not allocate memory.\n");
 
        INIT_WORK(&data->work, pmi_notify_handlers);
 
-       dev->dev.driver_data = data;
        data->dev = dev;
 
        data->irq = irq_of_parse_and_map(np, 0);
                goto error_cleanup_iomap;
        }
 
-       rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", data);
+       rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", NULL);
        if (rc) {
                printk(KERN_ERR "pmi: can't request IRQ %d: returned %d\n",
                                data->irq, rc);
 
 static int pmi_of_remove(struct of_device *dev)
 {
-       struct pmi_data *data;
        struct pmi_handler *handler, *tmp;
 
-       data = dev->dev.driver_data;
-
-       free_irq(data->irq, data);
+       free_irq(data->irq, NULL);
        iounmap(data->pmi_reg);
 
        spin_lock(&data->handler_spinlock);
 
        spin_unlock(&data->handler_spinlock);
 
-       kfree(dev->dev.driver_data);
+       kfree(data);
+       data = NULL;
 
        return 0;
 }
 }
 module_exit(pmi_module_exit);
 
-void pmi_send_message(struct of_device *device, pmi_message_t msg)
+int pmi_send_message(pmi_message_t msg)
 {
-       struct pmi_data *data;
        unsigned long flags;
        DECLARE_COMPLETION_ONSTACK(completion);
 
-       data = device->dev.driver_data;
+       if (!data)
+               return -ENODEV;
 
        mutex_lock(&data->msg_mutex);
 
        data->completion = NULL;
 
        mutex_unlock(&data->msg_mutex);
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(pmi_send_message);
 
-void pmi_register_handler(struct of_device *device,
-                         struct pmi_handler *handler)
+int pmi_register_handler(struct pmi_handler *handler)
 {
-       struct pmi_data *data;
-       data = device->dev.driver_data;
-
        if (!data)
-               return;
+               return -ENODEV;
 
        spin_lock(&data->handler_spinlock);
        list_add_tail(&handler->node, &data->handler);
        spin_unlock(&data->handler_spinlock);
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(pmi_register_handler);
 
-void pmi_unregister_handler(struct of_device *device,
-                           struct pmi_handler *handler)
+void pmi_unregister_handler(struct pmi_handler *handler)
 {
-       struct pmi_data *data;
-       data = device->dev.driver_data;
-
        if (!data)
                return;