Index: linux-2.6.14-rc3/arch/mips/au1000/common/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/au1000/common/irq.c
+++ linux-2.6.14-rc3/arch/mips/au1000/common/irq.c
@@ -253,47 +253,43 @@ void restore_local_and_enable(int contro
static struct hw_interrupt_type rise_edge_irq_type = {
- "Au1000 Rise Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_rise_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_rise_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type fall_edge_irq_type = {
- "Au1000 Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_fall_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_fall_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type either_edge_irq_type = {
- "Au1000 Rise or Fall Edge",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_either_edge_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Rise or Fall Edge",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_either_edge_irq,
+ .end = end_irq,
};
static struct hw_interrupt_type level_irq_type = {
- "Au1000 Level",
- startup_irq,
- shutdown_irq,
- local_enable_irq,
- local_disable_irq,
- mask_and_ack_level_irq,
- end_irq,
- NULL
+ .typename = "Au1000 Level",
+ .startup = startup_irq,
+ .shutdown = shutdown_irq,
+ .enable = local_enable_irq,
+ .disable = local_disable_irq,
+ .ack = mask_and_ack_level_irq,
+ .end = end_irq,
};
#ifdef CONFIG_PM
Index: linux-2.6.14-rc3/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
+++ linux-2.6.14-rc3/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
@@ -209,14 +209,13 @@ static void nile4_irq_end(unsigned int i
#define nile4_irq_shutdown nile4_disable_irq
static hw_irq_controller nile4_irq_controller = {
- "nile4",
- nile4_irq_startup,
- nile4_irq_shutdown,
- nile4_enable_irq,
- nile4_disable_irq,
- nile4_ack_irq,
- nile4_irq_end,
- NULL
+ .typename = "nile4",
+ .startup = nile4_irq_startup,
+ .shutdown = nile4_irq_shutdown,
+ .enable = nile4_enable_irq,
+ .disable = nile4_disable_irq,
+ .ack = nile4_ack_irq,
+ .end = nile4_irq_end,
};
void nile4_irq_setup(u32 base) {
Index: linux-2.6.14-rc3/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
+++ linux-2.6.14-rc3/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
@@ -53,14 +53,13 @@ static void vrc5476_irq_end(uint irq)
}
static hw_irq_controller vrc5476_irq_controller = {
- "vrc5476",
- vrc5476_irq_startup,
- vrc5476_irq_shutdown,
- vrc5476_irq_enable,
- vrc5476_irq_disable,
- vrc5476_irq_ack,
- vrc5476_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5476",
+ .startup = vrc5476_irq_startup,
+ .shutdown = vrc5476_irq_shutdown,
+ .enable = vrc5476_irq_enable,
+ .disable = vrc5476_irq_disable,
+ .ack = vrc5476_irq_ack,
+ .end = vrc5476_irq_end
};
void __init
Index: linux-2.6.14-rc3/arch/mips/ddb5xxx/ddb5477/irq_5477.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/ddb5xxx/ddb5477/irq_5477.c
+++ linux-2.6.14-rc3/arch/mips/ddb5xxx/ddb5477/irq_5477.c
@@ -90,14 +90,13 @@ vrc5477_irq_end(unsigned int irq)
}
hw_irq_controller vrc5477_irq_controller = {
- "vrc5477_irq",
- vrc5477_irq_startup,
- vrc5477_irq_shutdown,
- vrc5477_irq_enable,
- vrc5477_irq_disable,
- vrc5477_irq_ack,
- vrc5477_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "vrc5477_irq",
+ .startup = vrc5477_irq_startup,
+ .shutdown = vrc5477_irq_shutdown,
+ .enable = vrc5477_irq_enable,
+ .disable = vrc5477_irq_disable,
+ .ack = vrc5477_irq_ack,
+ .end = vrc5477_irq_end
};
void __init vrc5477_irq_init(u32 irq_base)
Index: linux-2.6.14-rc3/arch/mips/ite-boards/generic/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/ite-boards/generic/irq.c
+++ linux-2.6.14-rc3/arch/mips/ite-boards/generic/irq.c
@@ -138,14 +138,13 @@ static void end_ite_irq(unsigned int irq
}
static struct hw_interrupt_type it8172_irq_type = {
- "ITE8172",
- startup_ite_irq,
- shutdown_ite_irq,
- enable_it8172_irq,
- disable_it8172_irq,
- mask_and_ack_ite_irq,
- end_ite_irq,
- NULL
+ .typename = "ITE8172",
+ .startup = startup_ite_irq,
+ .shutdown = shutdown_ite_irq,
+ .enable = enable_it8172_irq,
+ .disable = disable_it8172_irq,
+ .ack = mask_and_ack_ite_irq,
+ .end = end_ite_irq,
};
@@ -159,13 +158,13 @@ static void ack_none(unsigned int irq) {
#define end_none enable_none
static struct hw_interrupt_type cp0_irq_type = {
- "CP0 Count",
- startup_none,
- shutdown_none,
- enable_none,
- disable_none,
- ack_none,
- end_none
+ .typename = "CP0 Count",
+ .startup = startup_none,
+ .shutdown = shutdown_none,
+ .enable = enable_none,
+ .disable = disable_none,
+ .ack = ack_none,
+ .end = end_none
};
void enable_cpu_timer(void)
Index: linux-2.6.14-rc3/arch/mips/jazz/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/jazz/irq.c
+++ linux-2.6.14-rc3/arch/mips/jazz/irq.c
@@ -58,14 +58,13 @@ static void end_r4030_irq(unsigned int i
}
static struct hw_interrupt_type r4030_irq_type = {
- "R4030",
- startup_r4030_irq,
- shutdown_r4030_irq,
- enable_r4030_irq,
- disable_r4030_irq,
- mask_and_ack_r4030_irq,
- end_r4030_irq,
- NULL
+ .typename = "R4030",
+ .startup = startup_r4030_irq,
+ .shutdown = shutdown_r4030_irq,
+ .enable = enable_r4030_irq,
+ .disable = disable_r4030_irq,
+ .ack = mask_and_ack_r4030_irq,
+ .end = end_r4030_irq,
};
void __init init_r4030_ints(void)
Index: linux-2.6.14-rc3/arch/mips/jmr3927/rbhma3100/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/jmr3927/rbhma3100/irq.c
+++ linux-2.6.14-rc3/arch/mips/jmr3927/rbhma3100/irq.c
@@ -412,13 +412,13 @@ void __init arch_init_irq(void)
}
static hw_irq_controller jmr3927_irq_controller = {
- "jmr3927_irq",
- jmr3927_irq_startup,
- jmr3927_irq_shutdown,
- jmr3927_irq_enable,
- jmr3927_irq_disable,
- jmr3927_irq_ack,
- jmr3927_irq_end,
+ .typename = "jmr3927_irq",
+ .startup = jmr3927_irq_startup,
+ .shutdown = jmr3927_irq_shutdown,
+ .enable = jmr3927_irq_enable,
+ .disable = jmr3927_irq_disable,
+ .ack = jmr3927_irq_ack,
+ .end = jmr3927_irq_end,
};
void jmr3927_irq_init(u32 irq_base)
Index: linux-2.6.14-rc3/arch/mips/kernel/i8259.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/kernel/i8259.c
+++ linux-2.6.14-rc3/arch/mips/kernel/i8259.c
@@ -52,14 +52,13 @@ static unsigned int startup_8259A_irq(un
}
static struct hw_interrupt_type i8259A_irq_type = {
- "XT-PIC",
- startup_8259A_irq,
- shutdown_8259A_irq,
- enable_8259A_irq,
- disable_8259A_irq,
- mask_and_ack_8259A,
- end_8259A_irq,
- NULL
+ .typename = "XT-PIC",
+ .startup = startup_8259A_irq,
+ .shutdown = shutdown_8259A_irq,
+ .enable = enable_8259A_irq,
+ .disable = disable_8259A_irq,
+ .ack = mask_and_ack_8259A,
+ .end = end_8259A_irq,
};
/*
Index: linux-2.6.14-rc3/arch/mips/kernel/irq-msc01.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/kernel/irq-msc01.c
+++ linux-2.6.14-rc3/arch/mips/kernel/irq-msc01.c
@@ -129,25 +129,23 @@ msc_bind_eic_interrupt (unsigned int irq
#define shutdown_msc_irq disable_msc_irq
struct hw_interrupt_type msc_levelirq_type = {
- "SOC-it-Level",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- level_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Level",
+ .startup = startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = level_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
struct hw_interrupt_type msc_edgeirq_type = {
- "SOC-it-Edge",
- startup_msc_irq,
- shutdown_msc_irq,
- enable_msc_irq,
- disable_msc_irq,
- edge_mask_and_ack_msc_irq,
- end_msc_irq,
- NULL
+ .typename = "SOC-it-Edge",
+ .startup =startup_msc_irq,
+ .shutdown = shutdown_msc_irq,
+ .enable = enable_msc_irq,
+ .disable = disable_msc_irq,
+ .ack = edge_mask_and_ack_msc_irq,
+ .end = end_msc_irq,
};
Index: linux-2.6.14-rc3/arch/mips/kernel/irq-mv6434x.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/kernel/irq-mv6434x.c
+++ linux-2.6.14-rc3/arch/mips/kernel/irq-mv6434x.c
@@ -135,14 +135,13 @@ void ll_mv64340_irq(struct pt_regs *regs
#define shutdown_mv64340_irq disable_mv64340_irq
struct hw_interrupt_type mv64340_irq_type = {
- "MV-64340",
- startup_mv64340_irq,
- shutdown_mv64340_irq,
- enable_mv64340_irq,
- disable_mv64340_irq,
- mask_and_ack_mv64340_irq,
- end_mv64340_irq,
- NULL
+ .typename = "MV-64340",
+ .startup = startup_mv64340_irq,
+ .shutdown = shutdown_mv64340_irq,
+ .enable = enable_mv64340_irq,
+ .disable = disable_mv64340_irq,
+ .ack = mask_and_ack_mv64340_irq,
+ .end = end_mv64340_irq,
};
void __init mv64340_irq_init(unsigned int base)
Index: linux-2.6.14-rc3/arch/mips/kernel/irq-rm7000.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/kernel/irq-rm7000.c
+++ linux-2.6.14-rc3/arch/mips/kernel/irq-rm7000.c
@@ -72,13 +72,13 @@ static void rm7k_cpu_irq_end(unsigned in
}
static hw_irq_controller rm7k_irq_controller = {
- "RM7000",
- rm7k_cpu_irq_startup,
- rm7k_cpu_irq_shutdown,
- rm7k_cpu_irq_enable,
- rm7k_cpu_irq_disable,
- rm7k_cpu_irq_ack,
- rm7k_cpu_irq_end,
+ .typename = "RM7000",
+ .startup = rm7k_cpu_irq_startup,
+ .shutdown = rm7k_cpu_irq_shutdown,
+ .enable = rm7k_cpu_irq_enable,
+ .disable = rm7k_cpu_irq_disable,
+ .ack = rm7k_cpu_irq_ack,
+ .end = rm7k_cpu_irq_end,
};
void __init rm7k_cpu_irq_init(int base)
Index: linux-2.6.14-rc3/arch/mips/kernel/irq-rm9000.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/kernel/irq-rm9000.c
+++ linux-2.6.14-rc3/arch/mips/kernel/irq-rm9000.c
@@ -106,23 +106,23 @@ static void rm9k_cpu_irq_end(unsigned in
}
static hw_irq_controller rm9k_irq_controller = {
- "RM9000",
- rm9k_cpu_irq_startup,
- rm9k_cpu_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_cpu_irq_startup,
+ .shutdown = rm9k_cpu_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
static hw_irq_controller rm9k_perfcounter_irq = {
- "RM9000",
- rm9k_perfcounter_irq_startup,
- rm9k_perfcounter_irq_shutdown,
- rm9k_cpu_irq_enable,
- rm9k_cpu_irq_disable,
- rm9k_cpu_irq_ack,
- rm9k_cpu_irq_end,
+ .typename = "RM9000",
+ .startup = rm9k_perfcounter_irq_startup,
+ .shutdown = rm9k_perfcounter_irq_shutdown,
+ .enable = rm9k_cpu_irq_enable,
+ .disable = rm9k_cpu_irq_disable,
+ .ack = rm9k_cpu_irq_ack,
+ .end = rm9k_cpu_irq_end,
};
unsigned int rm9000_perfcount_irq;
Index: linux-2.6.14-rc3/arch/mips/kernel/irq_cpu.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/kernel/irq_cpu.c
+++ linux-2.6.14-rc3/arch/mips/kernel/irq_cpu.c
@@ -92,14 +92,13 @@ static void mips_cpu_irq_end(unsigned in
}
static hw_irq_controller mips_cpu_irq_controller = {
- "MIPS",
- mips_cpu_irq_startup,
- mips_cpu_irq_shutdown,
- mips_cpu_irq_enable,
- mips_cpu_irq_disable,
- mips_cpu_irq_ack,
- mips_cpu_irq_end,
- NULL /* no affinity stuff for UP */
+ .typename = "MIPS",
+ .startup = mips_cpu_irq_startup,
+ .shutdown = mips_cpu_irq_shutdown,
+ .enable = mips_cpu_irq_enable,
+ .disable = mips_cpu_irq_disable,
+ .ack = mips_cpu_irq_ack,
+ .end = mips_cpu_irq_end,
};
Index: linux-2.6.14-rc3/arch/mips/lasat/interrupt.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/lasat/interrupt.c
+++ linux-2.6.14-rc3/arch/mips/lasat/interrupt.c
@@ -71,14 +71,13 @@ static void end_lasat_irq(unsigned int i
}
static struct hw_interrupt_type lasat_irq_type = {
- "Lasat",
- startup_lasat_irq,
- shutdown_lasat_irq,
- enable_lasat_irq,
- disable_lasat_irq,
- mask_and_ack_lasat_irq,
- end_lasat_irq,
- NULL
+ .typename = "Lasat",
+ .startup = startup_lasat_irq,
+ .shutdown = shutdown_lasat_irq,
+ .enable = enable_lasat_irq,
+ .disable = disable_lasat_irq,
+ .ack = mask_and_ack_lasat_irq,
+ .end = end_lasat_irq,
};
static inline int ls1bit32(unsigned int x)
Index: linux-2.6.14-rc3/arch/mips/mips-boards/atlas/atlas_int.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/mips-boards/atlas/atlas_int.c
+++ linux-2.6.14-rc3/arch/mips/mips-boards/atlas/atlas_int.c
@@ -76,14 +76,13 @@ static void end_atlas_irq(unsigned int i
}
static struct hw_interrupt_type atlas_irq_type = {
- "Atlas",
- startup_atlas_irq,
- shutdown_atlas_irq,
- enable_atlas_irq,
- disable_atlas_irq,
- mask_and_ack_atlas_irq,
- end_atlas_irq,
- NULL
+ .typename = "Atlas",
+ .startup = startup_atlas_irq,
+ .shutdown = shutdown_atlas_irq,
+ .enable = enable_atlas_irq,
+ .disable = disable_atlas_irq,
+ .ack = mask_and_ack_atlas_irq,
+ .end = end_atlas_irq,
};
static inline int ls1bit32(unsigned int x)
Index: linux-2.6.14-rc3/arch/mips/momentum/ocelot_c/cpci-irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/momentum/ocelot_c/cpci-irq.c
+++ linux-2.6.14-rc3/arch/mips/momentum/ocelot_c/cpci-irq.c
@@ -129,14 +129,13 @@ void ll_cpci_irq(struct pt_regs *regs)
#define shutdown_cpci_irq disable_cpci_irq
struct hw_interrupt_type cpci_irq_type = {
- "CPCI/FPGA",
- startup_cpci_irq,
- shutdown_cpci_irq,
- enable_cpci_irq,
- disable_cpci_irq,
- mask_and_ack_cpci_irq,
- end_cpci_irq,
- NULL
+ .typename = "CPCI/FPGA",
+ .startup = startup_cpci_irq,
+ .shutdown = shutdown_cpci_irq,
+ .enable = enable_cpci_irq,
+ .disable = disable_cpci_irq,
+ .ack = mask_and_ack_cpci_irq,
+ .end = end_cpci_irq,
};
void cpci_irq_init(void)
Index: linux-2.6.14-rc3/arch/mips/momentum/ocelot_c/uart-irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/momentum/ocelot_c/uart-irq.c
+++ linux-2.6.14-rc3/arch/mips/momentum/ocelot_c/uart-irq.c
@@ -122,14 +122,13 @@ void ll_uart_irq(struct pt_regs *regs)
#define shutdown_uart_irq disable_uart_irq
struct hw_interrupt_type uart_irq_type = {
- "UART/FPGA",
- startup_uart_irq,
- shutdown_uart_irq,
- enable_uart_irq,
- disable_uart_irq,
- mask_and_ack_uart_irq,
- end_uart_irq,
- NULL
+ .typename = "UART/FPGA",
+ .startup = startup_uart_irq,
+ .shutdown = shutdown_uart_irq,
+ .enable = enable_uart_irq,
+ .disable = disable_uart_irq,
+ .ack = mask_and_ack_uart_irq,
+ .end = end_uart_irq,
};
void uart_irq_init(void)
Index: linux-2.6.14-rc3/arch/mips/sgi-ip32/ip32-irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/sgi-ip32/ip32-irq.c
+++ linux-2.6.14-rc3/arch/mips/sgi-ip32/ip32-irq.c
@@ -163,14 +163,13 @@ static void end_cpu_irq(unsigned int irq
#define mask_and_ack_cpu_irq disable_cpu_irq
static struct hw_interrupt_type ip32_cpu_interrupt = {
- "IP32 CPU",
- startup_cpu_irq,
- shutdown_cpu_irq,
- enable_cpu_irq,
- disable_cpu_irq,
- mask_and_ack_cpu_irq,
- end_cpu_irq,
- NULL
+ .typename = "IP32 CPU",
+ .startup = startup_cpu_irq,
+ .shutdown = shutdown_cpu_irq,
+ .enable = enable_cpu_irq,
+ .disable = disable_cpu_irq,
+ .ack = mask_and_ack_cpu_irq,
+ .end = end_cpu_irq,
};
/*
@@ -234,14 +233,13 @@ static void end_crime_irq(unsigned int i
#define shutdown_crime_irq disable_crime_irq
static struct hw_interrupt_type ip32_crime_interrupt = {
- "IP32 CRIME",
- startup_crime_irq,
- shutdown_crime_irq,
- enable_crime_irq,
- disable_crime_irq,
- mask_and_ack_crime_irq,
- end_crime_irq,
- NULL
+ .typename = "IP32 CRIME",
+ .startup = startup_crime_irq,
+ .shutdown = shutdown_crime_irq,
+ .enable = enable_crime_irq,
+ .disable = disable_crime_irq,
+ .ack = mask_and_ack_crime_irq,
+ .end = end_crime_irq,
};
/*
@@ -294,14 +292,13 @@ static void end_macepci_irq(unsigned int
#define mask_and_ack_macepci_irq disable_macepci_irq
static struct hw_interrupt_type ip32_macepci_interrupt = {
- "IP32 MACE PCI",
- startup_macepci_irq,
- shutdown_macepci_irq,
- enable_macepci_irq,
- disable_macepci_irq,
- mask_and_ack_macepci_irq,
- end_macepci_irq,
- NULL
+ .typename = "IP32 MACE PCI",
+ .startup = startup_macepci_irq,
+ .shutdown = shutdown_macepci_irq,
+ .enable = enable_macepci_irq,
+ .disable = disable_macepci_irq,
+ .ack = mask_and_ack_macepci_irq,
+ .end = end_macepci_irq,
};
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
@@ -425,14 +422,13 @@ static void end_maceisa_irq(unsigned irq
#define shutdown_maceisa_irq disable_maceisa_irq
static struct hw_interrupt_type ip32_maceisa_interrupt = {
- "IP32 MACE ISA",
- startup_maceisa_irq,
- shutdown_maceisa_irq,
- enable_maceisa_irq,
- disable_maceisa_irq,
- mask_and_ack_maceisa_irq,
- end_maceisa_irq,
- NULL
+ .typename = "IP32 MACE ISA",
+ .startup = startup_maceisa_irq,
+ .shutdown = shutdown_maceisa_irq,
+ .enable = enable_maceisa_irq,
+ .disable = disable_maceisa_irq,
+ .ack = mask_and_ack_maceisa_irq,
+ .end = end_maceisa_irq,
};
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
@@ -476,14 +472,13 @@ static void end_mace_irq(unsigned int ir
#define mask_and_ack_mace_irq disable_mace_irq
static struct hw_interrupt_type ip32_mace_interrupt = {
- "IP32 MACE",
- startup_mace_irq,
- shutdown_mace_irq,
- enable_mace_irq,
- disable_mace_irq,
- mask_and_ack_mace_irq,
- end_mace_irq,
- NULL
+ .typename = "IP32 MACE",
+ .startup = startup_mace_irq,
+ .shutdown = shutdown_mace_irq,
+ .enable = enable_mace_irq,
+ .disable = disable_mace_irq,
+ .ack = mask_and_ack_mace_irq,
+ .end = end_mace_irq,
};
static void ip32_unknown_interrupt(struct pt_regs *regs)
Index: linux-2.6.14-rc3/arch/mips/sibyte/sb1250/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/sibyte/sb1250/irq.c
+++ linux-2.6.14-rc3/arch/mips/sibyte/sb1250/irq.c
@@ -71,17 +71,15 @@ extern char sb1250_duart_present[];
#endif
static struct hw_interrupt_type sb1250_irq_type = {
- "SB1250-IMR",
- startup_sb1250_irq,
- shutdown_sb1250_irq,
- enable_sb1250_irq,
- disable_sb1250_irq,
- ack_sb1250_irq,
- end_sb1250_irq,
+ .typename = "SB1250-IMR",
+ .startup = startup_sb1250_irq,
+ .shutdown = shutdown_sb1250_irq,
+ .enable = enable_sb1250_irq,
+ .disable = disable_sb1250_irq,
+ .ack = ack_sb1250_irq,
+ .end = end_sb1250_irq,
#ifdef CONFIG_SMP
- sb1250_set_affinity
-#else
- NULL
+ .set_affinity = sb1250_set_affinity
#endif
};
Index: linux-2.6.14-rc3/arch/mips/sni/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/mips/sni/irq.c
+++ linux-2.6.14-rc3/arch/mips/sni/irq.c
@@ -58,14 +58,13 @@ static void end_pciasic_irq(unsigned int
}
static struct hw_interrupt_type pciasic_irq_type = {
- "ASIC-PCI",
- startup_pciasic_irq,
- shutdown_pciasic_irq,
- enable_pciasic_irq,
- disable_pciasic_irq,
- mask_and_ack_pciasic_irq,
- end_pciasic_irq,
- NULL
+ .typename = "ASIC-PCI",
+ .startup = startup_pciasic_irq,
+ .shutdown = shutdown_pciasic_irq,
+ .enable = enable_pciasic_irq,
+ .disable = disable_pciasic_irq,
+ .ack = mask_and_ack_pciasic_irq,
+ .end = end_pciasic_irq,
};
/*
Index: linux-2.6.14-rc3/Documentation/DocBook/genericirq.tmpl
===================================================================
--- /dev/null
+++ linux-2.6.14-rc3/Documentation/DocBook/genericirq.tmpl
@@ -0,0 +1,560 @@
+
+
+
+
+
+ Linux generic IRQ handling
+
+
+
+ Thomas
+ Gleixner
+
+
+ tglx@linutronix.de
+
+
+
+
+ Ingo
+ Molnar
+
+
+ mingo@elte.hu
+
+
+
+
+
+
+ 2005
+ Thomas Gleixner
+
+
+ 2005
+ Ingo Molnar
+
+
+
+
+ This documentation is free software; you can redistribute
+ it and/or modify it under the terms of the GNU General Public
+ License version 2 as published by the Free Software Foundation.
+
+
+
+ This program is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ MA 02111-1307 USA
+
+
+
+ For more details see the file COPYING in the source
+ distribution of Linux.
+
+
+
+
+
+
+
+ Introduction
+
+ The generic interrupt handling layer is designed to provide a
+ complete abstraction of interrupt handling for device drivers
+ and is able to handle all different types of interrupt controller
+ hardware. Device drivers use generic API function to request, enable,
+ disable and free interrupts. The drivers do not have to know anything
+ about interrupt hardware, so they can be used on different hardware
+ platforms without code changes.
+
+
+ This documentation is provided for developers who want to implement
+ architecture interrupt support based on the Generic IRQ handling layer.
+
+
+
+
+ Rationale
+
+ The original implementation of interrupt handling in Linux is using
+ the __do_IRQ() super-handler, which must be able to deal with every
+ type of interrupt logic. This is achieved by an 'interrupt type'
+ structure and runtime flags to handle special cases.
+ Furthermore the superhandler assumed a certain type of interrupt
+ handling hardware and turned out to be not capable of handling all
+ kind of interrupt controller hardware which can be found through
+ the architectures. The all in one approach also adds unnecessary
+ complexity for every user.
+
+
+ Originally, Russell King identified different types of handlers to
+ build a quite universal set for the ARM interrupt handler
+ implementation in Linux 2.5/2.6. He distiguished between:
+
+ Level type
+ Edge type
+ Simple type
+
+ In the SMP world of the __do_IRQ() super-handler another type
+ was identified:
+
+ Per CPU type
+
+
+
+ This split implementation of handlers allows to optimize the flow
+ of the interrupt handling for each specific interrupt type.
+ This reduces complexitiy in that particular code path and allows
+ the optimized handling of a given type.
+
+
+ The original general implementation uses interrupt_type structures
+ to differentiate the flow control in the super-handler. This
+ leads to a mix of flow logic and code related to hardware details.
+ Russell Kings ARM implementation which replaced the type by a chip
+ abstraction did the mix the other way around.
+
+
+ The natural conclusion was a clean seperation of the 'type flow'
+ and the 'chip'. Analysing a couple of architecture implementations
+ reveals that many of them can use a generic set of 'type flow'
+ implementations and only need to add the chip level specific code.
+ The seperation is also valuable for the (sub)architectures,
+ which need specific quirks in the type flow itself, because it
+ provides a more transparent design.
+
+
+ Each interrupt type implementation has assigned its own flow
+ handler, which should be normally one of the generic
+ implementations. The flow handler implementation makes it
+ simple to provide demultiplexing handlers which can be found in
+ embedded platforms on various architectures.
+
+
+ The seperation makes the generic interrupt handling more flexible
+ and extensible. An (sub)architecture can use a generic type flow
+ implementation for e.g. 'level type' interrupts and add a
+ (sub)architecture specific 'edge type' implementation.
+
+
+ To make the transition to the new model easier and prevent the
+ breakage of existing implementations the __do_IRQ() super-handler
+ is still available. This leads to a kind of duality for the time
+ being. Over time the new model should achieve a homogeneous
+ implementation scheme over all architectures with enhanced
+ maintainability and cleanliness.
+
+
+
+ Known Bugs And Assumptions
+
+ None (hopefully).
+
+
+
+
+ Abstraction layers
+
+ There are three main levels of abstraction in the interrupt code:
+
+ Highlevel driver API
+ Abstract interrupt type
+ Chiplevel hardware encapsulation
+
+
+
+ The seperation of interrupt type and chip level functionality
+ provides the most flexible design. This implementation can handle
+ all kinds of interrupt hardware and the necessary workarounds for
+ the interrupt types without the need of redundant implementations.
+ The seperation handles also edge and level type interrupts
+ on the same hardware chip.
+
+
+ Interrupt control flow
+
+ Each interrupt is described by an interrupt description structure
+ irq_desc. The interrupt is referenced by an 'unsigned int' numeric
+ value which selects the corresponding interrupt decription structure
+ in the description structures array.
+ The description structure contains status information and pointers
+ to the interrupt type structure and the interrupt chip structure
+ which are assigned to this interrupt.
+
+
+ Whenever an interrupt triggers, the lowlevel arch code calls into
+ the generic interrupt code by calling desc->handler->handle_irq().
+ This highlevel IRQ handling function only uses other
+ desc->handler primitives which describe the control flow operation
+ necessary for the interrupt type. These operations are calling
+ the chip primitives referenced by the assigned chip description
+ structure.
+
+
+
+ Highlevel Driver API
+
+ The highlevel Driver API consists of following functions:
+
+ request_irq()
+ free_irq()
+ disable_irq()
+ enable_irq()
+ disable_irq_nosync() (SMP only)
+ synchronize_irq() (SMP only)
+ set_irq_type()
+ set_irq_wake()
+ set_irq_data()
+ set_irq_chip()
+ set_irq_chip_data()
+
+ See the autogenerated function documentation for details.
+
+
+
+ Abstract interrupt type
+
+ The 'interrupt type' (struct irq_type) abstraction mainly consists of
+ methods which implement the 'interrupt handling flow'. The generic
+ layer provides a set of pre-defined types:
+
+ default_level_type
+ default_edge_type
+ default_simple_type
+ default_percpu_type
+
+ The default type implementations use the generic type handlers.
+
+ handle_level_type
+ handle_edge_type
+ handle_simple_type
+ handle_percpu_type
+
+ The interrupt types (either predefined or architecture specific) are
+ assigned to specific interrupts by the architecture either during
+ bootup or during device initialization.
+
+
+ Default type implementations
+
+ Helper functions
+
+ The helper functions call the chip primitives and
+ are used by the default type implementations.
+ Following helper functions are implemented (simplified excerpt):
+
+default_enable(irq)
+{
+ desc->chip->unmask(irq);
+}
+
+default_disable(irq)
+{
+ desc->chip->mask(irq);
+}
+
+default_ack(irq)
+{
+ chip->ack(irq);
+}
+
+default_mask_ack(irq)
+{
+ if (chip->mask_ack) {
+ chip->mask_ack(irq);
+ } else {
+ chip->mask(irq);
+ chip->ack(irq);
+ }
+}
+
+noop(irq)
+{
+}
+
+default_set_type(irq, type)
+{
+ if (desc->chip->set_type) {
+ if (desc->chip->set_type(irq, type))
+ return NULL;
+ }
+
+ return default_handler for type;
+}
+
+
+
+
+ Default Level IRQ type
+
+ The default Level IRQ type implements the functions
+
+ enabledefault_enable
+ disabledefault_disable
+ startdefault_mask_ack
+ enddefault_enable
+ handle_irqhandle_level_irq
+ set_typedefault_set_type
+
+
+
+
+ Default Edge IRQ type
+
+ The default Edge IRQ type implements the functions
+
+ enabledefault_enable
+ disabledefault_disable
+ startdefault_ack
+ holddefault_mask_ack
+ endnoop
+ handle_irqhandle_edge_irq
+ set_typedefault_set_type
+
+
+
+
+ Default simple IRQ type
+
+ The default simple IRQ type implements the functions
+
+ enablenoop
+ disablenoop
+ handle_irqhandle_simple_irq
+
+
+
+
+ Default per CPU IRQ type
+
+ The default per CPU IRQ type implements the functions
+
+ enabledefault_enable
+ disabledefault_disable
+ startdefault_ack
+ enddefault_enable
+ handle_irqhandle_percpu_irq
+
+
+
+
+
+ Default type handler implementations
+
+ Default Level IRQ type handler
+
+ handle_level_type provides a generic implementation
+ for level type interrupts.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+desc->handler->start();
+handle_IRQ_event(desc->action);
+desc->handler->end();
+
+
+
+
+ Default Edge IRQ type handler
+
+ handle_edge_type provides a generic implementation
+ for edge type interrupts.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+if (desc->status & running) {
+ desc->handler->hold();
+ desc->status |= pending | masked;
+ return;
+}
+desc->handler->start();
+desc->status |= running;
+do {
+ if (desc->status & masked)
+ desc->handler->enable();
+ desc-status &= ~pending;
+ handle_IRQ_event(desc->action);
+} while (status & pending);
+desc-status &= ~running;
+desc->handler->end();
+
+
+
+
+ Default simple IRQ type handler
+
+ handle_simple_type provides a generic implementation
+ for simple type interrupts.
+
+
+ Note: The simple type handler does not call any
+ handler/chip primitives.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+handle_IRQ_event(desc->action);
+
+
+
+
+ Default per CPU type handler
+
+ handle_percpu_type provides a generic implementation
+ for per CPU type interrupts.
+
+
+ Per CPU interrupts are only available on SMP and
+ the handler provides a simplified version without
+ locking.
+
+
+ Following control flow is implemented (simplified excerpt):
+
+desc->handler->start();
+handle_IRQ_event(desc->action);
+desc->handler->end();
+
+
+
+
+
+ Architecture specific type implementation
+
+ If an architecture needs to implement its own type structures, then
+ the following primitives have to be implemented:
+
+ handle_irq() - The handle_irq function pointer should preferably point to
+ one of the generic type handler functions
+ startup() - Optional
+ shutdown() - Optional
+ enable()
+ disable()
+ start()
+ hold() - For edge type interupts only
+ end()
+ set_type - Optional
+ set_affinity - SMP only
+
+
+
+
+ Quirks and optimizations
+
+ The generic functions are intended for 'clean' architectures and chips,
+ which have no platform-specific IRQ handling quirks. If an architecture
+ needs to implement quirks on the 'flow' level then it can do so by
+ overriding the irqtype. This is also done for compatibility reasons, as
+ most architectures use irqtypes only at the moment.
+
+
+ An architecture could implement all of its IRQ logic via pushing
+ chip handling details into the irqtype's ->start()/->end()/->hold()
+ functions. This is only recommended when the underlying primitives
+ are pure chip primitives without additional quirks. The direct pointer
+ to the chip functions reduces the indirection level by one.
+
+
+
+
+ Chiplevel hardware encapsulation
+
+ The chip level hardware description structure irq_chip
+ contains all the direct chip relevant functions, which
+ can be utilized by the irq_type implementations.
+
+ ack()
+ mask_ack() - Optional, recommended for performance
+ mask()
+ unmask()
+ retrigger() - Optional
+ set_type() - Optional
+ set_wake() - Optional
+
+ These primitives are strictly intended to mean what they say: ack means
+ ACK, masking means masking of an IRQ line, etc. It is up to the flow
+ handler(s) to use these basic units of lowlevel functionality.
+
+
+
+
+
+ __do_IRQ entry point
+
+ The original implementation __do_IRQ() is an alternative entry
+ point for all types of interrupts.
+
+
+ This handler turned out to be not suitable for all
+ interrupt hardware and was therefor reimplemented with split
+ functionality for egde/level/simple/percpu interrupts. This is not
+ only a functional optimization. It also shortenes code pathes for
+ interrupts.
+
+
+ To make use of the split implementation, replace the call to
+ __do_IRQ by a call to desc->handler->handle_irq() and associate
+ the appropriate handler function to desc->handler->handle_irq().
+ In most cases the generic type and handler implementations should
+ be sufficient.
+
+
+
+
+ Locking on SMP
+
+ The locking of chip registers is up to the architecture that
+ defines the chip primitives. There is a chip->lock field that can be used
+ for serialization, but the generic layer does not touch it. The per-irq
+ structure is protected via desc->lock, by the generic layer.
+
+
+
+ Structures
+
+ This chapter contains the autogenerated documentation of the structures which are
+ used in the generic IRQ layer.
+
+!Iinclude/linux/irq.h
+
+
+
+ Public Functions Provided
+
+ This chapter contains the autogenerated documentation of the kernel API functions
+ which are exported.
+
+!Ekernel/irq/manage.c
+
+
+
+ Internal Functions Provided
+
+ This chapter contains the autogenerated documentation of the internal functions.
+
+!Ikernel/irq/handle.c
+
+
+
+ Credits
+
+ The following people have contributed to this document:
+
+ Thomas Gleixnertglx@linutronix.de
+ Ingo Molnarmingo@elte.hu
+
+
+
+
Index: linux-2.6.14-rc3/Documentation/DocBook/Makefile
===================================================================
--- linux-2.6.14-rc3.orig/Documentation/DocBook/Makefile
+++ linux-2.6.14-rc3/Documentation/DocBook/Makefile
@@ -10,7 +10,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml \
sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
- gadget.xml libata.xml mtdnand.xml librs.xml
+ gadget.xml libata.xml mtdnand.xml librs.xml genericirq.xml
###
# The build process is as follows (targets):
Index: linux-2.6.14-rc3/kernel/irq/Makefile
===================================================================
--- linux-2.6.14-rc3.orig/kernel/irq/Makefile
+++ linux-2.6.14-rc3/kernel/irq/Makefile
@@ -1,5 +1,5 @@
-obj-y := handle.o manage.o spurious.o
+obj-y := handle.o manage.o spurious.o resend.o
obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
obj-$(CONFIG_PROC_FS) += proc.o
Index: linux-2.6.14-rc3/kernel/irq/handle.c
===================================================================
--- linux-2.6.14-rc3.orig/kernel/irq/handle.c
+++ linux-2.6.14-rc3/kernel/irq/handle.c
@@ -1,9 +1,13 @@
/*
* linux/kernel/irq/handle.c
*
- * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 1992, 1998-2005 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005, Thomas Gleixner, Russell King
*
* This file contains the core interrupt handling code.
+ *
+ * Detailed information is available in Documentation/DocBook/genericirq
+ *
*/
#include
@@ -12,57 +16,57 @@
#include
#include
+#if defined(CONFIG_NO_IDLE_HZ)
+#include
+#endif
+
#include "internals.h"
/*
- * Linux has a controller-independent interrupt architecture.
- * Every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * The code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic or
- * having to touch the generic code.
- *
- * Controller mappings for all interrupt sources:
+ * Default initialization for all interrupt sources
*/
irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.handler = &no_irq_type,
- .lock = SPIN_LOCK_UNLOCKED
+ .lock = SPIN_LOCK_UNLOCKED,
+ .depth = 1,
}
};
/*
- * Generic 'no controller' code
+ * What should we do if we get a hw irq event on an illegal vector?
+ * Each architecture has to answer this themself.
*/
-static void end_none(unsigned int irq) { }
-static void enable_none(unsigned int irq) { }
-static void disable_none(unsigned int irq) { }
-static void shutdown_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-
-static void ack_none(unsigned int irq)
+static void ack_bad(unsigned int irq)
{
- /*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themself.
- */
ack_bad_irq(irq);
}
-struct hw_interrupt_type no_irq_type = {
+/*
+ * NOP functions
+ */
+static void noop(unsigned int irq)
+{
+}
+
+static unsigned int noop_ret(unsigned int irq)
+{
+ return 0;
+}
+
+/*
+ * Generic no controller implementation
+ */
+struct irq_type no_irq_type = {
.typename = "none",
- .startup = startup_none,
- .shutdown = shutdown_none,
- .enable = enable_none,
- .disable = disable_none,
- .ack = ack_none,
- .end = end_none,
- .set_affinity = NULL
+ .startup = noop_ret,
+ .shutdown = noop,
+ .enable = noop,
+ .disable = noop,
+ .ack = ack_bad,
+ .end = noop,
+ .handle_irq = handle_bad_irq,
};
/*
@@ -74,7 +78,147 @@ irqreturn_t no_action(int cpl, void *dev
}
/*
- * Have got an event to handle:
+ * default ack function
+ */
+static void default_ack(unsigned int irq)
+{
+ irq_desc[irq].chip->ack(irq);
+}
+
+/*
+ * default mask ack function
+ */
+static void default_mask_ack(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ if (desc->chip->mask_ack) {
+ desc->chip->mask_ack(irq);
+ } else {
+ desc->chip->mask(irq);
+ desc->chip->ack(irq);
+ }
+}
+
+/*
+ * default enable function
+ */
+static void default_enable(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ desc->chip->unmask(irq);
+ desc->status &= ~IRQ_MASKED;
+}
+
+/*
+ * default end function
+ */
+static void default_end(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ if (!desc->depth)
+ desc->chip->unmask(irq);
+}
+
+/*
+ * default disable function
+ */
+static void default_disable(unsigned int irq)
+{
+ irq_desc[irq].chip->mask(irq);
+}
+
+/*
+ * Default set type function
+ */
+static struct irq_type *default_set_type(unsigned int irq, unsigned int type)
+{
+ irq_desc_t *desc = irq_desc + irq;
+
+ if (desc->chip->set_type)
+ if (desc->chip->set_type(irq, type))
+ return NULL;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ return &no_irq_type;
+
+ case IRQ_TYPE_EDGEL:
+ case IRQ_TYPE_EDGEH:
+ case IRQ_TYPE_EDGEB:
+ return &default_edge_type;
+ case IRQ_TYPE_LEVELL:
+ case IRQ_TYPE_LEVELH:
+ return &default_level_type;
+ case IRQ_TYPE_SIMPLE:
+ return &default_simple_type;
+ }
+ return NULL;
+}
+
+/*
+ * Generic edge type interrupt
+ *
+ */
+struct irq_type default_edge_type = {
+ .typename = "default_edge",
+ .enable = default_enable,
+ .disable = default_disable,
+ .ack = default_ack,
+ .hold = default_mask_ack,
+ .end = noop,
+ .handle_irq = handle_edge_irq,
+ .set_type = default_set_type,
+};
+
+/*
+ * Generic level type interrupt
+ */
+struct irq_type default_level_type = {
+ .typename = "default_level",
+ .enable = default_enable,
+ .disable = default_disable,
+ .ack = default_mask_ack,
+ .end = default_end,
+ .handle_irq = handle_level_irq,
+ .set_type = default_set_type,
+};
+
+/*
+ * Generic simple type interrupt
+ *
+ * No hardware handling necessary
+ */
+struct irq_type default_simple_type = {
+ .typename = "default_simple",
+ .enable = noop,
+ .disable = noop,
+ .handle_irq = handle_simple_irq,
+};
+
+#ifdef CONFIG_SMP
+/*
+ * Generic per cpu type interrupt
+ */
+struct irq_type default_percpu_type = {
+ .typename = "default_percpu",
+ .enable = default_enable,
+ .disable = default_disable,
+ .ack = default_ack,
+ .end = default_end,
+ .handle_irq = handle_percpu_irq,
+};
+#endif
+
+/**
+ * handle_IRQ_event - irq action chain handler
+ * @irq: the interrupt number
+ * @regs: pointer to a register structure
+ * @action: the interrupt action chain for this irq
+ *
+ * Handles the action chain of an irq event
*/
fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
struct irqaction *action)
@@ -84,6 +228,15 @@ fastcall int handle_IRQ_event(unsigned i
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
+#if defined(CONFIG_NO_IDLE_HZ)
+ if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
+ write_seqlock(&xtime_lock);
+ if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
+ system_timer->dyn_tick->handler(irq, 0, regs);
+ write_sequnlock(&xtime_lock);
+ }
+#endif
+
do {
ret = action->handler(irq, action->dev_id, regs);
if (ret == IRQ_HANDLED)
@@ -99,10 +252,208 @@ fastcall int handle_IRQ_event(unsigned i
return retval;
}
-/*
- * do_IRQ handles all normal device IRQ's (the special
+/**
+ * handle_bad_irq - handle spurious and unhandled irqs
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ */
+void handle_bad_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+}
+
+/**
+ * handle_simple_irq - Simple and software-decoded IRQs.
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Simple interrupts are either sent from a demultiplexing interrupt
+ * handler or come from hardware, where no interrupt hardware control
+ * is necessary.
+ *
+ * Note: The caller is expected to handle the ack, clear, mask and
+ * unmask issues if necessary.
+ *
+ * Must be called with the irq_desc->lock held
+ */
+void handle_simple_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ irqreturn_t action_ret;
+ const unsigned int cpu = smp_processor_id();
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+ action = desc->action;
+ if (unlikely(!action || desc->depth))
+ return;
+
+ desc->status |= IRQ_INPROGRESS;
+ spin_unlock(&desc->lock);
+ action_ret = handle_IRQ_event(irq, regs, action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ spin_lock(&desc->lock);
+ desc->status &= ~IRQ_INPROGRESS;
+}
+
+/**
+ * handle_level_irq - Level type irq handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Level type interrupts are active as long as the hardware line has
+ * the active level. This may require to mask the interrupt and unmask it
+ * after the associated handler has acknowledged the device, so the
+ * interrupt line is back to inactive.
+ *
+ * Must be called with the irq_desc->lock held
+ */
+void handle_level_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ irqreturn_t action_ret;
+ const unsigned int cpu = smp_processor_id();
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+ desc->handler->ack(irq);
+
+ /*
+ * If its disabled or no action available
+ * keep it masked and get out of here
+ */
+ action = desc->action;
+ if (unlikely(!action || desc->depth))
+ goto out;
+
+ desc->status |= IRQ_INPROGRESS;
+ spin_unlock(&desc->lock);
+ action_ret = handle_IRQ_event(irq, regs, action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ spin_lock(&desc->lock);
+
+ desc->status &= ~IRQ_INPROGRESS;
+out:
+ desc->handler->end(irq);
+}
+
+/**
+ * handle_edge_irq - edge type IRQ handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Interrupt occures on the falling and/or rising edge of a hardware
+ * signal. The occurence is latched into the irq controller hardware
+ * and must be acked in order to be reenabled. After the ack another
+ * interrupt can happen on the same source even before the first one
+ * is handled by the assosiacted event handler. If this happens it
+ * might be necessary to disable (mask) the interrupt depending on the
+ * controller hardware. This requires to reenable the interrupt inside
+ * of the loop which handles the interrupts which have arrived while
+ * the handler was running. If all pending interrupts are handled, the
+ * loop is left and depending on the hardware controller some final
+ * ack might be necessary.
+ *
+ * Must be called with the irq_desc->lock held
+ */
+void handle_edge_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+ const unsigned int cpu = smp_processor_id();
+
+ kstat_cpu(cpu).irqs[irq]++;
+
+ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
+
+ /*
+ * If we're currently running this IRQ, or its disabled,
+ * we shouldn't process the IRQ. Mark it pending, handle
+ * the necessary masking and go out
+ */
+ if (unlikely((desc->status & IRQ_INPROGRESS) || desc->depth ||
+ !desc->action)) {
+ desc->status |= (IRQ_PENDING | IRQ_MASKED);
+ desc->handler->hold(irq);
+ return;
+ }
+
+ /* Start handling the irq */
+ desc->handler->ack(irq);
+
+ /* Mark the IRQ currently in progress.*/
+ desc->status |= IRQ_INPROGRESS;
+
+ do {
+ struct irqaction *action = desc->action;
+ irqreturn_t action_ret;
+
+ if (unlikely(!action)) {
+ desc->handler->disable(irq);
+ return;
+ }
+
+ /*
+ * When another irq arrived while we were handling
+ * one, we could have masked the irq.
+ * Renable it, if it was not disabled in meantime.
+ */
+ if (unlikely(((desc->status & (IRQ_PENDING | IRQ_MASKED)) ==
+ (IRQ_PENDING | IRQ_MASKED)) && !desc->depth))
+ desc->handler->enable(irq);
+
+ desc->status &= ~IRQ_PENDING;
+ spin_unlock(&desc->lock);
+ action_ret = handle_IRQ_event(irq, regs, action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ spin_lock(&desc->lock);
+
+ } while ((desc->status & IRQ_PENDING) && !desc->depth);
+
+ desc->status &= ~IRQ_INPROGRESS;
+ desc->handler->end(irq);
+}
+
+#ifdef CONFIG_SMP
+/**
+ * handle_percpu_IRQ - Per CPU local irq handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ * @regs: pointer to a register structure
+ *
+ * Per CPU interrupts on SMP machines without locking requirements
+ */
+void handle_percpu_irq(unsigned int irq, irq_desc_t *desc, struct pt_regs *regs)
+{
+ irqreturn_t action_ret;
+
+ kstat_this_cpu.irqs[irq]++;
+ desc->handler->ack(irq);
+ action_ret = handle_IRQ_event(irq, regs, desc->action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret, regs);
+ desc->handler->end(irq);
+}
+#endif /* CONFIG_SMP */
+
+/**
+ * __do_IRQ - original all in one handler
+ * @irq: the interrupt number
+ * @regs: pointer to a register structure
+ *
+ * __do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
- * handlers).
+ * handlers). * This is the original x86 implementation which is used for every
+ * type of interrupt.
+ *
*/
fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
{
Index: linux-2.6.14-rc3/kernel/irq/manage.c
===================================================================
--- linux-2.6.14-rc3.orig/kernel/irq/manage.c
+++ linux-2.6.14-rc3/kernel/irq/manage.c
@@ -1,7 +1,8 @@
/*
* linux/kernel/irq/manage.c
*
- * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 1992, 1998-2005 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005, Thomas Gleixner
*
* This file contains driver APIs to the irq subsystem.
*/
@@ -24,6 +25,7 @@ cpumask_t __cacheline_aligned pending_ir
/**
* synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ * @irq: Interrupt to synchronize
*
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
@@ -115,11 +117,9 @@ void enable_irq(unsigned int irq)
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;
- desc->status = status;
- if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
- desc->status = status | IRQ_REPLAY;
- hw_resend_irq(desc->handler,irq);
- }
+ /* Prevent probing on this irq */
+ desc->status = status | IRQ_NOPROBE;
+ check_irq_resend(desc, irq);
desc->handler->enable(irq);
/* fall-through */
}
@@ -131,6 +131,28 @@ void enable_irq(unsigned int irq)
EXPORT_SYMBOL(enable_irq);
+/**
+ * set_irq_wake - control irq power management wakeup
+ * @irq: Interrupt to control
+ * @mode: power management wakeup mode
+ *
+ * Enable/disable power management wakeup mode
+ */
+int set_irq_wake(unsigned int irq, unsigned int mode)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+ int ret = -ENXIO;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ if (desc->chip && desc->chip->set_wake)
+ ret = desc->chip->set_wake(irq, mode);
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return ret;
+}
+
+EXPORT_SYMBOL(set_irq_wake);
+
/*
* Internal function that tells the architecture code whether a
* particular irq has been exclusively allocated or is available
@@ -140,7 +162,7 @@ int can_request_irq(unsigned int irq, un
{
struct irqaction *action;
- if (irq >= NR_IRQS)
+ if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
return 0;
action = irq_desc[irq].action;
@@ -184,12 +206,12 @@ int setup_irq(unsigned int irq, struct i
/*
* The following block of code has to be executed atomically
*/
- spin_lock_irqsave(&desc->lock,flags);
+ spin_lock_irqsave(&desc->lock, flags);
p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
if (!(old->flags & new->flags & SA_SHIRQ)) {
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
return -EBUSY;
}
@@ -212,7 +234,7 @@ int setup_irq(unsigned int irq, struct i
else
desc->handler->enable(irq);
}
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
new->irq = irq;
register_irq_proc(irq);
@@ -246,7 +268,7 @@ void free_irq(unsigned int irq, void *de
return;
desc = irq_desc + irq;
- spin_lock_irqsave(&desc->lock,flags);
+ spin_lock_irqsave(&desc->lock, flags);
p = &desc->action;
for (;;) {
struct irqaction * action = *p;
@@ -274,7 +296,7 @@ void free_irq(unsigned int irq, void *de
else
desc->handler->disable(irq);
}
- spin_unlock_irqrestore(&desc->lock,flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
unregister_handler_proc(irq, action);
/* Make sure it's not being used on another CPU */
@@ -282,8 +304,8 @@ void free_irq(unsigned int irq, void *de
kfree(action);
return;
}
- printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
- spin_unlock_irqrestore(&desc->lock,flags);
+ printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
+ spin_unlock_irqrestore(&desc->lock, flags);
return;
}
}
@@ -336,6 +358,8 @@ int request_irq(unsigned int irq,
return -EINVAL;
if (irq >= NR_IRQS)
return -EINVAL;
+ if (irq_desc[irq].status & IRQ_NOREQUEST)
+ return -EINVAL;
if (!handler)
return -EINVAL;
@@ -359,3 +383,145 @@ int request_irq(unsigned int irq,
EXPORT_SYMBOL(request_irq);
+/**
+ * generic_set_irq_type - set the hardware irq type structure for an irq
+ * @irq: Interrupt number
+ * @type: Pointer to irq_type structure
+ */
+int generic_set_irq_type(unsigned int irq, struct irq_type *type)
+{
+ irq_desc_t *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install type for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ if (!type)
+ type = &no_irq_type;
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->handler = type;
+ spin_unlock_irqrestore(&desc->lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(generic_set_irq_type);
+
+/**
+ * set_irq_data - set irq type data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to interrupt specific data
+ *
+ * Set the hardware irq controller data for an irq
+ */
+int set_irq_data(unsigned int irq, void *data)
+{
+ irq_desc_t *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install controller data for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->handler_data = data;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_irq_data);
+
+/**
+ * set_irq_chip - set irq chip for an IRQ
+ * @irq: Interrupt number
+ * @chip: Pointer to irq_chip structure
+ *
+ * Set the hardware chip structure for an IRQ
+ */
+int set_irq_chip(unsigned int irq, struct irq_chip *chip)
+{
+ irq_desc_t *desc;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->chip = chip;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(set_irq_chip);
+
+/**
+ * set_irq_chip_data - set irq chip data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to chip specific data
+ *
+ * Set the hardware irq chip data for an irq
+ */
+int set_irq_chip_data(unsigned int irq, void *data)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned long flags;
+
+ if (irq >= NR_IRQS || !desc->handler || !desc->chip) {
+ printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->chip->chip_data = data;
+ spin_unlock_irqrestore(&desc->lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(set_irq_chip_data);
+
+/*
+ * set_hwirq_type - Set the irq type (level/edge/simple/percpu)
+ * @irq: Interrupt number
+ * @hw_type: interrupt type (see constants in include/linux/irq.h)
+ *
+ * Called from device drivers to configure GPIO interrupts
+ * according to their requirements. The set_type function of the
+ * handler returns a pointer to an irq_type structure which is
+ * able to handle this interrupt type. The handler in the irq
+ * descriptor structure is set to the new handler type.
+ *
+ */
+int set_hwirq_type(unsigned int irq, unsigned int hw_type)
+{
+ struct irq_type *type = NULL;
+ unsigned long flags;
+ irq_desc_t *desc;
+
+ if (irq >= NR_IRQS) {
+ printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
+ return -ENODEV;
+ }
+
+ desc = irq_desc + irq;
+ spin_lock_irqsave(&desc->lock, flags);
+ if (desc->handler->set_type) {
+ type = desc->handler->set_type(irq, hw_type);
+ if (type)
+ desc->handler = type;
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return type ? -ENXIO : 0;
+}
+
+EXPORT_SYMBOL(set_hwirq_type);
+
Index: linux-2.6.14-rc3/kernel/irq/resend.c
===================================================================
--- /dev/null
+++ linux-2.6.14-rc3/kernel/irq/resend.c
@@ -0,0 +1,82 @@
+/*
+ * linux/kernel/irq/resend.c
+ *
+ * Copyright (C) 1992, 1998-2005 Linus Torvalds, Ingo Molnar
+ * Copyright (C) 2005, Thomas Gleixner
+ *
+ * This file contains the tasklet-based IRQ-resend code
+ */
+
+#include
+#include
+#include
+#include
+
+#include "internals.h"
+
+/* Bitmap to handle software resend of interrupts: */
+static DECLARE_BITMAP(irqs_resend, NR_IRQS);
+
+/*
+ * Run software resends of IRQ's
+ */
+static void resend_irqs(unsigned long arg)
+{
+ unsigned long flags;
+ int irq;
+
+ for (;;) {
+ if (bitmap_empty(irqs_resend, NR_IRQS))
+ break;
+ irq = find_first_bit(irqs_resend, NR_IRQS);
+ clear_bit(irq, irqs_resend);
+ local_irq_save(flags);
+ desc_handle_irq(irq, (irq_desc + irq), NULL);
+ local_irq_restore(flags);
+ }
+}
+
+/* Tasklet to handle resend: */
+static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
+
+/*
+ * Handle irq resend
+ *
+ * If the interrupt is waiting to be processed, try to re-run it. We
+ * can't directly run it from here since the caller might be in an
+ * interrupt-protected region. Not all irq controller chips can
+ * retrigger interrupts at hardware level. For edge type interrupts it
+ * is necessary to resend them by software. At the moment the pending
+ * list is handled at the end of asm_do_IRQ. That means the next
+ * interrupt (on any irq line) will invoke the do_pending function. It
+ * could also be done by a thread which is woken up by the
+ * check_irq_resend function.
+ *
+ * Is called with interrupts disabled and desc->lock held
+ */
+void check_irq_resend(irq_desc_t *desc, unsigned int irq)
+{
+
+ /* Chipless implementation. This should vanish in the long run */
+ if (!desc->chip) {
+ unsigned int status = desc->status;
+ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+ desc->status = status | IRQ_REPLAY;
+ hw_resend_irq(desc->handler, irq);
+ }
+ return;
+ }
+
+ /* Chip based implementation */
+ if ((desc->status & IRQ_PENDING) && !test_bit(irq, irqs_resend)) {
+ desc->status &= ~IRQ_PENDING;
+ /* Try to retrigger it in hardware */
+ if (!desc->chip || !desc->chip->retrigger ||
+ desc->chip->retrigger(irq)) {
+ /* Mark it pending */
+ set_bit(irq, irqs_resend);
+ tasklet_schedule(&resend_tasklet);
+ }
+ }
+}
+
Index: linux-2.6.14-rc3/include/linux/irq.h
===================================================================
--- linux-2.6.14-rc3.orig/include/linux/irq.h
+++ linux-2.6.14-rc3/include/linux/irq.h
@@ -1,14 +1,6 @@
#ifndef __irq_h
#define __irq_h
-/*
- * Please do not include this file in generic code. There is currently
- * no requirement for any architecture to implement anything held
- * within this file.
- *
- * Thanks. --rmk
- */
-
#include
#if !defined(CONFIG_ARCH_S390)
@@ -39,48 +31,141 @@
# define CHECK_IRQ_PER_CPU(var) 0
#endif
+#define IRQ_NOPROBE 512 /* IRQ is not valid for probing */
+#define IRQ_NOREQUEST 1024 /* IRQ cannot be requested */
+
/*
- * Interrupt controller descriptor. This is all we need
- * to describe about the low-level hardware.
+ * IRQ types
+ */
+#define IRQ_TYPE_NONE 0x0000 /* Default, unspecified type */
+#define IRQ_TYPE_EDGEL 0x0001 /* Edge low/falling type */
+#define IRQ_TYPE_EDGEH 0x0002 /* Edge high/rising type */
+#define IRQ_TYPE_EDGEB \
+ (IRQ_TYPE_EDGEL | IRQ_TYPE_EDGEH) /* Edge low+high/both type */
+#define IRQ_TYPE_LEVELL 0x0004 /* Level low type */
+#define IRQ_TYPE_LEVELH 0x0008 /* Level high type */
+#define IRQ_TYPE_SIMPLE 0x0010 /* Simple type */
+
+
+/*
+ * IRQ wakeup control modes
+ */
+#define IRQ_WAKE_NORESUME 0x0000 /* Do not resume on this irq */
+#define IRQ_WAKE_RESUME 0x0001 /* Enable resume on this irq */
+
+/**
+ * struct irq_chip - Low level interrupt controller hardware descriptor
+ *
+ * @ack: acknowledge IRQ
+ * @mask: mask the IRQ
+ * @mask_ack: acknowledge and mask the IRQ
+ * @unmask: unmask the IRQ
+ * @retrigger: retrigger the IRQ in hardware, if possible. Return 0 on success.
+ * @set_type: set the IRQ type (level, edge[high,low,both])
+ * @set_wake: Set the IRQ PM-wakeup function
+ * @options: option field to store type, wake information
+ * @lock: locking for SMP
+ * @chip_data: platform-specific private data for the chip
+ */
+struct irq_chip {
+ spinlock_t lock;
+ void (*ack)(unsigned int irq);
+ void (*mask)(unsigned int irq);
+ void (*mask_ack)(unsigned int irq);
+ void (*unmask)(unsigned int irq);
+ int (*retrigger)(unsigned int irq);
+ int (*set_type)(unsigned int irq, unsigned int hw_type);
+ int (*set_wake)(unsigned int irq, unsigned int mode);
+ unsigned long options;
+ void *chip_data;
+};
+
+struct irq_desc;
+struct irq_type;
+
+/**
+ * struct irq_type - high level hardware interrupt type descriptor
+ *
+ * @typename: name for /proc/interrupts
+ * @startup: start up the interrupt (defaults to ->enable if NULL)
+ * @shutdown: shut down the interrupt (defaults to ->disable if NULL)
+ * @enable: enable the interrupt (defaults to chip->unmask if NULL)
+ * @disable: disable the interrupt (defaults to chip->mask if NULL)
+ * @handle_irq: irq flow handler called from the arch IRQ glue code
+ * @ack: start of new interrupt. (Note: This will be renamed to 'start')
+ * @hold: same interrupt while the handler is running
+ * @end: end of interrupt
+ * @set_affinity: set the CPU affinity on SMP machines
+ * @set_type: set the interrupt type (level, edge[high,low,both]),
+ * returns a pointer to the irq_type structure which can
+ * handle the requested type or NULL, if the type cannot
+ * be handled.
*/
-struct hw_interrupt_type {
- const char * typename;
- unsigned int (*startup)(unsigned int irq);
- void (*shutdown)(unsigned int irq);
- void (*enable)(unsigned int irq);
- void (*disable)(unsigned int irq);
- void (*ack)(unsigned int irq);
- void (*end)(unsigned int irq);
- void (*set_affinity)(unsigned int irq, cpumask_t dest);
+struct irq_type {
+ const char *typename;
+ unsigned int (*startup)(unsigned int irq);
+ void (*shutdown)(unsigned int irq);
+ void (*enable)(unsigned int irq);
+ void (*disable)(unsigned int irq);
+
+ void (*handle_irq)(unsigned int irq, struct irq_desc *desc,
+ struct pt_regs *regs);
+
+ /* (*start) Will be renamed */
+ void (*ack)(unsigned int irq);
+ void (*hold)(unsigned int irq);
+ void (*end)(unsigned int irq);
+ void (*set_affinity)(unsigned int irq, cpumask_t dest);
+ struct irq_type *(*set_type)(unsigned int irq, unsigned int type);
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
void (*release)(unsigned int irq, void *dev_id);
#endif
};
-typedef struct hw_interrupt_type hw_irq_controller;
-
-/*
- * This is the "IRQ descriptor", which contains various information
- * about the irq, including what kind of hardware handling it has,
- * whether it is disabled etc etc.
+/**
+ * struct irq_desc - interrupt descriptor
+ *
+ * @handler: interrupt type dependent handler functions,
+ * (this should be renamed to 'type')
+ * @handler_data: data for the type handlers
+ * @chip: low level hardware access functions - comes from type
+ * @action: the irq action chain
+ * @status: status information
+ * @depth: disable-depth, for nested irq_disable() calls
+ * @irq_count: stats field to detect stalled irqs
+ * @irqs_unhandled: stats field for spurious unhandled interrupts
+ * @lock: locking for SMP
+ * @move_irq: Flag need to re-target interrupt destination
*
* Pad this out to 32 bytes for cache and indexing reasons.
*/
typedef struct irq_desc {
- hw_irq_controller *handler;
- void *handler_data;
- struct irqaction *action; /* IRQ action list */
- unsigned int status; /* IRQ status */
- unsigned int depth; /* nested irq disables */
- unsigned int irq_count; /* For detecting broken interrupts */
- unsigned int irqs_unhandled;
- spinlock_t lock;
+ struct irq_type *handler;
+ void *handler_data;
+ struct irq_chip *chip;
+ struct irqaction *action;
+ unsigned int status;
+
+ unsigned int depth;
+ unsigned int irq_count;
+ unsigned int irqs_unhandled;
+ spinlock_t lock;
#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
- unsigned int move_irq; /* Flag need to re-target intr dest*/
+ unsigned int move_irq;
#endif
} ____cacheline_aligned irq_desc_t;
+
+/*
+ * Migration helpers for obsolete names, they will go away:
+ */
+#define irqdesc irq_desc
+#define irqchip irq_chip
+#define hw_interrupt_type irq_type
+#define set_irq_type set_hwirq_type
+typedef struct irq_type hw_irq_controller;
+
extern irq_desc_t irq_desc [NR_IRQS];
/* Return a pointer to the irq descriptor for IRQ. */
@@ -210,16 +295,73 @@ static inline void set_irq_info(int irq,
#endif // CONFIG_SMP
extern int no_irq_affinity;
-extern int noirqdebug_setup(char *str);
+/* Handle irq action chains */
extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
- struct irqaction *action);
+ struct irqaction *action);
+
+/*
+ * Built-in IRQ handlers for various IRQ types,
+ * callable via desc->handler->handle_irq()
+ */
+extern void handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
+extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
+extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
+extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
+extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
+
+#define desc_handle_irq(irq, desc, regs) \
+do { \
+ spin_lock(&(desc)->lock); \
+ (desc)->handler->handle_irq(irq, (desc), regs); \
+ spin_unlock(&(desc)->lock); \
+} while(0)
+
+/* Monolithic do_IRQ implementation */
extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
+
+/* Handling of unhandled and spurious interrupts */
extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
int action_ret, struct pt_regs *regs);
-extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+/* Resending of interrupts */
+void check_irq_resend(irq_desc_t *desc, unsigned int irq);
+
+/* Proc filesystem */
extern void init_irq_proc(void);
+
+/* Enable/disable irq debugging output */
+extern int noirqdebug_setup(char *str);
+
+/* Set/get irq type */
+extern int set_irq_type(unsigned int irq, unsigned int type);
+extern int get_irq_type(unsigned int irq, unsigned int type);
+
+/* Irq wakeup (PM) control) */
+extern int set_irq_wake(unsigned int irq, unsigned int mode);
+#define enable_irq_wake(irq) set_irq_wake(irq, IRQ_WAKE_RESUME)
+#define disable_irq_wake(irq) set_irq_wake(irq, IRQ_WAKE_NORESUME)
+
+/* Checks whether the interrupt can be requested by request_irq() */
+extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+
+/* Set type control/chip/data for an interrupt */
+extern int generic_set_irq_type(unsigned int irq, struct irq_type *type);
+extern int set_irq_data(unsigned int irq, void *data);
+extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
+extern int set_irq_chip_data(unsigned int irq, void *data);
+
+/* Get chip/data for an interrupt */
+#define get_irq_chip(irq) (irq_desc[irq].chip)
+#define get_irq_chip_data(irq) (irq_desc[irq].chip->chip_data)
+
+/* Interrupt type default implementations */
+extern struct irq_type no_irq_type;
+extern struct irq_type default_edge_type;
+extern struct irq_type default_level_type;
+extern struct irq_type default_simple_type;
+extern struct irq_type default_percpu_type;
+
#endif
extern hw_irq_controller no_irq_type; /* needed in every arch ? */
Index: linux-2.6.14-rc3/arch/arm/Kconfig
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/Kconfig
+++ linux-2.6.14-rc3/arch/arm/Kconfig
@@ -50,6 +50,10 @@ config UID16
bool
default y
+config GENERIC_HARDIRQS
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
default y
Index: linux-2.6.14-rc3/arch/arm/kernel/fiq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/kernel/fiq.c
+++ linux-2.6.14-rc3/arch/arm/kernel/fiq.c
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/kernel/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/kernel/irq.c
+++ linux-2.6.14-rc3/arch/arm/kernel/irq.c
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -38,193 +39,11 @@
#include
#include
-#include
#include
-#include
#include
-/*
- * Maximum IRQ count. Currently, this is arbitary. However, it should
- * not be set too low to prevent false triggering. Conversely, if it
- * is set too high, then you could miss a stuck IRQ.
- *
- * Maybe we ought to set a timer and re-enable the IRQ at a later time?
- */
-#define MAX_IRQ_CNT 100000
-
-static int noirqdebug;
-static volatile unsigned long irq_err_count;
-static DEFINE_SPINLOCK(irq_controller_lock);
-static LIST_HEAD(irq_pending);
-
-struct irqdesc irq_desc[NR_IRQS];
void (*init_arch_irq)(void) __initdata = NULL;
-/*
- * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
- */
-#ifndef irq_finish
-#define irq_finish(irq) do { } while (0)
-#endif
-
-/*
- * Dummy mask/unmask handler
- */
-void dummy_mask_unmask_irq(unsigned int irq)
-{
-}
-
-irqreturn_t no_action(int irq, void *dev_id, struct pt_regs *regs)
-{
- return IRQ_NONE;
-}
-
-void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- irq_err_count += 1;
- printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
-}
-
-static struct irqchip bad_chip = {
- .ack = dummy_mask_unmask_irq,
- .mask = dummy_mask_unmask_irq,
- .unmask = dummy_mask_unmask_irq,
-};
-
-static struct irqdesc bad_irq_desc = {
- .chip = &bad_chip,
- .handle = do_bad_IRQ,
- .pend = LIST_HEAD_INIT(bad_irq_desc.pend),
- .disable_depth = 1,
-};
-
-#ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
-
- while (desc->running)
- barrier();
-}
-EXPORT_SYMBOL(synchronize_irq);
-
-#define smp_set_running(desc) do { desc->running = 1; } while (0)
-#define smp_clear_running(desc) do { desc->running = 0; } while (0)
-#else
-#define smp_set_running(desc) do { } while (0)
-#define smp_clear_running(desc) do { } while (0)
-#endif
-
-/**
- * disable_irq_nosync - disable an irq without waiting
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Enables and disables
- * are nested. We do this lazily.
- *
- * This function may be called from IRQ context.
- */
-void disable_irq_nosync(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- desc->disable_depth++;
- list_del_init(&desc->pend);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(disable_irq_nosync);
-
-/**
- * disable_irq - disable an irq and wait for completion
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Enables and disables
- * are nested. This functions waits for any pending IRQ
- * handlers for this interrupt to complete before returning.
- * If you use this function while holding a resource the IRQ
- * handler may need you will deadlock.
- *
- * This function may be called - with care - from IRQ context.
- */
-void disable_irq(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
-
- disable_irq_nosync(irq);
- if (desc->action)
- synchronize_irq(irq);
-}
-EXPORT_SYMBOL(disable_irq);
-
-/**
- * enable_irq - enable interrupt handling on an irq
- * @irq: Interrupt to enable
- *
- * Re-enables the processing of interrupts on this IRQ line.
- * Note that this may call the interrupt handler, so you may
- * get unexpected results if you hold IRQs disabled.
- *
- * This function may be called from IRQ context.
- */
-void enable_irq(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (unlikely(!desc->disable_depth)) {
- printk("enable_irq(%u) unbalanced from %p\n", irq,
- __builtin_return_address(0));
- } else if (!--desc->disable_depth) {
- desc->probing = 0;
- desc->chip->unmask(irq);
-
- /*
- * If the interrupt is waiting to be processed,
- * try to re-run it. We can't directly run it
- * from here since the caller might be in an
- * interrupt-protected region.
- */
- if (desc->pending && list_empty(&desc->pend)) {
- desc->pending = 0;
- if (!desc->chip->retrigger ||
- desc->chip->retrigger(irq))
- list_add(&desc->pend, &irq_pending);
- }
- }
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(enable_irq);
-
-/*
- * Enable wake on selected irq
- */
-void enable_irq_wake(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (desc->chip->set_wake)
- desc->chip->set_wake(irq, 1);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(enable_irq_wake);
-
-void disable_irq_wake(unsigned int irq)
-{
- struct irqdesc *desc = irq_desc + irq;
- unsigned long flags;
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (desc->chip->set_wake)
- desc->chip->set_wake(irq, 0);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-EXPORT_SYMBOL(disable_irq_wake);
-
int show_interrupts(struct seq_file *p, void *v)
{
int i = *(loff_t *) v, cpu;
@@ -243,7 +62,7 @@ int show_interrupts(struct seq_file *p,
}
if (i < NR_IRQS) {
- spin_lock_irqsave(&irq_controller_lock, flags);
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
if (!action)
goto unlock;
@@ -257,7 +76,7 @@ int show_interrupts(struct seq_file *p,
seq_putc(p, '\n');
unlock:
- spin_unlock_irqrestore(&irq_controller_lock, flags);
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
#ifdef CONFIG_ARCH_ACORN
show_fiq_list(p, v);
@@ -265,270 +84,21 @@ unlock:
#ifdef CONFIG_SMP
show_ipi_list(p);
#endif
+#ifdef FIXME_TGLX
seq_printf(p, "Err: %10lu\n", irq_err_count);
- }
- return 0;
-}
-
-/*
- * IRQ lock detection.
- *
- * Hopefully, this should get us out of a few locked situations.
- * However, it may take a while for this to happen, since we need
- * a large number if IRQs to appear in the same jiffie with the
- * same instruction pointer (or within 2 instructions).
- */
-static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
-{
- unsigned long instr_ptr = instruction_pointer(regs);
-
- if (desc->lck_jif == jiffies &&
- desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) {
- desc->lck_cnt += 1;
-
- if (desc->lck_cnt > MAX_IRQ_CNT) {
- printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
- return 1;
- }
- } else {
- desc->lck_cnt = 0;
- desc->lck_pc = instruction_pointer(regs);
- desc->lck_jif = jiffies;
- }
- return 0;
-}
-
-static void
-report_bad_irq(unsigned int irq, struct pt_regs *regs, struct irqdesc *desc, int ret)
-{
- static int count = 100;
- struct irqaction *action;
-
- if (!count || noirqdebug)
- return;
-
- count--;
-
- if (ret != IRQ_HANDLED && ret != IRQ_NONE) {
- printk("irq%u: bogus retval mask %x\n", irq, ret);
- } else {
- printk("irq%u: nobody cared\n", irq);
- }
- show_regs(regs);
- dump_stack();
- printk(KERN_ERR "handlers:");
- action = desc->action;
- do {
- printk("\n" KERN_ERR "[<%p>]", action->handler);
- print_symbol(" (%s)", (unsigned long)action->handler);
- action = action->next;
- } while (action);
- printk("\n");
-}
-
-static int
-__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
-{
- unsigned int status;
- int ret, retval = 0;
-
- spin_unlock(&irq_controller_lock);
-
-#ifdef CONFIG_NO_IDLE_HZ
- if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
- write_seqlock(&xtime_lock);
- if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
- system_timer->dyn_tick->handler(irq, 0, regs);
- write_sequnlock(&xtime_lock);
- }
#endif
-
- if (!(action->flags & SA_INTERRUPT))
- local_irq_enable();
-
- status = 0;
- do {
- ret = action->handler(irq, action->dev_id, regs);
- if (ret == IRQ_HANDLED)
- status |= action->flags;
- retval |= ret;
- action = action->next;
- } while (action);
-
- if (status & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
-
- spin_lock_irq(&irq_controller_lock);
-
- return retval;
-}
-
-/*
- * This is for software-decoded IRQs. The caller is expected to
- * handle the ack, clear, mask and unmask issues.
- */
-void
-do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- struct irqaction *action;
- const unsigned int cpu = smp_processor_id();
-
- desc->triggered = 1;
-
- kstat_cpu(cpu).irqs[irq]++;
-
- smp_set_running(desc);
-
- action = desc->action;
- if (action) {
- int ret = __do_irq(irq, action, regs);
- if (ret != IRQ_HANDLED)
- report_bad_irq(irq, regs, desc, ret);
- }
-
- smp_clear_running(desc);
-}
-
-/*
- * Most edge-triggered IRQ implementations seem to take a broken
- * approach to this. Hence the complexity.
- */
-void
-do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- const unsigned int cpu = smp_processor_id();
-
- desc->triggered = 1;
-
- /*
- * If we're currently running this IRQ, or its disabled,
- * we shouldn't process the IRQ. Instead, turn on the
- * hardware masks.
- */
- if (unlikely(desc->running || desc->disable_depth))
- goto running;
-
- /*
- * Acknowledge and clear the IRQ, but don't mask it.
- */
- desc->chip->ack(irq);
-
- /*
- * Mark the IRQ currently in progress.
- */
- desc->running = 1;
-
- kstat_cpu(cpu).irqs[irq]++;
-
- do {
- struct irqaction *action;
-
- action = desc->action;
- if (!action)
- break;
-
- if (desc->pending && !desc->disable_depth) {
- desc->pending = 0;
- desc->chip->unmask(irq);
- }
-
- __do_irq(irq, action, regs);
- } while (desc->pending && !desc->disable_depth);
-
- desc->running = 0;
-
- /*
- * If we were disabled or freed, shut down the handler.
- */
- if (likely(desc->action && !check_irq_lock(desc, irq, regs)))
- return;
-
- running:
- /*
- * We got another IRQ while this one was masked or
- * currently running. Delay it.
- */
- desc->pending = 1;
- desc->chip->mask(irq);
- desc->chip->ack(irq);
-}
-
-/*
- * Level-based IRQ handler. Nice and simple.
- */
-void
-do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- struct irqaction *action;
- const unsigned int cpu = smp_processor_id();
-
- desc->triggered = 1;
-
- /*
- * Acknowledge, clear _AND_ disable the interrupt.
- */
- desc->chip->ack(irq);
-
- if (likely(!desc->disable_depth)) {
- kstat_cpu(cpu).irqs[irq]++;
-
- smp_set_running(desc);
-
- /*
- * Return with this interrupt masked if no action
- */
- action = desc->action;
- if (action) {
- int ret = __do_irq(irq, desc->action, regs);
-
- if (ret != IRQ_HANDLED)
- report_bad_irq(irq, regs, desc, ret);
-
- if (likely(!desc->disable_depth &&
- !check_irq_lock(desc, irq, regs)))
- desc->chip->unmask(irq);
- }
-
- smp_clear_running(desc);
}
+ return 0;
}
-static void do_pending_irqs(struct pt_regs *regs)
-{
- struct list_head head, *l, *n;
-
- do {
- struct irqdesc *desc;
-
- /*
- * First, take the pending interrupts off the list.
- * The act of calling the handlers may add some IRQs
- * back onto the list.
- */
- head = irq_pending;
- INIT_LIST_HEAD(&irq_pending);
- head.next->prev = &head;
- head.prev->next = &head;
-
- /*
- * Now run each entry. We must delete it from our
- * list before calling the handler.
- */
- list_for_each_safe(l, n, &head) {
- desc = list_entry(l, struct irqdesc, pend);
- list_del_init(&desc->pend);
- desc_handle_irq(desc - irq_desc, desc, regs);
- }
-
- /*
- * The list must be empty.
- */
- BUG_ON(!list_empty(&head));
- } while (!list_empty(&irq_pending));
-}
+/* Handle bad interrupts */
+static struct irq_desc bad_irq = {
+ .handler = &no_irq_type,
+ .lock = SPIN_LOCK_UNLOCKED
+};
/*
- * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
+ * asm_do_IRQ handles all hardware IRQ's. Decoded IRQs should not
* come via this function. Instead, they should provide their
* own 'handler'
*/
@@ -541,98 +111,54 @@ asmlinkage void asm_do_IRQ(unsigned int
* than crashing, do something sensible.
*/
if (irq >= NR_IRQS)
- desc = &bad_irq_desc;
+ desc = &bad_irq;
irq_enter();
- spin_lock(&irq_controller_lock);
- desc_handle_irq(irq, desc, regs);
- /*
- * Now re-run any pending interrupts.
- */
- if (!list_empty(&irq_pending))
- do_pending_irqs(regs);
-
- irq_finish(irq);
+ desc_handle_irq(irq, desc, regs);
- spin_unlock(&irq_controller_lock);
irq_exit();
}
-void __set_irq_handler(unsigned int irq, irq_handler_t handle, int is_chained)
+void __set_irq_handler(unsigned int irq, struct irq_type *type, int is_chained)
{
struct irqdesc *desc;
unsigned long flags;
if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
+ printk(KERN_ERR "Trying to install type control for IRQ%d\n", irq);
return;
}
- if (handle == NULL)
- handle = do_bad_IRQ;
-
desc = irq_desc + irq;
- if (is_chained && desc->chip == &bad_chip)
- printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (handle == do_bad_IRQ) {
- desc->chip->mask(irq);
- desc->chip->ack(irq);
- desc->disable_depth = 1;
- }
- desc->handle = handle;
- if (handle != do_bad_IRQ && is_chained) {
- desc->valid = 0;
- desc->probe_ok = 0;
- desc->disable_depth = 0;
- desc->chip->unmask(irq);
+ /* Uninstall ? */
+ if (type == NULL || type == &no_irq_type) {
+ spin_lock_irqsave(&desc->lock, flags);
+ if (desc->chip) {
+ desc->chip->mask(irq);
+ desc->chip->ack(irq);
+ }
+ desc->depth = 1;
+ spin_unlock_irqrestore(&desc->lock, flags);
}
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-void set_irq_chip(unsigned int irq, struct irqchip *chip)
-{
- struct irqdesc *desc;
- unsigned long flags;
-
- if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
+ /* Install the irq_type */
+ if (generic_set_irq_type(irq, type))
return;
- }
-
- if (chip == NULL)
- chip = &bad_chip;
-
- desc = irq_desc + irq;
- spin_lock_irqsave(&irq_controller_lock, flags);
- desc->chip = chip;
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-int set_irq_type(unsigned int irq, unsigned int type)
-{
- struct irqdesc *desc;
- unsigned long flags;
- int ret = -ENXIO;
+ spin_lock_irqsave(&desc->lock, flags);
+ if (is_chained && (desc->handler == &no_irq_type || !desc->chip))
+ printk(KERN_WARNING "Trying to install chained interrupt type for IRQ%d\n", irq);
- if (irq >= NR_IRQS) {
- printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
- return -ENODEV;
- }
-
- desc = irq_desc + irq;
- if (desc->chip->set_type) {
- spin_lock_irqsave(&irq_controller_lock, flags);
- ret = desc->chip->set_type(irq, type);
- spin_unlock_irqrestore(&irq_controller_lock, flags);
+ if (type != NULL && is_chained) {
+ desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+ desc->depth = 0;
+ if (desc->chip)
+ desc->chip->unmask(irq);
}
-
- return ret;
+ spin_unlock_irqrestore(&desc->lock, flags);
}
-EXPORT_SYMBOL(set_irq_type);
void set_irq_flags(unsigned int irq, unsigned int iflags)
{
@@ -645,408 +171,28 @@ void set_irq_flags(unsigned int irq, uns
}
desc = irq_desc + irq;
- spin_lock_irqsave(&irq_controller_lock, flags);
- desc->valid = (iflags & IRQF_VALID) != 0;
- desc->probe_ok = (iflags & IRQF_PROBE) != 0;
- desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-}
-
-int setup_irq(unsigned int irq, struct irqaction *new)
-{
- int shared = 0;
- struct irqaction *old, **p;
- unsigned long flags;
- struct irqdesc *desc;
-
- /*
- * Some drivers like serial.c use request_irq() heavily,
- * so we have to be careful not to interfere with a
- * running system.
- */
- if (new->flags & SA_SAMPLE_RANDOM) {
- /*
- * This function might sleep, we want to call it first,
- * outside of the atomic block.
- * Yes, this might clear the entropy pool if the wrong
- * driver is attempted to be loaded, without actually
- * installing a new handler, but is this really a problem,
- * only the sysadmin is able to do this.
- */
- rand_initialize_irq(irq);
- }
-
- /*
- * The following block of code has to be executed atomically
- */
- desc = irq_desc + irq;
- spin_lock_irqsave(&irq_controller_lock, flags);
- p = &desc->action;
- if ((old = *p) != NULL) {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & new->flags & SA_SHIRQ)) {
- spin_unlock_irqrestore(&irq_controller_lock, flags);
- return -EBUSY;
- }
-
- /* add new interrupt at end of irq queue */
- do {
- p = &old->next;
- old = *p;
- } while (old);
- shared = 1;
- }
-
- *p = new;
-
- if (!shared) {
- desc->probing = 0;
- desc->running = 0;
- desc->pending = 0;
- desc->disable_depth = 1;
- if (!desc->noautoenable) {
- desc->disable_depth = 0;
- desc->chip->unmask(irq);
- }
- }
-
- spin_unlock_irqrestore(&irq_controller_lock, flags);
- return 0;
-}
-
-/**
- * request_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs
- * @irqflags: Interrupt type flags
- * @devname: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. From the point this
- * call is made your handler function may be invoked. Since
- * your handler function must clear any interrupt the board
- * raises, you must take care both to initialise your hardware
- * and to set up the interrupt handler in the right order.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
- *
- * If your interrupt is shared you must pass a non NULL dev_id
- * as this is required when freeing the interrupt.
- *
- * Flags:
- *
- * SA_SHIRQ Interrupt is shared
- *
- * SA_INTERRUPT Disable local interrupts while processing
- *
- * SA_SAMPLE_RANDOM The interrupt can be used for entropy
- *
- */
-int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irq_flags, const char * devname, void *dev_id)
-{
- unsigned long retval;
- struct irqaction *action;
-
- if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
- (irq_flags & SA_SHIRQ && !dev_id))
- return -EINVAL;
-
- action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
- if (!action)
- return -ENOMEM;
-
- action->handler = handler;
- action->flags = irq_flags;
- cpus_clear(action->mask);
- action->name = devname;
- action->next = NULL;
- action->dev_id = dev_id;
-
- retval = setup_irq(irq, action);
-
- if (retval)
- kfree(action);
- return retval;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-/**
- * free_irq - free an interrupt
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
- *
- * Remove an interrupt handler. The handler is removed and if the
- * interrupt line is no longer in use by any driver it is disabled.
- * On a shared IRQ the caller must ensure the interrupt is disabled
- * on the card it drives before calling this function.
- *
- * This function must not be called from interrupt context.
- */
-void free_irq(unsigned int irq, void *dev_id)
-{
- struct irqaction * action, **p;
- unsigned long flags;
-
- if (irq >= NR_IRQS || !irq_desc[irq].valid) {
- printk(KERN_ERR "Trying to free IRQ%d\n",irq);
- dump_stack();
- return;
- }
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
- if (action->dev_id != dev_id)
- continue;
-
- /* Found it - now free it */
- *p = action->next;
- break;
- }
- spin_unlock_irqrestore(&irq_controller_lock, flags);
-
- if (!action) {
- printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
- dump_stack();
- } else {
- synchronize_irq(irq);
- kfree(action);
- }
-}
-
-EXPORT_SYMBOL(free_irq);
-
-static DECLARE_MUTEX(probe_sem);
-
-/* Start the interrupt probing. Unlike other architectures,
- * we don't return a mask of interrupts from probe_irq_on,
- * but return the number of interrupts enabled for the probe.
- * The interrupts which have been enabled for probing is
- * instead recorded in the irq_desc structure.
- */
-unsigned long probe_irq_on(void)
-{
- unsigned int i, irqs = 0;
- unsigned long delay;
-
- down(&probe_sem);
-
- /*
- * first snaffle up any unassigned but
- * probe-able interrupts
- */
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
- if (!irq_desc[i].probe_ok || irq_desc[i].action)
- continue;
-
- irq_desc[i].probing = 1;
- irq_desc[i].triggered = 0;
- if (irq_desc[i].chip->set_type)
- irq_desc[i].chip->set_type(i, IRQT_PROBE);
- irq_desc[i].chip->unmask(i);
- irqs += 1;
- }
- spin_unlock_irq(&irq_controller_lock);
-
- /*
- * wait for spurious interrupts to mask themselves out again
- */
- for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
- /* min 100ms delay */;
-
- /*
- * now filter out any obviously spurious interrupts
- */
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
- if (irq_desc[i].probing && irq_desc[i].triggered) {
- irq_desc[i].probing = 0;
- irqs -= 1;
- }
- }
- spin_unlock_irq(&irq_controller_lock);
-
- return irqs;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-unsigned int probe_irq_mask(unsigned long irqs)
-{
- unsigned int mask = 0, i;
-
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < 16 && i < NR_IRQS; i++)
- if (irq_desc[i].probing && irq_desc[i].triggered)
- mask |= 1 << i;
- spin_unlock_irq(&irq_controller_lock);
-
- up(&probe_sem);
-
- return mask;
-}
-EXPORT_SYMBOL(probe_irq_mask);
-
-/*
- * Possible return values:
- * >= 0 - interrupt number
- * -1 - no interrupt/many interrupts
- */
-int probe_irq_off(unsigned long irqs)
-{
- unsigned int i;
- int irq_found = NO_IRQ;
-
- /*
- * look at the interrupts, and find exactly one
- * that we were probing has been triggered
- */
- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
- if (irq_desc[i].probing &&
- irq_desc[i].triggered) {
- if (irq_found != NO_IRQ) {
- irq_found = NO_IRQ;
- goto out;
- }
- irq_found = i;
- }
- }
-
- if (irq_found == -1)
- irq_found = NO_IRQ;
-out:
- spin_unlock_irq(&irq_controller_lock);
-
- up(&probe_sem);
-
- return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-#ifdef CONFIG_SMP
-static void route_irq(struct irqdesc *desc, unsigned int irq, unsigned int cpu)
-{
- pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu);
-
- spin_lock_irq(&irq_controller_lock);
- desc->cpu = cpu;
- desc->chip->set_cpu(desc, irq, cpu);
- spin_unlock_irq(&irq_controller_lock);
-}
-
-#ifdef CONFIG_PROC_FS
-static int
-irq_affinity_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- struct irqdesc *desc = irq_desc + ((int)data);
- int len = cpumask_scnprintf(page, count, desc->affinity);
-
- if (count - len < 2)
- return -EINVAL;
- page[len++] = '\n';
- page[len] = '\0';
-
- return len;
-}
-
-static int
-irq_affinity_write_proc(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- unsigned int irq = (unsigned int)data;
- struct irqdesc *desc = irq_desc + irq;
- cpumask_t affinity, tmp;
- int ret = -EIO;
-
- if (!desc->chip->set_cpu)
- goto out;
-
- ret = cpumask_parse(buffer, count, affinity);
- if (ret)
- goto out;
-
- cpus_and(tmp, affinity, cpu_online_map);
- if (cpus_empty(tmp)) {
- ret = -EINVAL;
- goto out;
- }
-
- desc->affinity = affinity;
- route_irq(desc, irq, first_cpu(tmp));
- ret = count;
-
- out:
- return ret;
-}
-#endif
-#endif
-
-void __init init_irq_proc(void)
-{
-#if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS)
- struct proc_dir_entry *dir;
- int irq;
-
- dir = proc_mkdir("irq", 0);
- if (!dir)
- return;
-
- for (irq = 0; irq < NR_IRQS; irq++) {
- struct proc_dir_entry *entry;
- struct irqdesc *desc;
- char name[16];
-
- desc = irq_desc + irq;
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name) - 1, "%u", irq);
-
- desc->procdir = proc_mkdir(name, dir);
- if (!desc->procdir)
- continue;
-
- entry = create_proc_entry("smp_affinity", 0600, desc->procdir);
- if (entry) {
- entry->nlink = 1;
- entry->data = (void *)irq;
- entry->read_proc = irq_affinity_read_proc;
- entry->write_proc = irq_affinity_write_proc;
- }
- }
-#endif
+ spin_lock_irqsave(&desc->lock, flags);
+ desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+ if (iflags & IRQF_VALID)
+ desc->status &= ~IRQ_NOREQUEST;
+ if (iflags & IRQF_PROBE)
+ desc->status &= ~IRQ_NOPROBE;
+ spin_unlock_irqrestore(&desc->lock, flags);
}
void __init init_IRQ(void)
{
- struct irqdesc *desc;
extern void init_dma(void);
int irq;
+ for (irq = 0; irq < NR_IRQS; irq++)
+ irq_desc[irq].status |= IRQ_NOREQUEST;
+
#ifdef CONFIG_SMP
bad_irq_desc.affinity = CPU_MASK_ALL;
bad_irq_desc.cpu = smp_processor_id();
#endif
- for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
- *desc = bad_irq_desc;
- INIT_LIST_HEAD(&desc->pend);
- }
-
init_arch_irq();
init_dma();
}
-
-static int __init noirqdebug_setup(char *str)
-{
- noirqdebug = 1;
- return 1;
-}
-
-__setup("noirqdebug", noirqdebug_setup);
Index: linux-2.6.14-rc3/include/asm-arm/hw_irq.h
===================================================================
--- /dev/null
+++ linux-2.6.14-rc3/include/asm-arm/hw_irq.h
@@ -0,0 +1,9 @@
+/*
+ * Nothing to see here yet
+ */
+#ifndef _ARCH_ARM_HW_IRQ_H
+#define _ARCH_ARM_HW_IRQ_H
+
+#include
+
+#endif
Index: linux-2.6.14-rc3/include/asm-arm/irq.h
===================================================================
--- linux-2.6.14-rc3.orig/include/asm-arm/irq.h
+++ linux-2.6.14-rc3/include/asm-arm/irq.h
@@ -19,16 +19,10 @@
#define NO_IRQ ((unsigned int)(-1))
#endif
-struct irqaction;
-
-extern void disable_irq_nosync(unsigned int);
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-#define __IRQT_FALEDGE (1 << 0)
-#define __IRQT_RISEDGE (1 << 1)
-#define __IRQT_LOWLVL (1 << 2)
-#define __IRQT_HIGHLVL (1 << 3)
+#define __IRQT_FALEDGE IRQ_TYPE_EDGEL
+#define __IRQT_RISEDGE IRQ_TYPE_EDGEH
+#define __IRQT_LOWLVL IRQ_TYPE_LEVELL
+#define __IRQT_HIGHLVL IRQ_TYPE_LEVELH
#define IRQT_NOEDGE (0)
#define IRQT_RISING (__IRQT_RISEDGE)
@@ -36,16 +30,9 @@ extern void enable_irq(unsigned int);
#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
#define IRQT_LOW (__IRQT_LOWLVL)
#define IRQT_HIGH (__IRQT_HIGHLVL)
-#define IRQT_PROBE (1 << 4)
-
-int set_irq_type(unsigned int irq, unsigned int type);
-void disable_irq_wake(unsigned int irq);
-void enable_irq_wake(unsigned int irq);
-int setup_irq(unsigned int, struct irqaction *);
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
+/* FIXME_TGLX */
+#define IRQT_PROBE (1 << 7)
#endif
Index: linux-2.6.14-rc3/include/asm-arm/mach/irq.h
===================================================================
--- linux-2.6.14-rc3.orig/include/asm-arm/mach/irq.h
+++ linux-2.6.14-rc3/include/asm-arm/mach/irq.h
@@ -10,94 +10,9 @@
#ifndef __ASM_ARM_MACH_IRQ_H
#define __ASM_ARM_MACH_IRQ_H
-struct irqdesc;
-struct pt_regs;
-struct seq_file;
-
-typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
-typedef void (*irq_control_t)(unsigned int);
+#include
-struct irqchip {
- /*
- * Acknowledge the IRQ.
- * If this is a level-based IRQ, then it is expected to mask the IRQ
- * as well.
- */
- void (*ack)(unsigned int);
- /*
- * Mask the IRQ in hardware.
- */
- void (*mask)(unsigned int);
- /*
- * Unmask the IRQ in hardware.
- */
- void (*unmask)(unsigned int);
- /*
- * Ask the hardware to re-trigger the IRQ.
- * Note: This method _must_ _not_ call the interrupt handler.
- * If you are unable to retrigger the interrupt, do not
- * provide a function, or if you do, return non-zero.
- */
- int (*retrigger)(unsigned int);
- /*
- * Set the type of the IRQ.
- */
- int (*set_type)(unsigned int, unsigned int);
- /*
- * Set wakeup-enable on the selected IRQ
- */
- int (*set_wake)(unsigned int, unsigned int);
-
-#ifdef CONFIG_SMP
- /*
- * Route an interrupt to a CPU
- */
- void (*set_cpu)(struct irqdesc *desc, unsigned int irq, unsigned int cpu);
-#endif
-};
-
-struct irqdesc {
- irq_handler_t handle;
- struct irqchip *chip;
- struct irqaction *action;
- struct list_head pend;
- void *chipdata;
- void *data;
- unsigned int disable_depth;
-
- unsigned int triggered: 1; /* IRQ has occurred */
- unsigned int running : 1; /* IRQ is running */
- unsigned int pending : 1; /* IRQ is pending */
- unsigned int probing : 1; /* IRQ in use for a probe */
- unsigned int probe_ok : 1; /* IRQ can be used for probe */
- unsigned int valid : 1; /* IRQ claimable */
- unsigned int noautoenable : 1; /* don't automatically enable IRQ */
- unsigned int unused :25;
-
- struct proc_dir_entry *procdir;
-
-#ifdef CONFIG_SMP
- cpumask_t affinity;
- unsigned int cpu;
-#endif
-
- /*
- * IRQ lock detection
- */
- unsigned int lck_cnt;
- unsigned int lck_pc;
- unsigned int lck_jif;
-};
-
-extern struct irqdesc irq_desc[];
-
-/*
- * Helpful inline function for calling irq descriptor handlers.
- */
-static inline void desc_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
- desc->handle(irq, desc, regs);
-}
+struct seq_file;
/*
* This is internal. Do not use it.
@@ -105,31 +20,52 @@ static inline void desc_handle_irq(unsig
extern void (*init_arch_irq)(void);
extern void init_FIQ(void);
extern int show_fiq_list(struct seq_file *, void *);
-void __set_irq_handler(unsigned int irq, irq_handler_t, int);
+void __set_irq_handler(unsigned int irq, struct irq_type *, int);
/*
* External stuff.
*/
#define set_irq_handler(irq,handler) __set_irq_handler(irq,handler,0)
-#define set_irq_chained_handler(irq,handler) __set_irq_handler(irq,handler,1)
-#define set_irq_data(irq,d) do { irq_desc[irq].data = d; } while (0)
-#define set_irq_chipdata(irq,d) do { irq_desc[irq].chipdata = d; } while (0)
-#define get_irq_chipdata(irq) (irq_desc[irq].chipdata)
-void set_irq_chip(unsigned int irq, struct irqchip *);
+
+#define set_irq_chipdata(irq,d) set_irq_chip_data(irq, d)
+#define get_irq_chipdata(irq) get_irq_chip_data(irq)
+
void set_irq_flags(unsigned int irq, unsigned int flags);
#define IRQF_VALID (1 << 0)
#define IRQF_PROBE (1 << 1)
#define IRQF_NOAUTOEN (1 << 2)
+/* ARM uses the retrigger functions in desc->chip or software retrigger */
+static inline void hw_resend_irq(struct irq_type *t, unsigned int i) {}
+
/*
- * Built-in IRQ handlers.
+ * Hack alert. This is for easy migration, but should be changed in the source
*/
-void do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs);
-void dummy_mask_unmask_irq(unsigned int irq);
+#define do_level_IRQ (&default_level_type)
+#define do_edge_IRQ (&default_edge_type)
+#define do_simple_IRQ (&default_simple_type)
+
+/* Hack to get around set_irq_chained_handler(nr,NULL) problem */
+#define irq_NULL_type no_irq_type
+#define set_irq_chained_handler(irq,handler) \
+ __set_irq_handler(irq,&irq_##handler##_type,1)
+
+#define DEFINE_IRQ_CHAINED_TYPE(function) \
+struct irq_type irq_##function##_type = { \
+ .typename = #function"-chained_type", \
+ .handle_irq = function, \
+}
+
+#define do_bad_IRQ(irq,desc,regs) \
+do { \
+ spin_lock(&desc->lock); \
+ handle_bad_irq(irq, desc, regs); \
+ spin_unlock(&desc->lock); \
+} while(0)
+
+/* FIXME */
+#define ack_bad_irq(irq) do {} while (0)
#endif
Index: linux-2.6.14-rc3/include/asm-arm/dyntick.h
===================================================================
--- /dev/null
+++ linux-2.6.14-rc3/include/asm-arm/dyntick.h
@@ -0,0 +1,6 @@
+#ifndef _ASMARM_DYNTICK_H
+#define _ASMARM_DYNTICK_H
+
+#include
+
+#endif /* _ASMARM_DYNTICK_H */
Index: linux-2.6.14-rc3/arch/arm/common/locomo.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/common/locomo.c
+++ linux-2.6.14-rc3/arch/arm/common/locomo.c
@@ -425,6 +425,12 @@ static struct irqchip locomo_spi_chip =
.unmask = locomo_spi_unmask_irq,
};
+static DEFINE_IRQ_CHAINED_TYPE(locomo_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_key_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_gpio_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_lt_handler);
+static DEFINE_IRQ_CHAINED_TYPE(locomo_spi_handler);
+
static void locomo_setup_irq(struct locomo *lchip)
{
int irq;
Index: linux-2.6.14-rc3/arch/arm/common/sa1111.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/common/sa1111.c
+++ linux-2.6.14-rc3/arch/arm/common/sa1111.c
@@ -159,11 +159,11 @@ sa1111_irq_handler(unsigned int irq, str
for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
if (stat0 & 1)
- do_edge_IRQ(i, irq_desc + i, regs);
+ handle_edge_irq(i, irq_desc + i, regs);
for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1)
- do_edge_IRQ(i, irq_desc + i, regs);
+ handle_edge_irq(i, irq_desc + i, regs);
/* For level-based interrupts */
desc->chip->unmask(irq);
@@ -368,6 +368,8 @@ static struct irqchip sa1111_high_chip =
.set_wake = sa1111_wake_highirq,
};
+static DEFINE_IRQ_CHAINED_TYPE(sa1111_irq_handler);
+
static void sa1111_setup_irq(struct sa1111 *sachip)
{
void __iomem *irqbase = sachip->base + SA1111_INTC;
Index: linux-2.6.14-rc3/arch/arm/common/time-acorn.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/common/time-acorn.c
+++ linux-2.6.14-rc3/arch/arm/common/time-acorn.c
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/kernel/ecard.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/kernel/ecard.c
+++ linux-2.6.14-rc3/arch/arm/kernel/ecard.c
@@ -619,7 +619,7 @@ ecard_irqexp_handler(unsigned int irq, s
ecard_t *ec = slot_to_ecard(slot);
if (ec->claimed) {
- struct irqdesc *d = irqdesc + ec->irq;
+ struct irqdesc *d = irq_desc + ec->irq;
/*
* this ugly code is so that we can operate a
* prioritorising system:
@@ -1052,6 +1052,9 @@ ecard_probe(int slot, card_type_t type)
return rc;
}
+static DEFINE_IRQ_CHAINED_TYPE(ecard_irqexp_handler);
+static DEFINE_IRQ_CHAINED_TYPE(ecard_irq_handler);
+
/*
* Initialise the expansion card system.
* Locate all hardware - interrupt management and
@@ -1081,8 +1084,10 @@ static int __init ecard_init(void)
irqhw = ecard_probeirqhw();
- set_irq_chained_handler(IRQ_EXPANSIONCARD,
- irqhw ? ecard_irqexp_handler : ecard_irq_handler);
+ if (irqhw)
+ set_irq_chained_handler(IRQ_EXPANSIONCARD, ecard_irqexp_handler);
+ else
+ set_irq_chained_handler(IRQ_EXPANSIONCARD, ecard_irq_handler);
ecard_proc_init();
Index: linux-2.6.14-rc3/arch/arm/mach-clps711x/time.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-clps711x/time.c
+++ linux-2.6.14-rc3/arch/arm/mach-clps711x/time.c
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-clps7500/core.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-clps7500/core.c
+++ linux-2.6.14-rc3/arch/arm/mach-clps7500/core.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-footbridge/dc21285-timer.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-footbridge/dc21285-timer.c
+++ linux-2.6.14-rc3/arch/arm/mach-footbridge/dc21285-timer.c
@@ -6,6 +6,7 @@
*/
#include
#include
+#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-footbridge/isa-irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-footbridge/isa-irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-footbridge/isa-irq.c
@@ -102,6 +102,17 @@ static struct irqaction irq_cascade = {
static struct resource pic1_resource = { "pic1", 0x20, 0x3f };
static struct resource pic2_resource = { "pic2", 0xa0, 0xbf };
+static DEFINE_IRQ_CHAINED_TYPE(isa_irq_handler);
+
+static unsigned int startup_irq_disabled(unsigned int irq)
+{
+ return 0;
+}
+
+/* Interrupt type for irqs which must not be
+ * automatically enabled in reqeust_irq */
+static struct irq_type level_type_nostart;
+
void __init isa_init_irq(unsigned int host_irq)
{
unsigned int irq;
@@ -159,9 +170,11 @@ void __init isa_init_irq(unsigned int ho
* There appears to be a missing pull-up
* resistor on this line.
*/
- if (machine_is_netwinder())
- set_irq_flags(_ISA_IRQ(11), IRQF_VALID |
- IRQF_PROBE | IRQF_NOAUTOEN);
+ if (machine_is_netwinder()) {
+ level_type_nostart = default_level_type;
+ level_type_nostart.startup = startup_irq_disabled;
+ set_irq_handler(_ISA_IRQ(11), &level_type_nostart);
+ }
}
}
Index: linux-2.6.14-rc3/arch/arm/mach-footbridge/isa-timer.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-footbridge/isa-timer.c
+++ linux-2.6.14-rc3/arch/arm/mach-footbridge/isa-timer.c
@@ -6,6 +6,7 @@
*/
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-h720x/common.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-h720x/common.c
+++ linux-2.6.14-rc3/arch/arm/mach-h720x/common.c
@@ -163,6 +163,11 @@ h720x_gpiod_demux_handler(unsigned int i
h720x_gpio_handler(mask, irq, desc, regs);
}
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpioa_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpiob_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpioc_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpiod_demux_handler);
+
#ifdef CONFIG_CPU_H7202
static void
h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
@@ -175,6 +180,7 @@ h720x_gpioe_demux_handler(unsigned int i
IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
h720x_gpio_handler(mask, irq, desc, regs);
}
+static DEFINE_IRQ_CHAINED_TYPE(h720x_gpioe_demux_handler);
#endif
static struct irqchip h720x_global_chip = {
Index: linux-2.6.14-rc3/arch/arm/mach-h720x/cpu-h7202.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-h720x/cpu-h7202.c
+++ linux-2.6.14-rc3/arch/arm/mach-h720x/cpu-h7202.c
@@ -175,6 +175,8 @@ static struct irqaction h7202_timer_irq
.handler = h7202_timer_interrupt,
};
+static DEFINE_IRQ_CHAINED_TYPE(h7202_timerx_demux_handler);
+
/*
* Setup TIMER0 as system timer
*/
Index: linux-2.6.14-rc3/arch/arm/mach-imx/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-imx/irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-imx/irq.c
@@ -217,6 +217,11 @@ static struct irqchip imx_gpio_chip = {
.set_type = imx_gpio_irq_type,
};
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpioa_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpiob_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpioc_demux_handler);
+static DEFINE_IRQ_CHAINED_TYPE(imx_gpiod_demux_handler);
+
void __init
imx_init_irq(void)
{
Index: linux-2.6.14-rc3/arch/arm/mach-imx/time.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-imx/time.c
+++ linux-2.6.14-rc3/arch/arm/mach-imx/time.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-integrator/core.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-integrator/core.c
+++ linux-2.6.14-rc3/arch/arm/mach-integrator/core.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-ixp2000/core.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-ixp2000/core.c
+++ linux-2.6.14-rc3/arch/arm/mach-ixp2000/core.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -288,7 +289,7 @@ void gpio_line_config(int line, int dire
local_irq_save(flags);
if (direction == GPIO_OUT) {
- irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0;
+ set_irq_flags(line + IRQ_IXP2000_GPIO0, 0);
/* if it's an output, it ain't an interrupt anymore */
GPIO_IRQ_falling_edge &= ~(1 << line);
@@ -354,8 +355,7 @@ static int ixp2000_GPIO_irq_type(unsigne
/*
* Finally, mark the corresponding IRQ as valid.
*/
- irq_desc[irq].valid = 1;
-
+ set_irq_flags(irq, IRQF_VALID);
return 0;
}
@@ -425,6 +425,8 @@ static struct irqchip ixp2000_irq_chip =
.unmask = ixp2000_irq_unmask
};
+static DEFINE_IRQ_CHAINED_TYPE(ixp2000_GPIO_irq_handler);
+
void __init ixp2000_init_irq(void)
{
int irq;
Index: linux-2.6.14-rc3/arch/arm/mach-ixp2000/ixdp2x00.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-ixp2000/ixdp2x00.c
+++ linux-2.6.14-rc3/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -146,6 +146,8 @@ static struct irqchip ixdp2x00_cpld_irq_
.unmask = ixdp2x00_irq_unmask
};
+static DEFINE_IRQ_CHAINED_TYPE(ixdp2x00_irq_handler);
+
void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
{
unsigned int irq;
@@ -168,7 +170,7 @@ void ixdp2x00_init_irq(volatile unsigned
}
/* Hook into PCI interrupt */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x00_irq_handler);
+ set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
}
/*************************************************************************
Index: linux-2.6.14-rc3/arch/arm/mach-ixp2000/ixdp2x01.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-ixp2000/ixdp2x01.c
+++ linux-2.6.14-rc3/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -95,6 +95,8 @@ static struct irqchip ixdp2x01_irq_chip
.unmask = ixdp2x01_irq_unmask
};
+static DEFINE_IRQ_CHAINED_TYPE(ixdp2x01_irq_handler);
+
/*
* We only do anything if we are the master NPU on the board.
* The slave NPU only has the ethernet chip going directly to
@@ -127,7 +129,7 @@ void __init ixdp2x01_init_irq(void)
}
/* Hook into PCI interrupts */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x01_irq_handler);
+ set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
}
Index: linux-2.6.14-rc3/arch/arm/mach-l7200/core.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-l7200/core.c
+++ linux-2.6.14-rc3/arch/arm/mach-l7200/core.c
@@ -7,6 +7,7 @@
*/
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-lh7a40x/arch-kev7a400.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ linux-2.6.14-rc3/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -72,6 +72,8 @@ static void kev7a400_cpld_handler (unsig
}
}
+static DEFINE_IRQ_CHAINED_TYPE(kev7a400_cpld_handler);
+
void __init lh7a40x_init_board_irq (void)
{
int irq;
Index: linux-2.6.14-rc3/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ linux-2.6.14-rc3/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -173,6 +174,7 @@ static void lpd7a40x_cpld_handler (unsig
desc->chip->unmask (irq); /* Level-triggered need this */
}
+static DEFINE_IRQ_CHAINED_TYPE(lpd7a40x_cpld_handler);
void __init lh7a40x_init_board_irq (void)
{
Index: linux-2.6.14-rc3/arch/arm/mach-lh7a40x/irq-kev7a400.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-lh7a40x/irq-kev7a400.c
+++ linux-2.6.14-rc3/arch/arm/mach-lh7a40x/irq-kev7a400.c
@@ -60,6 +60,8 @@ lh7a400_cpld_handler (unsigned int irq,
}
}
+static DEFINE_IRQ_CHAINED_TYPE(kev7a400_cpld_handler);
+
/* IRQ initialization */
void __init
Index: linux-2.6.14-rc3/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ linux-2.6.14-rc3/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -71,6 +71,7 @@ static void lh7a40x_cpld_handler (unsign
desc->chip->unmask (irq); /* Level-triggered need this */
}
+static DEFINE_IRQ_CHAINED_TYPE(lh7a40x_cpld_handler);
/* IRQ initialization */
Index: linux-2.6.14-rc3/arch/arm/mach-lh7a40x/time.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-lh7a40x/time.c
+++ linux-2.6.14-rc3/arch/arm/mach-lh7a40x/time.c
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-omap1/fpga.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-omap1/fpga.c
+++ linux-2.6.14-rc3/arch/arm/mach-omap1/fpga.c
@@ -120,6 +120,8 @@ static struct irqchip omap_fpga_irq = {
.unmask = fpga_unmask_irq,
};
+static DEFINE_IRQ_CHAINED_TYPE(innovator_fpga_IRQ_demux);
+
/*
* All of the FPGA interrupt request inputs except for the touchscreen are
* edge-sensitive; the touchscreen is level-sensitive. The edge-sensitive
Index: linux-2.6.14-rc3/arch/arm/mach-pxa/idp.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-pxa/idp.c
+++ linux-2.6.14-rc3/arch/arm/mach-pxa/idp.c
@@ -18,6 +18,7 @@
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-pxa/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-pxa/irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-pxa/irq.c
@@ -244,6 +244,7 @@ static struct irqchip pxa_muxed_gpio_chi
.set_type = pxa_gpio_irq_type,
};
+static DEFINE_IRQ_CHAINED_TYPE(pxa_gpio_demux_handler);
void __init pxa_init_irq(void)
{
Index: linux-2.6.14-rc3/arch/arm/mach-pxa/lubbock.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-pxa/lubbock.c
+++ linux-2.6.14-rc3/arch/arm/mach-pxa/lubbock.c
@@ -90,6 +90,8 @@ static void lubbock_irq_handler(unsigned
} while (pending);
}
+static DEFINE_IRQ_CHAINED_TYPE(lubbock_irq_handler);
+
static void __init lubbock_init_irq(void)
{
int irq;
Index: linux-2.6.14-rc3/arch/arm/mach-pxa/mainstone.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-pxa/mainstone.c
+++ linux-2.6.14-rc3/arch/arm/mach-pxa/mainstone.c
@@ -78,6 +78,8 @@ static void mainstone_irq_handler(unsign
} while (pending);
}
+static DEFINE_IRQ_CHAINED_TYPE(mainstone_irq_handler);
+
static void __init mainstone_init_irq(void)
{
int irq;
Index: linux-2.6.14-rc3/arch/arm/mach-rpc/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-rpc/irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-rpc/irq.c
@@ -112,6 +112,15 @@ static struct irqchip iomd_fiq_chip = {
.unmask = iomd_unmask_irq_fiq,
};
+static unsigned int startup_irq_disabled(unsigned int irq)
+{
+ return 0;
+}
+
+/* Interrupt type for irqs which must not be
+ * automatically enabled in reqeust_irq */
+static struct irq_type level_type_nostart;
+
void __init rpc_init_irq(void)
{
unsigned int irq, flags;
@@ -121,16 +130,15 @@ void __init rpc_init_irq(void)
iomd_writeb(0, IOMD_FIQMASK);
iomd_writeb(0, IOMD_DMAMASK);
+ level_type_nostart = default_level_type;
+ level_type_nostart.startup = startup_irq_disabled;
+
for (irq = 0; irq < NR_IRQS; irq++) {
flags = IRQF_VALID;
if (irq <= 6 || (irq >= 9 && irq <= 15))
flags |= IRQF_PROBE;
- if (irq == 21 || (irq >= 16 && irq <= 19) ||
- irq == IRQ_KEYBOARDTX)
- flags |= IRQF_NOAUTOEN;
-
switch (irq) {
case 0 ... 7:
set_irq_chip(irq, &iomd_a_chip);
@@ -155,6 +163,10 @@ void __init rpc_init_irq(void)
set_irq_flags(irq, IRQF_VALID);
break;
}
+
+ if (irq == 21 || (irq >= 16 && irq <= 19) ||
+ irq == IRQ_KEYBOARDTX)
+ set_irq_handler(irq, &level_type_nostart);
}
init_FIQ();
Index: linux-2.6.14-rc3/arch/arm/mach-s3c2410/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-s3c2410/irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-s3c2410/irq.c
@@ -573,6 +573,11 @@ s3c_irq_demux_uart2(unsigned int irq,
}
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_uart0);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_uart1);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_uart2);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_adc);
+
/* s3c24xx_init_irq
*
* Initialise S3C2410 IRQ system
Index: linux-2.6.14-rc3/arch/arm/mach-s3c2410/s3c2440-irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -157,6 +157,9 @@ static struct irqchip s3c_irq_cam = {
.ack = s3c_irq_cam_ack,
};
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_wdtac97);
+static DEFINE_IRQ_CHAINED_TYPE(s3c_irq_demux_cam);
+
static int s3c2440_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
Index: linux-2.6.14-rc3/arch/arm/mach-s3c2410/time.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-s3c2410/time.c
+++ linux-2.6.14-rc3/arch/arm/mach-s3c2410/time.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-sa1100/cerf.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-sa1100/cerf.c
+++ linux-2.6.14-rc3/arch/arm/mach-sa1100/cerf.c
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-sa1100/h3600.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-sa1100/h3600.c
+++ linux-2.6.14-rc3/arch/arm/mach-sa1100/h3600.c
@@ -788,6 +788,8 @@ static void h3800_unmask_gpio_irq(unsign
H3800_ASIC2_GPIINTSTAT |= mask;
}
+static DEFINE_IRQ_CHAINED_TYPE(h3800_IRQ_demux);
+
static void __init h3800_init_irq(void)
{
int i;
@@ -826,7 +828,7 @@ static void __init h3800_init_irq(void)
}
#endif
set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING);
- set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, &h3800_IRQ_demux);
+ set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
}
Index: linux-2.6.14-rc3/arch/arm/mach-sa1100/irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-sa1100/irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-sa1100/irq.c
@@ -11,12 +11,13 @@
*/
#include
#include
+#include
+#include
#include
#include
#include
#include
-#include
#include
#include "generic.h"
@@ -281,6 +282,8 @@ static int __init sa1100irq_init_devicef
return sysdev_register(&sa1100irq_device);
}
+static DEFINE_IRQ_CHAINED_TYPE(sa1100_high_gpio_handler);
+
device_initcall(sa1100irq_init_devicefs);
void __init sa1100_init_irq(void)
Index: linux-2.6.14-rc3/arch/arm/mach-sa1100/neponset.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-sa1100/neponset.c
+++ linux-2.6.14-rc3/arch/arm/mach-sa1100/neponset.c
@@ -137,6 +137,8 @@ static struct sa1100_port_fns neponset_p
.get_mctrl = neponset_get_mctrl,
};
+static DEFINE_IRQ_CHAINED_TYPE(neponset_irq_handler);
+
static int neponset_probe(struct device *dev)
{
sa1100_register_uart_fns(&neponset_port_fns);
Index: linux-2.6.14-rc3/arch/arm/mach-sa1100/pleb.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-sa1100/pleb.c
+++ linux-2.6.14-rc3/arch/arm/mach-sa1100/pleb.c
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-sa1100/time.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-sa1100/time.c
+++ linux-2.6.14-rc3/arch/arm/mach-sa1100/time.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-shark/core.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-shark/core.c
+++ linux-2.6.14-rc3/arch/arm/mach-shark/core.c
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-versatile/core.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-versatile/core.c
+++ linux-2.6.14-rc3/arch/arm/mach-versatile/core.c
@@ -112,6 +112,8 @@ sic_handle_irq(unsigned int irq, struct
} while (status);
}
+static DEFINE_IRQ_CHAINED_TYPE(sic_handle_irq);
+
#if 1
#define IRQ_MMCI0A IRQ_VICSOURCE22
#define IRQ_AACI IRQ_VICSOURCE24
@@ -161,7 +163,7 @@ void __init versatile_init_irq(void)
}
}
- set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
+ set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
vic_unmask_irq(IRQ_VICSOURCE31);
/* Do second interrupt controller */
Index: linux-2.6.14-rc3/arch/arm/plat-omap/gpio.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/plat-omap/gpio.c
+++ linux-2.6.14-rc3/arch/arm/plat-omap/gpio.c
@@ -837,6 +837,8 @@ static struct irqchip mpuio_irq_chip = {
.unmask = mpuio_unmask_irq
};
+static DEFINE_IRQ_CHAINED_TYPE(gpio_irq_handler);
+
static int initialized = 0;
static struct clk * gpio_ck = NULL;
Index: linux-2.6.14-rc3/arch/arm/mach-s3c2410/bast-irq.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-s3c2410/bast-irq.c
+++ linux-2.6.14-rc3/arch/arm/mach-s3c2410/bast-irq.c
@@ -136,13 +136,15 @@ bast_irq_pc104_demux(unsigned int irq,
for (i = 0; stat != 0; i++, stat >>= 1) {
if (stat & 1) {
irqno = bast_pc104_irqs[i];
-
- desc_handle_irq(irqno, irq_desc + irqno, regs);
+ desc = irq_desc + irqno;
+ desc_handle_irq(irqno, desc, regs);
}
}
}
}
+DEFINE_IRQ_CHAINED_TYPE(bast_irq_pc104_demux);
+
static __init int bast_irq_init(void)
{
unsigned int i;
@@ -156,7 +158,7 @@ static __init int bast_irq_init(void)
set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
- /* reigster our IRQs */
+ /* register our IRQs */
for (i = 0; i < 4; i++) {
unsigned int irqno = bast_pc104_irqs[i];
Index: linux-2.6.14-rc3/arch/arm/mach-ixp4xx/ixdp425-pci.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ linux-2.6.14-rc3/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -16,6 +16,7 @@
#include
#include
+#include
#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-ixp4xx/coyote-pci.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-ixp4xx/coyote-pci.c
+++ linux-2.6.14-rc3/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/arch/arm/mach-omap1/serial.c
===================================================================
--- linux-2.6.14-rc3.orig/arch/arm/mach-omap1/serial.c
+++ linux-2.6.14-rc3/arch/arm/mach-omap1/serial.c
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: linux-2.6.14-rc3/drivers/char/s3c2410-rtc.c
===================================================================
--- linux-2.6.14-rc3.orig/drivers/char/s3c2410-rtc.c
+++ linux-2.6.14-rc3/drivers/char/s3c2410-rtc.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/drivers/i2c/chips/tps65010.c
===================================================================
--- linux-2.6.14-rc3.orig/drivers/i2c/chips/tps65010.c
+++ linux-2.6.14-rc3/drivers/i2c/chips/tps65010.c
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -33,7 +34,6 @@
#include
#include
-#include
#include
#include
Index: linux-2.6.14-rc3/drivers/input/serio/sa1111ps2.c
===================================================================
--- linux-2.6.14-rc3.orig/drivers/input/serio/sa1111ps2.c
+++ linux-2.6.14-rc3/drivers/input/serio/sa1111ps2.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
#include
Index: linux-2.6.14-rc3/drivers/net/smc91x.c
===================================================================
--- linux-2.6.14-rc3.orig/drivers/net/smc91x.c
+++ linux-2.6.14-rc3/drivers/net/smc91x.c
@@ -74,6 +74,7 @@ static const char version[] =
#include
#include
#include
+#include
#include
#include
#include
@@ -1998,7 +1999,7 @@ static int __init smc_probe(struct net_d
if (retval)
goto err_out;
- set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
+ SMC_SET_IRQ_TYPE(dev->irq, SMC_IRQ_TRIGGER_TYPE);
#ifdef SMC_USE_PXA_DMA
{
Index: linux-2.6.14-rc3/drivers/net/smc91x.h
===================================================================
--- linux-2.6.14-rc3.orig/drivers/net/smc91x.h
+++ linux-2.6.14-rc3/drivers/net/smc91x.h
@@ -90,7 +90,7 @@
__l--; \
} \
} while (0)
-#define set_irq_type(irq, type)
+#define SMC_SET_IRQ_TYPE(irq, type)
#elif defined(CONFIG_SA1100_PLEB)
/* We can only do 16-bit reads and writes in the static memory space. */
@@ -109,7 +109,7 @@
#define SMC_outw(v, a, r) outw(v, (a) + (r))
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
-#define set_irq_type(irq, type) do {} while (0)
+#define SMC_SET_IRQ_TYPE(irq, type) do {} while (0)
#elif defined(CONFIG_SA1100_ASSABET)
@@ -209,7 +209,7 @@ SMC_outw(u16 val, void __iomem *ioaddr,
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
-#define set_irq_type(irq, type) do {} while(0)
+#define SMC_SET_IRQ_TYPE(irq, type) do {} while(0)
#elif defined(CONFIG_ISA)
@@ -237,7 +237,7 @@ SMC_outw(u16 val, void __iomem *ioaddr,
#define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l)
-#define set_irq_type(irq, type) do {} while(0)
+#define SMC_SET_IRQ_TYPE(irq, type) do {} while(0)
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
@@ -310,6 +310,10 @@ static inline void SMC_outsw (unsigned l
#endif
+#ifndef SMC_SET_IRQ_TYPE
+#define SMC_SET_IRQ_TYPE set_irq_type
+#endif
+
#ifndef SMC_IRQ_TRIGGER_TYPE
#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING
#endif
Index: linux-2.6.14-rc3/drivers/pcmcia/soc_common.c
===================================================================
--- linux-2.6.14-rc3.orig/drivers/pcmcia/soc_common.c
+++ linux-2.6.14-rc3/drivers/pcmcia/soc_common.c
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
Index: linux-2.6.14-rc3/Makefile
===================================================================
--- linux-2.6.14-rc3.orig/Makefile
+++ linux-2.6.14-rc3/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 14
-EXTRAVERSION =-rc3
+EXTRAVERSION =-rc3-armirq1
NAME=Affluent Albatross
# *DOCUMENTATION*