X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Fpowerpc%2Fsysdev%2Fpmi.c;h=20edd1e94eff7111927fef861236f8827e002b4d;hb=d773b33972a663cfaf066e966f87922a74088a1e;hp=a5282011d39e6b2f4bb0a31008cc4729cc3ce60c;hpb=2370965c5065b24b28b5ba09b60ddfbfb6d7649b;p=linux-2.6-omap-h63xx.git diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index a5282011d39..20edd1e94ef 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -33,7 +33,7 @@ #include #include #include - +#include struct pmi_data { struct list_head handler; @@ -48,30 +48,13 @@ struct pmi_data { struct work_struct work; }; - - -static void __iomem *of_iomap(struct device_node *np) -{ - struct resource res; - - if (of_address_to_resource(np, 0, &res)) - return NULL; - - pr_debug("Resource start: 0x%lx\n", res.start); - pr_debug("Resource end: 0x%lx\n", res.end); - - return ioremap(res.start, 1 + res.end - res.start); -} - +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); @@ -118,6 +101,7 @@ out: static struct of_device_id pmi_match[] = { { .type = "ibm,pmi", .name = "ibm,pmi" }, + { .type = "ibm,pmi" }, {}, }; @@ -125,16 +109,13 @@ MODULE_DEVICE_TABLE(of, pmi_match); 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); } @@ -143,9 +124,14 @@ static int pmi_of_probe(struct of_device *dev, 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"); @@ -153,7 +139,7 @@ static int pmi_of_probe(struct of_device *dev, goto out; } - data->pmi_reg = of_iomap(np); + data->pmi_reg = of_iomap(np, 0); if (!data->pmi_reg) { printk(KERN_ERR "pmi: invalid register address.\n"); rc = -EFAULT; @@ -168,7 +154,6 @@ static int pmi_of_probe(struct of_device *dev, INIT_WORK(&data->work, pmi_notify_handlers); - dev->dev.driver_data = data; data->dev = dev; data->irq = irq_of_parse_and_map(np, 0); @@ -178,7 +163,7 @@ static int pmi_of_probe(struct of_device *dev, 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); @@ -201,12 +186,9 @@ out: 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); @@ -216,16 +198,19 @@ static int pmi_of_remove(struct of_device *dev) spin_unlock(&data->handler_spinlock); - kfree(dev->dev.driver_data); + kfree(data); + data = NULL; return 0; } static struct of_platform_driver pmi_of_platform_driver = { - .name = "pmi", .match_table = pmi_match, .probe = pmi_of_probe, - .remove = pmi_of_remove + .remove = pmi_of_remove, + .driver = { + .name = "pmi", + }, }; static int __init pmi_module_init(void) @@ -240,13 +225,13 @@ static void __exit pmi_module_exit(void) } 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); @@ -270,30 +255,31 @@ void pmi_send_message(struct of_device *device, pmi_message_t msg) 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 -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; + if (!data) + return; pr_debug("pmi: unregistering handler %p\n", handler); - data = device->dev.driver_data; - spin_lock(&data->handler_spinlock); list_del(&handler->node); spin_unlock(&data->handler_spinlock);