aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c3
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c61
-rw-r--r--arch/powerpc/sysdev/mpic.c54
-rw-r--r--arch/powerpc/sysdev/mpic_msgr.c12
-rw-r--r--arch/powerpc/sysdev/scom.c1
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c7
6 files changed, 65 insertions, 73 deletions
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index d3be961e2ae7..10386b676d87 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -51,8 +51,7 @@
51static intctl_cpm2_t __iomem *cpm2_intctl; 51static intctl_cpm2_t __iomem *cpm2_intctl;
52 52
53static struct irq_domain *cpm2_pic_host; 53static struct irq_domain *cpm2_pic_host;
54#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 54static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */
55static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
56 55
57static const u_char irq_to_siureg[] = { 56static const u_char irq_to_siureg[] = {
58 1, 1, 1, 1, 1, 1, 1, 1, 57 1, 1, 1, 1, 1, 1, 1, 1,
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index d5f5416be310..b724622c3a0b 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -18,69 +18,45 @@
18extern int cpm_get_irq(struct pt_regs *regs); 18extern int cpm_get_irq(struct pt_regs *regs);
19 19
20static struct irq_domain *mpc8xx_pic_host; 20static struct irq_domain *mpc8xx_pic_host;
21#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 21static unsigned long mpc8xx_cached_irq_mask;
22static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
23static sysconf8xx_t __iomem *siu_reg; 22static sysconf8xx_t __iomem *siu_reg;
24 23
25int cpm_get_irq(struct pt_regs *regs); 24static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d)
25{
26 return 0x80000000 >> irqd_to_hwirq(d);
27}
26 28
27static void mpc8xx_unmask_irq(struct irq_data *d) 29static void mpc8xx_unmask_irq(struct irq_data *d)
28{ 30{
29 int bit, word; 31 mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
30 unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); 32 out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
31
32 bit = irq_nr & 0x1f;
33 word = irq_nr >> 5;
34
35 ppc_cached_irq_mask[word] |= (1 << (31-bit));
36 out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
37} 33}
38 34
39static void mpc8xx_mask_irq(struct irq_data *d) 35static void mpc8xx_mask_irq(struct irq_data *d)
40{ 36{
41 int bit, word; 37 mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d);
42 unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); 38 out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
43
44 bit = irq_nr & 0x1f;
45 word = irq_nr >> 5;
46
47 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
48 out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
49} 39}
50 40
51static void mpc8xx_ack(struct irq_data *d) 41static void mpc8xx_ack(struct irq_data *d)
52{ 42{
53 int bit; 43 out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d));
54 unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
55
56 bit = irq_nr & 0x1f;
57 out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
58} 44}
59 45
60static void mpc8xx_end_irq(struct irq_data *d) 46static void mpc8xx_end_irq(struct irq_data *d)
61{ 47{
62 int bit, word; 48 mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
63 unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); 49 out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
64
65 bit = irq_nr & 0x1f;
66 word = irq_nr >> 5;
67
68 ppc_cached_irq_mask[word] |= (1 << (31-bit));
69 out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
70} 50}
71 51
72static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) 52static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
73{ 53{
74 if (flow_type & IRQ_TYPE_EDGE_FALLING) { 54 /* only external IRQ senses are programmable */
75 irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); 55 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) {
76 unsigned int siel = in_be32(&siu_reg->sc_siel); 56 unsigned int siel = in_be32(&siu_reg->sc_siel);
77 57 siel |= mpc8xx_irqd_to_bit(d);
78 /* only external IRQ senses are programmable */ 58 out_be32(&siu_reg->sc_siel, siel);
79 if ((hw & 1) == 0) { 59 __irq_set_handler_locked(d->irq, handle_edge_irq);
80 siel |= (0x80000000 >> hw);
81 out_be32(&siu_reg->sc_siel, siel);
82 __irq_set_handler_locked(d->irq, handle_edge_irq);
83 }
84 } 60 }
85 return 0; 61 return 0;
86} 62}
@@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
132 IRQ_TYPE_EDGE_FALLING, 108 IRQ_TYPE_EDGE_FALLING,
133 }; 109 };
134 110
111 if (intspec[0] > 0x1f)
112 return 0;
113
135 *out_hwirq = intspec[0]; 114 *out_hwirq = intspec[0];
136 if (intsize > 1 && intspec[1] < 4) 115 if (intsize > 1 && intspec[1] < 4)
137 *out_flags = map_pic_senses[intspec[1]]; 116 *out_flags = map_pic_senses[intspec[1]];
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 9ac71ebd2c40..395af1347749 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq)
604} 604}
605 605
606/* Determine if the linux irq is an IPI */ 606/* Determine if the linux irq is an IPI */
607static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) 607static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src)
608{ 608{
609 unsigned int src = virq_to_hw(irq);
610
611 return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]); 609 return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
612} 610}
613 611
614/* Determine if the linux irq is a timer */ 612/* Determine if the linux irq is a timer */
615static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) 613static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src)
616{ 614{
617 unsigned int src = virq_to_hw(irq);
618
619 return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]); 615 return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);
620} 616}
621 617
@@ -876,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
876 if (src >= mpic->num_sources) 872 if (src >= mpic->num_sources)
877 return -EINVAL; 873 return -EINVAL;
878 874
875 vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
876
877 /* We don't support "none" type */
879 if (flow_type == IRQ_TYPE_NONE) 878 if (flow_type == IRQ_TYPE_NONE)
880 if (mpic->senses && src < mpic->senses_count) 879 flow_type = IRQ_TYPE_DEFAULT;
881 flow_type = mpic->senses[src]; 880
882 if (flow_type == IRQ_TYPE_NONE) 881 /* Default: read HW settings */
883 flow_type = IRQ_TYPE_LEVEL_LOW; 882 if (flow_type == IRQ_TYPE_DEFAULT) {
883 switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) |
884 MPIC_INFO(VECPRI_SENSE_MASK))) {
885 case MPIC_INFO(VECPRI_SENSE_EDGE) |
886 MPIC_INFO(VECPRI_POLARITY_POSITIVE):
887 flow_type = IRQ_TYPE_EDGE_RISING;
888 break;
889 case MPIC_INFO(VECPRI_SENSE_EDGE) |
890 MPIC_INFO(VECPRI_POLARITY_NEGATIVE):
891 flow_type = IRQ_TYPE_EDGE_FALLING;
892 break;
893 case MPIC_INFO(VECPRI_SENSE_LEVEL) |
894 MPIC_INFO(VECPRI_POLARITY_POSITIVE):
895 flow_type = IRQ_TYPE_LEVEL_HIGH;
896 break;
897 case MPIC_INFO(VECPRI_SENSE_LEVEL) |
898 MPIC_INFO(VECPRI_POLARITY_NEGATIVE):
899 flow_type = IRQ_TYPE_LEVEL_LOW;
900 break;
901 }
902 }
884 903
904 /* Apply to irq desc */
885 irqd_set_trigger_type(d, flow_type); 905 irqd_set_trigger_type(d, flow_type);
886 906
907 /* Apply to HW */
887 if (mpic_is_ht_interrupt(mpic, src)) 908 if (mpic_is_ht_interrupt(mpic, src))
888 vecpri = MPIC_VECPRI_POLARITY_POSITIVE | 909 vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
889 MPIC_VECPRI_SENSE_EDGE; 910 MPIC_VECPRI_SENSE_EDGE;
890 else 911 else
891 vecpri = mpic_type_to_vecpri(mpic, flow_type); 912 vecpri = mpic_type_to_vecpri(mpic, flow_type);
892 913
893 vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
894 vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | 914 vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
895 MPIC_INFO(VECPRI_SENSE_MASK)); 915 MPIC_INFO(VECPRI_SENSE_MASK));
896 vnew |= vecpri; 916 vnew |= vecpri;
@@ -1026,7 +1046,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
1026 irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq); 1046 irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
1027 1047
1028 /* Set default irq type */ 1048 /* Set default irq type */
1029 irq_set_irq_type(virq, IRQ_TYPE_NONE); 1049 irq_set_irq_type(virq, IRQ_TYPE_DEFAULT);
1030 1050
1031 /* If the MPIC was reset, then all vectors have already been 1051 /* If the MPIC was reset, then all vectors have already been
1032 * initialized. Otherwise, a per source lazy initialization 1052 * initialized. Otherwise, a per source lazy initialization
@@ -1417,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
1417 mpic->num_sources = isu_first + mpic->isu_size; 1437 mpic->num_sources = isu_first + mpic->isu_size;
1418} 1438}
1419 1439
1420void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count)
1421{
1422 mpic->senses = senses;
1423 mpic->senses_count = count;
1424}
1425
1426void __init mpic_init(struct mpic *mpic) 1440void __init mpic_init(struct mpic *mpic)
1427{ 1441{
1428 int i, cpu; 1442 int i, cpu;
@@ -1555,12 +1569,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
1555 return; 1569 return;
1556 1570
1557 raw_spin_lock_irqsave(&mpic_lock, flags); 1571 raw_spin_lock_irqsave(&mpic_lock, flags);
1558 if (mpic_is_ipi(mpic, irq)) { 1572 if (mpic_is_ipi(mpic, src)) {
1559 reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & 1573 reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
1560 ~MPIC_VECPRI_PRIORITY_MASK; 1574 ~MPIC_VECPRI_PRIORITY_MASK;
1561 mpic_ipi_write(src - mpic->ipi_vecs[0], 1575 mpic_ipi_write(src - mpic->ipi_vecs[0],
1562 reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); 1576 reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
1563 } else if (mpic_is_tm(mpic, irq)) { 1577 } else if (mpic_is_tm(mpic, src)) {
1564 reg = mpic_tm_read(src - mpic->timer_vecs[0]) & 1578 reg = mpic_tm_read(src - mpic->timer_vecs[0]) &
1565 ~MPIC_VECPRI_PRIORITY_MASK; 1579 ~MPIC_VECPRI_PRIORITY_MASK;
1566 mpic_tm_write(src - mpic->timer_vecs[0], 1580 mpic_tm_write(src - mpic->timer_vecs[0],
diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
index 6e7fa386e76a..483d8fa72e8b 100644
--- a/arch/powerpc/sysdev/mpic_msgr.c
+++ b/arch/powerpc/sysdev/mpic_msgr.c
@@ -27,6 +27,7 @@
27 27
28static struct mpic_msgr **mpic_msgrs; 28static struct mpic_msgr **mpic_msgrs;
29static unsigned int mpic_msgr_count; 29static unsigned int mpic_msgr_count;
30static DEFINE_RAW_SPINLOCK(msgrs_lock);
30 31
31static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value) 32static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value)
32{ 33{
@@ -56,12 +57,11 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num)
56 if (reg_num >= mpic_msgr_count) 57 if (reg_num >= mpic_msgr_count)
57 return ERR_PTR(-ENODEV); 58 return ERR_PTR(-ENODEV);
58 59
59 raw_spin_lock_irqsave(&msgr->lock, flags); 60 raw_spin_lock_irqsave(&msgrs_lock, flags);
60 if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) { 61 msgr = mpic_msgrs[reg_num];
61 msgr = mpic_msgrs[reg_num]; 62 if (msgr->in_use == MSGR_FREE)
62 msgr->in_use = MSGR_INUSE; 63 msgr->in_use = MSGR_INUSE;
63 } 64 raw_spin_unlock_irqrestore(&msgrs_lock, flags);
64 raw_spin_unlock_irqrestore(&msgr->lock, flags);
65 65
66 return msgr; 66 return msgr;
67} 67}
@@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev)
228 228
229 reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i; 229 reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i;
230 msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE; 230 msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE;
231 msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET; 231 msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET);
232 msgr->in_use = MSGR_FREE; 232 msgr->in_use = MSGR_FREE;
233 msgr->num = i; 233 msgr->num = i;
234 raw_spin_lock_init(&msgr->lock); 234 raw_spin_lock_init(&msgr->lock);
diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c
index 49a3ece1c6b3..702256a1ca11 100644
--- a/arch/powerpc/sysdev/scom.c
+++ b/arch/powerpc/sysdev/scom.c
@@ -22,6 +22,7 @@
22#include <linux/debugfs.h> 22#include <linux/debugfs.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <asm/debug.h>
25#include <asm/prom.h> 26#include <asm/prom.h>
26#include <asm/scom.h> 27#include <asm/scom.h>
27 28
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index ea5e204e3450..cd1d18db92c6 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void)
188{ 188{
189 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); 189 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
190 unsigned int irq, virq; 190 unsigned int irq, virq;
191 struct irq_desc *desc;
191 192
192 /* If we used to be the default server, move to the new "boot_cpuid" */ 193 /* If we used to be the default server, move to the new "boot_cpuid" */
193 if (hw_cpu == xics_default_server) 194 if (hw_cpu == xics_default_server)
@@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void)
202 /* Allow IPIs again... */ 203 /* Allow IPIs again... */
203 icp_ops->set_priority(DEFAULT_PRIORITY); 204 icp_ops->set_priority(DEFAULT_PRIORITY);
204 205
205 for_each_irq(virq) { 206 for_each_irq_desc(virq, desc) {
206 struct irq_desc *desc;
207 struct irq_chip *chip; 207 struct irq_chip *chip;
208 long server; 208 long server;
209 unsigned long flags; 209 unsigned long flags;
@@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void)
212 /* We can't set affinity on ISA interrupts */ 212 /* We can't set affinity on ISA interrupts */
213 if (virq < NUM_ISA_INTERRUPTS) 213 if (virq < NUM_ISA_INTERRUPTS)
214 continue; 214 continue;
215 desc = irq_to_desc(virq);
216 /* We only need to migrate enabled IRQS */ 215 /* We only need to migrate enabled IRQS */
217 if (!desc || !desc->action) 216 if (!desc->action)
218 continue; 217 continue;
219 if (desc->irq_data.domain != xics_host) 218 if (desc->irq_data.domain != xics_host)
220 continue; 219 continue;