Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+99 -271
+10
arch/powerpc/Kconfig
··· 275 275 config PPC_PSERIES 276 276 depends on PPC_MULTIPLATFORM && PPC64 277 277 bool " IBM pSeries & new (POWER5-based) iSeries" 278 + select PPC_I8259 278 279 default y 279 280 280 281 config PPC_CHRP 281 282 bool " Common Hardware Reference Platform (CHRP) based machines" 282 283 depends on PPC_MULTIPLATFORM && PPC32 284 + select PPC_I8259 283 285 select PPC_INDIRECT_PCI 284 286 default y 285 287 ··· 300 298 config PPC_PREP 301 299 bool " PowerPC Reference Platform (PReP) based machines" 302 300 depends on PPC_MULTIPLATFORM && PPC32 301 + select PPC_I8259 303 302 select PPC_INDIRECT_PCI 304 303 default y 305 304 ··· 631 628 config ISA 632 629 bool "Support for ISA-bus hardware" 633 630 depends on PPC_PREP || PPC_CHRP 631 + select PPC_I8259 634 632 help 635 633 Find out whether you have ISA slots on your motherboard. ISA is the 636 634 name of a bus system, i.e. the way the CPU talks to the other stuff ··· 643 639 bool 644 640 depends on PPC64 || POWER4 || 6xx && !CPM2 645 641 default y 642 + 643 + config PPC_I8259 644 + bool 645 + default y if 85xx 646 + default n 646 647 647 648 config PPC_INDIRECT_PCI 648 649 bool ··· 688 679 config PCI_QSPAN 689 680 bool "QSpan PCI" 690 681 depends on !4xx && !CPM2 && 8xx 682 + select PPC_I8259 691 683 help 692 684 Say Y here if you have a system based on a Motorola 8xx-series 693 685 embedded processor with a QSPAN PCI interface, otherwise say N.
+5
arch/powerpc/platforms/embedded6xx/Kconfig
··· 48 48 49 49 config LOPEC 50 50 bool "Motorola-LoPEC" 51 + select PPC_I8259 51 52 52 53 config MVME5100 53 54 bool "Motorola-MVME5100" ··· 56 55 57 56 config PPLUS 58 57 bool "Motorola-PowerPlus" 58 + select PPC_I8259 59 59 select PPC_INDIRECT_PCI 60 60 61 61 config PRPMC750 ··· 69 67 70 68 config SANDPOINT 71 69 bool "Motorola-Sandpoint" 70 + select PPC_I8259 72 71 help 73 72 Select SANDPOINT if configuring for a Motorola Sandpoint X3 74 73 (any flavor). 75 74 76 75 config RADSTONE_PPC7D 77 76 bool "Radstone Technology PPC7D board" 77 + select PPC_I8259 78 78 79 79 config PAL4 80 80 bool "SBS-Palomar4" ··· 311 307 config MVME5100_IPMC761_PRESENT 312 308 bool "MVME5100 configured with an IPMC761" 313 309 depends on MVME5100 310 + select PPC_I8259 314 311 315 312 config SPRUCE_BAUD_33M 316 313 bool "Spruce baud clock support"
+4 -15
arch/powerpc/platforms/pseries/setup.c
··· 87 87 static void pseries_shared_idle(void); 88 88 static void pseries_dedicated_idle(void); 89 89 90 - static volatile void __iomem * chrp_int_ack_special; 91 90 struct mpic *pSeries_mpic; 92 91 93 92 void pSeries_show_cpuinfo(struct seq_file *m) ··· 118 119 fwnmi_active = 1; 119 120 } 120 121 121 - static int pSeries_irq_cascade(struct pt_regs *regs, void *data) 122 - { 123 - if (chrp_int_ack_special) 124 - return readb(chrp_int_ack_special); 125 - else 126 - return i8259_irq(regs); 127 - } 128 - 129 122 static void __init pSeries_init_mpic(void) 130 123 { 131 124 unsigned int *addrp; 132 125 struct device_node *np; 133 - int i; 126 + unsigned long intack = 0; 134 127 135 128 /* All ISUs are setup, complete initialization */ 136 129 mpic_init(pSeries_mpic); ··· 133 142 get_property(np, "8259-interrupt-acknowledge", NULL))) 134 143 printk(KERN_ERR "Cannot find pci to get ack address\n"); 135 144 else 136 - chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1); 145 + intack = addrp[prom_n_addr_cells(np)-1]; 137 146 of_node_put(np); 138 147 139 148 /* Setup the legacy interrupts & controller */ 140 - for (i = 0; i < NUM_ISA_INTERRUPTS; i++) 141 - irq_desc[i].handler = &i8259_pic; 142 - i8259_init(0); 149 + i8259_init(intack, 0); 143 150 144 151 /* Hook cascade to mpic */ 145 - mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL); 152 + mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL); 146 153 } 147 154 148 155 static void __init pSeries_setup_mpic(void)
+1
arch/powerpc/sysdev/Makefile
··· 1 1 obj-$(CONFIG_MPIC) += mpic.o 2 2 obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o 3 + obj-$(CONFIG_PPC_I8259) += i8259.o
+14
arch/ppc/Kconfig
··· 589 589 590 590 config LOPEC 591 591 bool "Motorola-LoPEC" 592 + select PPC_I8259 592 593 593 594 config MVME5100 594 595 bool "Motorola-MVME5100" ··· 597 596 598 597 config PPLUS 599 598 bool "Motorola-PowerPlus" 599 + select PPC_I8259 600 600 select PPC_INDIRECT_PCI 601 601 602 602 config PRPMC750 ··· 610 608 611 609 config SANDPOINT 612 610 bool "Motorola-Sandpoint" 611 + select PPC_I8259 613 612 help 614 613 Select SANDPOINT if configuring for a Motorola Sandpoint X3 615 614 (any flavor). 616 615 617 616 config RADSTONE_PPC7D 618 617 bool "Radstone Technology PPC7D board" 618 + select PPC_I8259 619 619 620 620 config PAL4 621 621 bool "SBS-Palomar4" ··· 759 755 config PPC_CHRP 760 756 bool " Common Hardware Reference Platform (CHRP) based machines" 761 757 depends on PPC_MULTIPLATFORM 758 + select PPC_I8259 762 759 select PPC_INDIRECT_PCI 763 760 default y 764 761 ··· 777 772 config PPC_PREP 778 773 bool " PowerPC Reference Platform (PReP) based machines" 779 774 depends on PPC_MULTIPLATFORM 775 + select PPC_I8259 780 776 select PPC_INDIRECT_PCI 781 777 default y 782 778 ··· 887 881 config MVME5100_IPMC761_PRESENT 888 882 bool "MVME5100 configured with an IPMC761" 889 883 depends on MVME5100 884 + select PPC_I8259 890 885 891 886 config SPRUCE_BAUD_33M 892 887 bool "Spruce baud clock support" ··· 1145 1138 config ISA 1146 1139 bool "Support for ISA-bus hardware" 1147 1140 depends on PPC_PREP || PPC_CHRP 1141 + select PPC_I8259 1148 1142 help 1149 1143 Find out whether you have ISA slots on your motherboard. ISA is the 1150 1144 name of a bus system, i.e. the way the CPU talks to the other stuff ··· 1157 1149 bool 1158 1150 depends on POWER3 || POWER4 || 6xx && !CPM2 1159 1151 default y 1152 + 1153 + config PPC_I8259 1154 + bool 1155 + default y if 85xx 1156 + default n 1160 1157 1161 1158 config PPC_INDIRECT_PCI 1162 1159 bool ··· 1205 1192 config PCI_QSPAN 1206 1193 bool "QSpan PCI" 1207 1194 depends on !4xx && !CPM2 && 8xx 1195 + select PPC_I8259 1208 1196 help 1209 1197 Say Y here if you have a system based on a Motorola 8xx-series 1210 1198 embedded processor with a QSPAN PCI interface, otherwise say N.
+1 -4
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
··· 173 173 #ifdef CONFIG_PCI 174 174 openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); 175 175 176 - for (i = 0; i < NUM_8259_INTERRUPTS; i++) 177 - irq_desc[i].handler = &i8259_pic; 178 - 179 - i8259_init(0); 176 + i8259_init(0, 0); 180 177 #endif 181 178 182 179 #ifdef CONFIG_CPM2
+1 -3
arch/ppc/platforms/chrp_setup.c
··· 436 436 i8259_irq); 437 437 438 438 } 439 - for (i = 0; i < NUM_8259_INTERRUPTS; i++) 440 - irq_desc[i].handler = &i8259_pic; 441 - i8259_init(chrp_int_ack); 439 + i8259_init(chrp_int_ack, 0); 442 440 443 441 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 444 442 /* see if there is a keyboard in the device tree
+1 -5
arch/ppc/platforms/lopec.c
··· 267 267 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", 268 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 271 * The EPIC allows for a read in the range of 0xFEF00000 -> 276 272 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. 277 273 */ 278 - i8259_init(0xfef00000); 274 + i8259_init(0xfef00000, 0); 279 275 } 280 276 281 277 static int __init
+1 -5
arch/ppc/platforms/mvme5100.c
··· 223 223 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", 224 224 &i8259_irq); 225 225 226 - /* Map i8259 interrupts. */ 227 - for (i = 0; i < NUM_8259_INTERRUPTS; i++) 228 - irq_desc[i].handler = &i8259_pic; 229 - 230 - i8259_init(0); 226 + i8259_init(0, 0); 231 227 #else 232 228 openpic_init(0); 233 229 #endif
+1 -4
arch/ppc/platforms/pplus.c
··· 665 665 ppc_md.get_irq = openpic_get_irq; 666 666 } 667 667 668 - for (i = 0; i < NUM_8259_INTERRUPTS; i++) 669 - irq_desc[i].handler = &i8259_pic; 670 - 671 - i8259_init(0); 668 + i8259_init(0, 0); 672 669 673 670 if (ppc_md.progress) 674 671 ppc_md.progress("init_irq: exit", 0);
+3 -5
arch/ppc/platforms/prep_setup.c
··· 954 954 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", 955 955 i8259_irq); 956 956 } 957 - for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) 958 - irq_desc[i].handler = &i8259_pic; 959 957 960 958 if (have_residual_data) { 961 - i8259_init(residual_isapic_addr()); 959 + i8259_init(residual_isapic_addr(), 0); 962 960 return; 963 961 } 964 962 ··· 967 969 if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) 968 970 && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN) 969 971 || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK))) 970 - i8259_init(0); 972 + i8259_init(0, 0); 971 973 else 972 974 /* PCI interrupt ack address given in section 6.1.8 of the 973 975 * PReP specification. */ 974 - i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR); 976 + i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0); 975 977 } 976 978 977 979 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+1 -5
arch/ppc/platforms/radstone_ppc7d.c
··· 514 514 int irq; 515 515 516 516 pr_debug("%s\n", __FUNCTION__); 517 - i8259_init(0); 517 + i8259_init(0, 0); 518 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 520 /* IRQs 5,6,9,10,11,14,15 are level sensitive */ 525 521 irq_desc[5].status |= IRQ_LEVEL; 526 522 irq_desc[6].status |= IRQ_LEVEL;
+1 -9
arch/ppc/platforms/sandpoint.c
··· 494 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 497 * The EPIC allows for a read in the range of 0xFEF00000 -> 506 498 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction. 507 499 */ 508 - i8259_init(0xfef00000); 500 + i8259_init(0xfef00000, 0); 509 501 } 510 502 511 503 static unsigned long __init
+8 -11
arch/ppc/syslib/Makefile
··· 36 36 endif 37 37 obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ 38 38 ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o 39 - ifeq ($(CONFIG_8xx),y) 40 - obj-$(CONFIG_PCI) += qspan_pci.o i8259.o 41 - endif 39 + obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o 42 40 obj-$(CONFIG_PPC_OF) += prom_init.o prom.o 43 41 obj-$(CONFIG_PPC_PMAC) += open_pic.o 44 42 obj-$(CONFIG_POWER4) += open_pic2.o 45 - obj-$(CONFIG_PPC_CHRP) += open_pic.o i8259.o 46 - obj-$(CONFIG_PPC_PREP) += open_pic.o i8259.o todc_time.o 43 + obj-$(CONFIG_PPC_CHRP) += open_pic.o 44 + obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o 47 45 obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o 48 46 obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o 49 47 obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o ··· 49 51 obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o 50 52 obj-$(CONFIG_GEMINI) += open_pic.o 51 53 obj-$(CONFIG_GT64260) += gt64260_pic.o 52 - obj-$(CONFIG_LOPEC) += i8259.o pci_auto.o todc_time.o 54 + obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o 53 55 obj-$(CONFIG_HDPU) += pci_auto.o 54 56 obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o 55 57 obj-$(CONFIG_KATANA) += pci_auto.o ··· 57 59 obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o 58 60 obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \ 59 61 pci_auto.o hawk_common.o 60 - obj-$(CONFIG_MVME5100_IPMC761_PRESENT) += i8259.o 61 62 obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o 62 63 obj-$(CONFIG_PAL4) += cpc700_pic.o 63 64 obj-$(CONFIG_POWERPMC250) += pci_auto.o 64 - obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o i8259.o \ 65 + obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \ 65 66 todc_time.o pci_auto.o 66 67 obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \ 67 68 hawk_common.o 68 69 obj-$(CONFIG_HARRIER) += harrier.o 69 70 obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o 70 - obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o 71 - obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o 71 + obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o 72 + obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o 72 73 obj-$(CONFIG_SBC82xx) += todc_time.o 73 74 obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \ 74 75 todc_time.o ··· 89 92 obj-$(CONFIG_40x) += dcr.o 90 93 obj-$(CONFIG_BOOKE) += dcr.o 91 94 obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ 92 - ppc_sys.o i8259.o mpc85xx_sys.o \ 95 + ppc_sys.o mpc85xx_sys.o \ 93 96 mpc85xx_devices.o 94 97 ifeq ($(CONFIG_85xx),y) 95 98 obj-$(CONFIG_PCI) += pci_auto.o
+39 -26
arch/ppc/syslib/i8259.c arch/powerpc/sysdev/i8259.c
··· 1 + /* 2 + * i8259 interrupt controller driver. 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License 6 + * as published by the Free Software Foundation; either version 7 + * 2 of the License, or (at your option) any later version. 8 + */ 1 9 #include <linux/init.h> 2 10 #include <linux/ioport.h> 3 11 #include <linux/interrupt.h> 4 12 #include <asm/io.h> 5 13 #include <asm/i8259.h> 6 14 7 - static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */ 15 + static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */ 8 16 9 - unsigned char cached_8259[2] = { 0xff, 0xff }; 17 + static unsigned char cached_8259[2] = { 0xff, 0xff }; 10 18 #define cached_A1 (cached_8259[0]) 11 19 #define cached_21 (cached_8259[1]) 12 20 13 21 static DEFINE_SPINLOCK(i8259_lock); 14 22 15 - int i8259_pic_irq_offset; 23 + static int i8259_pic_irq_offset; 16 24 17 25 /* 18 26 * Acknowledge the IRQ using either the PCI host bridge's interrupt ··· 28 20 * which is called. It should be noted that polling is broken on some 29 21 * IBM and Motorola PReP boxes so we must use the int-ack feature on them. 30 22 */ 31 - int 32 - i8259_irq(struct pt_regs *regs) 23 + int i8259_irq(struct pt_regs *regs) 33 24 { 34 25 int irq; 35 26 ··· 36 29 37 30 /* Either int-ack or poll for the IRQ */ 38 31 if (pci_intack) 39 - irq = *pci_intack; 32 + irq = readb(pci_intack); 40 33 else { 41 34 /* Perform an interrupt acknowledge cycle on controller 1. */ 42 35 outb(0x0C, 0x20); /* prepare for poll */ ··· 66 59 } 67 60 68 61 spin_unlock(&i8259_lock); 69 - return irq; 62 + return irq + i8259_pic_irq_offset; 63 + } 64 + 65 + int i8259_irq_cascade(struct pt_regs *regs, void *unused) 66 + { 67 + return i8259_irq(regs); 70 68 } 71 69 72 70 static void i8259_mask_and_ack_irq(unsigned int irq_nr) ··· 79 67 unsigned long flags; 80 68 81 69 spin_lock_irqsave(&i8259_lock, flags); 82 - if ( irq_nr >= i8259_pic_irq_offset ) 83 - irq_nr -= i8259_pic_irq_offset; 84 - 70 + irq_nr -= i8259_pic_irq_offset; 85 71 if (irq_nr > 7) { 86 72 cached_A1 |= 1 << (irq_nr-8); 87 - inb(0xA1); /* DUMMY */ 88 - outb(cached_A1,0xA1); 89 - outb(0x20,0xA0); /* Non-specific EOI */ 90 - outb(0x20,0x20); /* Non-specific EOI to cascade */ 73 + inb(0xA1); /* DUMMY */ 74 + outb(cached_A1, 0xA1); 75 + outb(0x20, 0xA0); /* Non-specific EOI */ 76 + outb(0x20, 0x20); /* Non-specific EOI to cascade */ 91 77 } else { 92 78 cached_21 |= 1 << irq_nr; 93 - inb(0x21); /* DUMMY */ 94 - outb(cached_21,0x21); 95 - outb(0x20,0x20); /* Non-specific EOI */ 79 + inb(0x21); /* DUMMY */ 80 + outb(cached_21, 0x21); 81 + outb(0x20, 0x20); /* Non-specific EOI */ 96 82 } 97 83 spin_unlock_irqrestore(&i8259_lock, flags); 98 84 } ··· 106 96 unsigned long flags; 107 97 108 98 spin_lock_irqsave(&i8259_lock, flags); 109 - if ( irq_nr >= i8259_pic_irq_offset ) 110 - irq_nr -= i8259_pic_irq_offset; 111 - if ( irq_nr < 8 ) 99 + irq_nr -= i8259_pic_irq_offset; 100 + if (irq_nr < 8) 112 101 cached_21 |= 1 << irq_nr; 113 102 else 114 103 cached_A1 |= 1 << (irq_nr-8); ··· 120 111 unsigned long flags; 121 112 122 113 spin_lock_irqsave(&i8259_lock, flags); 123 - if ( irq_nr >= i8259_pic_irq_offset ) 124 - irq_nr -= i8259_pic_irq_offset; 125 - if ( irq_nr < 8 ) 114 + irq_nr -= i8259_pic_irq_offset; 115 + if (irq_nr < 8) 126 116 cached_21 &= ~(1 << irq_nr); 127 117 else 128 118 cached_A1 &= ~(1 << (irq_nr-8)); ··· 177 169 * intack_addr - PCI interrupt acknowledge (real) address which will return 178 170 * the active irq from the 8259 179 171 */ 180 - void __init 181 - i8259_init(long intack_addr) 172 + void __init i8259_init(unsigned long intack_addr, int offset) 182 173 { 183 174 unsigned long flags; 175 + int i; 184 176 185 177 spin_lock_irqsave(&i8259_lock, flags); 178 + i8259_pic_irq_offset = offset; 179 + 186 180 /* init master interrupt controller */ 187 181 outb(0x11, 0x20); /* Start init sequence */ 188 182 outb(0x00, 0x21); /* Vector base */ ··· 208 198 spin_unlock_irqrestore(&i8259_lock, flags); 209 199 210 200 /* reserve our resources */ 211 - setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction); 201 + setup_irq(offset + 2, &i8259_irqaction); 212 202 request_resource(&ioport_resource, &pic1_iores); 213 203 request_resource(&ioport_resource, &pic2_iores); 214 204 request_resource(&ioport_resource, &pic_edgectrl_iores); 215 205 216 206 if (intack_addr != 0) 217 207 pci_intack = ioremap(intack_addr, 1); 208 + 209 + for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) 210 + irq_desc[offset + i].handler = &i8259_pic; 218 211 }
+5
arch/ppc64/Kconfig
··· 123 123 bool 124 124 default y 125 125 126 + config PPC_I8259 127 + depends on PPC_PSERIES 128 + bool 129 + default y 130 + 126 131 config BPA_IIC 127 132 depends on PPC_BPA 128 133 bool
+1 -1
arch/ppc64/kernel/Makefile
··· 24 24 25 25 obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) 26 26 27 - obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o 27 + obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o 28 28 ifneq ($(CONFIG_PPC_MERGE),y) 29 29 obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 30 30 endif
-177
arch/ppc64/kernel/i8259.c
··· 1 - /* 2 - * c 2001 PPC64 Team, IBM Corp 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - */ 9 - #include <linux/stddef.h> 10 - #include <linux/init.h> 11 - #include <linux/sched.h> 12 - #include <linux/signal.h> 13 - #include <linux/cache.h> 14 - #include <linux/irq.h> 15 - #include <linux/interrupt.h> 16 - #include <asm/io.h> 17 - #include <asm/ppcdebug.h> 18 - #include "i8259.h" 19 - 20 - unsigned char cached_8259[2] = { 0xff, 0xff }; 21 - #define cached_A1 (cached_8259[0]) 22 - #define cached_21 (cached_8259[1]) 23 - 24 - static __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock); 25 - 26 - static int i8259_pic_irq_offset; 27 - static int i8259_present; 28 - 29 - int i8259_irq(int cpu) 30 - { 31 - int irq; 32 - 33 - spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); 34 - /* 35 - * Perform an interrupt acknowledge cycle on controller 1 36 - */ 37 - outb(0x0C, 0x20); 38 - irq = inb(0x20) & 7; 39 - if (irq == 2) 40 - { 41 - /* 42 - * Interrupt is cascaded so perform interrupt 43 - * acknowledge on controller 2 44 - */ 45 - outb(0x0C, 0xA0); 46 - irq = (inb(0xA0) & 7) + 8; 47 - } 48 - else if (irq==7) 49 - { 50 - /* 51 - * This may be a spurious interrupt 52 - * 53 - * Read the interrupt status register. If the most 54 - * significant bit is not set then there is no valid 55 - * interrupt 56 - */ 57 - outb(0x0b, 0x20); 58 - if(~inb(0x20)&0x80) { 59 - spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); 60 - return -1; 61 - } 62 - } 63 - spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); 64 - return irq; 65 - } 66 - 67 - static void i8259_mask_and_ack_irq(unsigned int irq_nr) 68 - { 69 - unsigned long flags; 70 - 71 - spin_lock_irqsave(&i8259_lock, flags); 72 - if ( irq_nr >= i8259_pic_irq_offset ) 73 - irq_nr -= i8259_pic_irq_offset; 74 - 75 - if (irq_nr > 7) { 76 - cached_A1 |= 1 << (irq_nr-8); 77 - inb(0xA1); /* DUMMY */ 78 - outb(cached_A1,0xA1); 79 - outb(0x20,0xA0); /* Non-specific EOI */ 80 - outb(0x20,0x20); /* Non-specific EOI to cascade */ 81 - } else { 82 - cached_21 |= 1 << irq_nr; 83 - inb(0x21); /* DUMMY */ 84 - outb(cached_21,0x21); 85 - outb(0x20,0x20); /* Non-specific EOI */ 86 - } 87 - spin_unlock_irqrestore(&i8259_lock, flags); 88 - } 89 - 90 - static void i8259_set_irq_mask(int irq_nr) 91 - { 92 - outb(cached_A1,0xA1); 93 - outb(cached_21,0x21); 94 - } 95 - 96 - static void i8259_mask_irq(unsigned int irq_nr) 97 - { 98 - unsigned long flags; 99 - 100 - spin_lock_irqsave(&i8259_lock, flags); 101 - if ( irq_nr >= i8259_pic_irq_offset ) 102 - irq_nr -= i8259_pic_irq_offset; 103 - if ( irq_nr < 8 ) 104 - cached_21 |= 1 << irq_nr; 105 - else 106 - cached_A1 |= 1 << (irq_nr-8); 107 - i8259_set_irq_mask(irq_nr); 108 - spin_unlock_irqrestore(&i8259_lock, flags); 109 - } 110 - 111 - static void i8259_unmask_irq(unsigned int irq_nr) 112 - { 113 - unsigned long flags; 114 - 115 - spin_lock_irqsave(&i8259_lock, flags); 116 - if ( irq_nr >= i8259_pic_irq_offset ) 117 - irq_nr -= i8259_pic_irq_offset; 118 - if ( irq_nr < 8 ) 119 - cached_21 &= ~(1 << irq_nr); 120 - else 121 - cached_A1 &= ~(1 << (irq_nr-8)); 122 - i8259_set_irq_mask(irq_nr); 123 - spin_unlock_irqrestore(&i8259_lock, flags); 124 - } 125 - 126 - static void i8259_end_irq(unsigned int irq) 127 - { 128 - if (!(get_irq_desc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) && 129 - get_irq_desc(irq)->action) 130 - i8259_unmask_irq(irq); 131 - } 132 - 133 - struct hw_interrupt_type i8259_pic = { 134 - .typename = " i8259 ", 135 - .enable = i8259_unmask_irq, 136 - .disable = i8259_mask_irq, 137 - .ack = i8259_mask_and_ack_irq, 138 - .end = i8259_end_irq, 139 - }; 140 - 141 - void __init i8259_init(int offset) 142 - { 143 - unsigned long flags; 144 - 145 - spin_lock_irqsave(&i8259_lock, flags); 146 - i8259_pic_irq_offset = offset; 147 - i8259_present = 1; 148 - /* init master interrupt controller */ 149 - outb(0x11, 0x20); /* Start init sequence */ 150 - outb(0x00, 0x21); /* Vector base */ 151 - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ 152 - outb(0x01, 0x21); /* Select 8086 mode */ 153 - outb(0xFF, 0x21); /* Mask all */ 154 - /* init slave interrupt controller */ 155 - outb(0x11, 0xA0); /* Start init sequence */ 156 - outb(0x08, 0xA1); /* Vector base */ 157 - outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */ 158 - outb(0x01, 0xA1); /* Select 8086 mode */ 159 - outb(0xFF, 0xA1); /* Mask all */ 160 - outb(cached_A1, 0xA1); 161 - outb(cached_21, 0x21); 162 - spin_unlock_irqrestore(&i8259_lock, flags); 163 - 164 - } 165 - 166 - static int i8259_request_cascade(void) 167 - { 168 - if (!i8259_present) 169 - return -ENODEV; 170 - 171 - request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, 172 - "82c59 secondary cascade", NULL ); 173 - 174 - return 0; 175 - } 176 - 177 - arch_initcall(i8259_request_cascade);
+2 -1
include/asm-powerpc/i8259.h
··· 5 5 6 6 extern struct hw_interrupt_type i8259_pic; 7 7 8 - extern void i8259_init(long intack_addr); 8 + extern void i8259_init(unsigned long intack_addr, int offset); 9 9 extern int i8259_irq(struct pt_regs *regs); 10 + extern int i8259_irq_cascade(struct pt_regs *regs, void *unused); 10 11 11 12 #endif /* _ASM_POWERPC_I8259_H */