]> git.neil.brown.name Git - history.git/commitdiff
[ARM] Convert ambakmi.c to AMBA device driver.
authorRussell King <rmk@flint.arm.linux.org.uk>
Thu, 19 Jun 2003 00:45:53 +0000 (01:45 +0100)
committerRussell King <rmk@flint.arm.linux.org.uk>
Thu, 19 Jun 2003 00:45:53 +0000 (01:45 +0100)
This cset makes use of our AMBA device model, thereby allowing the
"KMI" PrimeCell driver to become ARM platform independent.

arch/arm/mach-integrator/core.c
drivers/input/serio/ambakmi.c

index 88dd84ad01dd7ea38ab4b7bc044a8d29b70b7267..c7e7eb4a9c4304f76c27257ba0c287d87a998f36 100644 (file)
@@ -31,6 +31,8 @@
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
+#include <asm/hardware/amba.h>
+#include <asm/hardware/amba_kmi.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
@@ -104,7 +106,7 @@ static struct irqchip sc_chip = {
        .mask   = sc_mask_irq,
        .unmask = sc_unmask_irq,
 };
+
 static void __init integrator_init_irq(void)
 {
        unsigned int i;
@@ -126,6 +128,52 @@ static void __init integrator_init_irq(void)
        }
 }
 
+static struct amba_device kmi0_device = {
+       .dev            = {
+               .bus_id = "mb:18",
+       },
+       .res            = {
+               .start  = KMI0_BASE,
+               .end    = KMI0_BASE + KMI_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = IRQ_KMIINT0,
+       .periphid       = 0x00041050,
+};
+
+static struct amba_device kmi1_device = {
+       .dev            = {
+               .bus_id = "mb:19",
+       },
+       .res            = {
+               .start  = KMI1_BASE,
+               .end    = KMI1_BASE + KMI_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq            = IRQ_KMIINT1,
+       .periphid       = 0x00041050,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+       &kmi0_device,
+       &kmi1_device,
+};
+
+static int __init register_devices(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+               struct amba_device *d = amba_devs[i];
+
+               amba_device_register(d, &iomem_resource);
+       }
+
+       return 0;
+}
+
+arch_initcall(register_devices);
+
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
        MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
        BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
index 297103a968d59dc5c0cd26f8b53422d03f1fb5d7..7112bdcda8f86b95f56802589a1424c1cc0b2488 100644 (file)
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/input/serio/amba_kmi.c
+ *  linux/drivers/input/serio/ambakmi.c
  *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd.
  *  Copyright (C) 2002 Russell King.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/hardware/amba.h>
 #include <asm/hardware/amba_kmi.h>
 
 #define KMI_BASE       (kmi->base)
 struct amba_kmi_port {
        struct serio            io;
        struct amba_kmi_port    *next;
-       void                    *base;
+       unsigned char           *base;
        unsigned int            irq;
        unsigned int            divisor;
-       char                    name[32];
-       char                    phys[16];
+       unsigned int            open;
        struct resource         *res;
 };
 
@@ -73,7 +73,7 @@ static int amba_kmi_open(struct serio *io)
        writeb(kmi->divisor, KMICLKDIV);
        writeb(KMICR_EN, KMICR);
 
-       ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->phys, kmi);
+       ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->io.phys, kmi);
        if (ret) {
                printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
                writeb(0, KMICR);
@@ -94,9 +94,7 @@ static void amba_kmi_close(struct serio *io)
        free_irq(kmi->irq, kmi);
 }
 
-static struct amba_kmi_port *list;
-
-static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int nr)
+static int amba_kmi_probe(struct amba_device *dev, void *id)
 {
        struct amba_kmi_port *kmi;
 
@@ -110,58 +108,83 @@ static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int
        kmi->io.write   = amba_kmi_write;
        kmi->io.open    = amba_kmi_open;
        kmi->io.close   = amba_kmi_close;
-       kmi->io.name    = kmi->name;
-       kmi->io.phys    = kmi->phys;
+       kmi->io.name    = dev->dev.name;
+       kmi->io.phys    = dev->dev.bus_id;
        kmi->io.driver  = kmi;
 
-       snprintf(kmi->name, sizeof(kmi->name), "AMBA KMI PS/2 %s port", type);
-       snprintf(kmi->phys, sizeof(kmi->phys), "amba/serio%d", nr);
-
-       kmi->res        = request_mem_region(base, KMI_SIZE, kmi->phys);
+       kmi->res        = request_mem_region(dev->res.start, KMI_SIZE, kmi->io.phys);
        if (!kmi->res) {
                kfree(kmi);
                return -EBUSY;
        }
 
-       kmi->base       = ioremap(base, KMI_SIZE);
+       kmi->base       = ioremap(dev->res.start, KMI_SIZE);
        if (!kmi->base) {
                release_resource(kmi->res);
                kfree(kmi);
                return -ENOMEM;
        }
 
-       kmi->irq        = irq;
+       kmi->irq        = dev->irq;
        kmi->divisor    = 24 / 8 - 1;
 
-       kmi->next       = list;
-       list            = kmi;
+       amba_set_drvdata(dev, kmi);
 
        serio_register_port(&kmi->io);
        return 0;
 }
 
-static int __init amba_kmi_init(void)
+static int amba_kmi_remove(struct amba_device *dev)
 {
-       amba_kmi_init_one("keyboard", KMI0_BASE, IRQ_KMIINT0, 0);
-       amba_kmi_init_one("mouse", KMI1_BASE, IRQ_KMIINT1, 1);
+       struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+
+       amba_set_drvdata(dev, NULL);
+
+       serio_unregister_port(&kmi->io);
+       iounmap(kmi->base);
+       release_resource(kmi->res);
+       kfree(kmi);
        return 0;
 }
 
-static void __exit amba_kmi_exit(void)
+static int amba_kmi_resume(struct amba_device *dev, u32 level)
 {
-       struct amba_kmi_port *kmi, *next;
+       struct amba_kmi_port *kmi = amba_get_drvdata(dev);
 
-       kmi = list;
-       while (kmi) {
-               next = kmi->next;
+       if (level == RESUME_ENABLE) {
+               /* kick the serio layer to rescan this port */
+               serio_rescan(&kmi->io);
+       }
 
-               serio_unregister_port(&kmi->io);
-               iounmap(kmi->base);
-               release_resource(kmi->res);
-               kfree(kmi);
+       return 0;
+}
 
-               kmi = next;
-       }
+static struct amba_id amba_kmi_idtable[] = {
+       {
+               .id     = 0x00041050,
+               .mask   = 0x000fffff,
+       },
+       { 0, 0 }
+};
+
+static struct amba_driver ambakmi_driver = {
+       .drv            = {
+               .name   = "kmi-pl050",
+       },
+       .id_table       = amba_kmi_idtable,
+       .probe          = amba_kmi_probe,
+       .remove         = amba_kmi_remove,
+       .resume         = amba_kmi_resume,
+};
+
+static int __init amba_kmi_init(void)
+{
+       return amba_driver_register(&ambakmi_driver);
+}
+
+static void __exit amba_kmi_exit(void)
+{
+       return amba_driver_unregister(&ambakmi_driver);
 }
 
 module_init(amba_kmi_init);