Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / input / serio / i8042-sparcio.h
index ed9446f..54adba2 100644 (file)
@@ -1,13 +1,10 @@
 #ifndef _I8042_SPARCIO_H
 #define _I8042_SPARCIO_H
 
-#include <linux/config.h>
 #include <asm/io.h>
-
-#ifdef CONFIG_PCI
 #include <asm/oplib.h>
-#include <asm/ebus.h>
-#endif
+#include <asm/prom.h>
+#include <asm/of_device.h>
 
 static int i8042_kbd_irq = -1;
 static int i8042_aux_irq = -1;
@@ -48,54 +45,83 @@ static inline void i8042_write_command(int val)
 #define OBP_PS2MS_NAME1                "kdmouse"
 #define OBP_PS2MS_NAME2                "mouse"
 
+static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match)
+{
+       struct device_node *dp = op->node;
+
+       dp = dp->child;
+       while (dp) {
+               if (!strcmp(dp->name, OBP_PS2KBD_NAME1) ||
+                   !strcmp(dp->name, OBP_PS2KBD_NAME2)) {
+                       struct of_device *kbd = of_find_device_by_node(dp);
+                       unsigned int irq = kbd->irqs[0];
+                       if (irq == 0xffffffff)
+                               irq = op->irqs[0];
+                       i8042_kbd_irq = irq;
+                       kbd_iobase = of_ioremap(&kbd->resource[0],
+                                               0, 8, "kbd");
+               } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) ||
+                          !strcmp(dp->name, OBP_PS2MS_NAME2)) {
+                       struct of_device *ms = of_find_device_by_node(dp);
+                       unsigned int irq = ms->irqs[0];
+                       if (irq == 0xffffffff)
+                               irq = op->irqs[0];
+                       i8042_aux_irq = irq;
+               }
+
+               dp = dp->sibling;
+       }
+
+       return 0;
+}
+
+static int __devexit sparc_i8042_remove(struct of_device *op)
+{
+       of_iounmap(kbd_iobase, 8);
+
+       return 0;
+}
+
+static struct of_device_id sparc_i8042_match[] = {
+       {
+               .name = "8042",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, sparc_i8042_match);
+
+static struct of_platform_driver sparc_i8042_driver = {
+       .name           = "i8042",
+       .match_table    = sparc_i8042_match,
+       .probe          = sparc_i8042_probe,
+       .remove         = __devexit_p(sparc_i8042_remove),
+};
+
 static int __init i8042_platform_init(void)
 {
 #ifndef CONFIG_PCI
        return -ENODEV;
 #else
-       char prop[128];
-       int len;
+       struct device_node *root = of_find_node_by_path("/");
 
-       len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop));
-       if (len < 0) {
-               printk("i8042: Cannot get name property of root OBP node.\n");
-               return -ENODEV;
-       }
-       if (strncmp(prop, "SUNW,JavaStation-1", len) == 0) {
+       if (!strcmp(root->name, "SUNW,JavaStation-1")) {
                /* Hardcoded values for MrCoffee.  */
                i8042_kbd_irq = i8042_aux_irq = 13 | 0x20;
                kbd_iobase = ioremap(0x71300060, 8);
                if (!kbd_iobase)
                        return -ENODEV;
        } else {
-               struct linux_ebus *ebus;
-               struct linux_ebus_device *edev;
-               struct linux_ebus_child *child;
-
-               for_each_ebus(ebus) {
-                       for_each_ebusdev(edev, ebus) {
-                               if (!strcmp(edev->prom_name, "8042"))
-                                       goto edev_found;
-                       }
-               }
-               return -ENODEV;
-
-       edev_found:
-               for_each_edevchild(edev, child) {
-                       if (!strcmp(child->prom_name, OBP_PS2KBD_NAME1) ||
-                           !strcmp(child->prom_name, OBP_PS2KBD_NAME2)) {
-                               i8042_kbd_irq = child->irqs[0];
-                               kbd_iobase =
-                                       ioremap(child->resource[0].start, 8);
-                       }
-                       if (!strcmp(child->prom_name, OBP_PS2MS_NAME1) ||
-                           !strcmp(child->prom_name, OBP_PS2MS_NAME2))
-                               i8042_aux_irq = child->irqs[0];
-               }
+               int err = of_register_driver(&sparc_i8042_driver,
+                                            &of_bus_type);
+               if (err)
+                       return err;
+
                if (i8042_kbd_irq == -1 ||
                    i8042_aux_irq == -1) {
-                       printk("i8042: Error, 8042 device lacks both kbd and "
-                              "mouse nodes.\n");
+                       if (kbd_iobase) {
+                               of_iounmap(kbd_iobase, 8);
+                               kbd_iobase = (void __iomem *) NULL;
+                       }
                        return -ENODEV;
                }
        }
@@ -109,7 +135,10 @@ static int __init i8042_platform_init(void)
 static inline void i8042_platform_exit(void)
 {
 #ifdef CONFIG_PCI
-       iounmap(kbd_iobase);
+       struct device_node *root = of_find_node_by_path("/");
+
+       if (strcmp(root->name, "SUNW,JavaStation-1"))
+               of_unregister_driver(&sparc_i8042_driver);
 #endif
 }