From 3e0ec1954da85d91dd0be309517346dd206ce0e3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Oct 2004 09:01:37 -0700 Subject: [PATCH] [PATCH] sh: ST40 updates This includes some ST40 updates from the ST tree. The most notable change is the ST40GX1 fixes for INTC2-based interrupts. Signed-off-by: Alex Bennee Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/harp/setup.c | 35 +++++++ arch/sh/kernel/cpu/irq_ipr.c | 10 +- arch/sh/kernel/cpu/sh4/irq_intc2.c | 153 +++++++++++++++++++++++------ 3 files changed, 168 insertions(+), 30 deletions(-) diff --git a/arch/sh/boards/harp/setup.c b/arch/sh/boards/harp/setup.c index 0d64b28b0c367..05b01b8f40aa3 100644 --- a/arch/sh/boards/harp/setup.c +++ b/arch/sh/boards/harp/setup.c @@ -54,3 +54,38 @@ int __init platform_setup(void) return 0; } + +/* + * pcibios_map_platform_irq + * + * This is board specific and returns the IRQ for a given PCI device. + * It is used by the PCI code (arch/sh/kernel/st40_pci*) + * + */ + +#define HARP_PCI_IRQ 1 +#define HARP_BRIDGE_IRQ 2 +#define OVERDRIVE_SLOT0_IRQ 0 + + +int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { +#ifdef CONFIG_SH_STB1_HARP + case 2: /*This is the PCI slot on the */ + return HARP_PCI_IRQ; + case 1: /* this is the bridge */ + return HARP_BRIDGE_IRQ; +#elif defined(CONFIG_SH_STB1_OVERDRIVE) + case 1: + case 2: + case 3: + return slot - 1; +#else +#error Unknown board +#endif + default: + return -1; + } +} + diff --git a/arch/sh/kernel/cpu/irq_ipr.c b/arch/sh/kernel/cpu/irq_ipr.c index daae02e6b56d4..7ea3d2d030e55 100644 --- a/arch/sh/kernel/cpu/irq_ipr.c +++ b/arch/sh/kernel/cpu/irq_ipr.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,7 @@ 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 */ } @@ -281,6 +282,10 @@ void __init init_IRQ(void) #endif /* !CONFIG_CPU_SUBTYPE_SH7300 */ #endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 || CONFIG_CPU_SUBTYPE_SH7300*/ +#ifdef CONFIG_CPU_SUBTYPE_ST40 + init_IRQ_intc2(); +#endif + /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq != NULL) { sh_mv.mv_init_irq(); @@ -329,3 +334,6 @@ int ipr_irq_demux(int irq) return irq; } #endif + +EXPORT_SYMBOL(make_ipr_irq); + diff --git a/arch/sh/kernel/cpu/sh4/irq_intc2.c b/arch/sh/kernel/cpu/sh4/irq_intc2.c index ec99f4cc47e4c..099ebbf897457 100644 --- a/arch/sh/kernel/cpu/sh4/irq_intc2.c +++ b/arch/sh/kernel/cpu/sh4/irq_intc2.c @@ -22,8 +22,11 @@ struct intc2_data { - unsigned int addr; /* Address of Interrupt Priority Register */ - int mask; /*Mask to apply */ + unsigned char msk_offset; + unsigned char msk_shift; +#ifdef CONFIG_CPU_SUBTYPE_ST40 + int (*clear_irq) (int); +#endif }; @@ -56,33 +59,34 @@ static struct hw_interrupt_type intc2_irq_type = { static void disable_intc2_irq(unsigned int irq) { - unsigned addr; - int offset=irq-INTC2_FIRST_IRQ; - unsigned val,flags; + int irq_offset = irq - INTC2_FIRST_IRQ; + int msk_shift, msk_offset; // Sanity check - if(offset<0 || offset>=NR_INTC2_IRQS) return; - - addr=intc2_data[offset].addr+INTC2_INTMSK_OFFSET; + if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) + return; - local_irq_save(flags); - val=ctrl_inl(addr); - val|=intc2_data[offset].mask; - ctrl_outl(val,addr); + msk_shift = intc2_data[irq_offset].msk_shift; + msk_offset = intc2_data[irq_offset].msk_offset; - local_irq_restore(flags); + ctrl_outl(1<=NR_INTC2_IRQS) return; + /* Sanity check */ + if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) + return; - ctrl_outl(intc2_data[offset].mask, - intc2_data[offset].addr+INTC2_INTMSKCLR_OFFSET); + msk_shift = intc2_data[irq_offset].msk_shift; + msk_offset = intc2_data[irq_offset].msk_offset; + ctrl_outl(1<=NR_INTC2_IRQS) { + if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) return; - } disable_irq_nosync(irq); + /* Fill the data we need */ - intc2_data[offset].addr=addr; - intc2_data[offset].mask=1<irq, p->ipr_offset, p->ipr_shift, + p-> msk_offset, p->msk_shift, 13); + } +} + +/* Adds a termination callback to the interrupt */ +void intc2_add_clear_irq(int irq, int (*fn)(int)) +{ + if (irq < INTC2_FIRST_IRQ) + return; + + intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; +} +#endif /* CONFIG_CPU_SUBTYPE_ST40 */ -- 2.53.0