Commit 4760b9d9 authored by Russell King's avatar Russell King

[ARM] Convert ambakmi.c to AMBA device driver.

This cset makes use of our AMBA device model, thereby allowing the
"KMI" PrimeCell driver to become ARM platform independent.
parent 489e068e
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.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/arch.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
...@@ -104,7 +106,7 @@ static struct irqchip sc_chip = { ...@@ -104,7 +106,7 @@ static struct irqchip sc_chip = {
.mask = sc_mask_irq, .mask = sc_mask_irq,
.unmask = sc_unmask_irq, .unmask = sc_unmask_irq,
}; };
static void __init integrator_init_irq(void) static void __init integrator_init_irq(void)
{ {
unsigned int i; unsigned int i;
...@@ -126,6 +128,52 @@ static void __init integrator_init_irq(void) ...@@ -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") MACHINE_START(INTEGRATOR, "ARM-Integrator")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
......
/* /*
* 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. * Copyright (C) 2002 Russell King.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_kmi.h> #include <asm/hardware/amba_kmi.h>
#define KMI_BASE (kmi->base) #define KMI_BASE (kmi->base)
...@@ -28,11 +29,10 @@ ...@@ -28,11 +29,10 @@
struct amba_kmi_port { struct amba_kmi_port {
struct serio io; struct serio io;
struct amba_kmi_port *next; struct amba_kmi_port *next;
void *base; unsigned char *base;
unsigned int irq; unsigned int irq;
unsigned int divisor; unsigned int divisor;
char name[32]; unsigned int open;
char phys[16];
struct resource *res; struct resource *res;
}; };
...@@ -73,7 +73,7 @@ static int amba_kmi_open(struct serio *io) ...@@ -73,7 +73,7 @@ static int amba_kmi_open(struct serio *io)
writeb(kmi->divisor, KMICLKDIV); writeb(kmi->divisor, KMICLKDIV);
writeb(KMICR_EN, KMICR); 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) { if (ret) {
printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq); printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
writeb(0, KMICR); writeb(0, KMICR);
...@@ -94,9 +94,7 @@ static void amba_kmi_close(struct serio *io) ...@@ -94,9 +94,7 @@ static void amba_kmi_close(struct serio *io)
free_irq(kmi->irq, kmi); free_irq(kmi->irq, kmi);
} }
static struct amba_kmi_port *list; static int amba_kmi_probe(struct amba_device *dev, void *id)
static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int nr)
{ {
struct amba_kmi_port *kmi; struct amba_kmi_port *kmi;
...@@ -110,58 +108,83 @@ static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int ...@@ -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.write = amba_kmi_write;
kmi->io.open = amba_kmi_open; kmi->io.open = amba_kmi_open;
kmi->io.close = amba_kmi_close; kmi->io.close = amba_kmi_close;
kmi->io.name = kmi->name; kmi->io.name = dev->dev.name;
kmi->io.phys = kmi->phys; kmi->io.phys = dev->dev.bus_id;
kmi->io.driver = kmi; kmi->io.driver = kmi;
snprintf(kmi->name, sizeof(kmi->name), "AMBA KMI PS/2 %s port", type); kmi->res = request_mem_region(dev->res.start, KMI_SIZE, kmi->io.phys);
snprintf(kmi->phys, sizeof(kmi->phys), "amba/serio%d", nr);
kmi->res = request_mem_region(base, KMI_SIZE, kmi->phys);
if (!kmi->res) { if (!kmi->res) {
kfree(kmi); kfree(kmi);
return -EBUSY; return -EBUSY;
} }
kmi->base = ioremap(base, KMI_SIZE); kmi->base = ioremap(dev->res.start, KMI_SIZE);
if (!kmi->base) { if (!kmi->base) {
release_resource(kmi->res); release_resource(kmi->res);
kfree(kmi); kfree(kmi);
return -ENOMEM; return -ENOMEM;
} }
kmi->irq = irq; kmi->irq = dev->irq;
kmi->divisor = 24 / 8 - 1; kmi->divisor = 24 / 8 - 1;
kmi->next = list; amba_set_drvdata(dev, kmi);
list = kmi;
serio_register_port(&kmi->io); serio_register_port(&kmi->io);
return 0; 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); struct amba_kmi_port *kmi = amba_get_drvdata(dev);
amba_kmi_init_one("mouse", KMI1_BASE, IRQ_KMIINT1, 1);
amba_set_drvdata(dev, NULL);
serio_unregister_port(&kmi->io);
iounmap(kmi->base);
release_resource(kmi->res);
kfree(kmi);
return 0; 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; if (level == RESUME_ENABLE) {
while (kmi) { /* kick the serio layer to rescan this port */
next = kmi->next; serio_rescan(&kmi->io);
}
serio_unregister_port(&kmi->io); return 0;
iounmap(kmi->base); }
release_resource(kmi->res);
kfree(kmi);
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); module_init(amba_kmi_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment