aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spider-pic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spider-pic.c')
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index ae7ef88f1a37..15217bb0402f 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
123static struct irq_chip spider_pic = { 117static 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
130static 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
136static 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
171static 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
179static 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
185static 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;