|
@@ -30,11 +30,11 @@
|
|
|
#include "ipic.h"
|
|
|
|
|
|
static struct ipic * primary_ipic;
|
|
|
+static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
|
|
|
static DEFINE_SPINLOCK(ipic_lock);
|
|
|
|
|
|
static struct ipic_info ipic_info[] = {
|
|
|
[1] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_C,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -42,7 +42,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 0,
|
|
|
},
|
|
|
[2] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_C,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -50,7 +49,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 1,
|
|
|
},
|
|
|
[4] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_C,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -58,7 +56,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 3,
|
|
|
},
|
|
|
[9] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -66,7 +63,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 0,
|
|
|
},
|
|
|
[10] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -74,7 +70,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 1,
|
|
|
},
|
|
|
[11] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -82,7 +77,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 2,
|
|
|
},
|
|
|
[12] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -90,7 +84,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 3,
|
|
|
},
|
|
|
[13] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -98,7 +91,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 4,
|
|
|
},
|
|
|
[14] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -106,7 +98,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 5,
|
|
|
},
|
|
|
[15] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -114,7 +105,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 6,
|
|
|
},
|
|
|
[16] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_D,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -122,7 +112,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 7,
|
|
|
},
|
|
|
[17] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -130,7 +120,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 5,
|
|
|
},
|
|
|
[18] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -138,7 +128,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 6,
|
|
|
},
|
|
|
[19] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -146,7 +136,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 7,
|
|
|
},
|
|
|
[20] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -154,7 +144,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 4,
|
|
|
},
|
|
|
[21] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -162,7 +152,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 5,
|
|
|
},
|
|
|
[22] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -170,7 +160,7 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 6,
|
|
|
},
|
|
|
[23] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
+ .ack = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -178,7 +168,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 7,
|
|
|
},
|
|
|
[32] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -186,7 +175,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 0,
|
|
|
},
|
|
|
[33] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -194,7 +182,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 1,
|
|
|
},
|
|
|
[34] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -202,7 +189,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 2,
|
|
|
},
|
|
|
[35] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -210,7 +196,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 3,
|
|
|
},
|
|
|
[36] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -218,7 +203,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 4,
|
|
|
},
|
|
|
[37] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -226,7 +210,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 5,
|
|
|
},
|
|
|
[38] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -234,7 +217,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 6,
|
|
|
},
|
|
|
[39] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_A,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -242,7 +224,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 7,
|
|
|
},
|
|
|
[42] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_B,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -250,7 +231,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 2,
|
|
|
},
|
|
|
[44] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_B,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -258,7 +238,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 4,
|
|
|
},
|
|
|
[45] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_B,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -266,7 +245,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 5,
|
|
|
},
|
|
|
[46] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_B,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -274,7 +252,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 6,
|
|
|
},
|
|
|
[47] = {
|
|
|
- .pend = IPIC_SIPNR_H,
|
|
|
.mask = IPIC_SIMSR_H,
|
|
|
.prio = IPIC_SIPRR_B,
|
|
|
.force = IPIC_SIFCR_H,
|
|
@@ -282,7 +259,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 7,
|
|
|
},
|
|
|
[48] = {
|
|
|
- .pend = IPIC_SEPNR,
|
|
|
.mask = IPIC_SEMSR,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SEFCR,
|
|
@@ -290,7 +266,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 4,
|
|
|
},
|
|
|
[64] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -298,7 +273,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 0,
|
|
|
},
|
|
|
[65] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -306,7 +280,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 1,
|
|
|
},
|
|
|
[66] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -314,7 +287,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 2,
|
|
|
},
|
|
|
[67] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_A,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -322,7 +294,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 3,
|
|
|
},
|
|
|
[68] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -330,7 +301,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 0,
|
|
|
},
|
|
|
[69] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -338,7 +308,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 1,
|
|
|
},
|
|
|
[70] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -346,7 +315,6 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 2,
|
|
|
},
|
|
|
[71] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = IPIC_SMPRR_B,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -354,133 +322,114 @@ static struct ipic_info ipic_info[] = {
|
|
|
.prio_mask = 3,
|
|
|
},
|
|
|
[72] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 8,
|
|
|
},
|
|
|
[73] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 9,
|
|
|
},
|
|
|
[74] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 10,
|
|
|
},
|
|
|
[75] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 11,
|
|
|
},
|
|
|
[76] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 12,
|
|
|
},
|
|
|
[77] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 13,
|
|
|
},
|
|
|
[78] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 14,
|
|
|
},
|
|
|
[79] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 15,
|
|
|
},
|
|
|
[80] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 16,
|
|
|
},
|
|
|
[81] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 17,
|
|
|
},
|
|
|
[82] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 18,
|
|
|
},
|
|
|
[84] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 20,
|
|
|
},
|
|
|
[85] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 21,
|
|
|
},
|
|
|
[86] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 22,
|
|
|
},
|
|
|
[87] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 23,
|
|
|
},
|
|
|
[88] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 24,
|
|
|
},
|
|
|
[89] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 25,
|
|
|
},
|
|
|
[90] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
|
.bit = 26,
|
|
|
},
|
|
|
[91] = {
|
|
|
- .pend = IPIC_SIPNR_L,
|
|
|
.mask = IPIC_SIMSR_L,
|
|
|
.prio = 0,
|
|
|
.force = IPIC_SIFCR_L,
|
|
@@ -534,6 +483,10 @@ static void ipic_mask_irq(unsigned int virq)
|
|
|
temp &= ~(1 << (31 - ipic_info[src].bit));
|
|
|
ipic_write(ipic->regs, ipic_info[src].mask, temp);
|
|
|
|
|
|
+ /* mb() can't guarantee that masking is finished. But it does finish
|
|
|
+ * for nearly all cases. */
|
|
|
+ mb();
|
|
|
+
|
|
|
spin_unlock_irqrestore(&ipic_lock, flags);
|
|
|
}
|
|
|
|
|
@@ -546,9 +499,13 @@ static void ipic_ack_irq(unsigned int virq)
|
|
|
|
|
|
spin_lock_irqsave(&ipic_lock, flags);
|
|
|
|
|
|
- temp = ipic_read(ipic->regs, ipic_info[src].pend);
|
|
|
+ temp = ipic_read(ipic->regs, ipic_info[src].ack);
|
|
|
temp |= (1 << (31 - ipic_info[src].bit));
|
|
|
- ipic_write(ipic->regs, ipic_info[src].pend, temp);
|
|
|
+ ipic_write(ipic->regs, ipic_info[src].ack, temp);
|
|
|
+
|
|
|
+ /* mb() can't guarantee that ack is finished. But it does finish
|
|
|
+ * for nearly all cases. */
|
|
|
+ mb();
|
|
|
|
|
|
spin_unlock_irqrestore(&ipic_lock, flags);
|
|
|
}
|
|
@@ -566,9 +523,13 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
|
|
|
temp &= ~(1 << (31 - ipic_info[src].bit));
|
|
|
ipic_write(ipic->regs, ipic_info[src].mask, temp);
|
|
|
|
|
|
- temp = ipic_read(ipic->regs, ipic_info[src].pend);
|
|
|
+ temp = ipic_read(ipic->regs, ipic_info[src].ack);
|
|
|
temp |= (1 << (31 - ipic_info[src].bit));
|
|
|
- ipic_write(ipic->regs, ipic_info[src].pend, temp);
|
|
|
+ ipic_write(ipic->regs, ipic_info[src].ack, temp);
|
|
|
+
|
|
|
+ /* mb() can't guarantee that ack is finished. But it does finish
|
|
|
+ * for nearly all cases. */
|
|
|
+ mb();
|
|
|
|
|
|
spin_unlock_irqrestore(&ipic_lock, flags);
|
|
|
}
|
|
@@ -590,14 +551,22 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
|
|
|
flow_type);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+ /* ipic supports only edge mode on external interrupts */
|
|
|
+ if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
|
|
|
+ printk(KERN_ERR "ipic: edge sense not supported on internal "
|
|
|
+ "interrupts\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
|
|
|
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
|
|
|
if (flow_type & IRQ_TYPE_LEVEL_LOW) {
|
|
|
desc->status |= IRQ_LEVEL;
|
|
|
desc->handle_irq = handle_level_irq;
|
|
|
+ desc->chip = &ipic_level_irq_chip;
|
|
|
} else {
|
|
|
desc->handle_irq = handle_edge_irq;
|
|
|
+ desc->chip = &ipic_edge_irq_chip;
|
|
|
}
|
|
|
|
|
|
/* only EXT IRQ senses are programmable on ipic
|
|
@@ -622,7 +591,16 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static struct irq_chip ipic_irq_chip = {
|
|
|
+/* level interrupts and edge interrupts have different ack operations */
|
|
|
+static struct irq_chip ipic_level_irq_chip = {
|
|
|
+ .typename = " IPIC ",
|
|
|
+ .unmask = ipic_unmask_irq,
|
|
|
+ .mask = ipic_mask_irq,
|
|
|
+ .mask_ack = ipic_mask_irq,
|
|
|
+ .set_type = ipic_set_irq_type,
|
|
|
+};
|
|
|
+
|
|
|
+static struct irq_chip ipic_edge_irq_chip = {
|
|
|
.typename = " IPIC ",
|
|
|
.unmask = ipic_unmask_irq,
|
|
|
.mask = ipic_mask_irq,
|
|
@@ -641,13 +619,9 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
|
|
|
irq_hw_number_t hw)
|
|
|
{
|
|
|
struct ipic *ipic = h->host_data;
|
|
|
- struct irq_chip *chip;
|
|
|
-
|
|
|
- /* Default chip */
|
|
|
- chip = &ipic->hc_irq;
|
|
|
|
|
|
set_irq_chip_data(virq, ipic);
|
|
|
- set_irq_chip_and_handler(virq, chip, handle_level_irq);
|
|
|
+ set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
|
|
|
|
|
|
/* Set default irq type */
|
|
|
set_irq_type(virq, IRQ_TYPE_NONE);
|
|
@@ -706,7 +680,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
|
|
|
ipic->regs = ioremap(res.start, res.end - res.start + 1);
|
|
|
|
|
|
ipic->irqhost->host_data = ipic;
|
|
|
- ipic->hc_irq = ipic_irq_chip;
|
|
|
|
|
|
/* init hw */
|
|
|
ipic_write(ipic->regs, IPIC_SICNR, 0x0);
|