diff options
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 58 |
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 | ||
51 | struct bus_type mpic_subsys = { | ||
52 | .name = "mpic", | ||
53 | .dev_name = "mpic", | ||
54 | }; | ||
55 | EXPORT_SYMBOL_GPL(mpic_subsys); | ||
56 | |||
51 | static struct mpic *mpics; | 57 | static struct mpic *mpics; |
52 | static struct mpic *mpic_primary; | 58 | static struct mpic *mpic_primary; |
53 | static DEFINE_RAW_SPINLOCK(mpic_lock); | 59 | static 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 | ||
929 | static 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 | |||
923 | void mpic_set_vector(unsigned int virq, unsigned int vector) | 945 | void 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 | ||
1200 | static 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 | ||
1217 | u32 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 | |||
1180 | struct mpic * __init mpic_alloc(struct device_node *node, | 1227 | struct 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 = { | |||
1999 | static int mpic_init_sys(void) | 2041 | static 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 | ||