diff options
Diffstat (limited to 'arch/powerpc/platforms/cell')
-rw-r--r-- | arch/powerpc/platforms/cell/interrupt.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spider-pic.c | 70 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 6 |
3 files changed, 45 insertions, 35 deletions
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 9d5da789689..d7bbb61109f 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c | |||
@@ -159,7 +159,7 @@ static void iic_request_ipi(int ipi, const char *name) | |||
159 | if (iic_hosts[node] == NULL) | 159 | if (iic_hosts[node] == NULL) |
160 | continue; | 160 | continue; |
161 | virq = irq_create_mapping(iic_hosts[node], | 161 | virq = irq_create_mapping(iic_hosts[node], |
162 | iic_ipi_to_irq(ipi), 0); | 162 | iic_ipi_to_irq(ipi)); |
163 | if (virq == NO_IRQ) { | 163 | if (virq == NO_IRQ) { |
164 | printk(KERN_ERR | 164 | printk(KERN_ERR |
165 | "iic: failed to map IPI %s on node %d\n", | 165 | "iic: failed to map IPI %s on node %d\n", |
@@ -197,7 +197,7 @@ static int iic_host_match(struct irq_host *h, struct device_node *node) | |||
197 | } | 197 | } |
198 | 198 | ||
199 | static int iic_host_map(struct irq_host *h, unsigned int virq, | 199 | static int iic_host_map(struct irq_host *h, unsigned int virq, |
200 | irq_hw_number_t hw, unsigned int flags) | 200 | irq_hw_number_t hw) |
201 | { | 201 | { |
202 | if (hw < IIC_IRQ_IPI0) | 202 | if (hw < IIC_IRQ_IPI0) |
203 | set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); | 203 | set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); |
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index ae7ef88f1a3..15217bb0402 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c | |||
@@ -85,9 +85,6 @@ static void spider_unmask_irq(unsigned int virq) | |||
85 | struct spider_pic *pic = spider_virq_to_pic(virq); | 85 | struct spider_pic *pic = spider_virq_to_pic(virq); |
86 | void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); | 86 | void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); |
87 | 87 | ||
88 | /* We use no locking as we should be covered by the descriptor lock | ||
89 | * for access to invidual source configuration registers | ||
90 | */ | ||
91 | out_be32(cfg, in_be32(cfg) | 0x30000000u); | 88 | out_be32(cfg, in_be32(cfg) | 0x30000000u); |
92 | } | 89 | } |
93 | 90 | ||
@@ -96,9 +93,6 @@ static void spider_mask_irq(unsigned int virq) | |||
96 | struct spider_pic *pic = spider_virq_to_pic(virq); | 93 | struct spider_pic *pic = spider_virq_to_pic(virq); |
97 | void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); | 94 | void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); |
98 | 95 | ||
99 | /* We use no locking as we should be covered by the descriptor lock | ||
100 | * for access to invidual source configuration registers | ||
101 | */ | ||
102 | out_be32(cfg, in_be32(cfg) & ~0x30000000u); | 96 | out_be32(cfg, in_be32(cfg) & ~0x30000000u); |
103 | } | 97 | } |
104 | 98 | ||
@@ -120,26 +114,14 @@ static void spider_ack_irq(unsigned int virq) | |||
120 | out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf)); | 114 | out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf)); |
121 | } | 115 | } |
122 | 116 | ||
123 | static struct irq_chip spider_pic = { | 117 | static int spider_set_irq_type(unsigned int virq, unsigned int type) |
124 | .typename = " SPIDER ", | ||
125 | .unmask = spider_unmask_irq, | ||
126 | .mask = spider_mask_irq, | ||
127 | .ack = spider_ack_irq, | ||
128 | }; | ||
129 | |||
130 | static int spider_host_match(struct irq_host *h, struct device_node *node) | ||
131 | { | ||
132 | struct spider_pic *pic = h->host_data; | ||
133 | return node == pic->of_node; | ||
134 | } | ||
135 | |||
136 | static int spider_host_map(struct irq_host *h, unsigned int virq, | ||
137 | irq_hw_number_t hw, unsigned int flags) | ||
138 | { | 118 | { |
139 | unsigned int sense = flags & IRQ_TYPE_SENSE_MASK; | 119 | unsigned int sense = type & IRQ_TYPE_SENSE_MASK; |
140 | struct spider_pic *pic = h->host_data; | 120 | struct spider_pic *pic = spider_virq_to_pic(virq); |
121 | unsigned int hw = irq_map[virq].hwirq; | ||
141 | void __iomem *cfg = spider_get_irq_config(pic, hw); | 122 | void __iomem *cfg = spider_get_irq_config(pic, hw); |
142 | int level = 0; | 123 | struct irq_desc *desc = get_irq_desc(virq); |
124 | u32 old_mask; | ||
143 | u32 ic; | 125 | u32 ic; |
144 | 126 | ||
145 | /* Note that only level high is supported for most interrupts */ | 127 | /* Note that only level high is supported for most interrupts */ |
@@ -157,29 +139,57 @@ static int spider_host_map(struct irq_host *h, unsigned int virq, | |||
157 | break; | 139 | break; |
158 | case IRQ_TYPE_LEVEL_LOW: | 140 | case IRQ_TYPE_LEVEL_LOW: |
159 | ic = 0x0; | 141 | ic = 0x0; |
160 | level = 1; | ||
161 | break; | 142 | break; |
162 | case IRQ_TYPE_LEVEL_HIGH: | 143 | case IRQ_TYPE_LEVEL_HIGH: |
163 | case IRQ_TYPE_NONE: | 144 | case IRQ_TYPE_NONE: |
164 | ic = 0x1; | 145 | ic = 0x1; |
165 | level = 1; | ||
166 | break; | 146 | break; |
167 | default: | 147 | default: |
168 | return -EINVAL; | 148 | return -EINVAL; |
169 | } | 149 | } |
170 | 150 | ||
151 | /* Update irq_desc */ | ||
152 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | ||
153 | desc->status |= type & IRQ_TYPE_SENSE_MASK; | ||
154 | if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) | ||
155 | desc->status |= IRQ_LEVEL; | ||
156 | |||
171 | /* Configure the source. One gross hack that was there before and | 157 | /* Configure the source. One gross hack that was there before and |
172 | * that I've kept around is the priority to the BE which I set to | 158 | * that I've kept around is the priority to the BE which I set to |
173 | * be the same as the interrupt source number. I don't know wether | 159 | * be the same as the interrupt source number. I don't know wether |
174 | * that's supposed to make any kind of sense however, we'll have to | 160 | * that's supposed to make any kind of sense however, we'll have to |
175 | * decide that, but for now, I'm not changing the behaviour. | 161 | * decide that, but for now, I'm not changing the behaviour. |
176 | */ | 162 | */ |
177 | out_be32(cfg, (ic << 24) | (0x7 << 16) | (pic->node_id << 4) | 0xe); | 163 | old_mask = in_be32(cfg) & 0x30000000u; |
164 | out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) | | ||
165 | (pic->node_id << 4) | 0xe); | ||
178 | out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff)); | 166 | out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff)); |
179 | 167 | ||
180 | if (level) | 168 | return 0; |
181 | get_irq_desc(virq)->status |= IRQ_LEVEL; | 169 | } |
170 | |||
171 | static struct irq_chip spider_pic = { | ||
172 | .typename = " SPIDER ", | ||
173 | .unmask = spider_unmask_irq, | ||
174 | .mask = spider_mask_irq, | ||
175 | .ack = spider_ack_irq, | ||
176 | .set_type = spider_set_irq_type, | ||
177 | }; | ||
178 | |||
179 | static int spider_host_match(struct irq_host *h, struct device_node *node) | ||
180 | { | ||
181 | struct spider_pic *pic = h->host_data; | ||
182 | return node == pic->of_node; | ||
183 | } | ||
184 | |||
185 | static int spider_host_map(struct irq_host *h, unsigned int virq, | ||
186 | irq_hw_number_t hw) | ||
187 | { | ||
182 | set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq); | 188 | set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq); |
189 | |||
190 | /* Set default irq type */ | ||
191 | set_irq_type(virq, IRQ_TYPE_NONE); | ||
192 | |||
183 | return 0; | 193 | return 0; |
184 | } | 194 | } |
185 | 195 | ||
@@ -283,7 +293,7 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) | |||
283 | if (iic_host == NULL) | 293 | if (iic_host == NULL) |
284 | return NO_IRQ; | 294 | return NO_IRQ; |
285 | /* Manufacture an IIC interrupt number of class 2 */ | 295 | /* Manufacture an IIC interrupt number of class 2 */ |
286 | virq = irq_create_mapping(iic_host, 0x20 | unit, 0); | 296 | virq = irq_create_mapping(iic_host, 0x20 | unit); |
287 | if (virq == NO_IRQ) | 297 | if (virq == NO_IRQ) |
288 | printk(KERN_ERR "spider_pic: failed to map cascade !"); | 298 | printk(KERN_ERR "spider_pic: failed to map cascade !"); |
289 | return virq; | 299 | return virq; |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 5d2313a6c82..d06042deb02 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -583,9 +583,9 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) | |||
583 | spu->isrc = isrc = tmp[0]; | 583 | spu->isrc = isrc = tmp[0]; |
584 | 584 | ||
585 | /* Now map interrupts of all 3 classes */ | 585 | /* Now map interrupts of all 3 classes */ |
586 | spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc, 0); | 586 | spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc); |
587 | spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc, 0); | 587 | spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc); |
588 | spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc, 0); | 588 | spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc); |
589 | 589 | ||
590 | /* Right now, we only fail if class 2 failed */ | 590 | /* Right now, we only fail if class 2 failed */ |
591 | return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; | 591 | return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; |