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>
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>
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);
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);
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
= {
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
;
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 */
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
));
94 int tmio_init_irq(int h_irq
, unsigned int phys_base
)
96 static int inited
; //FIXME hack!
102 tmio_io_res
= kmalloc(sizeof(*tmio_io_res
), GFP_KERNEL
);
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
);
116 tmio_io_base
= ioremap(phys_base
, 0x100);
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
);
145 release_resource(tmio_io_res
);
152 EXPORT_SYMBOL(tmio_init_irq
);