Blame view
arch/powerpc/sysdev/mpc8xx_pic.c
4.1 KB
f2a0bd375 [POWERPC] 8xx: po... |
1 |
#include <linux/kernel.h> |
f2a0bd375 [POWERPC] 8xx: po... |
2 3 4 5 6 7 8 9 10 11 |
#include <linux/stddef.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/signal.h> #include <linux/irq.h> #include <linux/dma-mapping.h> #include <asm/prom.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/8xx_immap.h> |
f2a0bd375 [POWERPC] 8xx: po... |
12 13 14 15 16 17 18 |
#include "mpc8xx_pic.h" #define PIC_VEC_SPURRIOUS 15 extern int cpm_get_irq(struct pt_regs *regs); |
f2a0bd375 [POWERPC] 8xx: po... |
19 20 21 |
static struct irq_host *mpc8xx_pic_host; #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; |
fb533d0c5 [POWERPC] 8xx: In... |
22 |
static sysconf8xx_t __iomem *siu_reg; |
f2a0bd375 [POWERPC] 8xx: po... |
23 24 |
int cpm_get_irq(struct pt_regs *regs); |
febd40178 powerpc: sysdev/m... |
25 |
static void mpc8xx_unmask_irq(struct irq_data *d) |
f2a0bd375 [POWERPC] 8xx: po... |
26 27 |
{ int bit, word; |
476eb4912 powerpc/irq: Stop... |
28 |
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); |
f2a0bd375 [POWERPC] 8xx: po... |
29 30 31 32 33 34 35 |
bit = irq_nr & 0x1f; word = irq_nr >> 5; ppc_cached_irq_mask[word] |= (1 << (31-bit)); out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } |
febd40178 powerpc: sysdev/m... |
36 |
static void mpc8xx_mask_irq(struct irq_data *d) |
f2a0bd375 [POWERPC] 8xx: po... |
37 38 |
{ int bit, word; |
476eb4912 powerpc/irq: Stop... |
39 |
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); |
f2a0bd375 [POWERPC] 8xx: po... |
40 41 42 43 44 45 46 |
bit = irq_nr & 0x1f; word = irq_nr >> 5; ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } |
febd40178 powerpc: sysdev/m... |
47 |
static void mpc8xx_ack(struct irq_data *d) |
f2a0bd375 [POWERPC] 8xx: po... |
48 49 |
{ int bit; |
476eb4912 powerpc/irq: Stop... |
50 |
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); |
f2a0bd375 [POWERPC] 8xx: po... |
51 52 53 54 |
bit = irq_nr & 0x1f; out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); } |
febd40178 powerpc: sysdev/m... |
55 |
static void mpc8xx_end_irq(struct irq_data *d) |
f2a0bd375 [POWERPC] 8xx: po... |
56 57 |
{ int bit, word; |
476eb4912 powerpc/irq: Stop... |
58 |
unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); |
f2a0bd375 [POWERPC] 8xx: po... |
59 60 61 62 63 64 65 |
bit = irq_nr & 0x1f; word = irq_nr >> 5; ppc_cached_irq_mask[word] |= (1 << (31-bit)); out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } |
febd40178 powerpc: sysdev/m... |
66 |
static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) |
f2a0bd375 [POWERPC] 8xx: po... |
67 |
{ |
f2a0bd375 [POWERPC] 8xx: po... |
68 |
if (flow_type & IRQ_TYPE_EDGE_FALLING) { |
476eb4912 powerpc/irq: Stop... |
69 |
irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); |
f2a0bd375 [POWERPC] 8xx: po... |
70 71 72 73 74 75 |
unsigned int siel = in_be32(&siu_reg->sc_siel); /* only external IRQ senses are programmable */ if ((hw & 1) == 0) { siel |= (0x80000000 >> hw); out_be32(&siu_reg->sc_siel, siel); |
b3cf2bb3d powerpc/8xx: Fix ... |
76 |
__irq_set_handler_locked(d->irq, handle_edge_irq); |
f2a0bd375 [POWERPC] 8xx: po... |
77 78 79 80 81 82 |
} } return 0; } static struct irq_chip mpc8xx_pic = { |
fc380c0c8 powerpc: Remove w... |
83 |
.name = "MPC8XX SIU", |
febd40178 powerpc: sysdev/m... |
84 85 86 87 88 |
.irq_unmask = mpc8xx_unmask_irq, .irq_mask = mpc8xx_mask_irq, .irq_ack = mpc8xx_ack, .irq_eoi = mpc8xx_end_irq, .irq_set_type = mpc8xx_set_irq_type, |
f2a0bd375 [POWERPC] 8xx: po... |
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
}; unsigned int mpc8xx_get_irq(void) { int irq; /* For MPC8xx, read the SIVEC register and shift the bits down * to get the irq number. */ irq = in_be32(&siu_reg->sc_sivec) >> 26; if (irq == PIC_VEC_SPURRIOUS) irq = NO_IRQ; return irq_linear_revmap(mpc8xx_pic_host, irq); } |
f2a0bd375 [POWERPC] 8xx: po... |
106 107 108 109 110 111 112 |
static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { pr_debug("mpc8xx_pic_host_map(%d, 0x%lx) ", virq, hw); /* Set default irq handle */ |
ec775d0e7 powerpc: Convert ... |
113 |
irq_set_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq); |
f2a0bd375 [POWERPC] 8xx: po... |
114 115 116 117 118 |
return 0; } static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct, |
40d50cf7c powerpc: Make "in... |
119 |
const u32 *intspec, unsigned int intsize, |
f2a0bd375 [POWERPC] 8xx: po... |
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
irq_hw_number_t *out_hwirq, unsigned int *out_flags) { static unsigned char map_pic_senses[4] = { IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_FALLING, }; *out_hwirq = intspec[0]; if (intsize > 1 && intspec[1] < 4) *out_flags = map_pic_senses[intspec[1]]; else *out_flags = IRQ_TYPE_NONE; return 0; } static struct irq_host_ops mpc8xx_pic_host_ops = { |
f2a0bd375 [POWERPC] 8xx: po... |
140 141 142 143 144 145 146 |
.map = mpc8xx_pic_host_map, .xlate = mpc8xx_pic_host_xlate, }; int mpc8xx_pic_init(void) { struct resource res; |
fb533d0c5 [POWERPC] 8xx: In... |
147 |
struct device_node *np; |
f2a0bd375 [POWERPC] 8xx: po... |
148 |
int ret; |
fb533d0c5 [POWERPC] 8xx: In... |
149 150 151 |
np = of_find_compatible_node(NULL, NULL, "fsl,pq1-pic"); if (np == NULL) np = of_find_node_by_type(NULL, "mpc8xx-pic"); |
f2a0bd375 [POWERPC] 8xx: po... |
152 |
if (np == NULL) { |
fb533d0c5 [POWERPC] 8xx: In... |
153 154 |
printk(KERN_ERR "Could not find fsl,pq1-pic node "); |
f2a0bd375 [POWERPC] 8xx: po... |
155 156 |
return -ENOMEM; } |
f2a0bd375 [POWERPC] 8xx: po... |
157 |
ret = of_address_to_resource(np, 0, &res); |
f2a0bd375 [POWERPC] 8xx: po... |
158 |
if (ret) |
52964f87c [POWERPC] Add an ... |
159 |
goto out; |
f2a0bd375 [POWERPC] 8xx: po... |
160 |
|
28f65c11f treewide: Convert... |
161 |
siu_reg = ioremap(res.start, resource_size(&res)); |
b1725c931 [POWERPC] arch/po... |
162 163 164 165 |
if (siu_reg == NULL) { ret = -EINVAL; goto out; } |
f2a0bd375 [POWERPC] 8xx: po... |
166 |
|
b1725c931 [POWERPC] arch/po... |
167 |
mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, |
52964f87c [POWERPC] Add an ... |
168 |
64, &mpc8xx_pic_host_ops, 64); |
f2a0bd375 [POWERPC] 8xx: po... |
169 170 171 172 |
if (mpc8xx_pic_host == NULL) { printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host! "); ret = -ENOMEM; |
b1725c931 [POWERPC] arch/po... |
173 |
goto out; |
f2a0bd375 [POWERPC] 8xx: po... |
174 |
} |
b1725c931 [POWERPC] arch/po... |
175 |
return 0; |
f2a0bd375 [POWERPC] 8xx: po... |
176 |
|
52964f87c [POWERPC] Add an ... |
177 178 |
out: of_node_put(np); |
f2a0bd375 [POWERPC] 8xx: po... |
179 180 |
return ret; } |