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.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 3cc2f9159ab1..1be54faf60dd 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -48,6 +48,12 @@
48#define DBG(fmt...) 48#define DBG(fmt...)
49#endif 49#endif
50 50
51struct bus_type mpic_subsys = {
52 .name = "mpic",
53 .dev_name = "mpic",
54};
55EXPORT_SYMBOL_GPL(mpic_subsys);
56
51static struct mpic *mpics; 57static struct mpic *mpics;
52static struct mpic *mpic_primary; 58static struct mpic *mpic_primary;
53static DEFINE_RAW_SPINLOCK(mpic_lock); 59static DEFINE_RAW_SPINLOCK(mpic_lock);
@@ -920,6 +926,22 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
920 return IRQ_SET_MASK_OK_NOCOPY; 926 return IRQ_SET_MASK_OK_NOCOPY;
921} 927}
922 928
929static int mpic_irq_set_wake(struct irq_data *d, unsigned int on)
930{
931 struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
932 struct mpic *mpic = mpic_from_irq_data(d);
933
934 if (!(mpic->flags & MPIC_FSL))
935 return -ENXIO;
936
937 if (on)
938 desc->action->flags |= IRQF_NO_SUSPEND;
939 else
940 desc->action->flags &= ~IRQF_NO_SUSPEND;
941
942 return 0;
943}
944
923void mpic_set_vector(unsigned int virq, unsigned int vector) 945void mpic_set_vector(unsigned int virq, unsigned int vector)
924{ 946{
925 struct mpic *mpic = mpic_from_irq(virq); 947 struct mpic *mpic = mpic_from_irq(virq);
@@ -957,6 +979,7 @@ static struct irq_chip mpic_irq_chip = {
957 .irq_unmask = mpic_unmask_irq, 979 .irq_unmask = mpic_unmask_irq,
958 .irq_eoi = mpic_end_irq, 980 .irq_eoi = mpic_end_irq,
959 .irq_set_type = mpic_set_irq_type, 981 .irq_set_type = mpic_set_irq_type,
982 .irq_set_wake = mpic_irq_set_wake,
960}; 983};
961 984
962#ifdef CONFIG_SMP 985#ifdef CONFIG_SMP
@@ -971,6 +994,7 @@ static struct irq_chip mpic_tm_chip = {
971 .irq_mask = mpic_mask_tm, 994 .irq_mask = mpic_mask_tm,
972 .irq_unmask = mpic_unmask_tm, 995 .irq_unmask = mpic_unmask_tm,
973 .irq_eoi = mpic_end_irq, 996 .irq_eoi = mpic_end_irq,
997 .irq_set_wake = mpic_irq_set_wake,
974}; 998};
975 999
976#ifdef CONFIG_MPIC_U3_HT_IRQS 1000#ifdef CONFIG_MPIC_U3_HT_IRQS
@@ -1173,10 +1197,33 @@ static struct irq_domain_ops mpic_host_ops = {
1173 .xlate = mpic_host_xlate, 1197 .xlate = mpic_host_xlate,
1174}; 1198};
1175 1199
1200static u32 fsl_mpic_get_version(struct mpic *mpic)
1201{
1202 u32 brr1;
1203
1204 if (!(mpic->flags & MPIC_FSL))
1205 return 0;
1206
1207 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
1208 MPIC_FSL_BRR1);
1209
1210 return brr1 & MPIC_FSL_BRR1_VER;
1211}
1212
1176/* 1213/*
1177 * Exported functions 1214 * Exported functions
1178 */ 1215 */
1179 1216
1217u32 fsl_mpic_primary_get_version(void)
1218{
1219 struct mpic *mpic = mpic_primary;
1220
1221 if (mpic)
1222 return fsl_mpic_get_version(mpic);
1223
1224 return 0;
1225}
1226
1180struct mpic * __init mpic_alloc(struct device_node *node, 1227struct mpic * __init mpic_alloc(struct device_node *node,
1181 phys_addr_t phys_addr, 1228 phys_addr_t phys_addr,
1182 unsigned int flags, 1229 unsigned int flags,
@@ -1323,7 +1370,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1323 mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); 1370 mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1324 1371
1325 if (mpic->flags & MPIC_FSL) { 1372 if (mpic->flags & MPIC_FSL) {
1326 u32 brr1;
1327 int ret; 1373 int ret;
1328 1374
1329 /* 1375 /*
@@ -1334,9 +1380,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1334 mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs, 1380 mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
1335 MPIC_CPU_THISBASE, 0x1000); 1381 MPIC_CPU_THISBASE, 0x1000);
1336 1382
1337 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs, 1383 fsl_version = fsl_mpic_get_version(mpic);
1338 MPIC_FSL_BRR1);
1339 fsl_version = brr1 & MPIC_FSL_BRR1_VER;
1340 1384
1341 /* Error interrupt mask register (EIMR) is required for 1385 /* Error interrupt mask register (EIMR) is required for
1342 * handling individual device error interrupts. EIMR 1386 * handling individual device error interrupts. EIMR
@@ -1526,9 +1570,7 @@ void __init mpic_init(struct mpic *mpic)
1526 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); 1570 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
1527 1571
1528 if (mpic->flags & MPIC_FSL) { 1572 if (mpic->flags & MPIC_FSL) {
1529 u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs, 1573 u32 version = fsl_mpic_get_version(mpic);
1530 MPIC_FSL_BRR1);
1531 u32 version = brr1 & MPIC_FSL_BRR1_VER;
1532 1574
1533 /* 1575 /*
1534 * Timer group B is present at the latest in MPIC 3.1 (e.g. 1576 * Timer group B is present at the latest in MPIC 3.1 (e.g.
@@ -1999,6 +2041,8 @@ static struct syscore_ops mpic_syscore_ops = {
1999static int mpic_init_sys(void) 2041static int mpic_init_sys(void)
2000{ 2042{
2001 register_syscore_ops(&mpic_syscore_ops); 2043 register_syscore_ops(&mpic_syscore_ops);
2044 subsys_system_register(&mpic_subsys, NULL);
2045
2002 return 0; 2046 return 0;
2003} 2047}
2004 2048