12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21cd8e506SKumar Gala /*
3f30c2269SUwe Zeisberger * arch/powerpc/sysdev/ipic.c
41cd8e506SKumar Gala *
51cd8e506SKumar Gala * IPIC routines implementations.
61cd8e506SKumar Gala *
71cd8e506SKumar Gala * Copyright 2005 Freescale Semiconductor, Inc.
81cd8e506SKumar Gala */
91cd8e506SKumar Gala #include <linux/kernel.h>
101cd8e506SKumar Gala #include <linux/init.h>
111cd8e506SKumar Gala #include <linux/errno.h>
121cd8e506SKumar Gala #include <linux/reboot.h>
131cd8e506SKumar Gala #include <linux/slab.h>
141cd8e506SKumar Gala #include <linux/stddef.h>
151cd8e506SKumar Gala #include <linux/sched.h>
161cd8e506SKumar Gala #include <linux/signal.h>
17f5a592f7SRafael J. Wysocki #include <linux/syscore_ops.h>
18b9f0f1bbSKim Phillips #include <linux/device.h>
19b9f0f1bbSKim Phillips #include <linux/spinlock.h>
20d49747bdSScott Wood #include <linux/fsl_devices.h>
21*e6f6390aSChristophe Leroy #include <linux/irqdomain.h>
22*e6f6390aSChristophe Leroy #include <linux/of_address.h>
231cd8e506SKumar Gala #include <asm/irq.h>
241cd8e506SKumar Gala #include <asm/io.h>
251cd8e506SKumar Gala #include <asm/ipic.h>
261cd8e506SKumar Gala
271cd8e506SKumar Gala #include "ipic.h"
281cd8e506SKumar Gala
291cd8e506SKumar Gala static struct ipic * primary_ipic;
3077d4309eSLi Yang static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
31a9e8bf21SThomas Gleixner static DEFINE_RAW_SPINLOCK(ipic_lock);
321cd8e506SKumar Gala
331cd8e506SKumar Gala static struct ipic_info ipic_info[] = {
34f03ca957SLi Yang [1] = {
35f03ca957SLi Yang .mask = IPIC_SIMSR_H,
36f03ca957SLi Yang .prio = IPIC_SIPRR_C,
37f03ca957SLi Yang .force = IPIC_SIFCR_H,
38f03ca957SLi Yang .bit = 16,
39f03ca957SLi Yang .prio_mask = 0,
40f03ca957SLi Yang },
41f03ca957SLi Yang [2] = {
42f03ca957SLi Yang .mask = IPIC_SIMSR_H,
43f03ca957SLi Yang .prio = IPIC_SIPRR_C,
44f03ca957SLi Yang .force = IPIC_SIFCR_H,
45f03ca957SLi Yang .bit = 17,
46f03ca957SLi Yang .prio_mask = 1,
47f03ca957SLi Yang },
48a7267d67SJohn Rigby [3] = {
49a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
50a7267d67SJohn Rigby .prio = IPIC_SIPRR_C,
51a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
52a7267d67SJohn Rigby .bit = 18,
53a7267d67SJohn Rigby .prio_mask = 2,
54a7267d67SJohn Rigby },
55f03ca957SLi Yang [4] = {
56f03ca957SLi Yang .mask = IPIC_SIMSR_H,
57f03ca957SLi Yang .prio = IPIC_SIPRR_C,
58f03ca957SLi Yang .force = IPIC_SIFCR_H,
59f03ca957SLi Yang .bit = 19,
60f03ca957SLi Yang .prio_mask = 3,
61f03ca957SLi Yang },
62a7267d67SJohn Rigby [5] = {
63a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
64a7267d67SJohn Rigby .prio = IPIC_SIPRR_C,
65a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
66a7267d67SJohn Rigby .bit = 20,
67a7267d67SJohn Rigby .prio_mask = 4,
68a7267d67SJohn Rigby },
69a7267d67SJohn Rigby [6] = {
70a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
71a7267d67SJohn Rigby .prio = IPIC_SIPRR_C,
72a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
73a7267d67SJohn Rigby .bit = 21,
74a7267d67SJohn Rigby .prio_mask = 5,
75a7267d67SJohn Rigby },
76a7267d67SJohn Rigby [7] = {
77a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
78a7267d67SJohn Rigby .prio = IPIC_SIPRR_C,
79a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
80a7267d67SJohn Rigby .bit = 22,
81a7267d67SJohn Rigby .prio_mask = 6,
82a7267d67SJohn Rigby },
83a7267d67SJohn Rigby [8] = {
84a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
85a7267d67SJohn Rigby .prio = IPIC_SIPRR_C,
86a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
87a7267d67SJohn Rigby .bit = 23,
88a7267d67SJohn Rigby .prio_mask = 7,
89a7267d67SJohn Rigby },
901cd8e506SKumar Gala [9] = {
911cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
921cd8e506SKumar Gala .prio = IPIC_SIPRR_D,
931cd8e506SKumar Gala .force = IPIC_SIFCR_H,
941cd8e506SKumar Gala .bit = 24,
951cd8e506SKumar Gala .prio_mask = 0,
961cd8e506SKumar Gala },
971cd8e506SKumar Gala [10] = {
981cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
991cd8e506SKumar Gala .prio = IPIC_SIPRR_D,
1001cd8e506SKumar Gala .force = IPIC_SIFCR_H,
1011cd8e506SKumar Gala .bit = 25,
1021cd8e506SKumar Gala .prio_mask = 1,
1031cd8e506SKumar Gala },
1041cd8e506SKumar Gala [11] = {
1051cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
1061cd8e506SKumar Gala .prio = IPIC_SIPRR_D,
1071cd8e506SKumar Gala .force = IPIC_SIFCR_H,
1081cd8e506SKumar Gala .bit = 26,
1091cd8e506SKumar Gala .prio_mask = 2,
1101cd8e506SKumar Gala },
111f03ca957SLi Yang [12] = {
112f03ca957SLi Yang .mask = IPIC_SIMSR_H,
113f03ca957SLi Yang .prio = IPIC_SIPRR_D,
114f03ca957SLi Yang .force = IPIC_SIFCR_H,
115f03ca957SLi Yang .bit = 27,
116f03ca957SLi Yang .prio_mask = 3,
117f03ca957SLi Yang },
118f03ca957SLi Yang [13] = {
119f03ca957SLi Yang .mask = IPIC_SIMSR_H,
120f03ca957SLi Yang .prio = IPIC_SIPRR_D,
121f03ca957SLi Yang .force = IPIC_SIFCR_H,
122f03ca957SLi Yang .bit = 28,
123f03ca957SLi Yang .prio_mask = 4,
124f03ca957SLi Yang },
1251cd8e506SKumar Gala [14] = {
1261cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
1271cd8e506SKumar Gala .prio = IPIC_SIPRR_D,
1281cd8e506SKumar Gala .force = IPIC_SIFCR_H,
1291cd8e506SKumar Gala .bit = 29,
1301cd8e506SKumar Gala .prio_mask = 5,
1311cd8e506SKumar Gala },
1321cd8e506SKumar Gala [15] = {
1331cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
1341cd8e506SKumar Gala .prio = IPIC_SIPRR_D,
1351cd8e506SKumar Gala .force = IPIC_SIFCR_H,
1361cd8e506SKumar Gala .bit = 30,
1371cd8e506SKumar Gala .prio_mask = 6,
1381cd8e506SKumar Gala },
1391cd8e506SKumar Gala [16] = {
1401cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
1411cd8e506SKumar Gala .prio = IPIC_SIPRR_D,
1421cd8e506SKumar Gala .force = IPIC_SIFCR_H,
1431cd8e506SKumar Gala .bit = 31,
1441cd8e506SKumar Gala .prio_mask = 7,
1451cd8e506SKumar Gala },
1461cd8e506SKumar Gala [17] = {
14777d4309eSLi Yang .ack = IPIC_SEPNR,
1481cd8e506SKumar Gala .mask = IPIC_SEMSR,
1491cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
1501cd8e506SKumar Gala .force = IPIC_SEFCR,
1511cd8e506SKumar Gala .bit = 1,
1521cd8e506SKumar Gala .prio_mask = 5,
1531cd8e506SKumar Gala },
1541cd8e506SKumar Gala [18] = {
15577d4309eSLi Yang .ack = IPIC_SEPNR,
1561cd8e506SKumar Gala .mask = IPIC_SEMSR,
1571cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
1581cd8e506SKumar Gala .force = IPIC_SEFCR,
1591cd8e506SKumar Gala .bit = 2,
1601cd8e506SKumar Gala .prio_mask = 6,
1611cd8e506SKumar Gala },
1621cd8e506SKumar Gala [19] = {
16377d4309eSLi Yang .ack = IPIC_SEPNR,
1641cd8e506SKumar Gala .mask = IPIC_SEMSR,
1651cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
1661cd8e506SKumar Gala .force = IPIC_SEFCR,
1671cd8e506SKumar Gala .bit = 3,
1681cd8e506SKumar Gala .prio_mask = 7,
1691cd8e506SKumar Gala },
1701cd8e506SKumar Gala [20] = {
17177d4309eSLi Yang .ack = IPIC_SEPNR,
1721cd8e506SKumar Gala .mask = IPIC_SEMSR,
1731cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
1741cd8e506SKumar Gala .force = IPIC_SEFCR,
1751cd8e506SKumar Gala .bit = 4,
1761cd8e506SKumar Gala .prio_mask = 4,
1771cd8e506SKumar Gala },
1781cd8e506SKumar Gala [21] = {
17977d4309eSLi Yang .ack = IPIC_SEPNR,
1801cd8e506SKumar Gala .mask = IPIC_SEMSR,
1811cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
1821cd8e506SKumar Gala .force = IPIC_SEFCR,
1831cd8e506SKumar Gala .bit = 5,
1841cd8e506SKumar Gala .prio_mask = 5,
1851cd8e506SKumar Gala },
1861cd8e506SKumar Gala [22] = {
18777d4309eSLi Yang .ack = IPIC_SEPNR,
1881cd8e506SKumar Gala .mask = IPIC_SEMSR,
1891cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
1901cd8e506SKumar Gala .force = IPIC_SEFCR,
1911cd8e506SKumar Gala .bit = 6,
1921cd8e506SKumar Gala .prio_mask = 6,
1931cd8e506SKumar Gala },
1941cd8e506SKumar Gala [23] = {
19577d4309eSLi Yang .ack = IPIC_SEPNR,
1961cd8e506SKumar Gala .mask = IPIC_SEMSR,
1971cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
1981cd8e506SKumar Gala .force = IPIC_SEFCR,
1991cd8e506SKumar Gala .bit = 7,
2001cd8e506SKumar Gala .prio_mask = 7,
2011cd8e506SKumar Gala },
2021cd8e506SKumar Gala [32] = {
2031cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2041cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2051cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2061cd8e506SKumar Gala .bit = 0,
2071cd8e506SKumar Gala .prio_mask = 0,
2081cd8e506SKumar Gala },
2091cd8e506SKumar Gala [33] = {
2101cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2111cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2121cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2131cd8e506SKumar Gala .bit = 1,
2141cd8e506SKumar Gala .prio_mask = 1,
2151cd8e506SKumar Gala },
2161cd8e506SKumar Gala [34] = {
2171cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2181cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2191cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2201cd8e506SKumar Gala .bit = 2,
2211cd8e506SKumar Gala .prio_mask = 2,
2221cd8e506SKumar Gala },
2231cd8e506SKumar Gala [35] = {
2241cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2251cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2261cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2271cd8e506SKumar Gala .bit = 3,
2281cd8e506SKumar Gala .prio_mask = 3,
2291cd8e506SKumar Gala },
2301cd8e506SKumar Gala [36] = {
2311cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2321cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2331cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2341cd8e506SKumar Gala .bit = 4,
2351cd8e506SKumar Gala .prio_mask = 4,
2361cd8e506SKumar Gala },
2371cd8e506SKumar Gala [37] = {
2381cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2391cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2401cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2411cd8e506SKumar Gala .bit = 5,
2421cd8e506SKumar Gala .prio_mask = 5,
2431cd8e506SKumar Gala },
2441cd8e506SKumar Gala [38] = {
2451cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2461cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2471cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2481cd8e506SKumar Gala .bit = 6,
2491cd8e506SKumar Gala .prio_mask = 6,
2501cd8e506SKumar Gala },
2511cd8e506SKumar Gala [39] = {
2521cd8e506SKumar Gala .mask = IPIC_SIMSR_H,
2531cd8e506SKumar Gala .prio = IPIC_SIPRR_A,
2541cd8e506SKumar Gala .force = IPIC_SIFCR_H,
2551cd8e506SKumar Gala .bit = 7,
2561cd8e506SKumar Gala .prio_mask = 7,
2571cd8e506SKumar Gala },
258a7267d67SJohn Rigby [40] = {
259a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
260a7267d67SJohn Rigby .prio = IPIC_SIPRR_B,
261a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
262a7267d67SJohn Rigby .bit = 8,
263a7267d67SJohn Rigby .prio_mask = 0,
264a7267d67SJohn Rigby },
265a7267d67SJohn Rigby [41] = {
266a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
267a7267d67SJohn Rigby .prio = IPIC_SIPRR_B,
268a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
269a7267d67SJohn Rigby .bit = 9,
270a7267d67SJohn Rigby .prio_mask = 1,
271a7267d67SJohn Rigby },
272f03ca957SLi Yang [42] = {
273f03ca957SLi Yang .mask = IPIC_SIMSR_H,
274f03ca957SLi Yang .prio = IPIC_SIPRR_B,
275f03ca957SLi Yang .force = IPIC_SIFCR_H,
276f03ca957SLi Yang .bit = 10,
277f03ca957SLi Yang .prio_mask = 2,
278f03ca957SLi Yang },
279a7267d67SJohn Rigby [43] = {
280a7267d67SJohn Rigby .mask = IPIC_SIMSR_H,
281a7267d67SJohn Rigby .prio = IPIC_SIPRR_B,
282a7267d67SJohn Rigby .force = IPIC_SIFCR_H,
283a7267d67SJohn Rigby .bit = 11,
284a7267d67SJohn Rigby .prio_mask = 3,
285a7267d67SJohn Rigby },
286f03ca957SLi Yang [44] = {
287f03ca957SLi Yang .mask = IPIC_SIMSR_H,
288f03ca957SLi Yang .prio = IPIC_SIPRR_B,
289f03ca957SLi Yang .force = IPIC_SIFCR_H,
290f03ca957SLi Yang .bit = 12,
291f03ca957SLi Yang .prio_mask = 4,
292f03ca957SLi Yang },
293f03ca957SLi Yang [45] = {
294f03ca957SLi Yang .mask = IPIC_SIMSR_H,
295f03ca957SLi Yang .prio = IPIC_SIPRR_B,
296f03ca957SLi Yang .force = IPIC_SIFCR_H,
297f03ca957SLi Yang .bit = 13,
298f03ca957SLi Yang .prio_mask = 5,
299f03ca957SLi Yang },
300f03ca957SLi Yang [46] = {
301f03ca957SLi Yang .mask = IPIC_SIMSR_H,
302f03ca957SLi Yang .prio = IPIC_SIPRR_B,
303f03ca957SLi Yang .force = IPIC_SIFCR_H,
304f03ca957SLi Yang .bit = 14,
305f03ca957SLi Yang .prio_mask = 6,
306f03ca957SLi Yang },
307f03ca957SLi Yang [47] = {
308f03ca957SLi Yang .mask = IPIC_SIMSR_H,
309f03ca957SLi Yang .prio = IPIC_SIPRR_B,
310f03ca957SLi Yang .force = IPIC_SIFCR_H,
311f03ca957SLi Yang .bit = 15,
312f03ca957SLi Yang .prio_mask = 7,
313f03ca957SLi Yang },
3141cd8e506SKumar Gala [48] = {
315446183e4SScott Wood .ack = IPIC_SEPNR,
3161cd8e506SKumar Gala .mask = IPIC_SEMSR,
3171cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
3181cd8e506SKumar Gala .force = IPIC_SEFCR,
3191cd8e506SKumar Gala .bit = 0,
3201cd8e506SKumar Gala .prio_mask = 4,
3211cd8e506SKumar Gala },
3221cd8e506SKumar Gala [64] = {
3231cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3241cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
3251cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3261cd8e506SKumar Gala .bit = 0,
3271cd8e506SKumar Gala .prio_mask = 0,
3281cd8e506SKumar Gala },
3291cd8e506SKumar Gala [65] = {
3301cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3311cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
3321cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3331cd8e506SKumar Gala .bit = 1,
3341cd8e506SKumar Gala .prio_mask = 1,
3351cd8e506SKumar Gala },
3361cd8e506SKumar Gala [66] = {
3371cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3381cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
3391cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3401cd8e506SKumar Gala .bit = 2,
3411cd8e506SKumar Gala .prio_mask = 2,
3421cd8e506SKumar Gala },
3431cd8e506SKumar Gala [67] = {
3441cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3451cd8e506SKumar Gala .prio = IPIC_SMPRR_A,
3461cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3471cd8e506SKumar Gala .bit = 3,
3481cd8e506SKumar Gala .prio_mask = 3,
3491cd8e506SKumar Gala },
3501cd8e506SKumar Gala [68] = {
3511cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3521cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
3531cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3541cd8e506SKumar Gala .bit = 4,
3551cd8e506SKumar Gala .prio_mask = 0,
3561cd8e506SKumar Gala },
3571cd8e506SKumar Gala [69] = {
3581cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3591cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
3601cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3611cd8e506SKumar Gala .bit = 5,
3621cd8e506SKumar Gala .prio_mask = 1,
3631cd8e506SKumar Gala },
3641cd8e506SKumar Gala [70] = {
3651cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3661cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
3671cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3681cd8e506SKumar Gala .bit = 6,
3691cd8e506SKumar Gala .prio_mask = 2,
3701cd8e506SKumar Gala },
3711cd8e506SKumar Gala [71] = {
3721cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3731cd8e506SKumar Gala .prio = IPIC_SMPRR_B,
3741cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3751cd8e506SKumar Gala .bit = 7,
3761cd8e506SKumar Gala .prio_mask = 3,
3771cd8e506SKumar Gala },
3781cd8e506SKumar Gala [72] = {
3791cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3801cd8e506SKumar Gala .prio = 0,
3811cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3821cd8e506SKumar Gala .bit = 8,
3831cd8e506SKumar Gala },
3841cd8e506SKumar Gala [73] = {
3851cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3861cd8e506SKumar Gala .prio = 0,
3871cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3881cd8e506SKumar Gala .bit = 9,
3891cd8e506SKumar Gala },
3901cd8e506SKumar Gala [74] = {
3911cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3921cd8e506SKumar Gala .prio = 0,
3931cd8e506SKumar Gala .force = IPIC_SIFCR_L,
3941cd8e506SKumar Gala .bit = 10,
3951cd8e506SKumar Gala },
3961cd8e506SKumar Gala [75] = {
3971cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
3981cd8e506SKumar Gala .prio = 0,
3991cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4001cd8e506SKumar Gala .bit = 11,
4011cd8e506SKumar Gala },
4021cd8e506SKumar Gala [76] = {
4031cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4041cd8e506SKumar Gala .prio = 0,
4051cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4061cd8e506SKumar Gala .bit = 12,
4071cd8e506SKumar Gala },
4081cd8e506SKumar Gala [77] = {
4091cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4101cd8e506SKumar Gala .prio = 0,
4111cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4121cd8e506SKumar Gala .bit = 13,
4131cd8e506SKumar Gala },
4141cd8e506SKumar Gala [78] = {
4151cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4161cd8e506SKumar Gala .prio = 0,
4171cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4181cd8e506SKumar Gala .bit = 14,
4191cd8e506SKumar Gala },
4201cd8e506SKumar Gala [79] = {
4211cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4221cd8e506SKumar Gala .prio = 0,
4231cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4241cd8e506SKumar Gala .bit = 15,
4251cd8e506SKumar Gala },
4261cd8e506SKumar Gala [80] = {
4271cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4281cd8e506SKumar Gala .prio = 0,
4291cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4301cd8e506SKumar Gala .bit = 16,
4311cd8e506SKumar Gala },
432f03ca957SLi Yang [81] = {
433f03ca957SLi Yang .mask = IPIC_SIMSR_L,
434f03ca957SLi Yang .prio = 0,
435f03ca957SLi Yang .force = IPIC_SIFCR_L,
436f03ca957SLi Yang .bit = 17,
437f03ca957SLi Yang },
438f03ca957SLi Yang [82] = {
439f03ca957SLi Yang .mask = IPIC_SIMSR_L,
440f03ca957SLi Yang .prio = 0,
441f03ca957SLi Yang .force = IPIC_SIFCR_L,
442f03ca957SLi Yang .bit = 18,
443f03ca957SLi Yang },
444a7267d67SJohn Rigby [83] = {
445a7267d67SJohn Rigby .mask = IPIC_SIMSR_L,
446a7267d67SJohn Rigby .prio = 0,
447a7267d67SJohn Rigby .force = IPIC_SIFCR_L,
448a7267d67SJohn Rigby .bit = 19,
449a7267d67SJohn Rigby },
4501cd8e506SKumar Gala [84] = {
4511cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4521cd8e506SKumar Gala .prio = 0,
4531cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4541cd8e506SKumar Gala .bit = 20,
4551cd8e506SKumar Gala },
4561cd8e506SKumar Gala [85] = {
4571cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4581cd8e506SKumar Gala .prio = 0,
4591cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4601cd8e506SKumar Gala .bit = 21,
4611cd8e506SKumar Gala },
462f03ca957SLi Yang [86] = {
463f03ca957SLi Yang .mask = IPIC_SIMSR_L,
464f03ca957SLi Yang .prio = 0,
465f03ca957SLi Yang .force = IPIC_SIFCR_L,
466f03ca957SLi Yang .bit = 22,
467f03ca957SLi Yang },
468f03ca957SLi Yang [87] = {
469f03ca957SLi Yang .mask = IPIC_SIMSR_L,
470f03ca957SLi Yang .prio = 0,
471f03ca957SLi Yang .force = IPIC_SIFCR_L,
472f03ca957SLi Yang .bit = 23,
473f03ca957SLi Yang },
474f03ca957SLi Yang [88] = {
475f03ca957SLi Yang .mask = IPIC_SIMSR_L,
476f03ca957SLi Yang .prio = 0,
477f03ca957SLi Yang .force = IPIC_SIFCR_L,
478f03ca957SLi Yang .bit = 24,
479f03ca957SLi Yang },
480f03ca957SLi Yang [89] = {
481f03ca957SLi Yang .mask = IPIC_SIMSR_L,
482f03ca957SLi Yang .prio = 0,
483f03ca957SLi Yang .force = IPIC_SIFCR_L,
484f03ca957SLi Yang .bit = 25,
485f03ca957SLi Yang },
4861cd8e506SKumar Gala [90] = {
4871cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4881cd8e506SKumar Gala .prio = 0,
4891cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4901cd8e506SKumar Gala .bit = 26,
4911cd8e506SKumar Gala },
4921cd8e506SKumar Gala [91] = {
4931cd8e506SKumar Gala .mask = IPIC_SIMSR_L,
4941cd8e506SKumar Gala .prio = 0,
4951cd8e506SKumar Gala .force = IPIC_SIFCR_L,
4961cd8e506SKumar Gala .bit = 27,
4971cd8e506SKumar Gala },
4988cf6b195SKim Phillips [94] = {
4998cf6b195SKim Phillips .mask = IPIC_SIMSR_L,
5008cf6b195SKim Phillips .prio = 0,
5018cf6b195SKim Phillips .force = IPIC_SIFCR_L,
5028cf6b195SKim Phillips .bit = 30,
5038cf6b195SKim Phillips },
5041cd8e506SKumar Gala };
5051cd8e506SKumar Gala
ipic_read(volatile u32 __iomem * base,unsigned int reg)5061cd8e506SKumar Gala static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg)
5071cd8e506SKumar Gala {
5081cd8e506SKumar Gala return in_be32(base + (reg >> 2));
5091cd8e506SKumar Gala }
5101cd8e506SKumar Gala
ipic_write(volatile u32 __iomem * base,unsigned int reg,u32 value)5111cd8e506SKumar Gala static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value)
5121cd8e506SKumar Gala {
5131cd8e506SKumar Gala out_be32(base + (reg >> 2), value);
5141cd8e506SKumar Gala }
5151cd8e506SKumar Gala
ipic_from_irq(unsigned int virq)516b9f0f1bbSKim Phillips static inline struct ipic * ipic_from_irq(unsigned int virq)
5171cd8e506SKumar Gala {
5181cd8e506SKumar Gala return primary_ipic;
5191cd8e506SKumar Gala }
5201cd8e506SKumar Gala
ipic_unmask_irq(struct irq_data * d)521687228adSLennert Buytenhek static void ipic_unmask_irq(struct irq_data *d)
5221cd8e506SKumar Gala {
523687228adSLennert Buytenhek struct ipic *ipic = ipic_from_irq(d->irq);
524476eb491SGrant Likely unsigned int src = irqd_to_hwirq(d);
525b9f0f1bbSKim Phillips unsigned long flags;
5261cd8e506SKumar Gala u32 temp;
5271cd8e506SKumar Gala
528a9e8bf21SThomas Gleixner raw_spin_lock_irqsave(&ipic_lock, flags);
529b9f0f1bbSKim Phillips
5301cd8e506SKumar Gala temp = ipic_read(ipic->regs, ipic_info[src].mask);
5311cd8e506SKumar Gala temp |= (1 << (31 - ipic_info[src].bit));
5321cd8e506SKumar Gala ipic_write(ipic->regs, ipic_info[src].mask, temp);
533b9f0f1bbSKim Phillips
534a9e8bf21SThomas Gleixner raw_spin_unlock_irqrestore(&ipic_lock, flags);
5351cd8e506SKumar Gala }
5361cd8e506SKumar Gala
ipic_mask_irq(struct irq_data * d)537687228adSLennert Buytenhek static void ipic_mask_irq(struct irq_data *d)
5381cd8e506SKumar Gala {
539687228adSLennert Buytenhek struct ipic *ipic = ipic_from_irq(d->irq);
540476eb491SGrant Likely unsigned int src = irqd_to_hwirq(d);
541b9f0f1bbSKim Phillips unsigned long flags;
5421cd8e506SKumar Gala u32 temp;
5431cd8e506SKumar Gala
544a9e8bf21SThomas Gleixner raw_spin_lock_irqsave(&ipic_lock, flags);
545b9f0f1bbSKim Phillips
5461cd8e506SKumar Gala temp = ipic_read(ipic->regs, ipic_info[src].mask);
5471cd8e506SKumar Gala temp &= ~(1 << (31 - ipic_info[src].bit));
5481cd8e506SKumar Gala ipic_write(ipic->regs, ipic_info[src].mask, temp);
549b9f0f1bbSKim Phillips
55077d4309eSLi Yang /* mb() can't guarantee that masking is finished. But it does finish
55177d4309eSLi Yang * for nearly all cases. */
55277d4309eSLi Yang mb();
55377d4309eSLi Yang
554a9e8bf21SThomas Gleixner raw_spin_unlock_irqrestore(&ipic_lock, flags);
5551cd8e506SKumar Gala }
5561cd8e506SKumar Gala
ipic_ack_irq(struct irq_data * d)557687228adSLennert Buytenhek static void ipic_ack_irq(struct irq_data *d)
5581cd8e506SKumar Gala {
559687228adSLennert Buytenhek struct ipic *ipic = ipic_from_irq(d->irq);
560476eb491SGrant Likely unsigned int src = irqd_to_hwirq(d);
561b9f0f1bbSKim Phillips unsigned long flags;
5621cd8e506SKumar Gala u32 temp;
5631cd8e506SKumar Gala
564a9e8bf21SThomas Gleixner raw_spin_lock_irqsave(&ipic_lock, flags);
5651cd8e506SKumar Gala
56630c40469Sdayu@datangmobile.cn temp = 1 << (31 - ipic_info[src].bit);
56777d4309eSLi Yang ipic_write(ipic->regs, ipic_info[src].ack, temp);
56877d4309eSLi Yang
56977d4309eSLi Yang /* mb() can't guarantee that ack is finished. But it does finish
57077d4309eSLi Yang * for nearly all cases. */
57177d4309eSLi Yang mb();
572b9f0f1bbSKim Phillips
573a9e8bf21SThomas Gleixner raw_spin_unlock_irqrestore(&ipic_lock, flags);
5741cd8e506SKumar Gala }
5751cd8e506SKumar Gala
ipic_mask_irq_and_ack(struct irq_data * d)576687228adSLennert Buytenhek static void ipic_mask_irq_and_ack(struct irq_data *d)
5771cd8e506SKumar Gala {
578687228adSLennert Buytenhek struct ipic *ipic = ipic_from_irq(d->irq);
579476eb491SGrant Likely unsigned int src = irqd_to_hwirq(d);
580b9f0f1bbSKim Phillips unsigned long flags;
581b9f0f1bbSKim Phillips u32 temp;
582b9f0f1bbSKim Phillips
583a9e8bf21SThomas Gleixner raw_spin_lock_irqsave(&ipic_lock, flags);
584b9f0f1bbSKim Phillips
585b9f0f1bbSKim Phillips temp = ipic_read(ipic->regs, ipic_info[src].mask);
586b9f0f1bbSKim Phillips temp &= ~(1 << (31 - ipic_info[src].bit));
587b9f0f1bbSKim Phillips ipic_write(ipic->regs, ipic_info[src].mask, temp);
588b9f0f1bbSKim Phillips
58930c40469Sdayu@datangmobile.cn temp = 1 << (31 - ipic_info[src].bit);
59077d4309eSLi Yang ipic_write(ipic->regs, ipic_info[src].ack, temp);
59177d4309eSLi Yang
59277d4309eSLi Yang /* mb() can't guarantee that ack is finished. But it does finish
59377d4309eSLi Yang * for nearly all cases. */
59477d4309eSLi Yang mb();
595b9f0f1bbSKim Phillips
596a9e8bf21SThomas Gleixner raw_spin_unlock_irqrestore(&ipic_lock, flags);
5971cd8e506SKumar Gala }
5981cd8e506SKumar Gala
ipic_set_irq_type(struct irq_data * d,unsigned int flow_type)599687228adSLennert Buytenhek static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
600b9f0f1bbSKim Phillips {
601687228adSLennert Buytenhek struct ipic *ipic = ipic_from_irq(d->irq);
602476eb491SGrant Likely unsigned int src = irqd_to_hwirq(d);
603b9f0f1bbSKim Phillips unsigned int vold, vnew, edibit;
604b9f0f1bbSKim Phillips
605b9f0f1bbSKim Phillips if (flow_type == IRQ_TYPE_NONE)
606b9f0f1bbSKim Phillips flow_type = IRQ_TYPE_LEVEL_LOW;
607b9f0f1bbSKim Phillips
608b9f0f1bbSKim Phillips /* ipic supports only low assertion and high-to-low change senses
609b9f0f1bbSKim Phillips */
610b9f0f1bbSKim Phillips if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) {
611b9f0f1bbSKim Phillips printk(KERN_ERR "ipic: sense type 0x%x not supported\n",
612b9f0f1bbSKim Phillips flow_type);
613b9f0f1bbSKim Phillips return -EINVAL;
614b9f0f1bbSKim Phillips }
61577d4309eSLi Yang /* ipic supports only edge mode on external interrupts */
61677d4309eSLi Yang if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
61777d4309eSLi Yang printk(KERN_ERR "ipic: edge sense not supported on internal "
61877d4309eSLi Yang "interrupts\n");
61977d4309eSLi Yang return -EINVAL;
620ecf4b196SThomas Gleixner
62177d4309eSLi Yang }
622b9f0f1bbSKim Phillips
623ecf4b196SThomas Gleixner irqd_set_trigger_type(d, flow_type);
624b9f0f1bbSKim Phillips if (flow_type & IRQ_TYPE_LEVEL_LOW) {
6259758a7b0SThomas Gleixner irq_set_handler_locked(d, handle_level_irq);
626ecf4b196SThomas Gleixner d->chip = &ipic_level_irq_chip;
627b9f0f1bbSKim Phillips } else {
6289758a7b0SThomas Gleixner irq_set_handler_locked(d, handle_edge_irq);
629ecf4b196SThomas Gleixner d->chip = &ipic_edge_irq_chip;
630b9f0f1bbSKim Phillips }
631b9f0f1bbSKim Phillips
632b9f0f1bbSKim Phillips /* only EXT IRQ senses are programmable on ipic
633b9f0f1bbSKim Phillips * internal IRQ senses are LEVEL_LOW
634b9f0f1bbSKim Phillips */
635b9f0f1bbSKim Phillips if (src == IPIC_IRQ_EXT0)
636b9f0f1bbSKim Phillips edibit = 15;
637b9f0f1bbSKim Phillips else
638b9f0f1bbSKim Phillips if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7)
639b9f0f1bbSKim Phillips edibit = (14 - (src - IPIC_IRQ_EXT1));
640b9f0f1bbSKim Phillips else
641b9f0f1bbSKim Phillips return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
642b9f0f1bbSKim Phillips
643b9f0f1bbSKim Phillips vold = ipic_read(ipic->regs, IPIC_SECNR);
644b9f0f1bbSKim Phillips if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) {
645b9f0f1bbSKim Phillips vnew = vold | (1 << edibit);
646b9f0f1bbSKim Phillips } else {
647b9f0f1bbSKim Phillips vnew = vold & ~(1 << edibit);
648b9f0f1bbSKim Phillips }
649b9f0f1bbSKim Phillips if (vold != vnew)
650b9f0f1bbSKim Phillips ipic_write(ipic->regs, IPIC_SECNR, vnew);
651ecf4b196SThomas Gleixner return IRQ_SET_MASK_OK_NOCOPY;
652b9f0f1bbSKim Phillips }
653b9f0f1bbSKim Phillips
65477d4309eSLi Yang /* level interrupts and edge interrupts have different ack operations */
65577d4309eSLi Yang static struct irq_chip ipic_level_irq_chip = {
656b27df672SThomas Gleixner .name = "IPIC",
657687228adSLennert Buytenhek .irq_unmask = ipic_unmask_irq,
658687228adSLennert Buytenhek .irq_mask = ipic_mask_irq,
659687228adSLennert Buytenhek .irq_mask_ack = ipic_mask_irq,
660687228adSLennert Buytenhek .irq_set_type = ipic_set_irq_type,
66177d4309eSLi Yang };
66277d4309eSLi Yang
66377d4309eSLi Yang static struct irq_chip ipic_edge_irq_chip = {
664b27df672SThomas Gleixner .name = "IPIC",
665687228adSLennert Buytenhek .irq_unmask = ipic_unmask_irq,
666687228adSLennert Buytenhek .irq_mask = ipic_mask_irq,
667687228adSLennert Buytenhek .irq_mask_ack = ipic_mask_irq_and_ack,
668687228adSLennert Buytenhek .irq_ack = ipic_ack_irq,
669687228adSLennert Buytenhek .irq_set_type = ipic_set_irq_type,
6701cd8e506SKumar Gala };
6711cd8e506SKumar Gala
ipic_host_match(struct irq_domain * h,struct device_node * node,enum irq_domain_bus_token bus_token)672ad3aedfbSMarc Zyngier static int ipic_host_match(struct irq_domain *h, struct device_node *node,
673ad3aedfbSMarc Zyngier enum irq_domain_bus_token bus_token)
6741cd8e506SKumar Gala {
675b9f0f1bbSKim Phillips /* Exact match, unless ipic node is NULL */
6765d4c9bc7SMarc Zyngier struct device_node *of_node = irq_domain_get_of_node(h);
6775d4c9bc7SMarc Zyngier return of_node == NULL || of_node == node;
678b9f0f1bbSKim Phillips }
6791cd8e506SKumar Gala
ipic_host_map(struct irq_domain * h,unsigned int virq,irq_hw_number_t hw)680bae1d8f1SGrant Likely static int ipic_host_map(struct irq_domain *h, unsigned int virq,
681b9f0f1bbSKim Phillips irq_hw_number_t hw)
682b9f0f1bbSKim Phillips {
683b9f0f1bbSKim Phillips struct ipic *ipic = h->host_data;
684b9f0f1bbSKim Phillips
685ec775d0eSThomas Gleixner irq_set_chip_data(virq, ipic);
686ec775d0eSThomas Gleixner irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
687b9f0f1bbSKim Phillips
688b9f0f1bbSKim Phillips /* Set default irq type */
689ec775d0eSThomas Gleixner irq_set_irq_type(virq, IRQ_TYPE_NONE);
690b9f0f1bbSKim Phillips
691b9f0f1bbSKim Phillips return 0;
692b9f0f1bbSKim Phillips }
693b9f0f1bbSKim Phillips
694202648a6SKrzysztof Kozlowski static const struct irq_domain_ops ipic_host_ops = {
695b9f0f1bbSKim Phillips .match = ipic_host_match,
696b9f0f1bbSKim Phillips .map = ipic_host_map,
697ff8c3ab8SGrant Likely .xlate = irq_domain_xlate_onetwocell,
698b9f0f1bbSKim Phillips };
699b9f0f1bbSKim Phillips
ipic_init(struct device_node * node,unsigned int flags)700126186a0SKumar Gala struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
701b9f0f1bbSKim Phillips {
702b9f0f1bbSKim Phillips struct ipic *ipic;
703b9f0f1bbSKim Phillips struct resource res;
704b9f0f1bbSKim Phillips u32 temp = 0, ret;
705b9f0f1bbSKim Phillips
70684f1c1e0SMichael Ellerman ret = of_address_to_resource(node, 0, &res);
70784f1c1e0SMichael Ellerman if (ret)
70884f1c1e0SMichael Ellerman return NULL;
70984f1c1e0SMichael Ellerman
710ea96025aSAnton Vorontsov ipic = kzalloc(sizeof(*ipic), GFP_KERNEL);
711b9f0f1bbSKim Phillips if (ipic == NULL)
712126186a0SKumar Gala return NULL;
713b9f0f1bbSKim Phillips
714a8db8cf0SGrant Likely ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
715a8db8cf0SGrant Likely &ipic_host_ops, ipic);
7167a626b66SJulia Lawall if (ipic->irqhost == NULL) {
7177a626b66SJulia Lawall kfree(ipic);
718126186a0SKumar Gala return NULL;
7197a626b66SJulia Lawall }
720b9f0f1bbSKim Phillips
72128f65c11SJoe Perches ipic->regs = ioremap(res.start, resource_size(&res));
722b9f0f1bbSKim Phillips
723b9f0f1bbSKim Phillips /* init hw */
724b9f0f1bbSKim Phillips ipic_write(ipic->regs, IPIC_SICNR, 0x0);
7251cd8e506SKumar Gala
7261cd8e506SKumar Gala /* default priority scheme is grouped. If spread mode is required
7271cd8e506SKumar Gala * configure SICFR accordingly */
7281cd8e506SKumar Gala if (flags & IPIC_SPREADMODE_GRP_A)
7291cd8e506SKumar Gala temp |= SICFR_IPSA;
730f03ca957SLi Yang if (flags & IPIC_SPREADMODE_GRP_B)
731f03ca957SLi Yang temp |= SICFR_IPSB;
732f03ca957SLi Yang if (flags & IPIC_SPREADMODE_GRP_C)
733f03ca957SLi Yang temp |= SICFR_IPSC;
7341cd8e506SKumar Gala if (flags & IPIC_SPREADMODE_GRP_D)
7351cd8e506SKumar Gala temp |= SICFR_IPSD;
7361cd8e506SKumar Gala if (flags & IPIC_SPREADMODE_MIX_A)
7371cd8e506SKumar Gala temp |= SICFR_MPSA;
7381cd8e506SKumar Gala if (flags & IPIC_SPREADMODE_MIX_B)
7391cd8e506SKumar Gala temp |= SICFR_MPSB;
7401cd8e506SKumar Gala
741f03ca957SLi Yang ipic_write(ipic->regs, IPIC_SICFR, temp);
7421cd8e506SKumar Gala
7431cd8e506SKumar Gala /* handle MCP route */
7441cd8e506SKumar Gala temp = 0;
7451cd8e506SKumar Gala if (flags & IPIC_DISABLE_MCP_OUT)
7461cd8e506SKumar Gala temp = SERCR_MCPR;
747b9f0f1bbSKim Phillips ipic_write(ipic->regs, IPIC_SERCR, temp);
7481cd8e506SKumar Gala
7491cd8e506SKumar Gala /* handle routing of IRQ0 to MCP */
750b9f0f1bbSKim Phillips temp = ipic_read(ipic->regs, IPIC_SEMSR);
7511cd8e506SKumar Gala
7521cd8e506SKumar Gala if (flags & IPIC_IRQ0_MCP)
7531cd8e506SKumar Gala temp |= SEMSR_SIRQ0;
7541cd8e506SKumar Gala else
7551cd8e506SKumar Gala temp &= ~SEMSR_SIRQ0;
7561cd8e506SKumar Gala
757b9f0f1bbSKim Phillips ipic_write(ipic->regs, IPIC_SEMSR, temp);
7581cd8e506SKumar Gala
759b9f0f1bbSKim Phillips primary_ipic = ipic;
760b9f0f1bbSKim Phillips irq_set_default_host(primary_ipic->irqhost);
761b9f0f1bbSKim Phillips
7628640d3bfSSebastian Andrzej Siewior ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
7638640d3bfSSebastian Andrzej Siewior ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
7648640d3bfSSebastian Andrzej Siewior
765b9f0f1bbSKim Phillips printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
766b9f0f1bbSKim Phillips primary_ipic->regs);
767126186a0SKumar Gala
768126186a0SKumar Gala return ipic;
7691cd8e506SKumar Gala }
7701cd8e506SKumar Gala
ipic_set_default_priority(void)7716c552983SNick Child void __init ipic_set_default_priority(void)
7721cd8e506SKumar Gala {
773f03ca957SLi Yang ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
774f03ca957SLi Yang ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
775f03ca957SLi Yang ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
776f03ca957SLi Yang ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
777f03ca957SLi Yang ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
778f03ca957SLi Yang ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
7791cd8e506SKumar Gala }
7801cd8e506SKumar Gala
ipic_get_mcp_status(void)7811cd8e506SKumar Gala u32 ipic_get_mcp_status(void)
7821cd8e506SKumar Gala {
7836beb3381SChristophe Leroy return primary_ipic ? ipic_read(primary_ipic->regs, IPIC_SERSR) : 0;
7841cd8e506SKumar Gala }
7851cd8e506SKumar Gala
ipic_clear_mcp_status(u32 mask)7861cd8e506SKumar Gala void ipic_clear_mcp_status(u32 mask)
7871cd8e506SKumar Gala {
7886b148a7cSChristophe Leroy ipic_write(primary_ipic->regs, IPIC_SERSR, mask);
7891cd8e506SKumar Gala }
7901cd8e506SKumar Gala
791ef24ba70SMichael Ellerman /* Return an interrupt vector or 0 if no interrupt is pending. */
ipic_get_irq(void)79235a84c2fSOlaf Hering unsigned int ipic_get_irq(void)
7931cd8e506SKumar Gala {
7941cd8e506SKumar Gala int irq;
7951cd8e506SKumar Gala
796b9f0f1bbSKim Phillips BUG_ON(primary_ipic == NULL);
797b9f0f1bbSKim Phillips
798b9f0f1bbSKim Phillips #define IPIC_SIVCR_VECTOR_MASK 0x7f
799b9f0f1bbSKim Phillips irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK;
8001cd8e506SKumar Gala
8011cd8e506SKumar Gala if (irq == 0) /* 0 --> no irq is pending */
802ef24ba70SMichael Ellerman return 0;
8031cd8e506SKumar Gala
804b9f0f1bbSKim Phillips return irq_linear_revmap(primary_ipic->irqhost, irq);
8051cd8e506SKumar Gala }
8061cd8e506SKumar Gala
807e2a02ba6SMichael Neuling #ifdef CONFIG_SUSPEND
808d49747bdSScott Wood static struct {
809d49747bdSScott Wood u32 sicfr;
810d49747bdSScott Wood u32 siprr[2];
811d49747bdSScott Wood u32 simsr[2];
812d49747bdSScott Wood u32 sicnr;
813d49747bdSScott Wood u32 smprr[2];
814d49747bdSScott Wood u32 semsr;
815d49747bdSScott Wood u32 secnr;
816d49747bdSScott Wood u32 sermr;
817d49747bdSScott Wood u32 sercr;
818d49747bdSScott Wood } ipic_saved_state;
819d49747bdSScott Wood
ipic_suspend(void)820f5a592f7SRafael J. Wysocki static int ipic_suspend(void)
821d49747bdSScott Wood {
822d49747bdSScott Wood struct ipic *ipic = primary_ipic;
823d49747bdSScott Wood
824d49747bdSScott Wood ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR);
825d49747bdSScott Wood ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A);
826d49747bdSScott Wood ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D);
827d49747bdSScott Wood ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H);
828d49747bdSScott Wood ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L);
829d49747bdSScott Wood ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR);
830d49747bdSScott Wood ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A);
831d49747bdSScott Wood ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B);
832d49747bdSScott Wood ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR);
833d49747bdSScott Wood ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR);
834d49747bdSScott Wood ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR);
835d49747bdSScott Wood ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR);
836d49747bdSScott Wood
837d49747bdSScott Wood if (fsl_deep_sleep()) {
838d49747bdSScott Wood /* In deep sleep, make sure there can be no
839d49747bdSScott Wood * pending interrupts, as this can cause
840d49747bdSScott Wood * problems on 831x.
841d49747bdSScott Wood */
842d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
843d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
844d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SEMSR, 0);
845d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SERMR, 0);
846d49747bdSScott Wood }
847d49747bdSScott Wood
848d49747bdSScott Wood return 0;
849d49747bdSScott Wood }
850d49747bdSScott Wood
ipic_resume(void)851f5a592f7SRafael J. Wysocki static void ipic_resume(void)
852d49747bdSScott Wood {
853d49747bdSScott Wood struct ipic *ipic = primary_ipic;
854d49747bdSScott Wood
855d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr);
856d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]);
857d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]);
858d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]);
859d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]);
860d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr);
861d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]);
862d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]);
863d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr);
864d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
865d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
866d49747bdSScott Wood ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
867d49747bdSScott Wood }
868d49747bdSScott Wood #else
869d49747bdSScott Wood #define ipic_suspend NULL
870d49747bdSScott Wood #define ipic_resume NULL
871d49747bdSScott Wood #endif
872d49747bdSScott Wood
873f5a592f7SRafael J. Wysocki static struct syscore_ops ipic_syscore_ops = {
874d49747bdSScott Wood .suspend = ipic_suspend,
875d49747bdSScott Wood .resume = ipic_resume,
8761cd8e506SKumar Gala };
8771cd8e506SKumar Gala
init_ipic_syscore(void)878f5a592f7SRafael J. Wysocki static int __init init_ipic_syscore(void)
8791cd8e506SKumar Gala {
8801428a9faSOlaf Hering if (!primary_ipic || !primary_ipic->regs)
8811cd8e506SKumar Gala return -ENODEV;
8821cd8e506SKumar Gala
883f5a592f7SRafael J. Wysocki printk(KERN_DEBUG "Registering ipic system core operations\n");
884f5a592f7SRafael J. Wysocki register_syscore_ops(&ipic_syscore_ops);
885f5a592f7SRafael J. Wysocki
8861cd8e506SKumar Gala return 0;
8871cd8e506SKumar Gala }
8881cd8e506SKumar Gala
889f5a592f7SRafael J. Wysocki subsys_initcall(init_ipic_syscore);
890