aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig10
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig5
-rw-r--r--arch/powerpc/platforms/pseries/setup.c19
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/i8259.c (renamed from arch/ppc/syslib/i8259.c)65
-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/ppc64/Kconfig5
-rw-r--r--arch/ppc64/kernel/Makefile2
-rw-r--r--arch/ppc64/kernel/i8259.c177
18 files changed, 97 insertions, 270 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a3451d5bb788..9f279e0d84f2 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -275,11 +275,13 @@ endchoice
275config PPC_PSERIES 275config PPC_PSERIES
276 depends on PPC_MULTIPLATFORM && PPC64 276 depends on PPC_MULTIPLATFORM && PPC64
277 bool " IBM pSeries & new (POWER5-based) iSeries" 277 bool " IBM pSeries & new (POWER5-based) iSeries"
278 select PPC_I8259
278 default y 279 default y
279 280
280config PPC_CHRP 281config PPC_CHRP
281 bool " Common Hardware Reference Platform (CHRP) based machines" 282 bool " Common Hardware Reference Platform (CHRP) based machines"
282 depends on PPC_MULTIPLATFORM && PPC32 283 depends on PPC_MULTIPLATFORM && PPC32
284 select PPC_I8259
283 select PPC_INDIRECT_PCI 285 select PPC_INDIRECT_PCI
284 default y 286 default y
285 287
@@ -298,6 +300,7 @@ config PPC_PMAC64
298config PPC_PREP 300config PPC_PREP
299 bool " PowerPC Reference Platform (PReP) based machines" 301 bool " PowerPC Reference Platform (PReP) based machines"
300 depends on PPC_MULTIPLATFORM && PPC32 302 depends on PPC_MULTIPLATFORM && PPC32
303 select PPC_I8259
301 select PPC_INDIRECT_PCI 304 select PPC_INDIRECT_PCI
302 default y 305 default y
303 306
@@ -628,6 +631,7 @@ menu "Bus options"
628config ISA 631config ISA
629 bool "Support for ISA-bus hardware" 632 bool "Support for ISA-bus hardware"
630 depends on PPC_PREP || PPC_CHRP 633 depends on PPC_PREP || PPC_CHRP
634 select PPC_I8259
631 help 635 help
632 Find out whether you have ISA slots on your motherboard. ISA is the 636 Find out whether you have ISA slots on your motherboard. ISA is the
633 name of a bus system, i.e. the way the CPU talks to the other stuff 637 name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -640,6 +644,11 @@ config GENERIC_ISA_DMA
640 depends on PPC64 || POWER4 || 6xx && !CPM2 644 depends on PPC64 || POWER4 || 6xx && !CPM2
641 default y 645 default y
642 646
647config PPC_I8259
648 bool
649 default y if 85xx
650 default n
651
643config PPC_INDIRECT_PCI 652config PPC_INDIRECT_PCI
644 bool 653 bool
645 depends on PCI 654 depends on PCI
@@ -679,6 +688,7 @@ config MPC83xx_PCI2
679config PCI_QSPAN 688config PCI_QSPAN
680 bool "QSpan PCI" 689 bool "QSpan PCI"
681 depends on !4xx && !CPM2 && 8xx 690 depends on !4xx && !CPM2 && 8xx
691 select PPC_I8259
682 help 692 help
683 Say Y here if you have a system based on a Motorola 8xx-series 693 Say Y here if you have a system based on a Motorola 8xx-series
684 embedded processor with a QSPAN PCI interface, otherwise say N. 694 embedded processor with a QSPAN PCI interface, otherwise say N.
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 784b41e19465..81250090f98d 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -48,6 +48,7 @@ config EV64260
48 48
49config LOPEC 49config LOPEC
50 bool "Motorola-LoPEC" 50 bool "Motorola-LoPEC"
51 select PPC_I8259
51 52
52config MVME5100 53config MVME5100
53 bool "Motorola-MVME5100" 54 bool "Motorola-MVME5100"
@@ -55,6 +56,7 @@ config MVME5100
55 56
56config PPLUS 57config PPLUS
57 bool "Motorola-PowerPlus" 58 bool "Motorola-PowerPlus"
59 select PPC_I8259
58 select PPC_INDIRECT_PCI 60 select PPC_INDIRECT_PCI
59 61
60config PRPMC750 62config PRPMC750
@@ -67,12 +69,14 @@ config PRPMC800
67 69
68config SANDPOINT 70config SANDPOINT
69 bool "Motorola-Sandpoint" 71 bool "Motorola-Sandpoint"
72 select PPC_I8259
70 help 73 help
71 Select SANDPOINT if configuring for a Motorola Sandpoint X3 74 Select SANDPOINT if configuring for a Motorola Sandpoint X3
72 (any flavor). 75 (any flavor).
73 76
74config RADSTONE_PPC7D 77config RADSTONE_PPC7D
75 bool "Radstone Technology PPC7D board" 78 bool "Radstone Technology PPC7D board"
79 select PPC_I8259
76 80
77config PAL4 81config PAL4
78 bool "SBS-Palomar4" 82 bool "SBS-Palomar4"
@@ -307,6 +311,7 @@ config HARRIER_STORE_GATHERING
307config MVME5100_IPMC761_PRESENT 311config MVME5100_IPMC761_PRESENT
308 bool "MVME5100 configured with an IPMC761" 312 bool "MVME5100 configured with an IPMC761"
309 depends on MVME5100 313 depends on MVME5100
314 select PPC_I8259
310 315
311config SPRUCE_BAUD_33M 316config SPRUCE_BAUD_33M
312 bool "Spruce baud clock support" 317 bool "Spruce baud clock support"
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 92d18003f152..0fa5beae6d1b 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -87,7 +87,6 @@ extern int pSeries_machine_check_exception(struct pt_regs *regs);
87static void pseries_shared_idle(void); 87static void pseries_shared_idle(void);
88static void pseries_dedicated_idle(void); 88static void pseries_dedicated_idle(void);
89 89
90static volatile void __iomem * chrp_int_ack_special;
91struct mpic *pSeries_mpic; 90struct mpic *pSeries_mpic;
92 91
93void pSeries_show_cpuinfo(struct seq_file *m) 92void pSeries_show_cpuinfo(struct seq_file *m)
@@ -119,19 +118,11 @@ static void __init fwnmi_init(void)
119 fwnmi_active = 1; 118 fwnmi_active = 1;
120} 119}
121 120
122static int pSeries_irq_cascade(struct pt_regs *regs, void *data)
123{
124 if (chrp_int_ack_special)
125 return readb(chrp_int_ack_special);
126 else
127 return i8259_irq(regs);
128}
129
130static void __init pSeries_init_mpic(void) 121static void __init pSeries_init_mpic(void)
131{ 122{
132 unsigned int *addrp; 123 unsigned int *addrp;
133 struct device_node *np; 124 struct device_node *np;
134 int i; 125 unsigned long intack = 0;
135 126
136 /* All ISUs are setup, complete initialization */ 127 /* All ISUs are setup, complete initialization */
137 mpic_init(pSeries_mpic); 128 mpic_init(pSeries_mpic);
@@ -142,16 +133,14 @@ static void __init pSeries_init_mpic(void)
142 get_property(np, "8259-interrupt-acknowledge", NULL))) 133 get_property(np, "8259-interrupt-acknowledge", NULL)))
143 printk(KERN_ERR "Cannot find pci to get ack address\n"); 134 printk(KERN_ERR "Cannot find pci to get ack address\n");
144 else 135 else
145 chrp_int_ack_special = ioremap(addrp[prom_n_addr_cells(np)-1], 1); 136 intack = addrp[prom_n_addr_cells(np)-1];
146 of_node_put(np); 137 of_node_put(np);
147 138
148 /* Setup the legacy interrupts & controller */ 139 /* Setup the legacy interrupts & controller */
149 for (i = 0; i < NUM_ISA_INTERRUPTS; i++) 140 i8259_init(intack, 0);
150 irq_desc[i].handler = &i8259_pic;
151 i8259_init(0);
152 141
153 /* Hook cascade to mpic */ 142 /* Hook cascade to mpic */
154 mpic_setup_cascade(NUM_ISA_INTERRUPTS, pSeries_irq_cascade, NULL); 143 mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
155} 144}
156 145
157static void __init pSeries_setup_mpic(void) 146static void __init pSeries_setup_mpic(void)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index e66fef652fac..f3c9e61c3910 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -1,2 +1,3 @@
1obj-$(CONFIG_MPIC) += mpic.o 1obj-$(CONFIG_MPIC) += mpic.o
2obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o 2obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
3obj-$(CONFIG_PPC_I8259) += i8259.o
diff --git a/arch/ppc/syslib/i8259.c b/arch/powerpc/sysdev/i8259.c
index 5c7908c20e43..90bce6e0c191 100644
--- a/arch/ppc/syslib/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -1,18 +1,26 @@
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#include <linux/init.h> 9#include <linux/init.h>
2#include <linux/ioport.h> 10#include <linux/ioport.h>
3#include <linux/interrupt.h> 11#include <linux/interrupt.h>
4#include <asm/io.h> 12#include <asm/io.h>
5#include <asm/i8259.h> 13#include <asm/i8259.h>
6 14
7static volatile unsigned char *pci_intack; /* RO, gives us the irq vector */ 15static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
8 16
9unsigned char cached_8259[2] = { 0xff, 0xff }; 17static unsigned char cached_8259[2] = { 0xff, 0xff };
10#define cached_A1 (cached_8259[0]) 18#define cached_A1 (cached_8259[0])
11#define cached_21 (cached_8259[1]) 19#define cached_21 (cached_8259[1])
12 20
13static DEFINE_SPINLOCK(i8259_lock); 21static DEFINE_SPINLOCK(i8259_lock);
14 22
15int i8259_pic_irq_offset; 23static int i8259_pic_irq_offset;
16 24
17/* 25/*
18 * Acknowledge the IRQ using either the PCI host bridge's interrupt 26 * Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -20,8 +28,7 @@ int i8259_pic_irq_offset;
20 * which is called. It should be noted that polling is broken on some 28 * 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. 29 * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
22 */ 30 */
23int 31int i8259_irq(struct pt_regs *regs)
24i8259_irq(struct pt_regs *regs)
25{ 32{
26 int irq; 33 int irq;
27 34
@@ -29,7 +36,7 @@ i8259_irq(struct pt_regs *regs)
29 36
30 /* Either int-ack or poll for the IRQ */ 37 /* Either int-ack or poll for the IRQ */
31 if (pci_intack) 38 if (pci_intack)
32 irq = *pci_intack; 39 irq = readb(pci_intack);
33 else { 40 else {
34 /* Perform an interrupt acknowledge cycle on controller 1. */ 41 /* Perform an interrupt acknowledge cycle on controller 1. */
35 outb(0x0C, 0x20); /* prepare for poll */ 42 outb(0x0C, 0x20); /* prepare for poll */
@@ -59,7 +66,12 @@ i8259_irq(struct pt_regs *regs)
59 } 66 }
60 67
61 spin_unlock(&i8259_lock); 68 spin_unlock(&i8259_lock);
62 return irq; 69 return irq + i8259_pic_irq_offset;
70}
71
72int i8259_irq_cascade(struct pt_regs *regs, void *unused)
73{
74 return i8259_irq(regs);
63} 75}
64 76
65static void i8259_mask_and_ack_irq(unsigned int irq_nr) 77static void i8259_mask_and_ack_irq(unsigned int irq_nr)
@@ -67,20 +79,18 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr)
67 unsigned long flags; 79 unsigned long flags;
68 80
69 spin_lock_irqsave(&i8259_lock, flags); 81 spin_lock_irqsave(&i8259_lock, flags);
70 if ( irq_nr >= i8259_pic_irq_offset ) 82 irq_nr -= i8259_pic_irq_offset;
71 irq_nr -= i8259_pic_irq_offset;
72
73 if (irq_nr > 7) { 83 if (irq_nr > 7) {
74 cached_A1 |= 1 << (irq_nr-8); 84 cached_A1 |= 1 << (irq_nr-8);
75 inb(0xA1); /* DUMMY */ 85 inb(0xA1); /* DUMMY */
76 outb(cached_A1,0xA1); 86 outb(cached_A1, 0xA1);
77 outb(0x20,0xA0); /* Non-specific EOI */ 87 outb(0x20, 0xA0); /* Non-specific EOI */
78 outb(0x20,0x20); /* Non-specific EOI to cascade */ 88 outb(0x20, 0x20); /* Non-specific EOI to cascade */
79 } else { 89 } else {
80 cached_21 |= 1 << irq_nr; 90 cached_21 |= 1 << irq_nr;
81 inb(0x21); /* DUMMY */ 91 inb(0x21); /* DUMMY */
82 outb(cached_21,0x21); 92 outb(cached_21, 0x21);
83 outb(0x20,0x20); /* Non-specific EOI */ 93 outb(0x20, 0x20); /* Non-specific EOI */
84 } 94 }
85 spin_unlock_irqrestore(&i8259_lock, flags); 95 spin_unlock_irqrestore(&i8259_lock, flags);
86} 96}
@@ -96,9 +106,8 @@ static void i8259_mask_irq(unsigned int irq_nr)
96 unsigned long flags; 106 unsigned long flags;
97 107
98 spin_lock_irqsave(&i8259_lock, flags); 108 spin_lock_irqsave(&i8259_lock, flags);
99 if ( irq_nr >= i8259_pic_irq_offset ) 109 irq_nr -= i8259_pic_irq_offset;
100 irq_nr -= i8259_pic_irq_offset; 110 if (irq_nr < 8)
101 if ( irq_nr < 8 )
102 cached_21 |= 1 << irq_nr; 111 cached_21 |= 1 << irq_nr;
103 else 112 else
104 cached_A1 |= 1 << (irq_nr-8); 113 cached_A1 |= 1 << (irq_nr-8);
@@ -111,9 +120,8 @@ static void i8259_unmask_irq(unsigned int irq_nr)
111 unsigned long flags; 120 unsigned long flags;
112 121
113 spin_lock_irqsave(&i8259_lock, flags); 122 spin_lock_irqsave(&i8259_lock, flags);
114 if ( irq_nr >= i8259_pic_irq_offset ) 123 irq_nr -= i8259_pic_irq_offset;
115 irq_nr -= i8259_pic_irq_offset; 124 if (irq_nr < 8)
116 if ( irq_nr < 8 )
117 cached_21 &= ~(1 << irq_nr); 125 cached_21 &= ~(1 << irq_nr);
118 else 126 else
119 cached_A1 &= ~(1 << (irq_nr-8)); 127 cached_A1 &= ~(1 << (irq_nr-8));
@@ -169,12 +177,14 @@ static struct irqaction i8259_irqaction = {
169 * intack_addr - PCI interrupt acknowledge (real) address which will return 177 * intack_addr - PCI interrupt acknowledge (real) address which will return
170 * the active irq from the 8259 178 * the active irq from the 8259
171 */ 179 */
172void __init 180void __init i8259_init(unsigned long intack_addr, int offset)
173i8259_init(long intack_addr)
174{ 181{
175 unsigned long flags; 182 unsigned long flags;
183 int i;
176 184
177 spin_lock_irqsave(&i8259_lock, flags); 185 spin_lock_irqsave(&i8259_lock, flags);
186 i8259_pic_irq_offset = offset;
187
178 /* init master interrupt controller */ 188 /* init master interrupt controller */
179 outb(0x11, 0x20); /* Start init sequence */ 189 outb(0x11, 0x20); /* Start init sequence */
180 outb(0x00, 0x21); /* Vector base */ 190 outb(0x00, 0x21); /* Vector base */
@@ -198,11 +208,14 @@ i8259_init(long intack_addr)
198 spin_unlock_irqrestore(&i8259_lock, flags); 208 spin_unlock_irqrestore(&i8259_lock, flags);
199 209
200 /* reserve our resources */ 210 /* reserve our resources */
201 setup_irq( i8259_pic_irq_offset + 2, &i8259_irqaction); 211 setup_irq(offset + 2, &i8259_irqaction);
202 request_resource(&ioport_resource, &pic1_iores); 212 request_resource(&ioport_resource, &pic1_iores);
203 request_resource(&ioport_resource, &pic2_iores); 213 request_resource(&ioport_resource, &pic2_iores);
204 request_resource(&ioport_resource, &pic_edgectrl_iores); 214 request_resource(&ioport_resource, &pic_edgectrl_iores);
205 215
206 if (intack_addr != 0) 216 if (intack_addr != 0)
207 pci_intack = ioremap(intack_addr, 1); 217 pci_intack = ioremap(intack_addr, 1);
218
219 for (i = 0; i < NUM_ISA_INTERRUPTS; ++i)
220 irq_desc[offset + i].handler = &i8259_pic;
208} 221}
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/ppc64/Kconfig b/arch/ppc64/Kconfig
index 8cbac7f32092..963f519b7713 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -123,6 +123,11 @@ config MPIC
123 bool 123 bool
124 default y 124 default y
125 125
126config PPC_I8259
127 depends on PPC_PSERIES
128 bool
129 default y
130
126config BPA_IIC 131config BPA_IIC
127 depends on PPC_BPA 132 depends on PPC_BPA
128 bool 133 bool
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index cb6ac3d1a06f..2c541c6652b2 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -24,7 +24,7 @@ pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
24 24
25obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) 25obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
26 26
27obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o 27obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
28ifneq ($(CONFIG_PPC_MERGE),y) 28ifneq ($(CONFIG_PPC_MERGE),y)
29obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 29obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
30endif 30endif
diff --git a/arch/ppc64/kernel/i8259.c b/arch/ppc64/kernel/i8259.c
deleted file mode 100644
index 74dcfd68fc75..000000000000
--- a/arch/ppc64/kernel/i8259.c
+++ /dev/null
@@ -1,177 +0,0 @@
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
20unsigned char cached_8259[2] = { 0xff, 0xff };
21#define cached_A1 (cached_8259[0])
22#define cached_21 (cached_8259[1])
23
24static __cacheline_aligned_in_smp DEFINE_SPINLOCK(i8259_lock);
25
26static int i8259_pic_irq_offset;
27static int i8259_present;
28
29int 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
67static 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
90static void i8259_set_irq_mask(int irq_nr)
91{
92 outb(cached_A1,0xA1);
93 outb(cached_21,0x21);
94}
95
96static 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
111static 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
126static 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
133struct 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
141void __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
166static 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
177arch_initcall(i8259_request_cascade);