sh: sh775x/titan fixes for irq header changes.
The following moves the creation of IPR interupts into setup-7750.c and updates a few other things to make it all work after the "Drop CPU subtype IRQ headers" commit. It boots and runs fine on my titan board. - adds an ipr_idx to the ipr_data and uses a function in the subtype code to calculate the address of the IPR registers - adds a function to enable individual interrupt mode for externals in the subtype code and calls that from the titan board code instead of doing it directly. - I changed the shift in the ipr_data to be the actual # of bits to shift, instead of the numnber / 4 - made it easier to match with the manual. Signed-off-by: Jamie Lenehan <lenehan@twibble.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
committed by
Paul Mundt
parent
fe9687dec0
commit
ea0f8feaa0
@ -1,8 +1,9 @@
|
||||
#
|
||||
# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
|
||||
#
|
||||
obj-y += ipr.o imask.o
|
||||
obj-y += imask.o
|
||||
|
||||
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
|
||||
obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
|
||||
obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
|
||||
obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
|
||||
|
@ -25,17 +25,15 @@
|
||||
static void disable_ipr_irq(unsigned int irq)
|
||||
{
|
||||
struct ipr_data *p = get_irq_chip_data(irq);
|
||||
int shift = p->shift*4;
|
||||
/* Set the priority in IPR to 0 */
|
||||
ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr);
|
||||
ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
|
||||
}
|
||||
|
||||
static void enable_ipr_irq(unsigned int irq)
|
||||
{
|
||||
struct ipr_data *p = get_irq_chip_data(irq);
|
||||
int shift = p->shift*4;
|
||||
/* Set priority in IPR back to original value */
|
||||
ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr);
|
||||
ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
|
||||
}
|
||||
|
||||
static struct irq_chip ipr_irq_chip = {
|
||||
@ -51,6 +49,10 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
|
||||
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
unsigned int irq = table[i].irq;
|
||||
table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
|
||||
/* could the IPR index be mapped, if not we ignore this */
|
||||
if (table[i].addr == 0)
|
||||
continue;
|
||||
disable_irq_nosync(irq);
|
||||
set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
|
||||
handle_level_irq, "level");
|
||||
@ -60,99 +62,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
|
||||
}
|
||||
EXPORT_SYMBOL(make_ipr_irq);
|
||||
|
||||
/*
|
||||
* XXX: Move this garbage in to the drivers, and kill off the ridiculous CPU
|
||||
* subtype checks.
|
||||
*/
|
||||
static struct ipr_data sys_ipr_map[] = {
|
||||
#ifndef CONFIG_CPU_SUBTYPE_SH7780
|
||||
{ TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY },
|
||||
{ TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY },
|
||||
#ifdef RTC_IRQ
|
||||
{ RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCI_ERI_IRQ
|
||||
{ SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
|
||||
{ SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
|
||||
{ SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCIF1_ERI_IRQ
|
||||
{ SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
{ SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
{ SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
{ SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCIF2_ERI_IRQ
|
||||
{ SCIF2_ERI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY },
|
||||
{ SCIF2_RXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY },
|
||||
{ SCIF2_BRI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY },
|
||||
{ SCIF2_TXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCIF3_ERI_IRQ
|
||||
{ SCIF3_ERI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY },
|
||||
{ SCIF3_RXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY },
|
||||
{ SCIF3_BRI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY },
|
||||
{ SCIF3_TXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY },
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7300)
|
||||
{ SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
|
||||
{ DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
|
||||
{ DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
|
||||
{ VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
|
||||
#endif
|
||||
#ifdef SCIF_ERI_IRQ
|
||||
{ SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
{ SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
{ SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
{ SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
|
||||
#endif
|
||||
#ifdef IRDA_ERI_IRQ
|
||||
{ IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
{ IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
{ IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
{ IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
|
||||
#endif
|
||||
#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)
|
||||
/*
|
||||
* Initialize the Interrupt Controller (INTC)
|
||||
* registers to their power on values
|
||||
*/
|
||||
|
||||
/*
|
||||
* Enable external irq (INTC IRQ mode).
|
||||
* You should set corresponding bits of PFC to "00"
|
||||
* to enable these interrupts.
|
||||
*/
|
||||
{ IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY },
|
||||
{ IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
|
||||
{ IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
|
||||
{ IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY },
|
||||
{ IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY },
|
||||
{ IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map));
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_PINT_IRQ
|
||||
init_IRQ_pint();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_INTC2_IRQ
|
||||
init_IRQ_intc2();
|
||||
#endif
|
||||
/* Perform the machine specific initialisation */
|
||||
if (sh_mv.mv_init_irq != NULL)
|
||||
sh_mv.mv_init_irq();
|
||||
|
||||
irq_ctx_init(smp_processor_id());
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
|
||||
int ipr_irq_demux(int irq)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
* SH7750/SH7751 Setup
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006 Jamie Lenehan
|
||||
*
|
||||
* 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
|
||||
@ -10,6 +11,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
@ -46,3 +48,71 @@ static int __init sh7750_devices_setup(void)
|
||||
ARRAY_SIZE(sh7750_devices));
|
||||
}
|
||||
__initcall(sh7750_devices_setup);
|
||||
|
||||
static struct ipr_data sh7750_ipr_map[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 12, 2 }, /* TMU1 TUNI */
|
||||
{ 18, 0, 4, 2 }, /* TMU2 TUNI */
|
||||
{ 19, 0, 4, 2 }, /* TMU2 TIPCI */
|
||||
{ 27, 1, 12, 2 }, /* WDT ITI */
|
||||
{ 20, 0, 0, 2 }, /* RTC ATI (alarm) */
|
||||
{ 21, 0, 0, 2 }, /* RTC PRI (period) */
|
||||
{ 22, 0, 0, 2 }, /* RTC CUI (carry) */
|
||||
{ 23, 1, 4, 3 }, /* SCI ERI */
|
||||
{ 24, 1, 4, 3 }, /* SCI RXI */
|
||||
{ 25, 1, 4, 3 }, /* SCI TXI */
|
||||
{ 40, 2, 4, 3 }, /* SCIF ERI */
|
||||
{ 41, 2, 4, 3 }, /* SCIF RXI */
|
||||
{ 42, 2, 4, 3 }, /* SCIF BRI */
|
||||
{ 43, 2, 4, 3 }, /* SCIF TXI */
|
||||
{ 34, 2, 8, 7 }, /* DMAC DMTE0 */
|
||||
{ 35, 2, 8, 7 }, /* DMAC DMTE1 */
|
||||
{ 36, 2, 8, 7 }, /* DMAC DMTE2 */
|
||||
{ 37, 2, 8, 7 }, /* DMAC DMTE3 */
|
||||
{ 28, 2, 8, 7 }, /* DMAC DMAE */
|
||||
};
|
||||
|
||||
static struct ipr_data sh7751_ipr_map[] = {
|
||||
{ 44, 2, 8, 7 }, /* DMAC DMTE4 */
|
||||
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */
|
||||
{ 46, 2, 8, 7 }, /* DMAC DMTE6 */
|
||||
{ 47, 2, 8, 7 }, /* DMAC DMTE7 */
|
||||
/* The following use INTC_INPRI00 for masking, which is a 32-bit
|
||||
register, not a 16-bit register like the IPRx registers, so it
|
||||
would need special support */
|
||||
/*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
|
||||
/*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
|
||||
};
|
||||
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xffd00004UL, /* 0: IPRA */
|
||||
0xffd00008UL, /* 1: IPRB */
|
||||
0xffd0000cUL, /* 2: IPRC */
|
||||
0xffd00010UL, /* 3: IPRD */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(ipr_offsets))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
|
||||
#define INTC_ICR 0xffd00000UL
|
||||
#define INTC_ICR_IRLM (1<<7)
|
||||
|
||||
/* enable individual interrupt mode for external interupts */
|
||||
void ipr_irq_enable_irlm(void)
|
||||
{
|
||||
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
|
||||
}
|
||||
|
||||
void __init init_IRQ_ipr()
|
||||
{
|
||||
make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map));
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7751
|
||||
make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map));
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user