diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-12 08:33:23 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-12 08:33:23 -0700 |
commit | 9eb200748878751310cd9848c5dd4d467960beec (patch) | |
tree | 16458876279abbc597843a7c1bb8216474691380 | |
parent | 8770c018da7bbaa3b41371abc401b2aa7e76a71a (diff) | |
parent | 8ae91b9ad88a130cd50fc0b78b16e7b9510b8067 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6:
sh: SH-4A UBC support
sh: interrupt exception handling rework
sh: Default enable R7780RP IRQs.
sh: Zero-out coherent buffer in consistent_alloc().
sh: Convert IPR-IRQ to IRQ chip.
sh: Convert INTC2 IRQ handler to irq_chip.
sh: Fix pr_debug statements for sh4
sh: Convert r7780rp IRQ handler to IRQ chip.
sh: Updates for IRQ handler changes.
sh: Kill off timer_ops get_frequency().
sh: First step at generic timeofday support.
32 files changed, 249 insertions, 1100 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index f6a0c443616..6a461d4caef 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -45,6 +45,9 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_IOMAP bool +config GENERIC_TIME + def_bool n + config ARCH_MAY_HAVE_PC_FDC bool @@ -357,6 +360,7 @@ config CPU_HAS_SR_RB endmenu menu "Timer support" +depends on !GENERIC_TIME config SH_TMU bool "TMU timer support" diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c index 75f91aaae07..219179114f0 100644 --- a/arch/sh/boards/hp6xx/hp6xx_apm.c +++ b/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -83,7 +83,7 @@ static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length) return p - buf; } -static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs) +static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev) { if (!apm_suspended) apm_queue_event(APM_USER_SUSPEND); @@ -96,7 +96,7 @@ static int __init hp6x0_apm_init(void) int ret; ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt, - SA_INTERRUPT, MODNAME, 0); + IRQF_DISABLED, MODNAME, 0); if (unlikely(ret < 0)) { printk(KERN_ERR MODNAME ": IRQ %d request failed\n", HP680_BTN_IRQ); diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c index 0b7bee1a9ca..e6252497816 100644 --- a/arch/sh/boards/landisk/landisk_pwb.c +++ b/arch/sh/boards/landisk/landisk_pwb.c @@ -135,7 +135,7 @@ static int swdrv_write(struct file *filp, const char *buff, size_t count, return count; } -static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t sw_interrupt(int irq, void *dev_id) { landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); disable_irq(IRQ_BUTTON); diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c index 01c10fa5c05..7c3d1d30415 100644 --- a/arch/sh/boards/mpc1211/setup.c +++ b/arch/sh/boards/mpc1211/setup.c @@ -69,7 +69,6 @@ static void __init pci_write_config(unsigned long busNo, static unsigned char m_irq_mask = 0xfb; static unsigned char s_irq_mask = 0xff; -volatile unsigned long irq_err_count; static void disable_mpc1211_irq(unsigned int irq) { @@ -118,7 +117,7 @@ static void mask_and_ack_mpc1211(unsigned int irq) if(irq < 8) { if(m_irq_mask & (1<<irq)){ if(!mpc1211_irq_real(irq)){ - irq_err_count++; + atomic_inc(&irq_err_count) printk("spurious 8259A interrupt: IRQ %x\n",irq); } } else { @@ -131,7 +130,7 @@ static void mask_and_ack_mpc1211(unsigned int irq) } else { if(s_irq_mask & (1<<(irq - 8))){ if(!mpc1211_irq_real(irq)){ - irq_err_count++; + atomic_inc(&irq_err_count); printk("spurious 8259A interrupt: IRQ %x\n",irq); } } else { diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c index 2d960e9a314..b544772cbc7 100644 --- a/arch/sh/boards/renesas/r7780rp/irq.c +++ b/arch/sh/boards/renesas/r7780rp/irq.c @@ -1,18 +1,16 @@ /* - * linux/arch/sh/boards/renesas/r7780rp/irq.c - * - * Copyright (C) 2000 Kazumoto Kojima - * * Renesas Solutions Highlander R7780RP-1 Support. * - * Modified for R7780RP-1 by - * Atom Create Engineering Co., Ltd. 2002. + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ #include <linux/init.h> #include <linux/irq.h> #include <asm/io.h> -#include <asm/irq.h> -#include <asm/r7780rp/r7780rp.h> #ifdef CONFIG_SH_R7780MP static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; @@ -20,71 +18,26 @@ static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; #endif -static void enable_r7780rp_irq(unsigned int irq); -static void disable_r7780rp_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_r7780rp_irq disable_r7780rp_irq - -static void ack_r7780rp_irq(unsigned int irq); -static void end_r7780rp_irq(unsigned int irq); - -static unsigned int startup_r7780rp_irq(unsigned int irq) -{ - enable_r7780rp_irq(irq); - return 0; /* never anything pending */ -} - -static void disable_r7780rp_irq(unsigned int irq) -{ - unsigned short val; - unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); - - /* Set the priority in IPR to 0 */ - val = ctrl_inw(IRLCNTR1); - val &= mask; - ctrl_outw(val, IRLCNTR1); -} - static void enable_r7780rp_irq(unsigned int irq) { - unsigned short val; - unsigned short value = (0x0001 << mask_pos[irq]); - /* Set priority in IPR back to original value */ - val = ctrl_inw(IRLCNTR1); - val |= value; - ctrl_outw(val, IRLCNTR1); -} - -static void ack_r7780rp_irq(unsigned int irq) -{ - disable_r7780rp_irq(irq); + ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1); } -static void end_r7780rp_irq(unsigned int irq) +static void disable_r7780rp_irq(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_r7780rp_irq(irq); + /* Set the priority in IPR to 0 */ + ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])), + IRLCNTR1); } -static struct hw_interrupt_type r7780rp_irq_type = { - .typename = "R7780RP-IRQ", - .startup = startup_r7780rp_irq, - .shutdown = shutdown_r7780rp_irq, - .enable = enable_r7780rp_irq, - .disable = disable_r7780rp_irq, - .ack = ack_r7780rp_irq, - .end = end_r7780rp_irq, +static struct irq_chip r7780rp_irq_chip __read_mostly = { + .name = "r7780rp", + .mask = disable_r7780rp_irq, + .unmask = enable_r7780rp_irq, + .mask_ack = disable_r7780rp_irq, }; -static void make_r7780rp_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].chip = &r7780rp_irq_type; - disable_r7780rp_irq(irq); -} - /* * Initialize IRQ setting */ @@ -92,24 +45,10 @@ void __init init_r7780rp_IRQ(void) { int i; - /* IRL0=PCI Slot #A - * IRL1=PCI Slot #B - * IRL2=PCI Slot #C - * IRL3=PCI Slot #D - * IRL4=CF Card - * IRL5=CF Card Insert - * IRL6=M66596 - * IRL7=SD Card - * IRL8=Touch Panel - * IRL9=SCI - * IRL10=Serial - * IRL11=Extention #A - * IRL11=Extention #B - * IRL12=Debug LAN - * IRL13=Push Switch - * IRL14=ZiggBee IO - */ - - for (i=0; i<15; i++) - make_r7780rp_irq(i); + for (i = 0; i < 15; i++) { + disable_irq_nosync(i); + set_irq_chip_and_handler(i, &r7780rp_irq_chip, + handle_level_irq); + enable_r7780rp_irq(i); + } } diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index f5e98c56b53..540d0bf1644 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -33,7 +33,7 @@ extern void pcibios_init(void); * EraseConfig handling functions */ -static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) { volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000; diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c index 38f1e8171a3..4d49b5cbcc1 100644 --- a/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -71,7 +71,7 @@ static struct hw_interrupt_type hd64461_irq_type = { .end = end_hd64461_irq, }; -static irqreturn_t hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t hd64461_interrupt(int irq, void *dev_id) { printk(KERN_INFO "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", diff --git a/arch/sh/cchips/hd6446x/hd64465/gpio.c b/arch/sh/cchips/hd6446x/hd64465/gpio.c index 72320d02d69..43431855ec8 100644 --- a/arch/sh/cchips/hd6446x/hd64465/gpio.c +++ b/arch/sh/cchips/hd6446x/hd64465/gpio.c @@ -85,7 +85,7 @@ static struct { void *dev; } handlers[GPIO_NPORTS * 8]; -static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev, struct pt_regs *regs) +static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev) { unsigned short port, pin, isr, mask, portpin; diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c index 30573d3e196..d126e1f30de 100644 --- a/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -84,7 +84,7 @@ static struct hw_interrupt_type hd64465_irq_type = { }; -static irqreturn_t hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t hd64465_interrupt(int irq, void *dev_id) { printk(KERN_INFO "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 392c8b12ce3..bf1b28feca0 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -88,8 +88,7 @@ static struct hw_interrupt_type voyagergx_irq_type = { .end = end_voyagergx_irq, }; -static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t voyagergx_interrupt(int irq, void *dev_id) { printk(KERN_INFO "VoyagerGX: spurious interrupt, status: 0x%x\n", diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c index 9cb07092418..0caf11bb7e2 100644 --- a/arch/sh/drivers/dma/dma-g2.c +++ b/arch/sh/drivers/dma/dma-g2.c @@ -51,7 +51,7 @@ static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa0 ((g2_dma->channel[i].size - \ g2_dma->status[i].size) & 0x0fffffff) -static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t g2_dma_interrupt(int irq, void *dev_id) { int i; diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index c1b6bc23c10..838fad566ea 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c @@ -21,7 +21,7 @@ static unsigned int xfer_complete; static int count; -static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id) { if (get_dma_residue(PVR2_CASCADE_CHAN)) { printk(KERN_WARNING "DMA: SH DMAC did not complete transfer " diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index cbbe8bce3d6..d8ece20bb2c 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -60,9 +60,9 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan) * Besides that it needs to waken any waiting process, which should handle * setting up the next transfer. */ -static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t dma_tei(int irq, void *dev_id) { - struct dma_channel *chan = (struct dma_channel *)dev_id; + struct dma_channel *chan = dev_id; u32 chcr; chcr = ctrl_inl(CHCR[chan->chan]); @@ -228,7 +228,7 @@ static inline int dmaor_reset(void) } #if defined(CONFIG_CPU_SH4) -static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t dma_err(int irq, void *dummy) { dmaor_reset(); disable_irq(irq); diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index dbe83788498..85e1ee2e2e7 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -155,7 +155,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) */ pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, (64 << 10), - SH4_PCI_IO_BASE + PCIBIOS_MIN_IO); + SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO); /* * XXX: For now, leave this board-specific. In the event we have other @@ -163,7 +163,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) */ #ifdef CONFIG_SH_BIGSUR bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10), - SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); + SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); #endif /* Make sure the MSB's of IO window are set to access PCI space diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c index 4ab5ea6b35f..efecb3d5995 100644 --- a/arch/sh/drivers/pci/pci-st40.c +++ b/arch/sh/drivers/pci/pci-st40.c @@ -161,7 +161,7 @@ static char * pci_commands[16]={ "Memory Write-and-Invalidate" }; -static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t st40_pci_irq(int irq, void *dev_instance) { unsigned pci_int, pci_air, pci_cir, pci_aint; static int count=0; diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index e30e4b7aa70..d4b2bb7e08c 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -10,93 +10,32 @@ * These are the "new Hitachi style" interrupts, as present on the * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. */ - #include <linux/kernel.h> #include <linux/init.h> #include <linux/irq.h> #include <asm/system.h> #include <asm/io.h> -#include <asm/machvec.h> - -struct intc2_data { - unsigned char msk_offset; - unsigned char msk_shift; - - int (*clear_irq) (int); -}; - -static struct intc2_data intc2_data[NR_INTC2_IRQS]; - -static void enable_intc2_irq(unsigned int irq); -static void disable_intc2_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_intc2_irq disable_intc2_irq - -static void mask_and_ack_intc2(unsigned int); -static void end_intc2_irq(unsigned int irq); - -static unsigned int startup_intc2_irq(unsigned int irq) -{ - enable_intc2_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type intc2_irq_type = { - .typename = "INTC2-IRQ", - .startup = startup_intc2_irq, - .shutdown = shutdown_intc2_irq, - .enable = enable_intc2_irq, - .disable = disable_intc2_irq, - .ack = mask_and_ack_intc2, - .end = end_intc2_irq -}; static void disable_intc2_irq(unsigned int irq) { - int irq_offset = irq - INTC2_FIRST_IRQ; - int msk_shift, msk_offset; - - /* Sanity check */ - if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) - return; - - msk_shift = intc2_data[irq_offset].msk_shift; - msk_offset = intc2_data[irq_offset].msk_offset; - - ctrl_outl(1 << msk_shift, - INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset); + struct intc2_data *p = get_irq_chip_data(irq); + ctrl_outl(1 << p->msk_shift, + INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset); } static void enable_intc2_irq(unsigned int irq) { - int irq_offset = irq - INTC2_FIRST_IRQ; - int msk_shift, msk_offset; - - /* Sanity check */ - if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) - return; - - msk_shift = intc2_data[irq_offset].msk_shift; - msk_offset = intc2_data[irq_offset].msk_offset; - - ctrl_outl(1 << msk_shift, - INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset); -} - -static void mask_and_ack_intc2(unsigned int irq) -{ - disable_intc2_irq(irq); + struct intc2_data *p = get_irq_chip_data(irq); + ctrl_outl(1 << p->msk_shift, + INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset); } -static void end_intc2_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_intc2_irq(irq); - - if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)) - intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq); -} +static struct irq_chip intc2_irq_chip = { + .typename = "intc2", + .mask = disable_intc2_irq, + .unmask = enable_intc2_irq, + .mask_ack = disable_intc2_irq, +}; /* * Setup an INTC2 style interrupt. @@ -108,46 +47,30 @@ static void end_intc2_irq(unsigned int irq) * | | | | * make_intc2_irq(84, 0, 16, 0, 13); */ -void make_intc2_irq(unsigned int irq, - unsigned int ipr_offset, unsigned int ipr_shift, - unsigned int msk_offset, unsigned int msk_shift, - unsigned int priority) +void make_intc2_irq(struct intc2_data *p) { - int irq_offset = irq - INTC2_FIRST_IRQ; unsigned int flags; unsigned long ipr; - if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) - return; - - disable_irq_nosync(irq); - - /* Fill the data we need */ - intc2_data[irq_offset].msk_offset = msk_offset; - intc2_data[irq_offset].msk_shift = msk_shift; - intc2_data[irq_offset].clear_irq = NULL; + disable_irq_nosync(p->irq); /* Set the priority level */ local_irq_save(flags); - ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); - ipr &= ~(0xf << ipr_shift); - ipr |= priority << ipr_shift; - ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); + ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset); + ipr &= ~(0xf << p->ipr_shift); + ipr |= p->priority << p->ipr_shift; + ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset); local_irq_restore(flags); - irq_desc[irq].chip = &intc2_irq_type; + set_irq_chip_and_handler(p->irq, &intc2_irq_chip, handle_level_irq); + set_irq_chip_data(p->irq, p); - disable_intc2_irq(irq); + enable_intc2_irq(p->irq); } -static struct intc2_init { - unsigned short irq; - unsigned char ipr_offset, ipr_shift; - unsigned char msk_offset, msk_shift; - unsigned char priority; -} intc2_init_data[] __initdata = { +static struct intc2_data intc2_irq_table[] = { #if defined(CONFIG_CPU_SUBTYPE_ST40) {64, 0, 0, 0, 0, 13}, /* PCI serr */ {65, 0, 4, 0, 1, 13}, /* PCI err */ @@ -266,19 +189,6 @@ void __init init_IRQ_intc2(void) { int i; - for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) { - struct intc2_init *p = intc2_init_data + i; - make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift, - p-> msk_offset, p->msk_shift, p->priority); - } -} - -/* Adds a termination callback to the interrupt */ -void intc2_add_clear_irq(int irq, int (*fn)(int)) -{ - if (unlikely(irq < INTC2_FIRST_IRQ)) - return; - - intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; + for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) + make_intc2_irq(intc2_irq_table + i); } - diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index f785822cd5d..8944abdf6e1 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -1,11 +1,10 @@ /* - * arch/sh/kernel/cpu/irq/ipr.c + * Interrupt handling for IPR-based IRQ. * * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> - * - * Interrupt handling for IPR-based IRQ. + * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> + * Copyright (C) 2006 Paul Mundt * * Supported system: * On-chip supporting modules (TMU, RTC, etc.). @@ -13,12 +12,13 @@ * Hitachi SolutionEngine external I/O: * MS7709SE01, MS7709ASE01, and MS7750SE01 * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ - #include <linux/init.h> #include <linux/irq.h> #include <linux/module.h> - #include <asm/system.h> #include <asm/io.h> #include <asm/machvec.h> @@ -28,93 +28,45 @@ struct ipr_data { int shift; /* Shifts of the 16-bit data */ int priority; /* The priority */ }; -static struct ipr_data ipr_data[NR_IRQS]; - -static void enable_ipr_irq(unsigned int irq); -static void disable_ipr_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_ipr_irq disable_ipr_irq - -static void mask_and_ack_ipr(unsigned int); -static void end_ipr_irq(unsigned int irq); - -static unsigned int startup_ipr_irq(unsigned int irq) -{ - enable_ipr_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type ipr_irq_type = { - .typename = "IPR-IRQ", - .startup = startup_ipr_irq, - .shutdown = shutdown_ipr_irq, - .enable = enable_ipr_irq, - .disable = disable_ipr_irq, - .ack = mask_and_ack_ipr, - .end = end_ipr_irq -}; static void disable_ipr_irq(unsigned int irq) { - unsigned long val; - unsigned int addr = ipr_data[irq].addr; - unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); - + struct ipr_data *p = get_irq_chip_data(irq); /* Set the priority in IPR to 0 */ - val = ctrl_inw(addr); - val &= mask; - ctrl_outw(val, addr); + ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); } static void enable_ipr_irq(unsigned int irq) { - unsigned long val; - unsigned int addr = ipr_data[irq].addr; - int priority = ipr_data[irq].priority; - unsigned short value = (priority << ipr_data[irq].shift); - + struct ipr_data *p = get_irq_chip_data(irq); /* Set priority in IPR back to original value */ - val = ctrl_inw(addr); - val |= value; - ctrl_outw(val, addr); + ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); } -static void mask_and_ack_ipr(unsigned int irq) -{ - disable_ipr_irq(irq); - -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) - /* This is needed when we use edge triggered setting */ - /* XXX: Is it really needed? */ - if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) { - /* Clear external interrupt request */ - int a = ctrl_inb(INTC_IRR0); - a &= ~(1 << (irq - IRQ0_IRQ)); - ctrl_outb(a, INTC_IRR0); - } -#endif -} - -static void end_ipr_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_ipr_irq(irq); -} +static struct irq_chip ipr_irq_chip = { + .name = "ipr", + .mask = disable_ipr_irq, + .unmask = enable_ipr_irq, + .mask_ack = disable_ipr_irq, +}; void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) { + struct ipr_data ipr_data; + disable_irq_nosync(irq); - ipr_data[irq].addr = addr; - ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ - ipr_data[irq].priority = priority; - irq_desc[irq].chip = &ipr_irq_type; - disable_ipr_irq(irq); + ipr_data.addr = addr; + ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */ + ipr_data.priority = priority; + + set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq); + set_irq_chip_data(irq, &ipr_data); + + enable_ipr_irq(irq); } +/* XXX: This needs to die a horrible death.. */ void __init init_IRQ(void) { #ifndef CONFIG_CPU_SUBTYPE_SH7780 diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index 44daf44833f..6be46f0686b 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -49,198 +49,3 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ -ENTRY(interrupt_table) - ! external hardware - .long do_IRQ ! 0000 /* 200 */ - .long do_IRQ ! 0001 - .long do_IRQ ! 0010 - .long do_IRQ ! 0011 - .long do_IRQ ! 0100 - .long do_IRQ ! 0101 - .long do_IRQ ! 0110 - .long do_IRQ ! 0111 - .long do_IRQ ! 1000 /* 300 */ - .long do_IRQ ! 1001 - .long do_IRQ ! 1010 - .long do_IRQ ! 1011 - .long do_IRQ ! 1100 - .long do_IRQ ! 1101 - .long do_IRQ ! 1110 - .long exception_error - ! Internal hardware - .long do_IRQ ! TMU0 tuni0 /* 400 */ - .long do_IRQ ! TMU1 tuni1 - .long do_IRQ ! TMU2 tuni2 - .long do_IRQ ! ticpi2 - .long do_IRQ ! RTC ati - .long do_IRQ ! pri - .long do_IRQ ! cui - .long do_IRQ ! SCI eri - .long do_IRQ ! rxi /* 500 */ - .long do_IRQ ! txi - .long do_IRQ ! tei - .long do_IRQ ! WDT iti /* 560 */ - .long do_IRQ ! REF rcmi - .long do_IRQ ! rovi - .long do_IRQ - .long do_IRQ /* 5E0 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) || \ - defined(CONFIG_CPU_SUBTYPE_SH7710) - .long do_IRQ ! 32 IRQ irq0 /* 600 */ - .long do_IRQ ! 33 irq1 - .long do_IRQ ! 34 irq2 - .long do_IRQ ! 35 irq3 - .long do_IRQ ! 36 irq4 - .long do_IRQ ! 37 irq5 - .long do_IRQ ! 38 - .long do_IRQ ! 39 - .long do_IRQ ! 40 PINT pint0-7 /* 700 */ - .long do_IRQ ! 41 pint8-15 - .long do_IRQ ! 42 - .long do_IRQ ! 43 - .long do_IRQ ! 44 - .long do_IRQ ! 45 - .long do_IRQ ! 46 - .long do_IRQ ! 47 - .long do_IRQ ! 48 DMAC dei0 /* 800 */ - .long do_IRQ ! 49 dei1 - .long do_IRQ ! 50 dei2 - .long do_IRQ ! 51 dei3 - .long do_IRQ ! 52 IrDA eri1 - .long do_IRQ ! 53 rxi1 |