aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 74c64c0d3b71..893e65439e85 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -156,8 +156,7 @@ static inline u32 _mpic_read(enum mpic_reg_type type,
156 switch(type) { 156 switch(type) {
157#ifdef CONFIG_PPC_DCR 157#ifdef CONFIG_PPC_DCR
158 case mpic_access_dcr: 158 case mpic_access_dcr:
159 return dcr_read(rb->dhost, 159 return dcr_read(rb->dhost, rb->dhost.base + reg);
160 rb->dbase + reg + rb->doff);
161#endif 160#endif
162 case mpic_access_mmio_be: 161 case mpic_access_mmio_be:
163 return in_be32(rb->base + (reg >> 2)); 162 return in_be32(rb->base + (reg >> 2));
@@ -174,8 +173,7 @@ static inline void _mpic_write(enum mpic_reg_type type,
174 switch(type) { 173 switch(type) {
175#ifdef CONFIG_PPC_DCR 174#ifdef CONFIG_PPC_DCR
176 case mpic_access_dcr: 175 case mpic_access_dcr:
177 return dcr_write(rb->dhost, 176 return dcr_write(rb->dhost, rb->dhost.base + reg, value);
178 rb->dbase + reg + rb->doff, value);
179#endif 177#endif
180 case mpic_access_mmio_be: 178 case mpic_access_mmio_be:
181 return out_be32(rb->base + (reg >> 2), value); 179 return out_be32(rb->base + (reg >> 2), value);
@@ -228,8 +226,13 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne
228 unsigned int isu = src_no >> mpic->isu_shift; 226 unsigned int isu = src_no >> mpic->isu_shift;
229 unsigned int idx = src_no & mpic->isu_mask; 227 unsigned int idx = src_no & mpic->isu_mask;
230 228
231 return _mpic_read(mpic->reg_type, &mpic->isus[isu], 229#ifdef CONFIG_MPIC_BROKEN_REGREAD
232 reg + (idx * MPIC_INFO(IRQ_STRIDE))); 230 if (reg == 0)
231 return mpic->isu_reg0_shadow[idx];
232 else
233#endif
234 return _mpic_read(mpic->reg_type, &mpic->isus[isu],
235 reg + (idx * MPIC_INFO(IRQ_STRIDE)));
233} 236}
234 237
235static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, 238static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -240,6 +243,11 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
240 243
241 _mpic_write(mpic->reg_type, &mpic->isus[isu], 244 _mpic_write(mpic->reg_type, &mpic->isus[isu],
242 reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); 245 reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
246
247#ifdef CONFIG_MPIC_BROKEN_REGREAD
248 if (reg == 0)
249 mpic->isu_reg0_shadow[idx] = value;
250#endif
243} 251}
244 252
245#define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r)) 253#define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r))
@@ -269,9 +277,11 @@ static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr,
269static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, 277static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
270 unsigned int offset, unsigned int size) 278 unsigned int offset, unsigned int size)
271{ 279{
272 rb->dbase = mpic->dcr_base; 280 const u32 *dbasep;
273 rb->doff = offset; 281
274 rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size); 282 dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL);
283
284 rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size);
275 BUG_ON(!DCR_MAP_OK(rb->dhost)); 285 BUG_ON(!DCR_MAP_OK(rb->dhost));
276} 286}
277 287
@@ -758,7 +768,7 @@ static void mpic_end_ipi(unsigned int irq)
758 768
759#endif /* CONFIG_SMP */ 769#endif /* CONFIG_SMP */
760 770
761static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask) 771void mpic_set_affinity(unsigned int irq, cpumask_t cpumask)
762{ 772{
763 struct mpic *mpic = mpic_from_irq(irq); 773 struct mpic *mpic = mpic_from_irq(irq);
764 unsigned int src = mpic_irq_to_hw(irq); 774 unsigned int src = mpic_irq_to_hw(irq);
@@ -861,10 +871,8 @@ static struct irq_chip mpic_irq_ht_chip = {
861 871
862static int mpic_host_match(struct irq_host *h, struct device_node *node) 872static int mpic_host_match(struct irq_host *h, struct device_node *node)
863{ 873{
864 struct mpic *mpic = h->host_data;
865
866 /* Exact match, unless mpic node is NULL */ 874 /* Exact match, unless mpic node is NULL */
867 return mpic->of_node == NULL || mpic->of_node == node; 875 return h->of_node == NULL || h->of_node == node;
868} 876}
869 877
870static int mpic_host_map(struct irq_host *h, unsigned int virq, 878static int mpic_host_map(struct irq_host *h, unsigned int virq,
@@ -985,10 +993,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
985 993
986 memset(mpic, 0, sizeof(struct mpic)); 994 memset(mpic, 0, sizeof(struct mpic));
987 mpic->name = name; 995 mpic->name = name;
988 mpic->of_node = of_node_get(node);
989 996
990 mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size, 997 mpic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
991 &mpic_host_ops, 998 isu_size, &mpic_host_ops,
992 flags & MPIC_LARGE_VECTORS ? 2048 : 256); 999 flags & MPIC_LARGE_VECTORS ? 2048 : 256);
993 if (mpic->irqhost == NULL) { 1000 if (mpic->irqhost == NULL) {
994 of_node_put(node); 1001 of_node_put(node);
@@ -1068,20 +1075,14 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1068 BUG_ON(paddr == 0 && node == NULL); 1075 BUG_ON(paddr == 0 && node == NULL);
1069 1076
1070 /* If no physical address passed in, check if it's dcr based */ 1077 /* If no physical address passed in, check if it's dcr based */
1071 if (paddr == 0 && of_get_property(node, "dcr-reg", NULL) != NULL) 1078 if (paddr == 0 && of_get_property(node, "dcr-reg", NULL) != NULL) {
1072 mpic->flags |= MPIC_USES_DCR;
1073
1074#ifdef CONFIG_PPC_DCR 1079#ifdef CONFIG_PPC_DCR
1075 if (mpic->flags & MPIC_USES_DCR) { 1080 mpic->flags |= MPIC_USES_DCR;
1076 const u32 *dbasep;
1077 dbasep = of_get_property(node, "dcr-reg", NULL);
1078 BUG_ON(dbasep == NULL);
1079 mpic->dcr_base = *dbasep;
1080 mpic->reg_type = mpic_access_dcr; 1081 mpic->reg_type = mpic_access_dcr;
1081 }
1082#else 1082#else
1083 BUG_ON (mpic->flags & MPIC_USES_DCR); 1083 BUG();
1084#endif /* CONFIG_PPC_DCR */ 1084#endif /* CONFIG_PPC_DCR */
1085 }
1085 1086
1086 /* If the MPIC is not DCR based, and no physical address was passed 1087 /* If the MPIC is not DCR based, and no physical address was passed
1087 * in, try to obtain one 1088 * in, try to obtain one