1#include <linux/init.h> 2#include <linux/list.h> 3#include <linux/io.h> 4 5#include <asm/mach/irq.h> 6#include <asm/hardware/iomd.h> 7#include <asm/irq.h> 8#include <asm/fiq.h> 9 10static void iomd_ack_irq_a(struct irq_data *d) 11{ 12 unsigned int val, mask; 13 14 mask = 1 << d->irq; 15 val = iomd_readb(IOMD_IRQMASKA); 16 iomd_writeb(val & ~mask, IOMD_IRQMASKA); 17 iomd_writeb(mask, IOMD_IRQCLRA); 18} 19 20static void iomd_mask_irq_a(struct irq_data *d) 21{ 22 unsigned int val, mask; 23 24 mask = 1 << d->irq; 25 val = iomd_readb(IOMD_IRQMASKA); 26 iomd_writeb(val & ~mask, IOMD_IRQMASKA); 27} 28 29static void iomd_unmask_irq_a(struct irq_data *d) 30{ 31 unsigned int val, mask; 32 33 mask = 1 << d->irq; 34 val = iomd_readb(IOMD_IRQMASKA); 35 iomd_writeb(val | mask, IOMD_IRQMASKA); 36} 37 38static struct irq_chip iomd_a_chip = { 39 .irq_ack = iomd_ack_irq_a, 40 .irq_mask = iomd_mask_irq_a, 41 .irq_unmask = iomd_unmask_irq_a, 42}; 43 44static void iomd_mask_irq_b(struct irq_data *d) 45{ 46 unsigned int val, mask; 47 48 mask = 1 << (d->irq & 7); 49 val = iomd_readb(IOMD_IRQMASKB); 50 iomd_writeb(val & ~mask, IOMD_IRQMASKB); 51} 52 53static void iomd_unmask_irq_b(struct irq_data *d) 54{ 55 unsigned int val, mask; 56 57 mask = 1 << (d->irq & 7); 58 val = iomd_readb(IOMD_IRQMASKB); 59 iomd_writeb(val | mask, IOMD_IRQMASKB); 60} 61 62static struct irq_chip iomd_b_chip = { 63 .irq_ack = iomd_mask_irq_b, 64 .irq_mask = iomd_mask_irq_b, 65 .irq_unmask = iomd_unmask_irq_b, 66}; 67 68static void iomd_mask_irq_dma(struct irq_data *d) 69{ 70 unsigned int val, mask; 71 72 mask = 1 << (d->irq & 7); 73 val = iomd_readb(IOMD_DMAMASK); 74 iomd_writeb(val & ~mask, IOMD_DMAMASK); 75} 76 77static void iomd_unmask_irq_dma(struct irq_data *d) 78{ 79 unsigned int val, mask; 80 81 mask = 1 << (d->irq & 7); 82 val = iomd_readb(IOMD_DMAMASK); 83 iomd_writeb(val | mask, IOMD_DMAMASK); 84} 85 86static struct irq_chip iomd_dma_chip = { 87 .irq_ack = iomd_mask_irq_dma, 88 .irq_mask = iomd_mask_irq_dma, 89 .irq_unmask = iomd_unmask_irq_dma, 90}; 91 92static void iomd_mask_irq_fiq(struct irq_data *d) 93{ 94 unsigned int val, mask; 95 96 mask = 1 << (d->irq & 7); 97 val = iomd_readb(IOMD_FIQMASK); 98 iomd_writeb(val & ~mask, IOMD_FIQMASK); 99} 100 101static void iomd_unmask_irq_fiq(struct irq_data *d) 102{ 103 unsigned int val, mask; 104 105 mask = 1 << (d->irq & 7); 106 val = iomd_readb(IOMD_FIQMASK); 107 iomd_writeb(val | mask, IOMD_FIQMASK); 108} 109 110static struct irq_chip iomd_fiq_chip = { 111 .irq_ack = iomd_mask_irq_fiq, 112 .irq_mask = iomd_mask_irq_fiq, 113 .irq_unmask = iomd_unmask_irq_fiq, 114}; 115 116extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; 117 118void __init rpc_init_irq(void) 119{ 120 unsigned int irq, clr, set = 0; 121 122 iomd_writeb(0, IOMD_IRQMASKA); 123 iomd_writeb(0, IOMD_IRQMASKB); 124 iomd_writeb(0, IOMD_FIQMASK); 125 iomd_writeb(0, IOMD_DMAMASK); 126 127 set_fiq_handler(&rpc_default_fiq_start, 128 &rpc_default_fiq_end - &rpc_default_fiq_start); 129 130 for (irq = 0; irq < NR_IRQS; irq++) { 131 clr = IRQ_NOREQUEST; 132 133 if (irq <= 6 || (irq >= 9 && irq <= 15)) 134 clr |= IRQ_NOPROBE; 135 136 if (irq == 21 || (irq >= 16 && irq <= 19) || 137 irq == IRQ_KEYBOARDTX) 138 set |= IRQ_NOAUTOEN; 139 140 switch (irq) { 141 case 0 ... 7: 142 irq_set_chip_and_handler(irq, &iomd_a_chip, 143 handle_level_irq); 144 irq_modify_status(irq, clr, set); 145 break; 146 147 case 8 ... 15: 148 irq_set_chip_and_handler(irq, &iomd_b_chip, 149 handle_level_irq); 150 irq_modify_status(irq, clr, set); 151 break; 152 153 case 16 ... 21: 154 irq_set_chip_and_handler(irq, &iomd_dma_chip, 155 handle_level_irq); 156 irq_modify_status(irq, clr, set); 157 break; 158 159 case 64 ... 71: 160 irq_set_chip(irq, &iomd_fiq_chip); 161 irq_modify_status(irq, clr, set); 162 break; 163 } 164 } 165 166 init_FIQ(FIQ_START); 167} 168 169