hh.org updates
[hh.org.git] / arch / arm / mach-pxa / eseries / tmio.c
blob39fd515b9a413069a95d335df467e1c46598f380
1 /*
2 * arch/arm/mach-pxa/eseries/tmio.c
4 * Support for the TMIO ASIC in the Toshiba e800
6 * Author: Ian Molton and Sebastian Carlier
7 * Created: Sat 7 Aug 2004
8 * Copyright: Ian Molton and Sebastian Carlier
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/device.h>
19 #include <linux/major.h>
20 #include <linux/fb.h>
21 #include <linux/interrupt.h>
23 #include <asm/setup.h>
24 #include <asm/memory.h>
25 #include <asm/mach-types.h>
26 #include <asm/hardware.h>
27 #include <asm/irq.h>
29 #include <asm/mach/arch.h>
30 #include <asm/mach/map.h>
31 #include <asm/mach/irq.h>
33 #include <asm/arch/pxa-regs.h>
34 #include <asm/arch/eseries-irq.h>
35 #include <asm/arch/eseries-gpio.h>
37 #define TMIO_B(n) (*(unsigned char *)(tmio_io_base + (n)))
39 static struct resource * tmio_io_res;
40 static void* tmio_io_base;
41 static int tmio_host_irq;
43 static void tmio_mask_irq(unsigned int irq)
45 int tmio_irq = irq - TMIO_IRQ_BASE;
46 // printk("tmio: mask %u\n", irq);
47 switch (tmio_irq) {
48 case 0: TMIO_B(0x52) |= 0x01; break;
49 case 1: TMIO_B(0x52) |= 0x02; break;
50 case 2: TMIO_B(0x52) |= 0x04; break;
51 case 3: TMIO_B(0x52) |= 0x10; break;
55 static void tmio_unmask_irq(unsigned int irq)
57 int tmio_irq = irq - TMIO_IRQ_BASE;
58 // printk("tmio: unmask %u\n", irq);
59 switch (tmio_irq) {
60 case 0: TMIO_B(0x52) &= ~0x01; break;
61 case 1: TMIO_B(0x52) &= ~0x02; break;
62 case 2: TMIO_B(0x52) &= ~0x04; break;
63 case 3: TMIO_B(0x52) &= ~0x10; break;
67 static struct irqchip tmio_irq_chip = {
68 .ack = tmio_mask_irq,
69 .mask = tmio_mask_irq,
70 .unmask = tmio_unmask_irq,
74 static void tmio_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
76 unsigned long mask, pending;
77 int count = 0;
79 mask = TMIO_B(0x52);
80 pending = TMIO_B(0x50) & ~mask;
81 // printk("TMIO: irq! %02x %02x\n", mask, pending);
82 TMIO_B(0x54) = 0xff; // Mask TMIO IRQs (note! winCE doesnt use this method)
83 GEDR(tmio_host_irq) = GPIO_bit(tmio_host_irq); /* XXX; clear our parent irq */
84 while (pending) {
85 irq = TMIO_IRQ_BASE + __ffs(pending);
86 // printk("IRQ: %d %d\n", count++, irq);
87 desc = irq_desc + irq;
88 desc->handle(irq, desc, regs);
89 pending &= ~(1<<__ffs(pending));
91 TMIO_B(0x54) = 0;
94 int tmio_init_irq(int h_irq, unsigned int phys_base)
96 static int inited; //FIXME hack!
97 int ret, irq;
99 if(inited)
100 return;
101 inited = 1;
102 tmio_io_res = kmalloc(sizeof(*tmio_io_res), GFP_KERNEL);
103 if (!tmio_io_res) {
104 ret = -ENOMEM;
105 goto fail;
108 tmio_io_res->name = "TMIO";
109 tmio_io_res->start = phys_base;
110 tmio_io_res->end = phys_base + 0xff;
111 tmio_io_res->flags = IORESOURCE_IO;
112 ret = request_resource(&iomem_resource, tmio_io_res);
113 if (ret)
114 goto fail_1;
116 tmio_io_base = ioremap(phys_base, 0x100);
117 if (!tmio_io_base) {
118 ret = -EBUSY;
119 goto fail_2;
121 tmio_host_irq = h_irq;
123 // Now initialize the hardware
124 set_irq_type(tmio_host_irq, IRQT_NOEDGE);
125 // Clear pending requests
126 TMIO_B(0x54) = 0xff; //FIXME - this doesnt clear, it masks.
128 /* setup extra lubbock irqs */
129 for (irq = TMIO_IRQ_BASE; irq < TMIO_IRQ_BASE+4; irq++) {
130 set_irq_chip(irq, &tmio_irq_chip);
131 set_irq_handler(irq, do_level_IRQ);
132 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); // XXX probe?
135 set_irq_chained_handler(tmio_host_irq, tmio_irq_handler);
137 printk("tmio: initialised.\n");
139 // Re-enable interrupt
140 set_irq_type(tmio_host_irq, IRQT_FALLING);
141 TMIO_B(0x54) = 0;
143 return 0;
144 fail_2:
145 release_resource(tmio_io_res);
146 fail_1:
147 kfree(tmio_io_res);
148 fail:
149 return ret;
152 EXPORT_SYMBOL(tmio_init_irq);