aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-26 02:47:42 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-26 02:47:42 -0400
commitf9bd170a87948a9e077149b70fb192c563770fdf (patch)
treec759b57b67ab41a859e19f7dcee571504b368202 /arch/ppc
parent25635c71e44111a6bd48f342e144e2fc02d0a314 (diff)
powerpc: Merge i8259.c into arch/powerpc/sysdev
This changes the parameters for i8259_init so that it takes two parameters: a physical address for generating an interrupt acknowledge cycle, and an interrupt number offset. i8259_init now sets the irq_desc[] for its interrupts; all the callers were doing this, and that code is gone now. This also defines a CONFIG_PPC_I8259 symbol to select i8259.o for inclusion, and makes the platforms that need it select that symbol. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc')
-rw-r--r--arch/ppc/Kconfig14
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c5
-rw-r--r--arch/ppc/platforms/chrp_setup.c4
-rw-r--r--arch/ppc/platforms/lopec.c6
-rw-r--r--arch/ppc/platforms/mvme5100.c6
-rw-r--r--arch/ppc/platforms/pplus.c5
-rw-r--r--arch/ppc/platforms/prep_setup.c8
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c6
-rw-r--r--arch/ppc/platforms/sandpoint.c10
-rw-r--r--arch/ppc/syslib/Makefile19
-rw-r--r--arch/ppc/syslib/i8259.c208
11 files changed, 32 insertions, 259 deletions
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index e3efaf47d083..114b90fdea24 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -589,6 +589,7 @@ config EV64260
589 589
590config LOPEC 590config LOPEC
591 bool "Motorola-LoPEC" 591 bool "Motorola-LoPEC"
592 select PPC_I8259
592 593
593config MVME5100 594config MVME5100
594 bool "Motorola-MVME5100" 595 bool "Motorola-MVME5100"
@@ -596,6 +597,7 @@ config MVME5100
596 597
597config PPLUS 598config PPLUS
598 bool "Motorola-PowerPlus" 599 bool "Motorola-PowerPlus"
600 select PPC_I8259
599 select PPC_INDIRECT_PCI 601 select PPC_INDIRECT_PCI
600 602
601config PRPMC750 603config PRPMC750
@@ -608,12 +610,14 @@ config PRPMC800
608 610
609config SANDPOINT 611config SANDPOINT
610 bool "Motorola-Sandpoint" 612 bool "Motorola-Sandpoint"
613 select PPC_I8259
611 help 614 help
612 Select SANDPOINT if configuring for a Motorola Sandpoint X3 615 Select SANDPOINT if configuring for a Motorola Sandpoint X3
613 (any flavor). 616 (any flavor).
614 617
615config RADSTONE_PPC7D 618config RADSTONE_PPC7D
616 bool "Radstone Technology PPC7D board" 619 bool "Radstone Technology PPC7D board"
620 select PPC_I8259
617 621
618config PAL4 622config PAL4
619 bool "SBS-Palomar4" 623 bool "SBS-Palomar4"
@@ -755,6 +759,7 @@ config CPM2
755config PPC_CHRP 759config PPC_CHRP
756 bool " Common Hardware Reference Platform (CHRP) based machines" 760 bool " Common Hardware Reference Platform (CHRP) based machines"
757 depends on PPC_MULTIPLATFORM 761 depends on PPC_MULTIPLATFORM
762 select PPC_I8259
758 select PPC_INDIRECT_PCI 763 select PPC_INDIRECT_PCI
759 default y 764 default y
760 765
@@ -772,6 +777,7 @@ config PPC_PMAC64
772config PPC_PREP 777config PPC_PREP
773 bool " PowerPC Reference Platform (PReP) based machines" 778 bool " PowerPC Reference Platform (PReP) based machines"
774 depends on PPC_MULTIPLATFORM 779 depends on PPC_MULTIPLATFORM
780 select PPC_I8259
775 select PPC_INDIRECT_PCI 781 select PPC_INDIRECT_PCI
776 default y 782 default y
777 783
@@ -881,6 +887,7 @@ config HARRIER_STORE_GATHERING
881config MVME5100_IPMC761_PRESENT 887config MVME5100_IPMC761_PRESENT
882 bool "MVME5100 configured with an IPMC761" 888 bool "MVME5100 configured with an IPMC761"
883 depends on MVME5100 889 depends on MVME5100
890 select PPC_I8259
884 891
885config SPRUCE_BAUD_33M 892config SPRUCE_BAUD_33M
886 bool "Spruce baud clock support" 893 bool "Spruce baud clock support"
@@ -1138,6 +1145,7 @@ menu "Bus options"
1138config ISA 1145config ISA
1139 bool "Support for ISA-bus hardware" 1146 bool "Support for ISA-bus hardware"
1140 depends on PPC_PREP || PPC_CHRP 1147 depends on PPC_PREP || PPC_CHRP
1148 select PPC_I8259
1141 help 1149 help
1142 Find out whether you have ISA slots on your motherboard. ISA is the 1150 Find out whether you have ISA slots on your motherboard. ISA is the
1143 name of a bus system, i.e. the way the CPU talks to the other stuff 1151 name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -1150,6 +1158,11 @@ config GENERIC_ISA_DMA
1150 depends on POWER3 || POWER4 || 6xx && !CPM2 1158 depends on POWER3 || POWER4 || 6xx && !CPM2
1151 default y 1159 default y
1152 1160
1161config PPC_I8259
1162 bool
1163 default y if 85xx
1164 default n
1165
1153config PPC_INDIRECT_PCI 1166config PPC_INDIRECT_PCI
1154 bool 1167 bool
1155 depends on PCI 1168 depends on PCI
@@ -1192,6 +1205,7 @@ config MPC83xx_PCI2
1192config PCI_QSPAN 1205config PCI_QSPAN
1193 bool "QSpan PCI" 1206 bool "QSpan PCI"
1194 depends on !4xx && !CPM2 && 8xx 1207 depends on !4xx && !CPM2 && 8xx
1208 select PPC_I8259
1195 help 1209 help
1196 Say Y here if you have a system based on a Motorola 8xx-series 1210 Say Y here if you have a system based on a Motorola 8xx-series
1197 embedded processor with a QSPAN PCI interface, otherwise say N. 1211 embedded processor with a QSPAN PCI interface, otherwise say N.
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 9f9039498ae5..eda659916f24 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -173,10 +173,7 @@ mpc85xx_cds_init_IRQ(void)
173#ifdef CONFIG_PCI 173#ifdef CONFIG_PCI
174 openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); 174 openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
175 175
176 for (i = 0; i < NUM_8259_INTERRUPTS; i++) 176 i8259_init(0, 0);
177 irq_desc[i].handler = &i8259_pic;
178
179 i8259_init(0);
180#endif 177#endif
181 178
182#ifdef CONFIG_CPM2 179#ifdef CONFIG_CPM2
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 56c53bb3dfd4..dad81ffd4013 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -436,9 +436,7 @@ void __init chrp_init_IRQ(void)
436 i8259_irq); 436 i8259_irq);
437 437
438 } 438 }
439 for (i = 0; i < NUM_8259_INTERRUPTS; i++) 439 i8259_init(chrp_int_ack, 0);
440 irq_desc[i].handler = &i8259_pic;
441 i8259_init(chrp_int_ack);
442 440
443#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 441#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
444 /* see if there is a keyboard in the device tree 442 /* see if there is a keyboard in the device tree
diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
index 800c56a07a97..06d247c23b82 100644
--- a/arch/ppc/platforms/lopec.c
+++ b/arch/ppc/platforms/lopec.c
@@ -267,15 +267,11 @@ lopec_init_IRQ(void)
267 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", 267 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
268 &i8259_irq); 268 &i8259_irq);
269 269
270 /* Map i8259 interrupts */
271 for(i = 0; i < NUM_8259_INTERRUPTS; i++)
272 irq_desc[i].handler = &i8259_pic;
273
274 /* 270 /*
275 * The EPIC allows for a read in the range of 0xFEF00000 -> 271 * The EPIC allows for a read in the range of 0xFEF00000 ->
276 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. 272 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
277 */ 273 */
278 i8259_init(0xfef00000); 274 i8259_init(0xfef00000, 0);
279} 275}
280 276
281static int __init 277static int __init
diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
index ce2ce88c8033..108eb182dddc 100644
--- a/arch/ppc/platforms/mvme5100.c
+++ b/arch/ppc/platforms/mvme5100.c
@@ -223,11 +223,7 @@ mvme5100_init_IRQ(void)
223 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", 223 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
224 &i8259_irq); 224 &i8259_irq);
225 225
226 /* Map i8259 interrupts. */ 226 i8259_init(0, 0);
227 for (i = 0; i < NUM_8259_INTERRUPTS; i++)
228 irq_desc[i].handler = &i8259_pic;
229
230 i8259_init(0);
231#else 227#else
232 openpic_init(0); 228 openpic_init(0);
233#endif 229#endif
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index 59eb330b2090..22bd40cfb092 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -665,10 +665,7 @@ static void __init pplus_init_IRQ(void)
665 ppc_md.get_irq = openpic_get_irq; 665 ppc_md.get_irq = openpic_get_irq;
666 } 666 }
667 667
668 for (i = 0; i < NUM_8259_INTERRUPTS; i++) 668 i8259_init(0, 0);
669 irq_desc[i].handler = &i8259_pic;
670
671 i8259_init(0);
672 669
673 if (ppc_md.progress) 670 if (ppc_md.progress)
674 ppc_md.progress("init_irq: exit", 0); 671 ppc_md.progress("init_irq: exit", 0);
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index 9e5637e5f5a9..067d7d53b81e 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -954,11 +954,9 @@ prep_init_IRQ(void)
954 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", 954 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
955 i8259_irq); 955 i8259_irq);
956 } 956 }
957 for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
958 irq_desc[i].handler = &i8259_pic;
959 957
960 if (have_residual_data) { 958 if (have_residual_data) {
961 i8259_init(residual_isapic_addr()); 959 i8259_init(residual_isapic_addr(), 0);
962 return; 960 return;
963 } 961 }
964 962
@@ -969,11 +967,11 @@ prep_init_IRQ(void)
969 if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) 967 if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
970 && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN) 968 && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
971 || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK))) 969 || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
972 i8259_init(0); 970 i8259_init(0, 0);
973 else 971 else
974 /* PCI interrupt ack address given in section 6.1.8 of the 972 /* PCI interrupt ack address given in section 6.1.8 of the
975 * PReP specification. */ 973 * PReP specification. */
976 i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR); 974 i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0);
977} 975}
978 976
979#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) 977#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 5058568c13ec..6f97911c330d 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -514,13 +514,9 @@ static void __init ppc7d_init_irq(void)
514 int irq; 514 int irq;
515 515
516 pr_debug("%s\n", __FUNCTION__); 516 pr_debug("%s\n", __FUNCTION__);
517 i8259_init(0); 517 i8259_init(0, 0);
518 mv64360_init_irq(); 518 mv64360_init_irq();
519 519
520 /* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */
521 for (irq = 0; irq < 16; irq++) {
522 irq_desc[irq].handler = &i8259_pic;
523 }
524 /* IRQs 5,6,9,10,11,14,15 are level sensitive */ 520 /* IRQs 5,6,9,10,11,14,15 are level sensitive */
525 irq_desc[5].status |= IRQ_LEVEL; 521 irq_desc[5].status |= IRQ_LEVEL;
526 irq_desc[6].status |= IRQ_LEVEL; 522 irq_desc[6].status |= IRQ_LEVEL;
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index d4c9781989fb..9eeed3572309 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -494,18 +494,10 @@ sandpoint_init_IRQ(void)
494 i8259_irq); 494 i8259_irq);
495 495
496 /* 496 /*
497 * openpic_init() has set up irq_desc[16-31] to be openpic
498 * interrupts. We need to set irq_desc[0-15] to be i8259
499 * interrupts.
500 */
501 for(i=0; i < NUM_8259_INTERRUPTS; i++)
502 irq_desc[i].handler = &i8259_pic;
503
504 /*
505 * The EPIC allows for a read in the range of 0xFEF00000 -> 497 * The EPIC allows for a read in the range of 0xFEF00000 ->
506 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. 498 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
507 */ 499 */
508 i8259_init(0xfef00000); 500 i8259_init(0xfef00000, 0);
509} 501}
510 502
511static unsigned long __init 503static unsigned long __init
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 5739a19b9ed9..e6e6aa4d291e 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -36,14 +36,12 @@ endif
36endif 36endif
37obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ 37obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
38 ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o 38 ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
39ifeq ($(CONFIG_8xx),y) 39obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
40obj-$(CONFIG_PCI) += qspan_pci.o i8259.o
41endif
42obj-$(CONFIG_PPC_OF) += prom_init.o prom.o 40obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
43obj-$(CONFIG_PPC_PMAC) += open_pic.o 41obj-$(CONFIG_PPC_PMAC) += open_pic.o
44obj-$(CONFIG_POWER4) += open_pic2.o 42obj-$(CONFIG_POWER4) += open_pic2.o
45obj-$(CONFIG_PPC_CHRP) += open_pic.o i8259.o 43obj-$(CONFIG_PPC_CHRP) += open_pic.o
46obj-$(CONFIG_PPC_PREP) += open_pic.o i8259.o todc_time.o 44obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
47obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o 45obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
48obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o 46obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
49obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o 47obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o
@@ -51,7 +49,7 @@ obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o
51obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o 49obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o
52obj-$(CONFIG_GEMINI) += open_pic.o 50obj-$(CONFIG_GEMINI) += open_pic.o
53obj-$(CONFIG_GT64260) += gt64260_pic.o 51obj-$(CONFIG_GT64260) += gt64260_pic.o
54obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o 52obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o
55obj-$(CONFIG_HDPU) += pci_auto.o 53obj-$(CONFIG_HDPU) += pci_auto.o
56obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o 54obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o
57obj-$(CONFIG_KATANA) += pci_auto.o 55obj-$(CONFIG_KATANA) += pci_auto.o
@@ -59,18 +57,17 @@ obj-$(CONFIG_MV64360) += mv64360_pic.o
59obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o 57obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o
60obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \ 58obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \
61 pci_auto.o hawk_common.o 59 pci_auto.o hawk_common.o
62obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o
63obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o 60obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o
64obj-$(CONFIG_PAL4) += cpc700_pic.o 61obj-$(CONFIG_PAL4) += cpc700_pic.o
65obj-$(CONFIG_POWERPMC250) += pci_auto.o 62obj-$(CONFIG_POWERPMC250) += pci_auto.o
66obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \ 63obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \
67 todc_time.o pci_auto.o 64 todc_time.o pci_auto.o
68obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \ 65obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \
69 hawk_common.o 66 hawk_common.o
70obj-$(CONFIG_HARRIER) += harrier.o 67obj-$(CONFIG_HARRIER) += harrier.o
71obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o 68obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o
72obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o 69obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o
73obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o 70obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o
74obj-$(CONFIG_SBC82xx) += todc_time.o 71obj-$(CONFIG_SBC82xx) += todc_time.o
75obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \ 72obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \
76 todc_time.o 73 todc_time.o
@@ -92,7 +89,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
92obj-$(CONFIG_40x) += dcr.o 89obj-$(CONFIG_40x) += dcr.o
93obj-$(CONFIG_BOOKE) += dcr.o 90obj-$(CONFIG_BOOKE) += dcr.o
94obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ 91obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
95 ppc_sys.o i8259.o mpc85xx_sys.o \ 92 ppc_sys.o mpc85xx_sys.o \
96 mpc85xx_devices.o 93 mpc85xx_devices.o
97ifeq ($(CONFIG_85xx),y) 94ifeq ($(CONFIG_85xx),y)
98obj-$(CONFIG_PCI) += pci_auto.o 95obj-$(CONFIG_PCI) += pci_auto.o
diff --git a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
deleted file mode 100644
index 5c7908c20e43..000000000000
--- a/arch/ppc/syslib/i8259.c
+++ /dev/null
@@ -1,208 +0,0 @@
1#include <linux/init.h>
2#include <linux/ioport.h>
3#include <linux/interrupt.h>
4#include <asm/io.h>
5#include <asm/i8259.h>
6
7static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */
8
9unsigned char cached_8259[2] = { 0xff, 0xff };
10#define cached_A1 (cached_8259[0])
11#define cached_21 (cached_8259[1])
12
13static DEFINE_SPINLOCK(i8259_lock);
14
15int i8259_pic_irq_offset;
16
17/*
18 * Acknowledge the IRQ using either the PCI host bridge's interrupt
19 * acknowledge feature or poll. How i8259_init() is called determines
20 * which is called. It should be noted that polling is broken on some
21 * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
22 */
23int
24i8259_irq(struct pt_regs *regs)
25{
26 int irq;
27
28 spin_lock(&i8259_lock);
29
30 /* Either int-ack or poll for the IRQ */
31 if (pci_intack)
32 irq = *pci_intack;
33 else {
34 /* Perform an interrupt acknowledge cycle on controller 1. */
35 outb(0x0C, 0x20); /* prepare for poll */
36 irq = inb(0x20) & 7;
37 if (irq == 2 ) {
38 /*
39 * Interrupt is cascaded so perform interrupt
40 * acknowledge on controller 2.
41 */
42 outb(0x0C, 0xA0); /* prepare for poll */
43 irq = (inb(0xA0) & 7) + 8;
44 }
45 }
46
47 if (irq == 7) {
48 /*
49 * This may be a spurious interrupt.
50 *
51 * Read the interrupt status register (ISR). If the most
52 * significant bit is not set then there is no valid
53 * interrupt.
54 */
55 if (!pci_intack)
56 outb(0x0B, 0x20); /* ISR register */
57 if(~inb(0x20) & 0x80)
58 irq = -1;
59 }
60
61 spin_unlock(&i8259_lock);
62 return irq;
63}
64
65static void i8259_mask_and_ack_irq(unsigned int irq_nr)
66{
67 unsigned long flags;
68
69 spin_lock_irqsave(&i8259_lock, flags);
70 if ( irq_nr >= i8259_pic_irq_offset )
71 irq_nr -= i8259_pic_irq_offset;
72
73 if (irq_nr > 7) {
74 cached_A1 |= 1 << (irq_nr-8);
75 inb(0xA1); /* DUMMY */
76 outb(cached_A1,0xA1);
77 outb(0x20,0xA0); /* Non-specific EOI */
78 outb(0x20,0x20); /* Non-specific EOI to cascade */
79 } else {
80 cached_21 |= 1 << irq_nr;
81 inb(0x21); /* DUMMY */
82 outb(cached_21,0x21);
83 outb(0x20,0x20); /* Non-specific EOI */
84 }
85 spin_unlock_irqrestore(&i8259_lock, flags);
86}
87
88static void i8259_set_irq_mask(int irq_nr)
89{
90 outb(cached_A1,0xA1);
91 outb(cached_21,0x21);
92}
93
94static void i8259_mask_irq(unsigned int irq_nr)
95{
96 unsigned long flags;
97
98 spin_lock_irqsave(&i8259_lock, flags);
99 if ( irq_nr >= i8259_pic_irq_offset )
100 irq_nr -= i8259_pic_irq_offset;
101 if ( irq_nr < 8 )
102 cached_21 |= 1 << irq_nr;
103 else
104 cached_A1 |= 1 << (irq_nr-8);
105 i8259_set_irq_mask(irq_nr);
106 spin_unlock_irqrestore(&i8259_lock, flags);
107}
108
109static void i8259_unmask_irq(unsigned int irq_nr)
110{
111 unsigned long flags;
112
113 spin_lock_irqsave(&i8259_lock, flags);
114 if ( irq_nr >= i8259_pic_irq_offset )
115 irq_nr -= i8259_pic_irq_offset;
116 if ( irq_nr < 8 )
117 cached_21 &= ~(1 << irq_nr);
118 else
119 cached_A1 &= ~(1 << (irq_nr-8));
120 i8259_set_irq_mask(irq_nr);
121 spin_unlock_irqrestore(&i8259_lock, flags);
122}
123
124static void i8259_end_irq(unsigned int irq)
125{
126 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
127 && irq_desc[irq].action)
128 i8259_unmask_irq(irq);
129}
130
131struct hw_interrupt_type i8259_pic = {
132 .typename = " i8259 ",
133 .enable = i8259_unmask_irq,
134 .disable = i8259_mask_irq,
135 .ack = i8259_mask_and_ack_irq,
136 .end = i8259_end_irq,
137};
138
139static struct resource pic1_iores = {
140 .name = "8259 (master)",
141 .start = 0x20,
142 .end = 0x21,
143 .flags = IORESOURCE_BUSY,
144};
145
146static struct resource pic2_iores = {
147 .name = "8259 (slave)",
148 .start = 0xa0,
149 .end = 0xa1,
150 .flags = IORESOURCE_BUSY,
151};
152
153static struct resource pic_edgectrl_iores = {
154 .name = "8259 edge control",
155 .start = 0x4d0,
156 .end = 0x4d1,
157 .flags = IORESOURCE_BUSY,
158};
159
160static struct irqaction i8259_irqaction = {
161 .handler = no_action,
162 .flags = SA_INTERRUPT,
163 .mask = CPU_MASK_NONE,
164 .name = "82c59 secondary cascade",
165};
166
167/*
168 * i8259_init()
169 * intack_addr - PCI interrupt acknowledge (real) address which will return
170 * the active irq from the 8259
171 */
172void __init
173i8259_init(long intack_addr)
174{
175 unsigned long flags;
176
177 spin_lock_irqsave(&i8259_lock, flags);
178 /* init master interrupt controller */
179 outb(0x11, 0x20); /* Start init sequence */
180 outb(0x00, 0x21); /* Vector base */
181 outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
182 outb(0x01, 0x21); /* Select 8086 mode */
183
184 /* init slave interrupt controller */
185 outb(0x11, 0xA0); /* Start init sequence */
186 outb(0x08, 0xA1); /* Vector base */
187 outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
188 outb(0x01, 0xA1); /* Select 8086 mode */
189
190 /* always read ISR */
191 outb(0x0B, 0x20);
192 outb(0x0B, 0xA0);
193
194 /* Mask all interrupts */
195 outb(cached_A1, 0xA1);
196 outb(cached_21, 0x21);
197
198 spin_unlock_irqrestore(&i8259_lock, flags);
199
200 /* reserve our resources */
201 setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction);
202 request_resource(&ioport_resource, &pic1_iores);
203 request_resource(&ioport_resource, &pic2_iores);
204 request_resource(&ioport_resource, &pic_edgectrl_iores);
205
206 if (intack_addr != 0)
207 pci_intack = ioremap(intack_addr, 1);
208}