diff options
Diffstat (limited to 'arch/mips')
176 files changed, 3861 insertions, 2797 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f5ecc0566bc2..f7f6419e4c84 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -4,6 +4,7 @@ config MIPS select HAVE_GENERIC_DMA_COHERENT select HAVE_IDE select HAVE_OPROFILE + select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select HAVE_ARCH_KGDB @@ -21,6 +22,7 @@ config MIPS select HAVE_DMA_API_DEBUG select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE + select GENERIC_IRQ_SHOW select HAVE_ARCH_JUMP_LABEL menu "Machine selection" @@ -208,6 +210,7 @@ config MACH_JZ4740 select ARCH_REQUIRE_GPIOLIB select SYS_HAS_EARLY_PRINTK select HAVE_PWM + select HAVE_CLK config LASAT bool "LASAT Networks platforms" @@ -333,6 +336,8 @@ config PNX8550_STB810 config PMC_MSP bool "PMC-Sierra MSP chipsets" depends on EXPERIMENTAL + select CEVT_R4K + select CSRC_R4K select DMA_NONCOHERENT select SWAP_IO_SPACE select NO_EXCEPT_FILL @@ -773,6 +778,10 @@ config GENERIC_FIND_NEXT_BIT bool default y +config GENERIC_FIND_BIT_LE + bool + default y + config GENERIC_HWEIGHT bool default y @@ -854,6 +863,9 @@ config GPIO_TXX9 config CFE bool +config ARCH_DMA_ADDR_T_64BIT + def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT + config DMA_COHERENT bool @@ -1123,7 +1135,7 @@ config CPU_LOONGSON2E The Loongson 2E processor implements the MIPS III instruction set with many extensions. - It has an internal FPGA northbridge, which is compatiable to + It has an internal FPGA northbridge, which is compatible to bonito64. config CPU_LOONGSON2F @@ -2327,6 +2339,7 @@ config MMU config I8253 bool + select CLKSRC_I8253 select MIPS_EXTERNAL_TIMER config ZONE_DMA32 @@ -2336,6 +2349,16 @@ source "drivers/pcmcia/Kconfig" source "drivers/pci/hotplug/Kconfig" +config RAPIDIO + bool "RapidIO support" + depends on PCI + default n + help + If you say Y here, the kernel will include drivers and + infrastructure code to support RapidIO interconnect devices. + +source "drivers/rapidio/Kconfig" + endmenu menu "Executable file formats" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 7c1102e41fe2..53e3514ba10e 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -101,7 +101,7 @@ cflags-y += -ffreestanding # carefully avoid to add it redundantly because gcc 3.3/3.4 complains # when fed the toolchain default! # -# Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of +# Certain gcc versions up to gcc 4.1.1 (probably 4.2-subversion as of # 2006-10-10 don't properly change the predefined symbols if -EB / -EL # are used, so we kludge that here. A bug has been filed at # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413. @@ -286,11 +286,11 @@ CLEAN_FILES += vmlinux.32 vmlinux.64 archprepare: ifdef CONFIG_MIPS32_N32 @echo ' Checking missing-syscalls for N32' - $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=n32" + $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=n32" endif ifdef CONFIG_MIPS32_O32 @echo ' Checking missing-syscalls for O32' - $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32" + $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=32" endif install: @@ -314,5 +314,5 @@ define archhelp echo ' vmlinuz.bin - Raw binary zboot image' echo ' vmlinuz.srec - SREC zboot image' echo - echo ' These will be default as apropriate for a configured platform.' + echo ' These will be default as appropriate for a configured platform.' endef diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c index af0fe41055af..f38298a8b98c 100644 --- a/arch/mips/alchemy/common/clocks.c +++ b/arch/mips/alchemy/common/clocks.c @@ -75,7 +75,7 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base) * counter, if it exists. If we don't have an accurate processor * speed, all of the peripherals that derive their clocks based on * this advertised speed will introduce error and sometimes not work - * properly. This function is futher convoluted to still allow configurations + * properly. This function is further convoluted to still allow configurations * to do that in case they have really, really old silicon with a * write-only PLL register. -- Dan */ diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 9f78ada83b3c..55dd7c888517 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c @@ -39,7 +39,7 @@ #include <asm/mach-pb1x00/pb1000.h> #endif -static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); +static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type); /* NOTE on interrupt priorities: The original writers of this code said: * @@ -218,17 +218,17 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = { }; -static void au1x_ic0_unmask(unsigned int irq_nr) +static void au1x_ic0_unmask(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; au_writel(1 << bit, IC0_MASKSET); au_writel(1 << bit, IC0_WAKESET); au_sync(); } -static void au1x_ic1_unmask(unsigned int irq_nr) +static void au1x_ic1_unmask(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; au_writel(1 << bit, IC1_MASKSET); au_writel(1 << bit, IC1_WAKESET); @@ -236,31 +236,31 @@ static void au1x_ic1_unmask(unsigned int irq_nr) * nowhere in the current kernel sources is it disabled. --mlau */ #if defined(CONFIG_MIPS_PB1000) - if (irq_nr == AU1000_GPIO15_INT) + if (d->irq == AU1000_GPIO15_INT) au_writel(0x4000, PB1000_MDR); /* enable int */ #endif au_sync(); } -static void au1x_ic0_mask(unsigned int irq_nr) +static void au1x_ic0_mask(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; au_writel(1 << bit, IC0_MASKCLR); au_writel(1 << bit, IC0_WAKECLR); au_sync(); } -static void au1x_ic1_mask(unsigned int irq_nr) +static void au1x_ic1_mask(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; au_writel(1 << bit, IC1_MASKCLR); au_writel(1 << bit, IC1_WAKECLR); au_sync(); } -static void au1x_ic0_ack(unsigned int irq_nr) +static void au1x_ic0_ack(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; /* * This may assume that we don't get interrupts from @@ -271,9 +271,9 @@ static void au1x_ic0_ack(unsigned int irq_nr) au_sync(); } -static void au1x_ic1_ack(unsigned int irq_nr) +static void au1x_ic1_ack(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; /* * This may assume that we don't get interrupts from @@ -284,9 +284,9 @@ static void au1x_ic1_ack(unsigned int irq_nr) au_sync(); } -static void au1x_ic0_maskack(unsigned int irq_nr) +static void au1x_ic0_maskack(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC0_INT_BASE; au_writel(1 << bit, IC0_WAKECLR); au_writel(1 << bit, IC0_MASKCLR); @@ -295,9 +295,9 @@ static void au1x_ic0_maskack(unsigned int irq_nr) au_sync(); } -static void au1x_ic1_maskack(unsigned int irq_nr) +static void au1x_ic1_maskack(struct irq_data *d) { - unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; + unsigned int bit = d->irq - AU1000_INTC1_INT_BASE; au_writel(1 << bit, IC1_WAKECLR); au_writel(1 << bit, IC1_MASKCLR); @@ -306,9 +306,9 @@ static void au1x_ic1_maskack(unsigned int irq_nr) au_sync(); } -static int au1x_ic1_setwake(unsigned int irq, unsigned int on) +static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) { - int bit = irq - AU1000_INTC1_INT_BASE; + int bit = d->irq - AU1000_INTC1_INT_BASE; unsigned long wakemsk, flags; /* only GPIO 0-7 can act as wakeup source. Fortunately these @@ -336,28 +336,30 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on) */ static struct irq_chip au1x_ic0_chip = { .name = "Alchemy-IC0", - .ack = au1x_ic0_ack, - .mask = au1x_ic0_mask, - .mask_ack = au1x_ic0_maskack, - .unmask = au1x_ic0_unmask, - .set_type = au1x_ic_settype, + .irq_ack = au1x_ic0_ack, + .irq_mask = au1x_ic0_mask, + .irq_mask_ack = au1x_ic0_maskack, + .irq_unmask = au1x_ic0_unmask, + .irq_set_type = au1x_ic_settype, }; static struct irq_chip au1x_ic1_chip = { .name = "Alchemy-IC1", - .ack = au1x_ic1_ack, - .mask = au1x_ic1_mask, - .mask_ack = au1x_ic1_maskack, - .unmask = au1x_ic1_unmask, - .set_type = au1x_ic_settype, - .set_wake = au1x_ic1_setwake, + .irq_ack = au1x_ic1_ack, + .irq_mask = au1x_ic1_mask, + .irq_mask_ack = au1x_ic1_maskack, + .irq_unmask = au1x_ic1_unmask, + .irq_set_type = au1x_ic_settype, + .irq_set_wake = au1x_ic1_setwake, }; -static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) +static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type) { struct irq_chip *chip; unsigned long icr[6]; - unsigned int bit, ic; + unsigned int bit, ic, irq = d->irq; + irq_flow_handler_t handler = NULL; + unsigned char *name = NULL; int ret; if (irq >= AU1000_INTC1_INT_BASE) { @@ -387,47 +389,47 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) au_writel(1 << bit, icr[5]); au_writel(1 << bit, icr[4]); au_writel(1 << bit, icr[0]); - set_irq_chip_and_handler_name(irq, chip, - handle_edge_irq, "riseedge"); + handler = handle_edge_irq; + name = "riseedge"; break; case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ au_writel(1 << bit, icr[5]); au_writel(1 << bit, icr[1]); au_writel(1 << bit, icr[3]); - set_irq_chip_and_handler_name(irq, chip, - handle_edge_irq, "falledge"); + handler = handle_edge_irq; + name = "falledge"; break; case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ au_writel(1 << bit, icr[5]); au_writel(1 << bit, icr[1]); au_writel(1 << bit, icr[0]); - set_irq_chip_and_handler_name(irq, chip, - handle_edge_irq, "bothedge"); + handler = handle_edge_irq; + name = "bothedge"; break; case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ au_writel(1 << bit, icr[2]); au_writel(1 << bit, icr[4]); au_writel(1 << bit, icr[0]); - set_irq_chip_and_handler_name(irq, chip, - handle_level_irq, "hilevel"); + handler = handle_level_irq; + name = "hilevel"; break; case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ au_writel(1 << bit, icr[2]); au_writel(1 << bit, icr[1]); au_writel(1 << bit, icr[3]); - set_irq_chip_and_handler_name(irq, chip, - handle_level_irq, "lowlevel"); + handler = handle_level_irq; + name = "lowlevel"; break; case IRQ_TYPE_NONE: /* 0:0:0 */ au_writel(1 << bit, icr[5]); au_writel(1 << bit, icr[4]); au_writel(1 << bit, icr[3]); - /* set at least chip so we can call set_irq_type() on it */ - set_irq_chip(irq, chip); break; default: ret = -EINVAL; } + __irq_set_chip_handler_name_locked(d->irq, chip, handler, name); + au_sync(); return ret; @@ -504,11 +506,11 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map) */ for (i = AU1000_INTC0_INT_BASE; (i < AU1000_INTC0_INT_BASE + 32); i++) - au1x_ic_settype(i, IRQ_TYPE_NONE); + au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); for (i = AU1000_INTC1_INT_BASE; (i < AU1000_INTC1_INT_BASE + 32); i++) - au1x_ic_settype(i, IRQ_TYPE_NONE); + au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); /* * Initialize IC0, which is fixed per processor. @@ -526,7 +528,7 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map) au_writel(1 << bit, IC0_ASSIGNSET); } - au1x_ic_settype(irq_nr, map->im_type); + au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type); ++map; } diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c index c52af8821da0..596ad00e7f05 100644 --- a/arch/mips/alchemy/devboards/bcsr.c +++ b/arch/mips/alchemy/devboards/bcsr.c @@ -97,26 +97,26 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d) * CPLD generates tons of spurious interrupts (at least on my DB1200). * -- mlau */ -static void bcsr_irq_mask(unsigned int irq_nr) +static void bcsr_irq_mask(struct irq_data *d) { - unsigned short v = 1 << (irq_nr - bcsr_csc_base); + unsigned short v = 1 << (d->irq - bcsr_csc_base); __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); wmb(); } -static void bcsr_irq_maskack(unsigned int irq_nr) +static void bcsr_irq_maskack(struct irq_data *d) { - unsigned short v = 1 << (irq_nr - bcsr_csc_base); + unsigned short v = 1 << (d->irq - bcsr_csc_base); __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */ wmb(); } -static void bcsr_irq_unmask(unsigned int irq_nr) +static void bcsr_irq_unmask(struct irq_data *d) { - unsigned short v = 1 << (irq_nr - bcsr_csc_base); + unsigned short v = 1 << (d->irq - bcsr_csc_base); __raw_writew(v, bcsr_virt + BCSR_REG_INTSET); __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET); wmb(); @@ -124,9 +124,9 @@ static void bcsr_irq_unmask(unsigned int irq_nr) static struct irq_chip bcsr_irq_type = { .name = "CPLD", - .mask = bcsr_irq_mask, - .mask_ack = bcsr_irq_maskack, - .unmask = bcsr_irq_unmask, + .irq_mask = bcsr_irq_mask, + .irq_mask_ack = bcsr_irq_maskack, + .irq_unmask = bcsr_irq_unmask, }; void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq) @@ -142,8 +142,8 @@ void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq) bcsr_csc_base = csc_start; for (irq = csc_start; irq <= csc_end; irq++) - set_irq_chip_and_handler_name(irq, &bcsr_irq_type, - handle_level_irq, "level"); + irq_set_chip_and_handler_name(irq, &bcsr_irq_type, + handle_level_irq, "level"); - set_irq_chained_handler(hook_irq, bcsr_csc_handler); + irq_set_chained_handler(hook_irq, bcsr_csc_handler); } diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c index 887619547553..4a8980027ecf 100644 --- a/arch/mips/alchemy/devboards/db1200/setup.c +++ b/arch/mips/alchemy/devboards/db1200/setup.c @@ -63,20 +63,19 @@ void __init board_setup(void) static int __init db1200_arch_init(void) { /* GPIO7 is low-level triggered CPLD cascade */ - set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); /* insert/eject pairs: one of both is always screaming. To avoid * issues they must not be automatically enabled when initially * requested. */ - irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN; - irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN; - irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN; - irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN; - irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN; - irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN; - + irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN); + irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN); + irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN); + irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN); + irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN); + irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN); return 0; } arch_initcall(db1200_arch_init); diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c index 9e45971343ed..05f120ff90f9 100644 --- a/arch/mips/alchemy/devboards/db1x00/board_setup.c +++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c @@ -215,35 +215,35 @@ void __init board_setup(void) static int __init db1x00_init_irq(void) { #if defined(CONFIG_MIPS_MIRAGE) - set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */ + irq_set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */ #elif defined(CONFIG_MIPS_DB1550) - set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */ - set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */ + irq_set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + irq_set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + irq_set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + irq_set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #elif defined(CONFIG_MIPS_DB1500) - set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ - set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ + irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #elif defined(CONFIG_MIPS_DB1100) - set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ - set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + irq_set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + irq_set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ + irq_set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + irq_set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + irq_set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + irq_set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #elif defined(CONFIG_MIPS_DB1000) - set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ - set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ - set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ - set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ - set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ + irq_set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */ + irq_set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */ + irq_set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */ + irq_set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */ + irq_set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + irq_set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */ #endif return 0; } diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c index f6540ec47a64..2d85c4b5be09 100644 --- a/arch/mips/alchemy/devboards/pb1000/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c @@ -197,7 +197,7 @@ void __init board_setup(void) static int __init pb1000_init_irq(void) { - set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW); return 0; } arch_initcall(pb1000_init_irq); diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c index 90dda5f3ecc5..d108fd573aaf 100644 --- a/arch/mips/alchemy/devboards/pb1100/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c @@ -117,10 +117,10 @@ void __init board_setup(void) static int __init pb1100_init_irq(void) { - set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */ - set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */ - set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */ - set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */ + irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */ + irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */ + irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */ + irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */ return 0; } diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c index 8b4466f2d44a..6d06b07c2381 100644 --- a/arch/mips/alchemy/devboards/pb1200/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c @@ -142,7 +142,7 @@ static int __init pb1200_init_irq(void) panic("Game over. Your score is 0."); } - set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT); return 0; diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c index 9cd9dfa698e7..83f46215eb0c 100644 --- a/arch/mips/alchemy/devboards/pb1500/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c @@ -134,14 +134,14 @@ void __init board_setup(void) static int __init pb1500_init_irq(void) { - set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */ - set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */ - set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ - set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); - set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */ + irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */ + irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */ + irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); + irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); return 0; } diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c index 9d7d6edafa8d..b790213848bd 100644 --- a/arch/mips/alchemy/devboards/pb1550/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c @@ -73,9 +73,9 @@ void __init board_setup(void) static int __init pb1550_init_irq(void) { - set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH); + irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH); /* enable both PCMCIA card irqs in the shared line */ alchemy_gpio2_enable_int(201); diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c index 6398fa95905c..cf436ab679ae 100644 --- a/arch/mips/alchemy/mtx-1/board_setup.c +++ b/arch/mips/alchemy/mtx-1/board_setup.c @@ -54,8 +54,8 @@ int mtx1_pci_idsel(unsigned int devsel, int assert); static void mtx1_reset(char *c) { - /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ - au_writel(0x00000000, 0xAE00001C); + /* Jump to the reset vector */ + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } static void mtx1_power_off(void) @@ -123,11 +123,11 @@ mtx1_pci_idsel(unsigned int devsel, int assert) static int __init mtx1_init_irq(void) { - set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); - set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); + irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); return 0; } diff --git a/arch/mips/alchemy/mtx-1/platform.c b/arch/mips/alchemy/mtx-1/platform.c index e30e42add697..956f946218c5 100644 --- a/arch/mips/alchemy/mtx-1/platform.c +++ b/arch/mips/alchemy/mtx-1/platform.c @@ -28,6 +28,8 @@ #include <linux/mtd/physmap.h> #include <mtd/mtd-abi.h> +#include <asm/mach-au1x00/au1xxx_eth.h> + static struct gpio_keys_button mtx1_gpio_button[] = { { .gpio = 207, @@ -140,10 +142,17 @@ static struct __initdata platform_device * mtx1_devs[] = { &mtx1_mtd, }; +static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = { + .phy_search_highest_addr = 1, + .phy1_search_mac0 = 1, +}; + static int __init mtx1_register_devices(void) { int rc; + au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata); + rc = gpio_request(mtx1_gpio_button[0].gpio, mtx1_gpio_button[0].desc); if (rc < 0) { diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c index b43c918925d3..febfb0fb0896 100644 --- a/arch/mips/alchemy/xxs1500/board_setup.c +++ b/arch/mips/alchemy/xxs1500/board_setup.c @@ -36,8 +36,8 @@ static void xxs1500_reset(char *c) { - /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ - au_writel(0x00000000, 0xAE00001C); + /* Jump to the reset vector */ + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } static void xxs1500_power_off(void) @@ -85,19 +85,19 @@ void __init board_setup(void) static int __init xxs1500_init_irq(void) { - set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); - set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); + irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); - set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */ - set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); + irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */ + irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); return 0; } diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c index 4ec2642c568f..03db3daadbd8 100644 --- a/arch/mips/ar7/irq.c +++ b/arch/mips/ar7/irq.c @@ -49,51 +49,51 @@ static int ar7_irq_base; -static void ar7_unmask_irq(unsigned int irq) +static void ar7_unmask_irq(struct irq_data *d) { - writel(1 << ((irq - ar7_irq_base) % 32), - REG(ESR_OFFSET(irq - ar7_irq_base))); + writel(1 << ((d->irq - ar7_irq_base) % 32), + REG(ESR_OFFSET(d->irq - ar7_irq_base))); } -static void ar7_mask_irq(unsigned int irq) +static void ar7_mask_irq(struct irq_data *d) { - writel(1 << ((irq - ar7_irq_base) % 32), - REG(ECR_OFFSET(irq - ar7_irq_base))); + writel(1 << ((d->irq - ar7_irq_base) % 32), + REG(ECR_OFFSET(d->irq - ar7_irq_base))); } -static void ar7_ack_irq(unsigned int irq) +static void ar7_ack_irq(struct irq_data *d) { - writel(1 << ((irq - ar7_irq_base) % 32), - REG(CR_OFFSET(irq - ar7_irq_base))); + writel(1 << ((d->irq - ar7_irq_base) % 32), + REG(CR_OFFSET(d->irq - ar7_irq_base))); } -static void ar7_unmask_sec_irq(unsigned int irq) +static void ar7_unmask_sec_irq(struct irq_data *d) { - writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET)); + writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET)); } -static void ar7_mask_sec_irq(unsigned int irq) +static void ar7_mask_sec_irq(struct irq_data *d) { - writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET)); + writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET)); } -static void ar7_ack_sec_irq(unsigned int irq) +static void ar7_ack_sec_irq(struct irq_data *d) { - writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET)); + writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET)); } static struct irq_chip ar7_irq_type = { .name = "AR7", - .unmask = ar7_unmask_irq, - .mask = ar7_mask_irq, - .ack = ar7_ack_irq + .irq_unmask = ar7_unmask_irq, + .irq_mask = ar7_mask_irq, + .irq_ack = ar7_ack_irq }; static struct irq_chip ar7_sec_irq_type = { .name = "AR7", - .unmask = ar7_unmask_sec_irq, - .mask = ar7_mask_sec_irq, - .ack = ar7_ack_sec_irq, + .irq_unmask = ar7_unmask_sec_irq, + .irq_mask = ar7_mask_sec_irq, + .irq_ack = ar7_ack_sec_irq, }; static struct irqaction ar7_cascade_action = { @@ -119,11 +119,11 @@ static void __init ar7_irq_init(int base) for (i = 0; i < 40; i++) { writel(i, REG(CHNL_OFFSET(i))); /* Primary IRQ's */ - set_irq_chip_and_handler(base + i, &ar7_irq_type, + irq_set_chip_and_handler(base + i, &ar7_irq_type, handle_level_irq); /* Secondary IRQ's */ if (i < 32) - set_irq_chip_and_handler(base + i + 40, + irq_set_chip_and_handler(base + i + 40, &ar7_sec_irq_type, handle_level_irq); } diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 1bf7f719ba53..ac610d5fe3ba 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -62,13 +62,12 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) spurious_interrupt(); } -static void ar71xx_misc_irq_unmask(unsigned int irq) +static void ar71xx_misc_irq_unmask(struct irq_data *d) { + unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; void __iomem *base = ath79_reset_base; u32 t; - irq -= ATH79_MISC_IRQ_BASE; - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); @@ -76,13 +75,12 @@ static void ar71xx_misc_irq_unmask(unsigned int irq) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); } -static void ar71xx_misc_irq_mask(unsigned int irq) +static void ar71xx_misc_irq_mask(struct irq_data *d) { + unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; void __iomem *base = ath79_reset_base; u32 t; - irq -= ATH79_MISC_IRQ_BASE; - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); @@ -90,13 +88,12 @@ static void ar71xx_misc_irq_mask(unsigned int irq) __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); } -static void ar724x_misc_irq_ack(unsigned int irq) +static void ar724x_misc_irq_ack(struct irq_data *d) { + unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE; void __iomem *base = ath79_reset_base; u32 t; - irq -= ATH79_MISC_IRQ_BASE; - t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); @@ -106,8 +103,8 @@ static void ar724x_misc_irq_ack(unsigned int irq) static struct irq_chip ath79_misc_irq_chip = { .name = "MISC", - .unmask = ar71xx_misc_irq_unmask, - .mask = ar71xx_misc_irq_mask, + .irq_unmask = ar71xx_misc_irq_unmask, + .irq_mask = ar71xx_misc_irq_mask, }; static void __init ath79_misc_irq_init(void) @@ -119,20 +116,19 @@ static void __init ath79_misc_irq_init(void) __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); if (soc_is_ar71xx() || soc_is_ar913x()) - ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask; + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; else if (soc_is_ar724x()) - ath79_misc_irq_chip.ack = ar724x_misc_irq_ack; + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; else BUG(); for (i = ATH79_MISC_IRQ_BASE; i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { - irq_desc[i].status = IRQ_DISABLED; - set_irq_chip_and_handler(i, &ath79_misc_irq_chip, + irq_set_chip_and_handler(i, &ath79_misc_irq_chip, handle_level_irq); } - set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); + irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); } asmlinkage void plat_irq_dispatch(void) diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile index e5cc86dc1da8..9f64fb414077 100644 --- a/arch/mips/bcm63xx/boards/Makefile +++ b/arch/mips/bcm63xx/boards/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o -EXTRA_CFLAGS += -Werror +ccflags-y := -Werror diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index 3be87f2422f0..cea6021cb8d7 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c @@ -76,88 +76,80 @@ asmlinkage void plat_irq_dispatch(void) * internal IRQs operations: only mask/unmask on PERF irq mask * register. */ -static inline void bcm63xx_internal_irq_mask(unsigned int irq) +static inline void bcm63xx_internal_irq_mask(struct irq_data *d) { + unsigned int irq = d->irq - IRQ_INTERNAL_BASE; u32 mask; - irq -= IRQ_INTERNAL_BASE; mask = bcm_perf_readl(PERF_IRQMASK_REG); mask &= ~(1 << irq); bcm_perf_writel(mask, PERF_IRQMASK_REG); } -static void bcm63xx_internal_irq_unmask(unsigned int irq) +static void bcm63xx_internal_irq_unmask(struct irq_data *d) { + unsigned int irq = d->irq - IRQ_INTERNAL_BASE; u32 mask; - irq -= IRQ_INTERNAL_BASE; mask = bcm_perf_readl(PERF_IRQMASK_REG); mask |= (1 << irq); bcm_perf_writel(mask, PERF_IRQMASK_REG); } -static unsigned int bcm63xx_internal_irq_startup(unsigned int irq) -{ - bcm63xx_internal_irq_unmask(irq); - return 0; -} - /* * external IRQs operations: mask/unmask and clear on PERF external * irq control register. */ -static void bcm63xx_external_irq_mask(unsigned int irq) +static void bcm63xx_external_irq_mask(struct irq_data *d) { + unsigned int irq = d->irq - IRQ_EXT_BASE; u32 reg; - irq -= IRQ_EXT_BASE; reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); reg &= ~EXTIRQ_CFG_MASK(irq); bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); } -static void bcm63xx_external_irq_unmask(unsigned int irq) +static void bcm63xx_external_irq_unmask(struct irq_data *d) { + unsigned int irq = d->irq - IRQ_EXT_BASE; u32 reg; - irq -= IRQ_EXT_BASE; reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); reg |= EXTIRQ_CFG_MASK(irq); bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); } -static void bcm63xx_external_irq_clear(unsigned int irq) +static void bcm63xx_external_irq_clear(struct irq_data *d) { + unsigned int irq = d->irq - IRQ_EXT_BASE; u32 reg; - irq -= IRQ_EXT_BASE; reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG); reg |= EXTIRQ_CFG_CLEAR(irq); bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); } -static unsigned int bcm63xx_external_irq_startup(unsigned int irq) +static unsigned int bcm63xx_external_irq_startup(struct irq_data *d) { - set_c0_status(0x100 << (irq - IRQ_MIPS_BASE)); + set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE)); irq_enable_hazard(); - bcm63xx_external_irq_unmask(irq); + bcm63xx_external_irq_unmask(d); return 0; } -static void bcm63xx_external_irq_shutdown(unsigned int irq) +static void bcm63xx_external_irq_shutdown(struct irq_data *d) { - bcm63xx_external_irq_mask(irq); - clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE)); + bcm63xx_external_irq_mask(d); + clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE)); irq_disable_hazard(); } -static int bcm63xx_external_irq_set_type(unsigned int irq, +static int bcm63xx_external_irq_set_type(struct irq_data *d, unsigned int flow_type) { + unsigned int irq = d->irq - IRQ_EXT_BASE; u32 reg; - struct irq_desc *desc = irq_desc + irq; - - irq -= IRQ_EXT_BASE; flow_type &= IRQ_TYPE_SENSE_MASK; @@ -199,37 +191,32 @@ static int bcm63xx_external_irq_set_type(unsigned int irq, } bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG); - if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { - desc->status |= IRQ_LEVEL; - desc->handle_irq = handle_level_irq; - } else { - desc->handle_irq = handle_edge_irq; - } + irqd_set_trigger_type(d, flow_type); + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) + __irq_set_handler_locked(d->irq, handle_level_irq); + else + __irq_set_handler_locked(d->irq, handle_edge_irq); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } static struct irq_chip bcm63xx_internal_irq_chip = { .name = "bcm63xx_ipic", - .startup = bcm63xx_internal_irq_startup, - .shutdown = bcm63xx_internal_irq_mask, - - .mask = bcm63xx_internal_irq_mask, - .mask_ack = bcm63xx_internal_irq_mask, - .unmask = bcm63xx_internal_irq_unmask, + .irq_mask = bcm63xx_internal_irq_mask, + .irq_unmask = bcm63xx_internal_irq_unmask, }; static struct irq_chip bcm63xx_external_irq_chip = { .name = "bcm63xx_epic", - .startup = bcm63xx_external_irq_startup, - .shutdown = bcm63xx_external_irq_shutdown, + .irq_startup = bcm63xx_external_irq_startup, + .irq_shutdown = bcm63xx_external_irq_shutdown, - .ack = bcm63xx_external_irq_clear, + .irq_ack = bcm63xx_external_irq_clear, - .mask = bcm63xx_external_irq_mask, - .unmask = bcm63xx_external_irq_unmask, + .irq_mask = bcm63xx_external_irq_mask, + .irq_unmask = bcm63xx_external_irq_unmask, - .set_type = bcm63xx_external_irq_set_type, + .irq_set_type = bcm63xx_external_irq_set_type, }; static struct irqaction cpu_ip2_cascade_action = { @@ -243,11 +230,11 @@ void __init arch_init_irq(void) mips_cpu_irq_init(); for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i) - set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip, + irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip, handle_level_irq); for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i) - set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip, + irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip, handle_edge_irq); setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action); diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index 9afc3794ed1b..c8d35684504e 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -75,7 +75,7 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) num_cores = cvmx_octeon_num_cores(); - /* Make sure the non existant devices look disabled */ + /* Make sure the non existent devices look disabled */ switch ((chip_id >> 8) & 0xff) { case 6: /* CN50XX */ case 2: /* CN30XX */ diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index ce7500cdf5b7..ffd4ae660f79 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -3,10 +3,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks + * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks */ -#include <linux/irq.h> + #include <linux/interrupt.h> +#include <linux/bitops.h> +#include <linux/percpu.h> +#include <linux/irq.h> #include <linux/smp.h> #include <asm/octeon/octeon.h> @@ -14,6 +17,47 @@ static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock); +static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror); +static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror); + +static __read_mostly u8 octeon_irq_ciu_to_irq[8][64]; + +union octeon_ciu_chip_data { + void *p; + unsigned long l; + struct { + unsigned int line:6; + unsigned int bit:6; + } s; +}; + +struct octeon_core_chip_data { + struct mutex core_irq_mutex; + bool current_en; + bool desired_en; + u8 bit; +}; + +#define MIPS_CORE_IRQ_LINES 8 + +static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES]; + +static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit, + struct irq_chip *chip, + irq_flow_handler_t handler) +{ + union octeon_ciu_chip_data cd; + + irq_set_chip_and_handler(irq, chip, handler); + + cd.l = 0; + cd.s.line = line; + cd.s.bit = bit; + + irq_set_chip_data(irq, cd.p); + octeon_irq_ciu_to_irq[line][bit] = irq; +} + static int octeon_coreid_for_cpu(int cpu) { #ifdef CONFIG_SMP @@ -23,9 +67,20 @@ static int octeon_coreid_for_cpu(int cpu) #endif } -static void octeon_irq_core_ack(unsigned int irq) +static int octeon_cpu_for_coreid(int coreid) +{ +#ifdef CONFIG_SMP + return cpu_number_map(coreid); +#else + return smp_processor_id(); +#endif +} + +static void octeon_irq_core_ack(struct irq_data *data) { - unsigned int bit = irq - OCTEON_IRQ_SW0; + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + unsigned int bit = cd->bit; + /* * We don't need to disable IRQs to make these atomic since * they are already disabled earlier in the low level @@ -37,131 +92,121 @@ static void octeon_irq_core_ack(unsigned int irq) clear_c0_cause(0x100 << bit); } -static void octeon_irq_core_eoi(unsigned int irq) +static void octeon_irq_core_eoi(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(irq); - unsigned int bit = irq - OCTEON_IRQ_SW0; - /* - * If an IRQ is being processed while we are disabling it the - * handler will attempt to unmask the interrupt after it has - * been disabled. - */ - if ((unlikely(desc->status & IRQ_DISABLED))) - return; + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + /* * We don't need to disable IRQs to make these atomic since * they are already disabled earlier in the low level * interrupt code. */ - set_c0_status(0x100 << bit); + set_c0_status(0x100 << cd->bit); } -static void octeon_irq_core_enable(unsigned int irq) +static void octeon_irq_core_set_enable_local(void *arg) { - unsigned long flags; - unsigned int bit = irq - OCTEON_IRQ_SW0; + struct irq_data *data = arg; + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + unsigned int mask = 0x100 << cd->bit; /* - * We need to disable interrupts to make sure our updates are - * atomic. + * Interrupts are already disabled, so these are atomic. */ - local_irq_save(flags); - set_c0_status(0x100 << bit); - local_irq_restore(flags); + if (cd->desired_en) + set_c0_status(mask); + else + clear_c0_status(mask); + } -static void octeon_irq_core_disable_local(unsigned int irq) +static void octeon_irq_core_disable(struct irq_data *data) { - unsigned long flags; - unsigned int bit = irq - OCTEON_IRQ_SW0; - /* - * We need to disable interrupts to make sure our updates are - * atomic. - */ - local_irq_save(flags); - clear_c0_status(0x100 << bit); - local_irq_restore(flags); + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + cd->desired_en = false; } -static void octeon_irq_core_disable(unsigned int irq) +static void octeon_irq_core_enable(struct irq_data *data) { -#ifdef CONFIG_SMP - on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local, - (void *) (long) irq, 1); -#else - octeon_irq_core_disable_local(irq); -#endif + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + cd->desired_en = true; } -static struct irq_chip octeon_irq_chip_core = { - .name = "Core", - .enable = octeon_irq_core_enable, - .disable = octeon_irq_core_disable, - .ack = octeon_irq_core_ack, - .eoi = octeon_irq_core_eoi, -}; +static void octeon_irq_core_bus_lock(struct irq_data *data) +{ + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + mutex_lock(&cd->core_irq_mutex); +} -static void octeon_irq_ciu0_ack(unsigned int irq) +static void octeon_irq_core_bus_sync_unlock(struct irq_data *data) { - switch (irq) { - case OCTEON_IRQ_GMX_DRP0: - case OCTEON_IRQ_GMX_DRP1: - case OCTEON_IRQ_IPD_DRP: - case OCTEON_IRQ_KEY_ZERO: - case OCTEON_IRQ_TIMER0: - case OCTEON_IRQ_TIMER1: - case OCTEON_IRQ_TIMER2: - case OCTEON_IRQ_TIMER3: - { - int index = cvmx_get_core_num() * 2; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - /* - * CIU timer type interrupts must be acknoleged by - * writing a '1' bit to their sum0 bit. - */ - cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask); - break; - } - default: - break; + struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data); + + if (cd->desired_en != cd->current_en) { + on_each_cpu(octeon_irq_core_set_enable_local, data, 1); + + cd->current_en = cd->desired_en; } - /* - * In order to avoid any locking accessing the CIU, we - * acknowledge CIU interrupts by disabling all of them. This - * way we can use a per core register and avoid any out of - * core locking requirements. This has the side affect that - * CIU interrupts can't be processed recursively. - * - * We don't need to disable IRQs to make these atomic since - * they are already disabled earlier in the low level - * interrupt code. - */ - clear_c0_status(0x100 << 2); + mutex_unlock(&cd->core_irq_mutex); } -static void octeon_irq_ciu0_eoi(unsigned int irq) +static struct irq_chip octeon_irq_chip_core = { + .name = "Core", + .irq_enable = octeon_irq_core_enable, + .irq_disable = octeon_irq_core_disable, + .irq_ack = octeon_irq_core_ack, + .irq_eoi = octeon_irq_core_eoi, + .irq_bus_lock = octeon_irq_core_bus_lock, + .irq_bus_sync_unlock = octeon_irq_core_bus_sync_unlock, + + .irq_cpu_online = octeon_irq_core_eoi, + .irq_cpu_offline = octeon_irq_core_ack, + .flags = IRQCHIP_ONOFFLINE_ENABLED, +}; + +static void __init octeon_irq_init_core(void) { - /* - * Enable all CIU interrupts again. We don't need to disable - * IRQs to make these atomic since they are already disabled - * earlier in the low level interrupt code. - */ - set_c0_status(0x100 << 2); + int i; + int irq; + struct octeon_core_chip_data *cd; + + for (i = 0; i < MIPS_CORE_IRQ_LINES; i++) { + cd = &octeon_irq_core_chip_data[i]; + cd->current_en = false; + cd->desired_en = false; + cd->bit = i; + mutex_init(&cd->core_irq_mutex); + + irq = OCTEON_IRQ_SW0 + i; + switch (irq) { + case OCTEON_IRQ_TIMER: + case OCTEON_IRQ_SW0: + case OCTEON_IRQ_SW1: + case OCTEON_IRQ_5: + case OCTEON_IRQ_PERF: + irq_set_chip_data(irq, cd); + irq_set_chip_and_handler(irq, &octeon_irq_chip_core, + handle_percpu_irq); + break; + default: + break; + } + } } -static int next_coreid_for_irq(struct irq_desc *desc) +static int next_cpu_for_irq(struct irq_data *data) { #ifdef CONFIG_SMP - int coreid; - int weight = cpumask_weight(desc->affinity); + int cpu; + int weight = cpumask_weight(data->affinity); if (weight > 1) { - int cpu = smp_processor_id(); + cpu = smp_processor_id(); for (;;) { - cpu = cpumask_next(cpu, desc->affinity); + cpu = cpumask_next(cpu, data->affinity); if (cpu >= nr_cpu_ids) { cpu = -1; continue; @@ -169,83 +214,175 @@ static int next_coreid_for_irq(struct irq_desc *desc) break; } } - coreid = octeon_coreid_for_cpu(cpu); } else if (weight == 1) { - coreid = octeon_coreid_for_cpu(cpumask_first(desc->affinity)); + cpu = cpumask_first(data->affinity); } else { - coreid = cvmx_get_core_num(); + cpu = smp_processor_id(); } - return coreid; + return cpu; #else - return cvmx_get_core_num(); + return smp_processor_id(); #endif } -static void octeon_irq_ciu0_enable(unsigned int irq) +static void octeon_irq_ciu_enable(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(irq); - int coreid = next_coreid_for_irq(desc); + int cpu = next_cpu_for_irq(data); + int coreid = octeon_coreid_for_cpu(cpu); + unsigned long *pen; unsigned long flags; - uint64_t en0; - int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ + union octeon_ciu_chip_data cd; + + cd.p = irq_data_get_irq_chip_data(data); - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); - en0 |= 1ull << bit; - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); - cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + if (cd.s.line == 0) { + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + } else { + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + } } -static void octeon_irq_ciu0_enable_mbox(unsigned int irq) +static void octeon_irq_ciu_enable_local(struct irq_data *data) { - int coreid = cvmx_get_core_num(); + unsigned long *pen; + unsigned long flags; + union octeon_ciu_chip_data cd; + + cd.p = irq_data_get_irq_chip_data(data); + + if (cd.s.line == 0) { + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror); + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + } else { + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror); + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen); + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + } +} + +static void octeon_irq_ciu_disable_local(struct irq_data *data) +{ + unsigned long *pen; unsigned long flags; - uint64_t en0; - int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ + union octeon_ciu_chip_data cd; + + cd.p = irq_data_get_irq_chip_data(data); - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); - en0 |= 1ull << bit; - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); - cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + if (cd.s.line == 0) { + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror); + clear_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + } else { + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror); + clear_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen); + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + } } -static void octeon_irq_ciu0_disable(unsigned int irq) +static void octeon_irq_ciu_disable_all(struct irq_data *data) { - int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ unsigned long flags; - uint64_t en0; + unsigned long *pen; int cpu; - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); - en0 &= ~(1ull << bit); - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); + union octeon_ciu_chip_data cd; + + wmb(); /* Make sure flag changes arrive before register updates. */ + + cd.p = irq_data_get_irq_chip_data(data); + + if (cd.s.line == 0) { + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); + clear_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); + } + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + } else { + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); + clear_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); + } + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + } +} + +static void octeon_irq_ciu_enable_all(struct irq_data *data) +{ + unsigned long flags; + unsigned long *pen; + int cpu; + union octeon_ciu_chip_data cd; + + cd.p = irq_data_get_irq_chip_data(data); + + if (cd.s.line == 0) { + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); + } + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + } else { + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); + } + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); } - /* - * We need to do a read after the last update to make sure all - * of them are done. - */ - cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); } /* * Enable the irq on the next core in the affinity set for chips that * have the EN*_W1{S,C} registers. */ -static void octeon_irq_ciu0_enable_v2(unsigned int irq) +static void octeon_irq_ciu_enable_v2(struct irq_data *data) { - int index; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - struct irq_desc *desc = irq_to_desc(irq); + u64 mask; + int cpu = next_cpu_for_irq(data); + union octeon_ciu_chip_data cd; + + cd.p = irq_data_get_irq_chip_data(data); + mask = 1ull << (cd.s.bit); - if ((desc->status & IRQ_DISABLED) == 0) { - index = next_coreid_for_irq(desc) * 2; + /* + * Called under the desc lock, so these should never get out + * of sync. + */ + if (cd.s.line == 0) { + int index = octeon_coreid_for_cpu(cpu) * 2; + set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu)); cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + } else { + int index = octeon_coreid_for_cpu(cpu) * 2 + 1; + set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); } } @@ -253,83 +390,155 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq) * Enable the irq on the current CPU for chips that * have the EN*_W1{S,C} registers. */ -static void octeon_irq_ciu0_enable_mbox_v2(unsigned int irq) +static void octeon_irq_ciu_enable_local_v2(struct irq_data *data) +{ + u64 mask; + union octeon_ciu_chip_data cd; + + cd.p = irq_data_get_irq_chip_data(data); + mask = 1ull << (cd.s.bit); + + if (cd.s.line == 0) { + int index = cvmx_get_core_num() * 2; + set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror)); + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + } else { + int index = cvmx_get_core_num() * 2 + 1; + set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror)); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); + } +} + +static void octeon_irq_ciu_disable_local_v2(struct irq_data *data) { - int index; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + u64 mask; + union octeon_ciu_chip_data cd; - index = cvmx_get_core_num() * 2; - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + cd.p = irq_data_get_irq_chip_data(data); + mask = 1ull << (cd.s.bit); + + if (cd.s.line == 0) { + int index = cvmx_get_core_num() * 2; + clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror)); + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); + } else { + int index = cvmx_get_core_num() * 2 + 1; + clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror)); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); + } } /* - * Disable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. + * Write to the W1C bit in CVMX_CIU_INTX_SUM0 to clear the irq. */ -static void octeon_irq_ciu0_ack_v2(unsigned int irq) -{ - int index = cvmx_get_core_num() * 2; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - - switch (irq) { - case OCTEON_IRQ_GMX_DRP0: - case OCTEON_IRQ_GMX_DRP1: - case OCTEON_IRQ_IPD_DRP: - case OCTEON_IRQ_KEY_ZERO: - case OCTEON_IRQ_TIMER0: - case OCTEON_IRQ_TIMER1: - case OCTEON_IRQ_TIMER2: - case OCTEON_IRQ_TIMER3: - /* - * CIU timer type interrupts must be acknoleged by - * writing a '1' bit to their sum0 bit. - */ +static void octeon_irq_ciu_ack(struct irq_data *data) +{ + u64 mask; + union octeon_ciu_chip_data cd; + + cd.p = data->chip_data; + mask = 1ull << (cd.s.bit); + + if (cd.s.line == 0) { + int index = cvmx_get_core_num() * 2; cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask); - break; - default: - break; + } else { + cvmx_write_csr(CVMX_CIU_INT_SUM1, mask); } - - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); } /* - * Enable the irq on the current core for chips that have the EN*_W1{S,C} + * Disable the irq on the all cores for chips that have the EN*_W1{S,C} * registers. */ -static void octeon_irq_ciu0_eoi_mbox_v2(unsigned int irq) +static void octeon_irq_ciu_disable_all_v2(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(irq); - int index = cvmx_get_core_num() * 2; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); + int cpu; + u64 mask; + union octeon_ciu_chip_data cd; - if (likely((desc->status & IRQ_DISABLED) == 0)) - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + wmb(); /* Make sure flag changes arrive before register updates. */ + + cd.p = data->chip_data; + mask = 1ull << (cd.s.bit); + + if (cd.s.line == 0) { + for_each_online_cpu(cpu) { + int index = octeon_coreid_for_cpu(cpu) * 2; + clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu)); + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); + } + } else { + for_each_online_cpu(cpu) { + int index = octeon_coreid_for_cpu(cpu) * 2 + 1; + clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); + } + } } /* - * Disable the irq on the all cores for chips that have the EN*_W1{S,C} + * Enable the irq on the all cores for chips that have the EN*_W1{S,C} * registers. */ -static void octeon_irq_ciu0_disable_all_v2(unsigned int irq) +static void octeon_irq_ciu_enable_all_v2(struct irq_data *data) { - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - int index; int cpu; - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2; - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); + u64 mask; + union octeon_ciu_chip_data cd; + + cd.p = data->chip_data; + mask = 1ull << (cd.s.bit); + + if (cd.s.line == 0) { + for_each_online_cpu(cpu) { + int index = octeon_coreid_for_cpu(cpu) * 2; + set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu)); + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + } + } else { + for_each_online_cpu(cpu) { + int index = octeon_coreid_for_cpu(cpu) * 2 + 1; + set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); + } } } #ifdef CONFIG_SMP -static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest) + +static void octeon_irq_cpu_offline_ciu(struct irq_data *data) +{ + int cpu = smp_processor_id(); + cpumask_t new_affinity; + + if (!cpumask_test_cpu(cpu, data->affinity)) + return; + + if (cpumask_weight(data->affinity) > 1) { + /* + * It has multi CPU affinity, just remove this CPU + * from the affinity set. + */ + cpumask_copy(&new_affinity, data->affinity); + cpumask_clear_cpu(cpu, &new_affinity); + } else { + /* Otherwise, put it on lowest numbered online CPU. */ + cpumask_clear(&new_affinity); + cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); + } + __irq_set_affinity_locked(data, &new_affinity); +} + +static int octeon_irq_ciu_set_affinity(struct irq_data *data, + const struct cpumask *dest, bool force) { int cpu; - struct irq_desc *desc = irq_to_desc(irq); - int enable_one = (desc->status & IRQ_DISABLED) == 0; + bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data); unsigned long flags; - int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ + union octeon_ciu_chip_data cd; + + cd.p = data->chip_data; /* * For non-v2 CIU, we will allow only single CPU affinity. @@ -339,26 +548,40 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask * if (cpumask_weight(dest) != 1) return -EINVAL; - raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - uint64_t en0 = - cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = 0; - en0 |= 1ull << bit; - } else { - en0 &= ~(1ull << bit); + if (!enable_one) + return 0; + + if (cd.s.line == 0) { + raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); + + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = false; + set_bit(cd.s.bit, pen); + } else { + clear_bit(cd.s.bit, pen); + } + cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen); } - cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); + raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); + } else { + raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); + for_each_online_cpu(cpu) { + int coreid = octeon_coreid_for_cpu(cpu); + unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); + + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = false; + set_bit(cd.s.bit, pen); + } else { + clear_bit(cd.s.bit, pen); + } + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); + } + raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); } - /* - * We need to do a read after the last update to make sure all - * of them are done. - */ - cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); - return 0; } @@ -366,22 +589,46 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask * * Set affinity for the irq for chips that have the EN*_W1{S,C} * registers. */ -static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq, - const struct cpumask *dest) +static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data, + const struct cpumask *dest, + bool force) { int cpu; - int index; - struct irq_desc *desc = irq_to_desc(irq); - int enable_one = (desc->status & IRQ_DISABLED) == 0; - u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); - - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2; - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = 0; - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); - } else { - cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); + bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data); + u64 mask; + union octeon_ciu_chip_data cd; + + if (!enable_one) + return 0; + + cd.p = data->chip_data; + mask = 1ull << cd.s.bit; + + if (cd.s.line == 0) { + for_each_online_cpu(cpu) { + unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu); + int index = octeon_coreid_for_cpu(cpu) * 2; + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = false; + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); + } else { + clear_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); + } + } + } else { + for_each_online_cpu(cpu) { + unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); + int index = octeon_coreid_for_cpu(cpu) * 2 + 1; + if (cpumask_test_cpu(cpu, dest) && enable_one) { + enable_one = false; + set_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); + } else { + clear_bit(cd.s.bit, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); + } } } return 0; @@ -389,80 +636,102 @@ static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq, #endif /* + * The v1 CIU code already masks things, so supply a dummy version to + * the core chip code. + */ +static void octeon_irq_dummy_mask(struct irq_data *data) +{ +} + +/* * Newer octeon chips have support for lockless CIU operation. */ -static struct irq_chip octeon_irq_chip_ciu0_v2 = { - .name = "CIU0", - .enable = octeon_irq_ciu0_enable_v2, - .disable = octeon_irq_ciu0_disable_all_v2, - .eoi = octeon_irq_ciu0_enable_v2, +static struct irq_chip octeon_irq_chip_ciu_v2 = { + .name = "CIU", + .irq_enable = octeon_irq_ciu_enable_v2, + .irq_disable = octeon_irq_ciu_disable_all_v2, + .irq_mask = octeon_irq_ciu_disable_local_v2, + .irq_unmask = octeon_irq_ciu_enable_v2, #ifdef CONFIG_SMP - .set_affinity = octeon_irq_ciu0_set_affinity_v2, + .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, + .irq_cpu_offline = octeon_irq_cpu_offline_ciu, #endif }; -static struct irq_chip octeon_irq_chip_ciu0 = { - .name = "CIU0", - .enable = octeon_irq_ciu0_enable, - .disable = octeon_irq_ciu0_disable, - .eoi = octeon_irq_ciu0_eoi, +static struct irq_chip octeon_irq_chip_ciu_edge_v2 = { + .name = "CIU-E", + .irq_enable = octeon_irq_ciu_enable_v2, + .irq_disable = octeon_irq_ciu_disable_all_v2, + .irq_ack = octeon_irq_ciu_ack, + .irq_mask = octeon_irq_ciu_disable_local_v2, + .irq_unmask = octeon_irq_ciu_enable_v2, #ifdef CONFIG_SMP - .set_affinity = octeon_irq_ciu0_set_affinity, + .irq_set_affinity = octeon_irq_ciu_set_affinity_v2, + .irq_cpu_offline = octeon_irq_cpu_offline_ciu, #endif }; -/* The mbox versions don't do any affinity or round-robin. */ -static struct irq_chip octeon_irq_chip_ciu0_mbox_v2 = { - .name = "CIU0-M", - .enable = octeon_irq_ciu0_enable_mbox_v2, - .disable = octeon_irq_ciu0_disable, - .eoi = octeon_irq_ciu0_eoi_mbox_v2, +static struct irq_chip octeon_irq_chip_ciu = { + .name = "CIU", + .irq_enable = octeon_irq_ciu_enable, + .irq_disable = octeon_irq_ciu_disable_all, + .irq_mask = octeon_irq_dummy_mask, +#ifdef CONFIG_SMP + .irq_set_affinity = octeon_irq_ciu_set_affinity, + .irq_cpu_offline = octeon_irq_cpu_offline_ciu, +#endif }; -static struct irq_chip octeon_irq_chip_ciu0_mbox = { - .name = "CIU0-M", - .enable = octeon_irq_ciu0_enable_mbox, - .disable = octeon_irq_ciu0_disable, - .eoi = octeon_irq_ciu0_eoi, +static struct irq_chip octeon_irq_chip_ciu_edge = { + .name = "CIU-E", + .irq_enable = octeon_irq_ciu_enable, + .irq_disable = octeon_irq_ciu_disable_all, + .irq_mask = octeon_irq_dummy_mask, + .irq_ack = octeon_irq_ciu_ack, +#ifdef CONFIG_SMP + .irq_set_affinity = octeon_irq_ciu_set_affinity, + .irq_cpu_offline = octeon_irq_cpu_offline_ciu, +#endif }; -static void octeon_irq_ciu1_ack(unsigned int irq) -{ - /* - * In order to avoid any locking accessing the CIU, we - * acknowledge CIU interrupts by disabling all of them. This - * way we can use a per core register and avoid any out of - * core locking requirements. This has the side affect that - * CIU interrupts can't be processed recursively. We don't - * need to disable IRQs to make these atomic since they are - * already disabled earlier in the low level interrupt code. - */ - clear_c0_status(0x100 << 3); -} +/* The mbox versions don't do any affinity or round-robin. */ +static struct irq_chip octeon_irq_chip_ciu_mbox_v2 = { + .name = "CIU-M", + .irq_enable = octeon_irq_ciu_enable_all_v2, + .irq_disable = octeon_irq_ciu_disable_all_v2, + .irq_ack = octeon_irq_ciu_disable_local_v2, + .irq_eoi = octeon_irq_ciu_enable_local_v2, + + .irq_cpu_online = octeon_irq_ciu_enable_local_v2, + .irq_cpu_offline = octeon_irq_ciu_disable_local_v2, + .flags = IRQCHIP_ONOFFLINE_ENABLED, +}; -static void octeon_irq_ciu1_eoi(unsigned int irq) -{ - /* - * Enable all CIU interrupts again. We don't need to disable - * IRQs to make these atomic since they are already disabled - * earlier in the low level interrupt code. - */ - set_c0_status(0x100 << 3); -} +static struct irq_chip octeon_irq_chip_ciu_mbox = { + .name = "CIU-M", + .irq_enable = octeon_irq_ciu_enable_all, + .irq_disable = octeon_irq_ciu_disable_all, + + .irq_cpu_online = octeon_irq_ciu_enable_local, + .irq_cpu_offline = octeon_irq_ciu_disable_local, + .flags = IRQCHIP_ONOFFLINE_ENABLED, +}; -static void octeon_irq_ciu1_enable(unsigned int irq) +/* + * Watchdog interrupts are special. They are associated with a single + * core, so we hardwire the affinity to that core. + */ +static void octeon_irq_ciu_wd_enable(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(irq); - int coreid = next_coreid_for_irq(desc); unsigned long flags; - uint64_t en1; - int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ + unsigned long *pen; + int coreid = data->irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ + int cpu = octeon_cpu_for_coreid(coreid); raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); - en1 |= 1ull << bit; - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); - cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); + pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu); + set_bit(coreid, pen); + cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen); raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); } @@ -470,286 +739,281 @@ static void octeon_irq_ciu1_enable(unsigned int irq) * Watchdog interrupts are special. They are associated with a single * core, so we hardwire the affinity to that core. */ -static void octeon_irq_ciu1_wd_enable(unsigned int irq) +static void octeon_irq_ciu1_wd_enable_v2(struct irq_data *data) { - unsigned long flags; - uint64_t en1; - int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ - int coreid = bit; + int coreid = data->irq - OCTEON_IRQ_WDOG0; + int cpu = octeon_cpu_for_coreid(coreid); - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); - en1 |= 1ull << bit; - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); - cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + set_bit(coreid, &per_cpu(octeon_irq_ciu1_en_mirror, cpu)); + cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(coreid * 2 + 1), 1ull << coreid); } -static void octeon_irq_ciu1_disable(unsigned int irq) + +static struct irq_chip octeon_irq_chip_ciu_wd_v2 = { + .name = "CIU-W", + .irq_enable = octeon_irq_ciu1_wd_enable_v2, + .irq_disable = octeon_irq_ciu_disable_all_v2, + .irq_mask = octeon_irq_ciu_disable_local_v2, + .irq_unmask = octeon_irq_ciu_enable_local_v2, +}; + +static struct irq_chip octeon_irq_chip_ciu_wd = { + .name = "CIU-W", + .irq_enable = octeon_irq_ciu_wd_enable, + .irq_disable = octeon_irq_ciu_disable_all, + .irq_mask = octeon_irq_dummy_mask, +}; + +static void octeon_irq_ip2_v1(void) { - int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ - unsigned long flags; - uint64_t en1; - int cpu; - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); - en1 &= ~(1ull << bit); - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); + const unsigned long core_id = cvmx_get_core_num(); + u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2)); + + ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror); + clear_c0_status(STATUSF_IP2); + if (likely(ciu_sum)) { + int bit = fls64(ciu_sum) - 1; + int irq = octeon_irq_ciu_to_irq[0][bit]; + if (likely(irq)) + do_IRQ(irq); + else + spurious_interrupt(); + } else { + spurious_interrupt(); } - /* - * We need to do a read after the last update to make sure all - * of them are done. - */ - cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); + set_c0_status(STATUSF_IP2); } -/* - * Enable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu1_enable_v2(unsigned int irq) +static void octeon_irq_ip2_v2(void) { - int index; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - struct irq_desc *desc = irq_to_desc(irq); - - if ((desc->status & IRQ_DISABLED) == 0) { - index = next_coreid_for_irq(desc) * 2 + 1; - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); + const unsigned long core_id = cvmx_get_core_num(); + u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2)); + + ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror); + if (likely(ciu_sum)) { + int bit = fls64(ciu_sum) - 1; + int irq = octeon_irq_ciu_to_irq[0][bit]; + if (likely(irq)) + do_IRQ(irq); + else + spurious_interrupt(); + } else { + spurious_interrupt(); } } - -/* - * Watchdog interrupts are special. They are associated with a single - * core, so we hardwire the affinity to that core. - */ -static void octeon_irq_ciu1_wd_enable_v2(unsigned int irq) +static void octeon_irq_ip3_v1(void) { - int index; - int coreid = irq - OCTEON_IRQ_WDOG0; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - struct irq_desc *desc = irq_to_desc(irq); - - if ((desc->status & IRQ_DISABLED) == 0) { - index = coreid * 2 + 1; - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); + u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1); + + ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror); + clear_c0_status(STATUSF_IP3); + if (likely(ciu_sum)) { + int bit = fls64(ciu_sum) - 1; + int irq = octeon_irq_ciu_to_irq[1][bit]; + if (likely(irq)) + do_IRQ(irq); + else + spurious_interrupt(); + } else { + spurious_interrupt(); } + set_c0_status(STATUSF_IP3); } -/* - * Disable the irq on the current core for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu1_ack_v2(unsigned int irq) +static void octeon_irq_ip3_v2(void) { - int index = cvmx_get_core_num() * 2 + 1; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); + u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1); + + ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror); + if (likely(ciu_sum)) { + int bit = fls64(ciu_sum) - 1; + int irq = octeon_irq_ciu_to_irq[1][bit]; + if (likely(irq)) + do_IRQ(irq); + else + spurious_interrupt(); + } else { + spurious_interrupt(); + } } -/* - * Disable the irq on the all cores for chips that have the EN*_W1{S,C} - * registers. - */ -static void octeon_irq_ciu1_disable_all_v2(unsigned int irq) +static void octeon_irq_ip4_mask(void) { - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - int index; - int cpu; - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2 + 1; - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } + clear_c0_status(STATUSF_IP4); + spurious_interrupt(); } -#ifdef CONFIG_SMP -static int octeon_irq_ciu1_set_affinity(unsigned int irq, - const struct cpumask *dest) -{ - int cpu; - struct irq_desc *desc = irq_to_desc(irq); - int enable_one = (desc->status & IRQ_DISABLED) == 0; - unsigned long flags; - int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ +static void (*octeon_irq_ip2)(void); +static void (*octeon_irq_ip3)(void); +static void (*octeon_irq_ip4)(void); - /* - * For non-v2 CIU, we will allow only single CPU affinity. - * This removes the need to do locking in the .ack/.eoi - * functions. - */ - if (cpumask_weight(dest) != 1) - return -EINVAL; +void __cpuinitdata (*octeon_irq_setup_secondary)(void); - raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); - for_each_online_cpu(cpu) { - int coreid = octeon_coreid_for_cpu(cpu); - uint64_t en1 = - cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = 0; - en1 |= 1ull << bit; - } else { - en1 &= ~(1ull << bit); - } - cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); - } +static void __cpuinit octeon_irq_percpu_enable(void) +{ + irq_cpu_online(); +} + +static void __cpuinit octeon_irq_init_ciu_percpu(void) +{ + int coreid = cvmx_get_core_num(); /* - * We need to do a read after the last update to make sure all - * of them are done. + * Disable All CIU Interrupts. The ones we need will be + * enabled later. Read the SUM register so we know the write + * completed. */ - cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); - raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); - - return 0; + cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0); + cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0); + cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2))); } -/* - * Set affinity for the irq for chips that have the EN*_W1{S,C} - * registers. - */ -static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq, - const struct cpumask *dest) +static void __cpuinit octeon_irq_setup_secondary_ciu(void) { - int cpu; - int index; - struct irq_desc *desc = irq_to_desc(irq); - int enable_one = (desc->status & IRQ_DISABLED) == 0; - u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); - for_each_online_cpu(cpu) { - index = octeon_coreid_for_cpu(cpu) * 2 + 1; - if (cpumask_test_cpu(cpu, dest) && enable_one) { - enable_one = 0; - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); - } else { - cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); - } - } - return 0; -} -#endif -/* - * Newer octeon chips have support for lockless CIU operation. - */ -static struct irq_chip octeon_irq_chip_ciu1_v2 = { - .name = "CIU1", - .enable = octeon_irq_ciu1_enable_v2, - .disable = octeon_irq_ciu1_disable_all_v2, - .eoi = octeon_irq_ciu1_enable_v2, -#ifdef CONFIG_SMP - .set_affinity = octeon_irq_ciu1_set_affinity_v2, -#endif -}; + __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0; + __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0; -static struct irq_chip octeon_irq_chip_ciu1 = { - .name = "CIU1", - .enable = octeon_irq_ciu1_enable, - .disable = octeon_irq_ciu1_disable, - .eoi = octeon_irq_ciu1_eoi, -#ifdef CONFIG_SMP - .set_affinity = octeon_irq_ciu1_set_affinity, -#endif -}; + octeon_irq_init_ciu_percpu(); + octeon_irq_percpu_enable(); -static struct irq_chip octeon_irq_chip_ciu1_wd_v2 = { - .name = "CIU1-W", - .enable = octeon_irq_ciu1_wd_enable_v2, - .disable = octeon_irq_ciu1_disable_all_v2, - .eoi = octeon_irq_ciu1_wd_enable_v2, -}; + /* Enable the CIU lines */ + set_c0_status(STATUSF_IP3 | STATUSF_IP2); + clear_c0_status(STATUSF_IP4); +} -static struct irq_chip octeon_irq_chip_ciu1_wd = { - .name = "CIU1-W", - .enable = octeon_irq_ciu1_wd_enable, - .disable = octeon_irq_ciu1_disable, - .eoi = octeon_irq_ciu1_eoi, -}; +static void __init octeon_irq_init_ciu(void) +{ + unsigned int i; + struct irq_chip *chip; + struct irq_chip *chip_edge; + struct irq_chip *chip_mbox; + struct irq_chip *chip_wd; + + octeon_irq_init_ciu_percpu(); + octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; -static void (*octeon_ciu0_ack)(unsigned int); -static void (*octeon_ciu1_ack)(unsigned int); + if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) || + OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) || + OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) || + OCTEON_IS_MODEL(OCTEON_CN6XXX)) { + octeon_irq_ip2 = octeon_irq_ip2_v2; + octeon_irq_ip3 = octeon_irq_ip3_v2; + chip = &octeon_irq_chip_ciu_v2; + chip_edge = &octeon_irq_chip_ciu_edge_v2; + chip_mbox = &octeon_irq_chip_ciu_mbox_v2; + chip_wd = &octeon_irq_chip_ciu_wd_v2; + } else { + octeon_irq_ip2 = octeon_irq_ip2_v1; + octeon_irq_ip3 = octeon_irq_ip3_v1; + chip = &octeon_irq_chip_ciu; + chip_edge = &octeon_irq_chip_ciu_edge; + chip_mbox = &octeon_irq_chip_ciu_mbox; + chip_wd = &octeon_irq_chip_ciu_wd; + } + octeon_irq_ip4 = octeon_irq_ip4_mask; + + /* Mips internal */ + octeon_irq_init_core(); + + /* CIU_0 */ + for (i = 0; i < 16; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); + for (i = 0; i < 16; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq); + + for (i = 0; i < 4; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); + for (i = 0; i < 4; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq); + + for (i = 0; i < 2; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq); + + for (i = 0; i < 4; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); + + /* CIU_1 */ + for (i = 0; i < 16; i++) + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq); + + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq); + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq); + + /* Enable the CIU lines */ + set_c0_status(STATUSF_IP3 | STATUSF_IP2); + clear_c0_status(STATUSF_IP4); +} void __init arch_init_irq(void) { - unsigned int irq; - struct irq_chip *chip0; - struct irq_chip *chip0_mbox; - struct irq_chip *chip1; - struct irq_chip *chip1_wd; - #ifdef CONFIG_SMP /* Set the default affinity to the boot cpu. */ cpumask_clear(irq_default_affinity); cpumask_set_cpu(smp_processor_id(), irq_default_affinity); #endif - - if (NR_IRQS < OCTEON_IRQ_LAST) - pr_err("octeon_irq_init: NR_IRQS is set too low\n"); - - if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) || - OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) { - octeon_ciu0_ack = octeon_irq_ciu0_ack_v2; - octeon_ciu1_ack = octeon_irq_ciu1_ack_v2; - chip0 = &octeon_irq_chip_ciu0_v2; - chip0_mbox = &octeon_irq_chip_ciu0_mbox_v2; - chip1 = &octeon_irq_chip_ciu1_v2; - chip1_wd = &octeon_irq_chip_ciu1_wd_v2; - } else { - octeon_ciu0_ack = octeon_irq_ciu0_ack; - octeon_ciu1_ack = octeon_irq_ciu1_ack; - chip0 = &octeon_irq_chip_ciu0; - chip0_mbox = &octeon_irq_chip_ciu0_mbox; - chip1 = &octeon_irq_chip_ciu1; - chip1_wd = &octeon_irq_chip_ciu1_wd; - } - - /* 0 - 15 reserved for i8259 master and slave controller. */ - - /* 17 - 23 Mips internal */ - for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) { - set_irq_chip_and_handler(irq, &octeon_irq_chip_core, - handle_percpu_irq); - } - - /* 24 - 87 CIU_INT_SUM0 */ - for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { - switch (irq) { - case OCTEON_IRQ_MBOX0: - case OCTEON_IRQ_MBOX1: - set_irq_chip_and_handler(irq, chip0_mbox, handle_percpu_irq); - break; - default: - set_irq_chip_and_handler(irq, chip0, handle_fasteoi_irq); - break; - } - } - - /* 88 - 151 CIU_INT_SUM1 */ - for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_WDOG15; irq++) - set_irq_chip_and_handler(irq, chip1_wd, handle_fasteoi_irq); - - for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED151; irq++) - set_irq_chip_and_handler(irq, chip1, handle_fasteoi_irq); - - set_c0_status(0x300 << 2); + octeon_irq_init_ciu(); } asmlinkage void plat_irq_dispatch(void) { - const unsigned long core_id = cvmx_get_core_num(); - const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2); - const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2); - const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1; - const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1); unsigned long cop0_cause; unsigned long cop0_status; - uint64_t ciu_en; - uint64_t ciu_sum; - unsigned int irq; while (1) { cop0_cause = read_c0_cause(); @@ -757,33 +1021,16 @@ asmlinkage void plat_irq_dispatch(void) cop0_cause &= cop0_status; cop0_cause &= ST0_IM; - if (unlikely(cop0_cause & STATUSF_IP2)) { - ciu_sum = cvmx_read_csr(ciu_sum0_address); - ciu_en = cvmx_read_csr(ciu_en0_address); - ciu_sum &= ciu_en; - if (likely(ciu_sum)) { - irq = fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1; - octeon_ciu0_ack(irq); - do_IRQ(irq); - } else { - spurious_interrupt(); - } - } else if (unlikely(cop0_cause & STATUSF_IP3)) { - ciu_sum = cvmx_read_csr(ciu_sum1_address); - ciu_en = cvmx_read_csr(ciu_en1_address); - ciu_sum &= ciu_en; - if (likely(ciu_sum)) { - irq = fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1; - octeon_ciu1_ack(irq); - do_IRQ(irq); - } else { - spurious_interrupt(); - } - } else if (likely(cop0_cause)) { + if (unlikely(cop0_cause & STATUSF_IP2)) + octeon_irq_ip2(); + else if (unlikely(cop0_cause & STATUSF_IP3)) + octeon_irq_ip3(); + else if (unlikely(cop0_cause & STATUSF_IP4)) + octeon_irq_ip4(); + else if (likely(cop0_cause)) do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE); - } else { + else break; - } } } @@ -791,83 +1038,7 @@ asmlinkage void plat_irq_dispatch(void) void fixup_irqs(void) { - int irq; - struct irq_desc *desc; - cpumask_t new_affinity; - unsigned long flags; - int do_set_affinity; - int cpu; - - cpu = smp_processor_id(); - - for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) - octeon_irq_core_disable_local(irq); - - for (irq = OCTEON_IRQ_WORKQ0; irq < OCTEON_IRQ_LAST; irq++) { - desc = irq_to_desc(irq); - switch (irq) { - case OCTEON_IRQ_MBOX0: - case OCTEON_IRQ_MBOX1: - /* The eoi function will disable them on this CPU. */ - desc->chip->eoi(irq); - break; - case OCTEON_IRQ_WDOG0: - case OCTEON_IRQ_WDOG1: - case OCTEON_IRQ_WDOG2: - case OCTEON_IRQ_WDOG3: - case OCTEON_IRQ_WDOG4: - case OCTEON_IRQ_WDOG5: - case OCTEON_IRQ_WDOG6: - case OCTEON_IRQ_WDOG7: - case OCTEON_IRQ_WDOG8: - case OCTEON_IRQ_WDOG9: - case OCTEON_IRQ_WDOG10: - case OCTEON_IRQ_WDOG11: - case OCTEON_IRQ_WDOG12: - case OCTEON_IRQ_WDOG13: - case OCTEON_IRQ_WDOG14: - case OCTEON_IRQ_WDOG15: - /* - * These have special per CPU semantics and - * are handled in the watchdog driver. - */ - break; - default: - raw_spin_lock_irqsave(&desc->lock, flags); - /* - * If this irq has an action, it is in use and - * must be migrated if it has affinity to this - * cpu. - */ - if (desc->action && cpumask_test_cpu(cpu, desc->affinity)) { - if (cpumask_weight(desc->affinity) > 1) { - /* - * It has multi CPU affinity, - * just remove this CPU from - * the affinity set. - */ - cpumask_copy(&new_affinity, desc->affinity); - cpumask_clear_cpu(cpu, &new_affinity); - } else { - /* - * Otherwise, put it on lowest - * numbered online CPU. - */ - cpumask_clear(&new_affinity); - cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); - } - do_set_affinity = 1; - } else { - do_set_affinity = 0; - } - raw_spin_unlock_irqrestore(&desc->lock, flags); - - if (do_set_affinity) - irq_set_affinity(irq, &new_affinity); - - break; - } - } + irq_cpu_offline(); } #endif /* CONFIG_HOTPLUG_CPU */ diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index cecaf62aef32..cd61d7281d91 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -75,7 +75,7 @@ static int __init octeon_cf_device_init(void) * zero. */ - /* Asume that CS1 immediately follows. */ + /* Assume that CS1 immediately follows. */ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); region_base = mio_boot_reg_cfg.s.base << 16; diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index b0c3686c96dd..0707fae3f0ee 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -420,7 +420,6 @@ void octeon_user_io_init(void) void __init prom_init(void) { struct cvmx_sysinfo *sysinfo; - const int coreid = cvmx_get_core_num(); int i; int argc; #ifdef CONFIG_CAVIUM_RESERVE32 @@ -537,17 +536,6 @@ void __init prom_init(void) octeon_uart = octeon_get_boot_uart(); - /* - * Disable All CIU Interrupts. The ones we need will be - * enabled later. Read the SUM register so we know the write - * completed. - */ - cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0); - cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2))); - #ifdef CONFIG_SMP octeon_write_lcd("LinuxSMP"); #else @@ -674,7 +662,7 @@ void __init plat_mem_setup(void) * some memory vectors. When SPARSEMEM is in use, it doesn't * verify that the size is big enough for the final * vectors. Making the smallest chuck 4MB seems to be enough - * to consistantly work. + * to consistently work. */ mem_alloc_size = 4 << 20; if (mem_alloc_size > MAX_MEMORY) diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 391cefe556b3..ba78b21cc8d0 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -171,41 +171,19 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle) * After we've done initial boot, this function is called to allow the * board code to clean up state, if needed */ -static void octeon_init_secondary(void) +static void __cpuinit octeon_init_secondary(void) { - const int coreid = cvmx_get_core_num(); - union cvmx_ciu_intx_sum0 interrupt_enable; unsigned int sr; -#ifdef CONFIG_HOTPLUG_CPU - struct linux_app_boot_info *labi; - - labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); - - if (labi->labi_signature != LABI_SIGNATURE) - panic("The bootloader version on this board is incorrect."); -#endif - sr = set_c0_status(ST0_BEV); write_c0_ebase((u32)ebase); write_c0_status(sr); octeon_check_cpu_bist(); octeon_init_cvmcount(); - /* - pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid); - */ - /* Enable Mailbox interrupts to this core. These are the only - interrupts allowed on line 3 */ - cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff); - interrupt_enable.u64 = 0; - interrupt_enable.s.mbox = 0x3; - cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64); - cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0); - cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0); - /* Enable core interrupt processing for 2,3 and 7 */ - set_c0_status(0x8c01); + + octeon_irq_setup_secondary(); + raw_local_irq_enable(); } /** @@ -214,6 +192,15 @@ static void octeon_init_secondary(void) */ void octeon_prepare_cpus(unsigned int max_cpus) { +#ifdef CONFIG_HOTPLUG_CPU + struct linux_app_boot_info *labi; + + labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); + + if (labi->labi_signature != LABI_SIGNATURE) + panic("The bootloader version on this board is incorrect."); +#endif + cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff); if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED, "mailbox0", mailbox_interrupt)) { diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index cb41954fc321..824e08c73798 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -17,80 +17,48 @@ #include <asm/dec/ioasic_addrs.h> #include <asm/dec/ioasic_ints.h> - static int ioasic_irq_base; - -static inline void unmask_ioasic_irq(unsigned int irq) +static void unmask_ioasic_irq(struct irq_data *d) { u32 simr; simr = ioasic_read(IO_REG_SIMR); - simr |= (1 << (irq - ioasic_irq_base)); + simr |= (1 << (d->irq - ioasic_irq_base)); ioasic_write(IO_REG_SIMR, simr); } -static inline void mask_ioasic_irq(unsigned int irq) +static void mask_ioasic_irq(struct irq_data *d) { u32 simr; simr = ioasic_read(IO_REG_SIMR); - simr &= ~(1 << (irq - ioasic_irq_base)); + simr &= ~(1 << (d->irq - ioasic_irq_base)); ioasic_write(IO_REG_SIMR, simr); } -static inline void clear_ioasic_irq(unsigned int irq) +static void ack_ioasic_irq(struct irq_data *d) { - u32 sir; - - sir = ~(1 << (irq - ioasic_irq_base)); - ioasic_write(IO_REG_SIR, sir); -} - -static inline void ack_ioasic_irq(unsigned int irq) -{ - mask_ioasic_irq(irq); + mask_ioasic_irq(d); fast_iob(); } -static inline void end_ioasic_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_ioasic_irq(irq); -} - static struct irq_chip ioasic_irq_type = { .name = "IO-ASIC", - .ack = ack_ioasic_irq, - .mask = mask_ioasic_irq, - .mask_ack = ack_ioasic_irq, - .unmask = unmask_ioasic_irq, + .irq_ack = ack_ioasic_irq, + .irq_mask = mask_ioasic_irq, + .irq_mask_ack = ack_ioasic_irq, + .irq_unmask = unmask_ioasic_irq, }; - -#define unmask_ioasic_dma_irq unmask_ioasic_irq - -#define mask_ioasic_dma_irq mask_ioasic_irq - -#define ack_ioasic_dma_irq ack_ioasic_irq - -static inline void end_ioasic_dma_irq(unsigned int irq) -{ - clear_ioasic_irq(irq); - fast_iob(); - end_ioasic_irq(irq); -} - static struct irq_chip ioasic_dma_irq_type = { .name = "IO-ASIC-DMA", - .ack = ack_ioasic_dma_irq, - .mask = mask_ioasic_dma_irq, - .mask_ack = ack_ioasic_dma_irq, - .unmask = unmask_ioasic_dma_irq, - .end = end_ioasic_dma_irq, + .irq_ack = ack_ioasic_irq, + .irq_mask = mask_ioasic_irq, + .irq_mask_ack = ack_ioasic_irq, + .irq_unmask = unmask_ioasic_irq, }; - void __init init_ioasic_irqs(int base) { int i; @@ -100,10 +68,10 @@ void __init init_ioasic_irqs(int base) fast_iob(); for (i = base; i < base + IO_INR_DMA; i++) - set_irq_chip_and_handler(i, &ioasic_irq_type, + irq_set_chip_and_handler(i, &ioasic_irq_type, handle_level_irq); for (; i < base + IO_IRQ_LINES; i++) - set_irq_chip(i, &ioasic_dma_irq_type); + irq_set_chip(i, &ioasic_dma_irq_type); ioasic_irq_base = base; } diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index ed90a8deabcc..37199f742c45 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c @@ -27,43 +27,40 @@ */ u32 cached_kn02_csr; - static int kn02_irq_base; - -static inline void unmask_kn02_irq(unsigned int irq) +static void unmask_kn02_irq(struct irq_data *d) { volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); - cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16)); + cached_kn02_csr |= (1 << (d->irq - kn02_irq_base + 16)); *csr = cached_kn02_csr; } -static inline void mask_kn02_irq(unsigned int irq) +static void mask_kn02_irq(struct irq_data *d) { volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); - cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16)); + cached_kn02_csr &= ~(1 << (d->irq - kn02_irq_base + 16)); *csr = cached_kn02_csr; } -static void ack_kn02_irq(unsigned int irq) +static void ack_kn02_irq(struct irq_data *d) { - mask_kn02_irq(irq); + mask_kn02_irq(d); iob(); } static struct irq_chip kn02_irq_type = { .name = "KN02-CSR", - .ack = ack_kn02_irq, - .mask = mask_kn02_irq, - .mask_ack = ack_kn02_irq, - .unmask = unmask_kn02_irq, + .irq_ack = ack_kn02_irq, + .irq_mask = mask_kn02_irq, + .irq_mask_ack = ack_kn02_irq, + .irq_unmask = unmask_kn02_irq, }; - void __init init_kn02_irqs(int base) { volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + @@ -76,7 +73,7 @@ void __init init_kn02_irqs(int base) iob(); for (i = base; i < base + KN02_IRQ_LINES; i++) - set_irq_chip_and_handler(i, &kn02_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &kn02_irq_type, handle_level_irq); kn02_irq_base = base; } diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c index 3a96799eb65f..3dbd7a5a6ad3 100644 --- a/arch/mips/emma/markeins/irq.c +++ b/arch/mips/emma/markeins/irq.c @@ -34,13 +34,10 @@ #include <asm/emma/emma2rh.h> -static void emma2rh_irq_enable(unsigned int irq) +static void emma2rh_irq_enable(struct irq_data *d) { - u32 reg_value; - u32 reg_bitmask; - u32 reg_index; - - irq -= EMMA2RH_IRQ_BASE; + unsigned int irq = d->irq - EMMA2RH_IRQ_BASE; + u32 reg_value, reg_bitmask, reg_index; reg_index = EMMA2RH_BHIF_INT_EN_0 + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); @@ -49,13 +46,10 @@ static void emma2rh_irq_enable(unsigned int irq) emma2rh_out32(reg_index, reg_value | reg_bitmask); } -static void emma2rh_irq_disable(unsigned int irq) +static void emma2rh_irq_disable(struct irq_data *d) { - u32 reg_value; - u32 reg_bitmask; - u32 reg_index; - - irq -= EMMA2RH_IRQ_BASE; + unsigned int irq = d->irq - EMMA2RH_IRQ_BASE; + u32 reg_value, reg_bitmask, reg_index; reg_index = EMMA2RH_BHIF_INT_EN_0 + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); @@ -66,10 +60,8 @@ static void emma2rh_irq_disable(unsigned int irq) struct irq_chip emma2rh_irq_controller = { .name = "emma2rh_irq", - .ack = emma2rh_irq_disable, - .mask = emma2rh_irq_disable, - .mask_ack = emma2rh_irq_disable, - .unmask = emma2rh_irq_enable, + .irq_mask = emma2rh_irq_disable, + .irq_unmask = emma2rh_irq_enable, }; void emma2rh_irq_init(void) @@ -77,28 +69,26 @@ void emma2rh_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ; i++) - set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i, + irq_set_chip_and_handler_name(EMMA2RH_IRQ_BASE + i, &emma2rh_irq_controller, handle_level_irq, "level"); } -static void emma2rh_sw_irq_enable(unsigned int irq) +static void emma2rh_sw_irq_enable(struct irq_data *d) { + unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE; u32 reg; - irq -= EMMA2RH_SW_IRQ_BASE; - reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); reg |= 1 << irq; emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); } -static void emma2rh_sw_irq_disable(unsigned int irq) +static void emma2rh_sw_irq_disable(struct irq_data *d) { + unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE; u32 reg; - irq -= EMMA2RH_SW_IRQ_BASE; - reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); reg &= ~(1 << irq); emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); @@ -106,10 +96,8 @@ static void emma2rh_sw_irq_disable(unsigned int irq) struct irq_chip emma2rh_sw_irq_controller = { .name = "emma2rh_sw_irq", - .ack = emma2rh_sw_irq_disable, - .mask = emma2rh_sw_irq_disable, - .mask_ack = emma2rh_sw_irq_disable, - .unmask = emma2rh_sw_irq_enable, + .irq_mask = emma2rh_sw_irq_disable, + .irq_unmask = emma2rh_sw_irq_enable, }; void emma2rh_sw_irq_init(void) @@ -117,44 +105,43 @@ void emma2rh_sw_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++) - set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i, + irq_set_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i, &emma2rh_sw_irq_controller, handle_level_irq, "level"); } -static void emma2rh_gpio_irq_enable(unsigned int irq) +static void emma2rh_gpio_irq_enable(struct irq_data *d) { + unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; u32 reg; - irq -= EMMA2RH_GPIO_IRQ_BASE; - reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); reg |= 1 << irq; emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); } -static void emma2rh_gpio_irq_disable(unsigned int irq) +static void emma2rh_gpio_irq_disable(struct irq_data *d) { + unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; u32 reg; - irq -= EMMA2RH_GPIO_IRQ_BASE; - reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); reg &= ~(1 << irq); emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); } -static void emma2rh_gpio_irq_ack(unsigned int irq) +static void emma2rh_gpio_irq_ack(struct irq_data *d) { - irq -= EMMA2RH_GPIO_IRQ_BASE; + unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; + emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); } -static void emma2rh_gpio_irq_mask_ack(unsigned int irq) +static void emma2rh_gpio_irq_mask_ack(struct irq_data *d) { + unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE; u32 reg; - irq -= EMMA2RH_GPIO_IRQ_BASE; emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); @@ -164,10 +151,10 @@ static void emma2rh_gpio_irq_mask_ack(unsigned int irq) struct irq_chip emma2rh_gpio_irq_controller = { .name = "emma2rh_gpio_irq", - .ack = emma2rh_gpio_irq_ack, - .mask = emma2rh_gpio_irq_disable, - .mask_ack = emma2rh_gpio_irq_mask_ack, - .unmask = emma2rh_gpio_irq_enable, + .irq_ack = emma2rh_gpio_irq_ack, + .irq_mask = emma2rh_gpio_irq_disable, + .irq_mask_ack = emma2rh_gpio_irq_mask_ack, + .irq_unmask = emma2rh_gpio_irq_enable, }; void emma2rh_gpio_irq_init(void) @@ -175,7 +162,7 @@ void emma2rh_gpio_irq_init(void) u32 i; for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++) - set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i, + irq_set_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i, &emma2rh_gpio_irq_controller, handle_edge_irq, "edge"); } diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile index e0aaad482b0e..5314b37aff2c 100644 --- a/arch/mips/fw/arc/Makefile +++ b/arch/mips/fw/arc/Makefile @@ -9,4 +9,4 @@ lib-$(CONFIG_ARC_MEMORY) += memory.o lib-$(CONFIG_ARC_CONSOLE) += arc_con.o lib-$(CONFIG_ARC_PROMLIB) += promlib.o -EXTRA_CFLAGS += -Werror +ccflags-y := -Werror diff --git a/arch/mips/fw/arc/promlib.c b/arch/mips/fw/arc/promlib.c index c508c00dbb64..b7f9dd3c93c6 100644 --- a/arch/mips/fw/arc/promlib.c +++ b/arch/mips/fw/arc/promlib.c @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1996 David S. Miller (dm@sgi.com) - * Compability with board caches, Ulf Carlsson + * Compatibility with board caches, Ulf Carlsson */ #include <linux/kernel.h> #include <asm/sgialib.h> diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 50b4ef288c53..2e1ad4c652b7 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -676,9 +676,8 @@ static inline int ffs(int word) #include <asm/arch_hweight.h> #include <asm-generic/bitops/const_hweight.h> -#include <asm-generic/bitops/ext2-non-atomic.h> +#include <asm-generic/bitops/le.h> #include <asm-generic/bitops/ext2-atomic.h> -#include <asm-generic/bitops/minix.h> #endif /* __KERNEL__ */ diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h index b9c8203688d5..c0ead6313845 100644 --- a/arch/mips/include/asm/dec/prom.h +++ b/arch/mips/include/asm/dec/prom.h @@ -108,7 +108,7 @@ extern int (*__pmax_close)(int); /* * On MIPS64 we have to call PROM functions via a helper - * dispatcher to accomodate ABI incompatibilities. + * dispatcher to accommodate ABI incompatibilities. */ #define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \ __asm__(#fun " = call_o32") diff --git a/arch/mips/include/asm/errno.h b/arch/mips/include/asm/errno.h index a0efc73819e4..6dcd3583ed04 100644 --- a/arch/mips/include/asm/errno.h +++ b/arch/mips/include/asm/errno.h @@ -121,6 +121,8 @@ #define ERFKILL 167 /* Operation not possible due to RF-kill */ +#define EHWPOISON 168 /* Memory page has hardware error */ + #define EDQUOT 1133 /* Quota exceeded */ #ifdef __KERNEL__ diff --git a/arch/mips/include/asm/floppy.h b/arch/mips/include/asm/floppy.h index 992d232adc83..c5c7c0e6064c 100644 --- a/arch/mips/include/asm/floppy.h +++ b/arch/mips/include/asm/floppy.h @@ -24,7 +24,7 @@ static inline void fd_cacheflush(char * addr, long size) * And on Mips's the CMOS info fails also ... * * FIXME: This information should come from the ARC configuration tree - * or whereever a particular machine has stored this ... + * or wherever a particular machine has stored this ... */ #define FLOPPY0_TYPE fd_drive_type(0) #define FLOPPY1_TYPE fd_drive_type(1) diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index b9cce90346cf..6ebf1734b411 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -75,7 +75,7 @@ } static inline int -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) { int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; @@ -85,7 +85,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) + if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; pagefault_disable(); @@ -132,11 +132,13 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) } static inline int -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) { - int retval; + int ret = 0; + u32 val; - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; if (cpu_has_llsc && R10000_LLSC_WAR) { @@ -145,25 +147,25 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) " .set push \n" " .set noat \n" " .set mips3 \n" - "1: ll %0, %2 \n" - " bne %0, %z3, 3f \n" + "1: ll %1, %3 \n" + " bne %1, %z4, 3f \n" " .set mips0 \n" - " move $1, %z4 \n" + " move $1, %z5 \n" " .set mips3 \n" - "2: sc $1, %1 \n" + "2: sc $1, %2 \n" " beqzl $1, 1b \n" __WEAK_LLSC_MB "3: \n" " .set pop \n" " .section .fixup,\"ax\" \n" - "4: li %0, %5 \n" + "4: li %0, %6 \n" " j 3b \n" " .previous \n" " .section __ex_table,\"a\" \n" " "__UA_ADDR "\t1b, 4b \n" " "__UA_ADDR "\t2b, 4b \n" " .previous \n" - : "=&r" (retval), "=R" (*uaddr) + : "+r" (ret), "=&r" (val), "=R" (*uaddr) : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) : "memory"); } else if (cpu_has_llsc) { @@ -172,31 +174,32 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) " .set push \n" " .set noat \n" " .set mips3 \n" - "1: ll %0, %2 \n" - " bne %0, %z3, 3f \n" + "1: ll %1, %3 \n" + " bne %1, %z4, 3f \n" " .set mips0 \n" - " move $1, %z4 \n" + " move $1, %z5 \n" " .set mips3 \n" - "2: sc $1, %1 \n" + "2: sc $1, %2 \n" " beqz $1, 1b \n" __WEAK_LLSC_MB "3: \n" " .set pop \n" " .section .fixup,\"ax\" \n" - "4: li %0, %5 \n" + "4: li %0, %6 \n" " j 3b \n" " .previous \n" " .section __ex_table,\"a\" \n" " "__UA_ADDR "\t1b, 4b \n" " "__UA_ADDR "\t2b, 4b \n" " .previous \n" - : "=&r" (retval), "=R" (*uaddr) + : "+r" (ret), "=&r" (val), "=R" (*uaddr) : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) : "memory"); } else return -ENOSYS; - return retval; + *uval = val; + return ret; } #endif diff --git a/arch/mips/include/asm/hw_irq.h b/arch/mips/include/asm/hw_irq.h index aca05a43a97b..77adda297ad9 100644 --- a/arch/mips/include/asm/hw_irq.h +++ b/arch/mips/include/asm/hw_irq.h @@ -13,7 +13,7 @@ extern atomic_t irq_err_count; /* - * interrupt-retrigger: NOP for now. This may not be apropriate for all + * interrupt-retrigger: NOP for now. This may not be appropriate for all * machines, we'll see ... */ diff --git a/arch/mips/include/asm/i8253.h b/arch/mips/include/asm/i8253.h index 48bb82372994..9ad011366f73 100644 --- a/arch/mips/include/asm/i8253.h +++ b/arch/mips/include/asm/i8253.h @@ -12,8 +12,13 @@ #define PIT_CH0 0x40 #define PIT_CH2 0x42 +#define PIT_LATCH LATCH + extern raw_spinlock_t i8253_lock; extern void setup_pit_timer(void); +#define inb_pit inb_p +#define outb_pit outb_p + #endif /* __ASM_I8253_H */ diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 5b017f23e243..b04e4de5dd2e 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -242,7 +242,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, * This version of ioremap ensures that the memory is marked uncachable * on the CPU as well as honouring existing caching rules from things like * the PCI bus. Note that there are other caches and buffers on many - * busses. In paticular driver authors should read up on PCI writes + * busses. In particular driver authors should read up on PCI writes * * It's useful if some control registers are in such an area and * write combining or read caching is not desirable: diff --git a/arch/mips/include/asm/ioctls.h b/arch/mips/include/asm/ioctls.h index d967b8997626..92403c3d6007 100644 --- a/arch/mips/include/asm/ioctls.h +++ b/arch/mips/include/asm/ioctls.h @@ -85,6 +85,7 @@ #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP 0x5437 /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index b003ed52ed17..0ec01294b063 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -55,9 +55,9 @@ static inline void smtc_im_ack_irq(unsigned int irq) #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF #include <linux/cpumask.h> -extern int plat_set_irq_affinity(unsigned int irq, - const struct cpumask *affinity); -extern void smtc_forward_irq(unsigned int irq); +extern int plat_set_irq_affinity(struct irq_data *d, + const struct cpumask *affinity, bool force); +extern void smtc_forward_irq(struct irq_data *d); /* * IRQ affinity hook invoked at the beginning of interrupt dispatch @@ -70,51 +70,53 @@ extern void smtc_forward_irq(unsigned int irq); * cpumask implementations, this version is optimistically assuming * that cpumask.h macro overhead is reasonable during interrupt dispatch. */ -#define IRQ_AFFINITY_HOOK(irq) \ -do { \ - if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\ - smtc_forward_irq(irq); \ - irq_exit(); \ - return; \ - } \ -} while (0) +static inline int handle_on_other_cpu(unsigned int irq) +{ + struct irq_data *d = irq_get_irq_data(irq); + + if (cpumask_test_cpu(smp_processor_id(), d->affinity)) + return 0; + smtc_forward_irq(d); + return 1; +} #else /* Not doing SMTC affinity */ -#define IRQ_AFFINITY_HOOK(irq) do { } while (0) +static inline int handle_on_other_cpu(unsigned int irq) { return 0; } #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP +static inline void smtc_im_backstop(unsigned int irq) +{ + if (irq_hwmask[irq] & 0x0000ff00) + write_c0_tccontext(read_c0_tccontext() & + ~(irq_hwmask[irq] & 0x0000ff00)); +} + /* * Clear interrupt mask handling "backstop" if irq_hwmask * entry so indicates. This implies that the ack() or end() * functions will take over re-enabling the low-level mask. * Otherwise it will be done on return from exception. */ -#define __DO_IRQ_SMTC_HOOK(irq) \ -do { \ - IRQ_AFFINITY_HOOK(irq); \ - if (irq_hwmask[irq] & 0x0000ff00) \ - write_c0_tccontext(read_c0_tccontext() & \ - ~(irq_hwmask[irq] & 0x0000ff00)); \ -} while (0) - -#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) \ -do { \ - if (irq_hwmask[irq] & 0x0000ff00) \ - write_c0_tccontext(read_c0_tccontext() & \ - ~(irq_hwmask[irq] & 0x0000ff00)); \ -} while (0) +static inline int smtc_handle_on_other_cpu(unsigned int irq) +{ + int ret = handle_on_other_cpu(irq); + + if (!ret) + smtc_im_backstop(irq); + return ret; +} #else -#define __DO_IRQ_SMTC_HOOK(irq) \ -do { \ - IRQ_AFFINITY_HOOK(irq); \ -} while (0) -#define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) do { } while (0) +static inline void smtc_im_backstop(unsigned int irq) { } +static inline int smtc_handle_on_other_cpu(unsigned int irq) +{ + return handle_on_other_cpu(irq); +} #endif diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 9ef3b0d17896..309cbcd6909c 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -174,7 +174,7 @@ __asm__( "mtc0 \\flags, $2, 1 \n" #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) /* - * Slow, but doesn't suffer from a relativly unlikely race + * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. */ " beqz \\flags, 1f \n" diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h index 5325084d5c48..32978d32561a 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h @@ -4,7 +4,7 @@ #define TAGVER_LEN 4 /* Length of Tag Version */ #define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ #define SIG1_LEN 20 /* Company Signature 1 Length */ -#define SIG2_LEN 14 /* Company Signature 2 Lenght */ +#define SIG2_LEN 14 /* Company Signature 2 Length */ #define BOARDID_LEN 16 /* Length of BoardId */ #define ENDIANFLAG_LEN 2 /* Endian Flag Length */ #define CHIPID_LEN 6 /* Chip Id Length */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h index 6ddab8aef644..5b05f186e395 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/irq.h +++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h @@ -11,172 +11,91 @@ #define NR_IRQS OCTEON_IRQ_LAST #define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0 -/* 0 - 7 represent the i8259 master */ -#define OCTEON_IRQ_I8259M0 0 -#define OCTEON_IRQ_I8259M1 1 -#define OCTEON_IRQ_I8259M2 2 -#define OCTEON_IRQ_I8259M3 3 -#define OCTEON_IRQ_I8259M4 4 -#define OCTEON_IRQ_I8259M5 5 -#define OCTEON_IRQ_I8259M6 6 -#define OCTEON_IRQ_I8259M7 7 -/* 8 - 15 represent the i8259 slave */ -#define OCTEON_IRQ_I8259S0 8 -#define OCTEON_IRQ_I8259S1 9 -#define OCTEON_IRQ_I8259S2 10 -#define OCTEON_IRQ_I8259S3 11 -#define OCTEON_IRQ_I8259S4 12 -#define OCTEON_IRQ_I8259S5 13 -#define OCTEON_IRQ_I8259S6 14 -#define OCTEON_IRQ_I8259S7 15 -/* 16 - 23 represent the 8 MIPS standard interrupt sources */ -#define OCTEON_IRQ_SW0 16 -#define OCTEON_IRQ_SW1 17 -#define OCTEON_IRQ_CIU0 18 -#define OCTEON_IRQ_CIU1 19 -#define OCTEON_IRQ_CIU4 20 -#define OCTEON_IRQ_5 21 -#define OCTEON_IRQ_PERF 22 -#define OCTEON_IRQ_TIMER 23 -/* 24 - 87 represent the sources in CIU_INTX_EN0 */ -#define OCTEON_IRQ_WORKQ0 24 -#define OCTEON_IRQ_WORKQ1 25 -#define OCTEON_IRQ_WORKQ2 26 -#define OCTEON_IRQ_WORKQ3 27 -#define OCTEON_IRQ_WORKQ4 28 -#define OCTEON_IRQ_WORKQ5 29 -#define OCTEON_IRQ_WORKQ6 30 -#define OCTEON_IRQ_WORKQ7 31 -#define OCTEON_IRQ_WORKQ8 32 -#define OCTEON_IRQ_WORKQ9 33 -#define OCTEON_IRQ_WORKQ10 34 -#define OCTEON_IRQ_WORKQ11 35 -#define OCTEON_IRQ_WORKQ12 36 -#define OCTEON_IRQ_WORKQ13 37 -#define OCTEON_IRQ_WORKQ14 38 -#define OCTEON_IRQ_WORKQ15 39 -#define OCTEON_IRQ_GPIO0 40 -#define OCTEON_IRQ_GPIO1 41 -#define OCTEON_IRQ_GPIO2 42 -#define OCTEON_IRQ_GPIO3 43 -#define OCTEON_IRQ_GPIO4 44 -#define OCTEON_IRQ_GPIO5 45 -#define OCTEON_IRQ_GPIO6 46 -#define OCTEON_IRQ_GPIO7 47 -#define OCTEON_IRQ_GPIO8 48 -#define OCTEON_IRQ_GPIO9 49 -#define OCTEON_IRQ_GPIO10 50 -#define OCTEON_IRQ_GPIO11 51 -#define OCTEON_IRQ_GPIO12 52 -#define OCTEON_IRQ_GPIO13 53 -#define OCTEON_IRQ_GPIO14 54 -#define OCTEON_IRQ_GPIO15 55 -#define OCTEON_IRQ_MBOX0 56 -#define OCTEON_IRQ_MBOX1 57 -#define OCTEON_IRQ_UART0 58 -#define OCTEON_IRQ_UART1 59 -#define OCTEON_IRQ_PCI_INT0 60 -#define OCTEON_IRQ_PCI_INT1 61 -#define OCTEON_IRQ_PCI_INT2 62 -#define OCTEON_IRQ_PCI_INT3 63 -#define OCTEON_IRQ_PCI_MSI0 64 -#define OCTEON_IRQ_PCI_MSI1 65 -#define OCTEON_IRQ_PCI_MSI2 66 -#define OCTEON_IRQ_PCI_MSI3 67 -#define OCTEON_IRQ_RESERVED68 68 /* Summary of CIU_INT_SUM1 */ -#define OCTEON_IRQ_TWSI 69 -#define OCTEON_IRQ_RML 70 -#define OCTEON_IRQ_TRACE 71 -#define OCTEON_IRQ_GMX_DRP0 72 -#define OCTEON_IRQ_GMX_DRP1 73 -#define OCTEON_IRQ_IPD_DRP 74 -#define OCTEON_IRQ_KEY_ZERO 75 -#define OCTEON_IRQ_TIMER0 76 -#define OCTEON_IRQ_TIMER1 77 -#define OCTEON_IRQ_TIMER2 78 -#define OCTEON_IRQ_TIMER3 79 -#define OCTEON_IRQ_USB0 80 -#define OCTEON_IRQ_PCM 81 -#define OCTEON_IRQ_MPI 82 -#define OCTEON_IRQ_TWSI2 83 -#define OCTEON_IRQ_POWIQ 84 -#define OCTEON_IRQ_IPDPPTHR 85 -#define OCTEON_IRQ_MII0 86 -#define OCTEON_IRQ_BOOTDMA 87 -/* 88 - 151 represent the sources in CIU_INTX_EN1 */ -#define OCTEON_IRQ_WDOG0 88 -#define OCTEON_IRQ_WDOG1 89 -#define OCTEON_IRQ_WDOG2 90 -#define OCTEON_IRQ_WDOG3 91 -#define OCTEON_IRQ_WDOG4 92 -#define OCTEON_IRQ_WDOG5 93 -#define OCTEON_IRQ_WDOG6 94 -#define OCTEON_IRQ_WDOG7 95 -#define OCTEON_IRQ_WDOG8 96 -#define OCTEON_IRQ_WDOG9 97 -#define OCTEON_IRQ_WDOG10 98 -#define OCTEON_IRQ_WDOG11 99 -#define OCTEON_IRQ_WDOG12 100 -#define OCTEON_IRQ_WDOG13 101 -#define OCTEON_IRQ_WDOG14 102 -#define OCTEON_IRQ_WDOG15 103 -#define OCTEON_IRQ_UART2 104 -#define OCTEON_IRQ_USB1 105 -#define OCTEON_IRQ_MII1 106 -#define OCTEON_IRQ_RESERVED107 107 -#define OCTEON_IRQ_RESERVED108 108 -#define OCTEON_IRQ_RESERVED109 109 -#define OCTEON_IRQ_RESERVED110 110 -#define OCTEON_IRQ_RESERVED111 111 -#define OCTEON_IRQ_RESERVED112 112 -#define OCTEON_IRQ_RESERVED113 113 -#define OCTEON_IRQ_RESERVED114 114 -#define OCTEON_IRQ_RESERVED115 115 -#define OCTEON_IRQ_RESERVED116 116 -#define OCTEON_IRQ_RESERVED117 117 -#define OCTEON_IRQ_RESERVED118 118 -#define OCTEON_IRQ_RESERVED119 119 -#define OCTEON_IRQ_RESERVED120 120 -#define OCTEON_IRQ_RESERVED121 121 -#define OCTEON_IRQ_RESERVED122 122 -#define OCTEON_IRQ_RESERVED123 123 -#define OCTEON_IRQ_RESERVED124 124 -#define OCTEON_IRQ_RESERVED125 125 -#define OCTEON_IRQ_RESERVED126 126 -#define OCTEON_IRQ_RESERVED127 127 -#define OCTEON_IRQ_RESERVED128 128 -#define OCTEON_IRQ_RESERVED129 129 -#define OCTEON_IRQ_RESERVED130 130 -#define OCTEON_IRQ_RESERVED131 131 -#define OCTEON_IRQ_RESERVED132 132 -#define OCTEON_IRQ_RESERVED133 133 -#define OCTEON_IRQ_RESERVED134 134 -#define OCTEON_IRQ_RESERVED135 135 -#define OCTEON_IRQ_RESERVED136 136 -#define OCTEON_IRQ_RESERVED137 137 -#define OCTEON_IRQ_RESERVED138 138 -#define OCTEON_IRQ_RESERVED139 139 -#define OCTEON_IRQ_RESERVED140 140 -#define OCTEON_IRQ_RESERVED141 141 -#define OCTEON_IRQ_RESERVED142 142 -#define OCTEON_IRQ_RESERVED143 143 -#define OCTEON_IRQ_RESERVED144 144 -#define OCTEON_IRQ_RESERVED145 145 -#define OCTEON_IRQ_RESERVED146 146 -#define OCTEON_IRQ_RESERVED147 147 -#define OCTEON_IRQ_RESERVED148 148 -#define OCTEON_IRQ_RESERVED149 149 -#define OCTEON_IRQ_RESERVED150 150 -#define OCTEON_IRQ_RESERVED151 151 +enum octeon_irq { +/* 1 - 8 represent the 8 MIPS standard interrupt sources */ + OCTEON_IRQ_SW0 = 1, + OCTEON_IRQ_SW1, +/* CIU0, CUI2, CIU4 are 3, 4, 5 */ + OCTEON_IRQ_5 = 6, + OCTEON_IRQ_PERF, + OCTEON_IRQ_TIMER, +/* sources in CIU_INTX_EN0 */ + OCTEON_IRQ_WORKQ0, + OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16, + OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16, + OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15, + OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16, + OCTEON_IRQ_MBOX1, + OCTEON_IRQ_UART0, + OCTEON_IRQ_UART1, + OCTEON_IRQ_UART2, + OCTEON_IRQ_PCI_INT0, + OCTEON_IRQ_PCI_INT1, + OCTEON_IRQ_PCI_INT2, + OCTEON_IRQ_PCI_INT3, + OCTEON_IRQ_PCI_MSI0, + OCTEON_IRQ_PCI_MSI1, + OCTEON_IRQ_PCI_MSI2, + OCTEON_IRQ_PCI_MSI3, + + OCTEON_IRQ_TWSI, + OCTEON_IRQ_TWSI2, + OCTEON_IRQ_RML, + OCTEON_IRQ_TRACE0, + OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4, + OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5, + OCTEON_IRQ_KEY_ZERO, + OCTEON_IRQ_TIMER0, + OCTEON_IRQ_TIMER1, + OCTEON_IRQ_TIMER2, + OCTEON_IRQ_TIMER3, + OCTEON_IRQ_USB0, + OCTEON_IRQ_USB1, + OCTEON_IRQ_PCM, + OCTEON_IRQ_MPI, + OCTEON_IRQ_POWIQ, + OCTEON_IRQ_IPDPPTHR, + OCTEON_IRQ_MII0, + OCTEON_IRQ_MII1, + OCTEON_IRQ_BOOTDMA, + + OCTEON_IRQ_NAND, + OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */ + OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */ + OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */ + OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */ + OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */ + OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */ + OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */ + OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */ + OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */ + OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */ + OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */ + OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */ + OCTEON_IRQ_DFA, /* Summary of DFA */ + OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */ + OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */ + OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */ + OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */ + OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5, + OCTEON_IRQ_PTP, + OCTEON_IRQ_PEM0, + OCTEON_IRQ_PEM1, + OCTEON_IRQ_SRIO0, + OCTEON_IRQ_SRIO1, + OCTEON_IRQ_LMC0, + OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */ + OCTEON_IRQ_RST, +}; #ifdef CONFIG_PCI_MSI -/* 152 - 215 represent the MSI interrupts 0-63 */ -#define OCTEON_IRQ_MSI_BIT0 152 -#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255) +/* 152 - 407 represent the MSI interrupts 0-255 */ +#define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1) -#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) +#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255) +#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) #else -#define OCTEON_IRQ_LAST 152 +#define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1) #endif #endif diff --git a/arch/mips/include/asm/mach-ip32/mc146818rtc.h b/arch/mips/include/asm/mach-ip32/mc146818rtc.h index c28ba8d84076..6b6bab43d5c1 100644 --- a/arch/mips/include/asm/mach-ip32/mc146818rtc.h +++ b/arch/mips/include/asm/mach-ip32/mc146818rtc.h @@ -26,7 +26,7 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr) } /* - * FIXME: Do it right. For now just assume that noone lives in 20th century + * FIXME: Do it right. For now just assume that no one lives in 20th century * and no O2 user in 22th century ;-) */ #define mc146818_decode_year(year) ((year) + 2000) diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h index 8987a76e9676..564ab81d6cdc 100644 --- a/arch/mips/include/asm/mach-jz4740/platform.h +++ b/arch/mips/include/asm/mach-jz4740/platform.h @@ -30,6 +30,7 @@ extern struct platform_device jz4740_i2s_device; extern struct platform_device jz4740_pcm_device; extern struct platform_device jz4740_codec_device; extern struct platform_device jz4740_adc_device; +extern struct platform_device jz4740_wdt_device; void jz4740_serial_device_register(void); diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h index 021f77ca59ec..2a8e2bb5d539 100644 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h +++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h @@ -1,5 +1,5 @@ /* - * The header file of cs5536 sourth bridge. + * The header file of cs5536 south bridge. * * Copyright (C) 2007 Lemote, Inc. * Author : jlliu <liujl@lemote.com> diff --git a/arch/mips/include/asm/mach-pb1x00/pb1000.h b/arch/mips/include/asm/mach-pb1x00/pb1000.h index 6d1ff9060e44..65059255dc1e 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1000.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1000.h @@ -1,5 +1,5 @@ /* - * Alchemy Semi Pb1000 Referrence Board + * Alchemy Semi Pb1000 Reference Board * * Copyright 2001, 2008 MontaVista Software Inc. * Author: MontaVista Software, Inc. <source@mvista.com> diff --git a/arch/mips/include/asm/mach-pb1x00/pb1200.h b/arch/mips/include/asm/mach-pb1x00/pb1200.h index 962eb55dc880..fce4332ebb7f 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1200.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1200.h @@ -1,5 +1,5 @@ /* - * AMD Alchemy Pb1200 Referrence Board + * AMD Alchemy Pb1200 Reference Board * Board Registers defines. * * ######################################################################## diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h index fc4d766641ce..f835c88e9593 100644 --- a/arch/mips/include/asm/mach-pb1x00/pb1550.h +++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h @@ -1,5 +1,5 @@ /* - * AMD Alchemy Semi PB1550 Referrence Board + * AMD Alchemy Semi PB1550 Reference Board * Board Registers defines. * * Copyright 2004 Embedded Edge LLC. diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h index f76029c2406e..a8e72cf12142 100644 --- a/arch/mips/include/asm/mach-powertv/dma-coherence.h +++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h @@ -48,7 +48,7 @@ static inline unsigned long virt_to_phys_from_pte(void *addr) /* check for a valid page */ if (pte_present(pte)) { /* get the physical address the page is - * refering to */ + * referring to */ phys_addr = (unsigned long) page_to_phys(pte_page(pte)); /* add the offset within the page */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 4d9870975382..6a6f8a8f542d 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -922,7 +922,7 @@ do { \ #define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) /* - * The WatchLo register. There may be upto 8 of them. + * The WatchLo register. There may be up to 8 of them. */ #define read_c0_watchlo0() __read_ulong_c0_register($18, 0) #define read_c0_watchlo1() __read_ulong_c0_register($18, 1) @@ -942,7 +942,7 @@ do { \ #define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) /* - * The WatchHi register. There may be upto 8 of them. + * The WatchHi register. There may be up to 8 of them. */ #define read_c0_watchhi0() __read_32bit_c0_register($19, 0) #define read_c0_watchhi1() __read_32bit_c0_register($19, 1) diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index f3c23a43f845..4e4c3a8282d6 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h @@ -200,7 +200,7 @@ enum cvmx_chip_types_enum { CVMX_CHIP_TYPE_MAX, }; -/* Compatability alias for NAC38 name change, planned to be removed +/* Compatibility alias for NAC38 name change, planned to be removed * from SDK 1.7 */ #define CVMX_BOARD_TYPE_NAO38 CVMX_BOARD_TYPE_NAC38 diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h index 8e708bdb43f7..877845b84b14 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h @@ -67,7 +67,7 @@ struct cvmx_bootmem_block_header { /* * Structure for named memory blocks. Number of descriptors available - * can be changed without affecting compatiblity, but name length + * can be changed without affecting compatibility, but name length * changes require a bump in the bootmem descriptor version Note: This * structure must be naturally 64 bit aligned, as a single memory * image will be used by both 32 and 64 bit programs. diff --git a/arch/mips/include/asm/octeon/cvmx-l2c.h b/arch/mips/include/asm/octeon/cvmx-l2c.h index 0b32c5b118e2..2c8ff9e33ec3 100644 --- a/arch/mips/include/asm/octeon/cvmx-l2c.h +++ b/arch/mips/include/asm/octeon/cvmx-l2c.h @@ -157,7 +157,7 @@ enum cvmx_l2c_tad_event { /** * Configure one of the four L2 Cache performance counters to capture event - * occurences. + * occurrences. * * @counter: The counter to configure. Range 0..3. * @event: The type of L2 Cache event occurrence to count. diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 9d9381e2e3d8..7e1286706d46 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -151,7 +151,7 @@ enum cvmx_mips_space { #endif /** - * Convert a memory pointer (void*) into a hardware compatable + * Convert a memory pointer (void*) into a hardware compatible * memory address (uint64_t). Octeon hardware widgets don't * understand logical addresses. * diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index 6b34afd0d4e7..f72f768cd3a4 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h @@ -257,4 +257,6 @@ extern struct cvmx_bootinfo *octeon_bootinfo; extern uint64_t octeon_bootloader_entry_addr; +extern void (*octeon_irq_setup_secondary)(void); + #endif /* __ASM_OCTEON_OCTEON_H */ diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h index c2394f8b0fe1..9ce5a1e7e14c 100644 --- a/arch/mips/include/asm/paccess.h +++ b/arch/mips/include/asm/paccess.h @@ -7,7 +7,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * * Protected memory access. Used for everything that might take revenge - * by sending a DBE error like accessing possibly non-existant memory or + * by sending a DBE error like accessing possibly non-existent memory or * devices. */ #ifndef _ASM_PACCESS_H diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h index f1f508e4f971..be44fb0266da 100644 --- a/arch/mips/include/asm/pci/bridge.h +++ b/arch/mips/include/asm/pci/bridge.h @@ -262,7 +262,7 @@ typedef volatile struct bridge_s { } bridge_t; /* - * Field formats for Error Command Word and Auxillary Error Command Word + * Field formats for Error Command Word and Auxiliary Error Command Word * of bridge. */ typedef struct bridge_err_cmdword_s { diff --git a/arch/mips/include/asm/perf_event.h b/arch/mips/include/asm/perf_event.h index e00007cf8162..d0c77496c728 100644 --- a/arch/mips/include/asm/perf_event.h +++ b/arch/mips/include/asm/perf_event.h @@ -11,15 +11,5 @@ #ifndef __MIPS_PERF_EVENT_H__ #define __MIPS_PERF_EVENT_H__ - -/* - * MIPS performance counters do not raise NMI upon overflow, a regular - * interrupt will be signaled. Hence we can do the pending perf event - * work at the tail of the irq handler. - */ -static inline void -set_perf_event_pending(void) -{ -} - +/* Leave it empty here. The file is required by linux/perf_event.h */ #endif /* __MIPS_PERF_EVENT_H__ */ diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h new file mode 100644 index 000000000000..a80801b094bd --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h @@ -0,0 +1,21 @@ +/* + * 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. + * + * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org) + */ +#ifndef __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H + +#define cpu_has_mips16 1 +#define cpu_has_dsp 1 +#define cpu_has_mipsmt 1 +#define cpu_has_fpu 0 + +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 1 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 + +#endif /* __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h new file mode 100644 index 000000000000..156f320c69e7 --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h @@ -0,0 +1,343 @@ +/* + * + * Macros for external SMP-safe access to the PMC MSP71xx reference + * board GPIO pins + * + * Copyright 2010 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MSP_GPIO_MACROS_H__ +#define __MSP_GPIO_MACROS_H__ + +#include <msp_regops.h> +#include <msp_regs.h> + +#ifdef CONFIG_PMC_MSP7120_GW +#define MSP_NUM_GPIOS 20 +#else +#define MSP_NUM_GPIOS 28 +#endif + +/* -- GPIO Enumerations -- */ +enum msp_gpio_data { + MSP_GPIO_LO = 0, + MSP_GPIO_HI = 1, + MSP_GPIO_NONE, /* Special - Means pin is out of range */ + MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */ +}; + +enum msp_gpio_mode { + MSP_GPIO_INPUT = 0x0, + /* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */ + MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */ + MSP_GPIO_OUTPUT = 0x8, + MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */ + MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */ + MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */ + MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */ +}; + +/* -- Static Tables -- */ + +/* Maps pins to data register */ +static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = { + /* GPIO 0 and 1 on the first register */ + GPIO_DATA1_REG, GPIO_DATA1_REG, + /* GPIO 2, 3, 4, and 5 on the second register */ + GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, + /* GPIO 6, 7, 8, and 9 on the third register */ + GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, + /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */ + GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, + GPIO_DATA4_REG, GPIO_DATA4_REG, + /* GPIO 16 - 23 on the first strange EXTENDED register */ + EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, + EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, + EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, + /* GPIO 24 - 27 on the second strange EXTENDED register */ + EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, + EXTENDED_GPIO2_REG, +}; + +/* Maps pins to mode register */ +static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = { + /* GPIO 0 and 1 on the first register */ + GPIO_CFG1_REG, GPIO_CFG1_REG, + /* GPIO 2, 3, 4, and 5 on the second register */ + GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, + /* GPIO 6, 7, 8, and 9 on the third register */ + GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, + /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */ + GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, + GPIO_CFG4_REG, GPIO_CFG4_REG, + /* GPIO 16 - 23 on the first strange EXTENDED register */ + EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, + EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, + EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, + /* GPIO 24 - 27 on the second strange EXTENDED register */ + EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, + EXTENDED_GPIO2_REG, +}; + +/* Maps 'basic' pins to relative offset from 0 per register */ +static int MSP_GPIO_OFFSET[] = { + /* GPIO 0 and 1 on the first register */ + 0, 0, + /* GPIO 2, 3, 4, and 5 on the second register */ + 2, 2, 2, 2, + /* GPIO 6, 7, 8, and 9 on the third register */ + 6, 6, 6, 6, + /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */ + 10, 10, 10, 10, 10, 10, +}; + +/* Maps MODE to allowed pin mask */ +static unsigned int MSP_GPIO_MODE_ALLOWED[] = { + 0xffffffff, /* Mode 0 - INPUT */ + 0x00000, /* Mode 1 - INTERRUPT */ + 0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/ + 0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */ + 0xffffffff, /* Mode 8 - OUTPUT */ + 0x0000f, /* Mode 9 - UART_OUTPUT/ + PERF_TIMERA (GPIO 0, 1, 2, 3) */ + 0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */ + 0x00000, /* Mode b - Not really a mode! */ +}; + +/* -- Bit masks -- */ + +/* This gives you the 'register relative offset gpio' number */ +#define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio]) + +/* These take the 'register relative offset gpio' number */ +#define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio) +#define BASIC_MODE_REG_VALUE(mode, ogpio) \ + (mode << BASIC_MODE_REG_SHIFT(ogpio)) +#define BASIC_MODE_REG_MASK(ogpio) \ + BASIC_MODE_REG_VALUE(0xf, ogpio) +#define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4) +#define BASIC_MODE_REG_FROM_REG(data, ogpio) \ + ((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio)) + +/* These take the actual GPIO number (0 through 15) */ +#define BASIC_DATA_MASK(gpio) \ + BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio)) +#define BASIC_MODE_MASK(gpio) \ + BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio)) +#define BASIC_MODE(mode, gpio) \ + BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio)) +#define BASIC_MODE_SHIFT(gpio) \ + BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio)) +#define BASIC_MODE_FROM_REG(data, gpio) \ + BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio)) + +/* + * Each extended GPIO register is 32 bits long and is responsible for up to + * eight GPIOs. The least significant 16 bits contain the set and clear bit + * pair for each of the GPIOs. The most significant 16 bits contain the + * disable and enable bit pair for each of the GPIOs. For example, the + * extended GPIO reg for GPIOs 16-23 is as follows: + * + * 31: GPIO23_DISABLE + * ... + * 19: GPIO17_DISABLE + * 18: GPIO17_ENABLE + * 17: GPIO16_DISABLE + * 16: GPIO16_ENABLE + * ... + * 3: GPIO17_SET + * 2: GPIO17_CLEAR + * 1: GPIO16_SET + * 0: GPIO16_CLEAR + */ + +/* This gives the 'register relative offset gpio' number */ +#define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24) + +/* These take the 'register relative offset gpio' number */ +#define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16)) +#define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16)) +#define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2)) +#define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2)) + +/* These take the actual GPIO number (16 through 27) */ +#define EXTENDED_DISABLE(gpio) \ + EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio)) +#define EXTENDED_ENABLE(gpio) \ + EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio)) +#define EXTENDED_SET(gpio) \ + EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio)) +#define EXTENDED_CLR(gpio) \ + EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio)) + +#define EXTENDED_FULL_MASK (0xffffffff) + +/* -- API inline-functions -- */ + +/* + * Gets the current value of the specified pin + */ +static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio) +{ + u32 pinhi_mask = 0, pinhi_mask2 = 0; + + if (gpio >= MSP_NUM_GPIOS) + return MSP_GPIO_NONE; + + if (gpio < 16) { + pinhi_mask = BASIC_DATA_MASK(gpio); + } else { + /* + * Two cases are possible with the EXTENDED register: + * - In output mode (ENABLED flag set), check the CLR bit + * - In input mode (ENABLED flag not set), check the SET bit + */ + pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio); + pinhi_mask2 = EXTENDED_SET(gpio); + } + if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) || + (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2)) + return MSP_GPIO_HI; + else + return MSP_GPIO_LO; +} + +/* Sets the specified pin to the specified value */ +static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio) +{ + if (gpio >= MSP_NUM_GPIOS) + return; + + if (gpio < 16) { + if (data == MSP_GPIO_TOGGLE) + toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio], + BASIC_DATA_MASK(gpio)); + else if (data == MSP_GPIO_HI) + set_reg32(MSP_GPIO_DATA_REGISTER[gpio], + BASIC_DATA_MASK(gpio)); + else + clear_reg32(MSP_GPIO_DATA_REGISTER[gpio], + BASIC_DATA_MASK(gpio)); + } else { + if (data == MSP_GPIO_TOGGLE) { + /* Special ugly case: + * We have to read the CLR bit. + * If set, we write the CLR bit. + * If not, we write the SET bit. + */ + u32 tmpdata; + + custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio], + tmpdata); + if (tmpdata & EXTENDED_CLR(gpio)) + tmpdata = EXTENDED_CLR(gpio); + else + tmpdata = EXTENDED_SET(gpio); + custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio], + tmpdata); + } else { + u32 newdata; + + if (data == MSP_GPIO_HI) + newdata = EXTENDED_SET(gpio); + else + newdata = EXTENDED_CLR(gpio); + set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio], + EXTENDED_FULL_MASK, newdata); + } + } +} + +/* Sets the specified pin to the specified value */ +static inline void msp_gpio_pin_hi(unsigned int gpio) +{ + msp_gpio_pin_set(MSP_GPIO_HI, gpio); +} + +/* Sets the specified pin to the specified value */ +static inline void msp_gpio_pin_lo(unsigned int gpio) +{ + msp_gpio_pin_set(MSP_GPIO_LO, gpio); +} + +/* Sets the specified pin to the opposite value */ +static inline void msp_gpio_pin_toggle(unsigned int gpio) +{ + msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio); +} + +/* Gets the mode of the specified pin */ +static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio) +{ + enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN; + uint32_t data; + + if (gpio >= MSP_NUM_GPIOS) + return retval; + + data = *MSP_GPIO_MODE_REGISTER[gpio]; + + if (gpio < 16) { + retval = BASIC_MODE_FROM_REG(data, gpio); + } else { + /* Extended pins can only be either INPUT or OUTPUT */ + if (data & EXTENDED_ENABLE(gpio)) + retval = MSP_GPIO_OUTPUT; + else + retval = MSP_GPIO_INPUT; + } + + return retval; +} + +/* + * Sets the specified mode on the requested pin + * Returns 0 on success, or -1 if that mode is not allowed on this pin + */ +static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio) +{ + u32 modemask, newmode; + + if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode]) + return -1; + + if (gpio >= MSP_NUM_GPIOS) + return -1; + + if (gpio < 16) { + modemask = BASIC_MODE_MASK(gpio); + newmode = BASIC_MODE(mode, gpio); + } else { + modemask = EXTENDED_FULL_MASK; + if (mode == MSP_GPIO_INPUT) + newmode = EXTENDED_DISABLE(gpio); + else + newmode = EXTENDED_ENABLE(gpio); + } + /* Do the set atomically */ + set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode); + + return 0; +} + +#endif /* __MSP_GPIO_MACROS_H__ */ diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h index 60a5a38dd5b2..7d41474e5488 100644 --- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h @@ -205,7 +205,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) * custom_read_reg32(address, tmp); <-- Reads the address and put the value * in the 'tmp' variable given * - * From here on out, you are (basicly) atomic, so don't do anything too + * From here on out, you are (basically) atomic, so don't do anything too * fancy! * Also, this code may loop if the end of this block fails to write * everything back safely due do the other CPU, so do NOT do anything diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h index 603eb737b4a8..692c1b658b92 100644 --- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h @@ -91,12 +91,10 @@ /* MAC C device registers */ #define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000) /* ADSL2 device registers */ -#define MSP_USB_BASE (MSP_MSB_BASE + 0xB40000) - /* USB device registers */ -#define MSP_USB_BASE_START (MSP_MSB_BASE + 0xB40100) - /* USB device registers */ -#define MSP_USB_BASE_END (MSP_MSB_BASE + 0xB401FF) - /* USB device registers */ +#define MSP_USB0_BASE (MSP_MSB_BASE + 0xB00000) + /* USB0 device registers */ +#define MSP_USB1_BASE (MSP_MSB_BASE + 0x300000) + /* USB1 device registers */ #define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000) /* CPU interface registers */ @@ -319,8 +317,11 @@ #define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184) /* CPU/SLP Error status 1 */ -#define EXTENDED_GPIO_REG regptr(MSP_SLP_BASE + 0x188) - /* Extended GPIO register */ +/* Extended GPIO registers */ +#define EXTENDED_GPIO1_REG regptr(MSP_SLP_BASE + 0x188) +#define EXTENDED_GPIO2_REG regptr(MSP_SLP_BASE + 0x18c) +#define EXTENDED_GPIO_REG EXTENDED_GPIO1_REG + /* Backward-compatibility */ /* System Error registers */ #define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190) diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h new file mode 100644 index 000000000000..4c9348df9df2 --- /dev/null +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h @@ -0,0 +1,144 @@ +/****************************************************************** + * Copyright (c) 2000-2007 PMC-Sierra INC. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * 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., 675 Mass Ave, Cambridge, MA + * 02139, USA. + * + * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS + * SOFTWARE. + */ +#ifndef MSP_USB_H_ +#define MSP_USB_H_ + +#ifdef CONFIG_MSP_HAS_DUAL_USB +#define NUM_USB_DEVS 2 +#else +#define NUM_USB_DEVS 1 +#endif + +/* Register spaces for USB host 0 */ +#define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0) +#define MSP_USB0_MAB_END (MSP_USB0_BASE + 0x17) +#define MSP_USB0_ID_START (MSP_USB0_BASE + 0x40000) +#define MSP_USB0_ID_END (MSP_USB0_BASE + 0x4008f) +#define MSP_USB0_HS_START (MSP_USB0_BASE + 0x40100) +#define MSP_USB0_HS_END (MSP_USB0_BASE + 0x401FF) + +/* Register spaces for USB host 1 */ +#define MSP_USB1_MAB_START (MSP_USB1_BASE + 0x0) +#define MSP_USB1_MAB_END (MSP_USB1_BASE + 0x17) +#define MSP_USB1_ID_START (MSP_USB1_BASE + 0x40000) +#define MSP_USB1_ID_END (MSP_USB1_BASE + 0x4008f) +#define MSP_USB1_HS_START (MSP_USB1_BASE + 0x40100) +#define MSP_USB1_HS_END (MSP_USB1_BASE + 0x401ff) + +/* USB Identification registers */ +struct msp_usbid_regs { + u32 id; /* 0x0: Identification register */ + u32 hwgen; /* 0x4: General HW params */ + u32 hwhost; /* 0x8: Host HW params */ + u32 hwdev; /* 0xc: Device HW params */ + u32 hwtxbuf; /* 0x10: Tx buffer HW params */ + u32 hwrxbuf; /* 0x14: Rx buffer HW params */ + u32 reserved[26]; + u32 timer0_load; /* 0x80: General-purpose timer 0 load*/ + u32 timer0_ctrl; /* 0x84: General-purpose timer 0 control */ + u32 timer1_load; /* 0x88: General-purpose timer 1 load*/ + u32 timer1_ctrl; /* 0x8c: General-purpose timer 1 control */ +}; + +/* MSBus to AMBA registers */ +struct msp_mab_regs { + u32 isr; /* 0x0: Interrupt status */ + u32 imr; /* 0x4: Interrupt mask */ + u32 thcr0; /* 0x8: Transaction header capture 0 */ + u32 thcr1; /* 0xc: Transaction header capture 1 */ + u32 int_stat; /* 0x10: Interrupt status summary */ + u32 phy_cfg; /* 0x14: USB phy config */ +}; + +/* EHCI registers */ +struct msp_usbhs_regs { + u32 hciver; /* 0x0: Version and offset to operational regs */ + u32 hcsparams; /* 0x4: Host control structural parameters */ + u32 hccparams; /* 0x8: Host control capability parameters */ + u32 reserved0[5]; + u32 dciver; /* 0x20: Device interface version */ + u32 dccparams; /* 0x24: Device control capability parameters */ + u32 reserved1[6]; + u32 cmd; /* 0x40: USB command */ + u32 sts; /* 0x44: USB status */ + u32 int_ena; /* 0x48: USB interrupt enable */ + u32 frindex; /* 0x4c: Frame index */ + u32 reserved3; + union { + struct { + u32 flb_addr; /* 0x54: Frame list base address */ + u32 next_async_addr; /* 0x58: next asynchronous addr */ + u32 ttctrl; /* 0x5c: embedded transaction translator + async buffer status */ + u32 burst_size; /* 0x60: Controller burst size */ + u32 tx_fifo_ctrl; /* 0x64: Tx latency FIFO tuning */ + u32 reserved0[4]; + u32 endpt_nak; /* 0x78: Endpoint NAK */ + u32 endpt_nak_ena; /* 0x7c: Endpoint NAK enable */ + u32 cfg_flag; /* 0x80: Config flag */ + u32 port_sc1; /* 0x84: Port status & control 1 */ + u32 reserved1[7]; + u32 otgsc; /* 0xa4: OTG status & control */ + u32 mode; /* 0xa8: USB controller mode */ + } host; + + struct { + u32 dev_addr; /* 0x54: Device address */ + u32 endpt_list_addr; /* 0x58: Endpoint list address */ + u32 reserved0[7]; + u32 endpt_nak; /* 0x74 */ + u32 endpt_nak_ctrl; /* 0x78 */ + u32 cfg_flag; /* 0x80 */ + u32 port_sc1; /* 0x84: Port status & control 1 */ + u32 reserved[7]; + u32 otgsc; /* 0xa4: OTG status & control */ + u32 mode; /* 0xa8: USB controller mode */ + u32 endpt_setup_stat; /* 0xac */ + u32 endpt_prime; /* 0xb0 */ + u32 endpt_flush; /* 0xb4 */ + u32 endpt_stat; /* 0xb8 */ + u32 endpt_complete; /* 0xbc */ + u32 endpt_ctrl0; /* 0xc0 */ + u32 endpt_ctrl1; /* 0xc4 */ + u32 endpt_ctrl2; /* 0xc8 */ + u32 endpt_ctrl3; /* 0xcc */ + } device; + } u; +}; +/* + * Container for the more-generic platform_device. + * This exists mainly as a way to map the non-standard register + * spaces and make them accessible to the USB ISR. + */ +struct mspusb_device { + struct msp_mab_regs __iomem *mab_regs; + struct msp_usbid_regs __iomem *usbid_regs; + struct msp_usbhs_regs __iomem *usbhs_regs; + struct platform_device dev; +}; + +#define to_mspusb_device(x) container_of((x), struct mspusb_device, dev) +#define TO_HOST_ID(x) ((x) & 0x3) +#endif /*MSP_USB_H_*/ diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index ead6928fa6b8..c104f1039a69 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -337,7 +337,7 @@ unsigned long get_wchan(struct task_struct *p); /* * Return_address is a replacement for __builtin_return_address(count) * which on certain architectures cannot reasonably be implemented in GCC - * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * (MIPS, Alpha) or is unusable with -fomit-frame-pointer (i386). * Note that __builtin_return_address(x>=1) is forbidden because GCC * aborts compilation on some CPUs. It's simply not possible to unwind * some CPU's stackframes. diff --git a/arch/mips/include/asm/sgi/ioc.h b/arch/mips/include/asm/sgi/ioc.h index 57a971904cfe..380347b648e2 100644 --- a/arch/mips/include/asm/sgi/ioc.h +++ b/arch/mips/include/asm/sgi/ioc.h @@ -17,7 +17,7 @@ #include <asm/sgi/pi1.h> /* - * All registers are 8-bit wide alligned on 32-bit boundary. Bad things + * All registers are 8-bit wide aligned on 32-bit boundary. Bad things * happen if you try word access them. You have been warned. */ diff --git a/arch/mips/include/asm/sibyte/sb1250_mac.h b/arch/mips/include/asm/sibyte/sb1250_mac.h index 591b9061fd8e..77f787284235 100644 --- a/arch/mips/include/asm/sibyte/sb1250_mac.h +++ b/arch/mips/include/asm/sibyte/sb1250_mac.h @@ -520,7 +520,7 @@ #define G_MAC_RX_EOP_COUNTER(x) _SB_GETVALUE(x, S_MAC_RX_EOP_COUNTER, M_MAC_RX_EOP_COUNTER) /* - * MAC Recieve Address Filter Exact Match Registers (Table 9-21) + * MAC Receive Address Filter Exact Match Registers (Table 9-21) * Registers: MAC_ADDR0_0 through MAC_ADDR7_0 * Registers: MAC_ADDR0_1 through MAC_ADDR7_1 * Registers: MAC_ADDR0_2 through MAC_ADDR7_2 @@ -538,7 +538,7 @@ /* No bitfields */ /* - * MAC Recieve Address Filter Hash Match Registers (Table 9-22) + * MAC Receive Address Filter Hash Match Registers (Table 9-22) * Registers: MAC_HASH0_0 through MAC_HASH7_0 * Registers: MAC_HASH0_1 through MAC_HASH7_1 * Registers: MAC_HASH0_2 through MAC_HASH7_2 diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h index 1ca64b4d33d9..20ebeb875ee6 100644 --- a/arch/mips/include/asm/siginfo.h +++ b/arch/mips/include/asm/siginfo.h @@ -101,7 +101,7 @@ typedef struct siginfo { /* * si_code values - * Again these have been choosen to be IRIX compatible. + * Again these have been chosen to be IRIX compatible. */ #undef SI_ASYNCIO #undef SI_TIMER diff --git a/arch/mips/include/asm/sn/klconfig.h b/arch/mips/include/asm/sn/klconfig.h index 09e590daca17..fe02900b930d 100644 --- a/arch/mips/include/asm/sn/klconfig.h +++ b/arch/mips/include/asm/sn/klconfig.h @@ -78,7 +78,7 @@ typedef s32 klconf_off_t; */ #define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2) -/* XXX if each node is guranteed to have some memory */ +/* XXX if each node is guaranteed to have some memory */ #define MAX_PCI_DEVS 8 @@ -539,7 +539,7 @@ typedef struct klinfo_s { /* Generic info */ #define KLSTRUCT_IOC3_TTY 24 /* Early Access IO proms are compatible - only with KLSTRUCT values upto 24. */ + only with KLSTRUCT values up to 24. */ #define KLSTRUCT_FIBERCHANNEL 25 #define KLSTRUCT_MOD_SERIAL_NUM 26 diff --git a/arch/mips/include/asm/sn/sn0/hubio.h b/arch/mips/include/asm/sn/sn0/hubio.h index 31c76c021bb6..46286d8302a7 100644 --- a/arch/mips/include/asm/sn/sn0/hubio.h +++ b/arch/mips/include/asm/sn/sn0/hubio.h @@ -622,7 +622,7 @@ typedef union h1_icrbb_u { */ #define IIO_ICRB_PROC0 0 /* Source of request is Proc 0 */ #define IIO_ICRB_PROC1 1 /* Source of request is Proc 1 */ -#define IIO_ICRB_GB_REQ 2 /* Source is Guranteed BW request */ +#define IIO_ICRB_GB_REQ 2 /* Source is Guaranteed BW request */ #define IIO_ICRB_IO_REQ 3 /* Source is Normal IO request */ /* diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 396e402fbe2c..ca61e846ab0f 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -245,16 +245,16 @@ static inline void arch_read_lock(arch_rwlock_t *rw) __asm__ __volatile__( " .set noreorder # arch_read_lock \n" "1: ll %1, %2 \n" - " bltz %1, 2f \n" + " bltz %1, 3f \n" " addu %1, 1 \n" - " sc %1, %0 \n" + "2: sc %1, %0 \n" " beqz %1, 1b \n" " nop \n" " .subsection 2 \n" - "2: ll %1, %2 \n" - " bltz %1, 2b \n" + "3: ll %1, %2 \n" + " bltz %1, 3b \n" " addu %1, 1 \n" - " b 1b \n" + " b 2b \n" " nop \n" " .previous \n" " .set reorder \n" @@ -324,16 +324,16 @@ static inline void arch_write_lock(arch_rwlock_t *rw) __asm__ __volatile__( " .set noreorder # arch_write_lock \n" "1: ll %1, %2 \n" - " bnez %1, 2f \n" + " bnez %1, 3f \n" " lui %1, 0x8000 \n" - " sc %1, %0 \n" - " beqz %1, 2f \n" + "2: sc %1, %0 \n" + " beqz %1, 3f \n" " nop \n" " .subsection 2 \n" - "2: ll %1, %2 \n" - " bnez %1, 2b \n" + "3: ll %1, %2 \n" + " bnez %1, 3b \n" " lui %1, 0x8000 \n" - " b 1b \n" + " b 2b \n" " nop \n" " .previous \n" " .set reorder \n" diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 58730c5ce4bf..b4ba2449444b 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -346,7 +346,7 @@ * we can't dispatch it directly without trashing * some registers, so we'll try to detect this unlikely * case and program a software interrupt in the VPE, - * as would be done for a cross-VPE IPI. To accomodate + * as would be done for a cross-VPE IPI. To accommodate * the handling of that case, we're doing a DVPE instead * of just a DMT here to protect against other threads. * This is a lot of cruft to cover a tiny window. diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index d309556cacf8..d71160de4d10 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -88,9 +88,11 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL) +#define alloc_thread_info_node(tsk, node) \ + kzalloc_node(THREAD_SIZE, GFP_KERNEL, node) #else -#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) +#define alloc_thread_info_node(tsk, node) \ + kmalloc_node(THREAD_SIZE, GFP_KERNEL, node) #endif #define free_thread_info(info) kfree(info) diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index 544a2854598f..533812b61881 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h @@ -33,14 +33,6 @@ typedef unsigned short umode_t; #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \ - || defined(CONFIG_64BIT) -typedef u64 dma_addr_t; -#else -typedef u32 dma_addr_t; -#endif -typedef u64 dma64_addr_t; - /* * Don't use phys_t. You've been warned. */ diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 550725b881d5..fa2e37ea2be1 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -359,16 +359,20 @@ #define __NR_fanotify_init (__NR_Linux + 336) #define __NR_fanotify_mark (__NR_Linux + 337) #define __NR_prlimit64 (__NR_Linux + 338) +#define __NR_name_to_handle_at (__NR_Linux + 339) +#define __NR_open_by_handle_at (__NR_Linux + 340) +#define __NR_clock_adjtime (__NR_Linux + 341) +#define __NR_syncfs (__NR_Linux + 342) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 338 +#define __NR_Linux_syscalls 342 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 338 +#define __NR_O32_Linux_syscalls 342 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -674,16 +678,20 @@ #define __NR_fanotify_init (__NR_Linux + 295) #define __NR_fanotify_mark (__NR_Linux + 296) #define __NR_prlimit64 (__NR_Linux + 297) +#define __NR_name_to_handle_at (__NR_Linux + 298) +#define __NR_open_by_handle_at (__NR_Linux + 299) +#define __NR_clock_adjtime (__NR_Linux + 300) +#define __NR_syncfs (__NR_Linux + 301) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 297 +#define __NR_Linux_syscalls 301 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 297 +#define __NR_64_Linux_syscalls 301 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -994,16 +1002,20 @@ #define __NR_fanotify_init (__NR_Linux + 300) #define __NR_fanotify_mark (__NR_Linux + 301) #define __NR_prlimit64 (__NR_Linux + 302) +#define __NR_name_to_handle_at (__NR_Linux + 303) +#define __NR_open_by_handle_at (__NR_Linux + 304) +#define __NR_clock_adjtime (__NR_Linux + 305) +#define __NR_syncfs (__NR_Linux + 306) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 302 +#define __NR_Linux_syscalls 306 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 302 +#define __NR_N32_Linux_syscalls 306 #ifdef __KERNEL__ diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h index 22361d5e3bf0..fa133c1bc1f9 100644 --- a/arch/mips/include/asm/war.h +++ b/arch/mips/include/asm/war.h @@ -227,7 +227,7 @@ #endif /* - * On the R10000 upto version 2.6 (not sure about 2.7) there is a bug that + * On the R10000 up to version 2.6 (not sure about 2.7) there is a bug that * may cause ll / sc and lld / scd sequences to execute non-atomically. */ #ifndef R10000_LLSC_WAR diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index 35b3e2f0af04..260df4750949 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -23,9 +23,9 @@ static DEFINE_RAW_SPINLOCK(r4030_lock); -static void enable_r4030_irq(unsigned int irq) +static void enable_r4030_irq(struct irq_data *d) { - unsigned int mask = 1 << (irq - JAZZ_IRQ_START); + unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START); unsigned long flags; raw_spin_lock_irqsave(&r4030_lock, flags); @@ -34,9 +34,9 @@ static void enable_r4030_irq(unsigned int irq) raw_spin_unlock_irqrestore(&r4030_lock, flags); } -void disable_r4030_irq(unsigned int irq) +void disable_r4030_irq(struct irq_data *d) { - unsigned int mask = ~(1 << (irq - JAZZ_IRQ_START)); + unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START)); unsigned long flags; raw_spin_lock_irqsave(&r4030_lock, flags); @@ -47,10 +47,8 @@ void disable_r4030_irq(unsigned int irq) static struct irq_chip r4030_irq_type = { .name = "R4030", - .ack = disable_r4030_irq, - .mask = disable_r4030_irq, - .mask_ack = disable_r4030_irq, - .unmask = enable_r4030_irq, + .irq_mask = disable_r4030_irq, + .irq_unmask = enable_r4030_irq, }; void __init init_r4030_ints(void) @@ -58,7 +56,7 @@ void __init init_r4030_ints(void) int i; for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++) - set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &r4030_irq_type, handle_level_irq); r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index a604eaeb6c08..a9dff3321251 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile @@ -17,4 +17,4 @@ obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o obj-$(CONFIG_PM) += pm.o -EXTRA_CFLAGS += -Werror -Wall +ccflags-y := -Werror -Wall diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 2c0e107966ad..c3b04be3fb2b 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -23,6 +23,7 @@ #include <linux/spi/spi_gpio.h> #include <linux/power_supply.h> #include <linux/power/jz4740-battery.h> +#include <linux/power/gpio-charger.h> #include <asm/mach-jz4740/jz4740_fb.h> #include <asm/mach-jz4740/jz4740_mmc.h> @@ -49,14 +50,14 @@ static bool is_avt2; /* NAND */ static struct nand_ecclayout qi_lb60_ecclayout_1gb = { -/* .eccbytes = 36, + .eccbytes = 36, .eccpos = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41 - },*/ + }, .oobfree = { { .offset = 2, .length = 4 }, { .offset = 42, .length = 22 } @@ -64,7 +65,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_1gb = { }; /* Early prototypes of the QI LB60 had only 1GB of NAND. - * In order to support these devices aswell the partition and ecc layout is + * In order to support these devices as well the partition and ecc layout is * initialized depending on the NAND size */ static struct mtd_partition qi_lb60_partitions_1gb[] = { { @@ -85,7 +86,7 @@ static struct mtd_partition qi_lb60_partitions_1gb[] = { }; static struct nand_ecclayout qi_lb60_ecclayout_2gb = { -/* .eccbytes = 72, + .eccbytes = 72, .eccpos = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, @@ -96,7 +97,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_2gb = { 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 - },*/ + }, .oobfree = { { .offset = 2, .length = 10 }, { .offset = 84, .length = 44 }, @@ -396,6 +397,28 @@ static struct platform_device qi_lb60_pwm_beeper = { }, }; +/* charger */ +static char *qi_lb60_batteries[] = { + "battery", +}; + +static struct gpio_charger_platform_data qi_lb60_charger_pdata = { + .name = "usb", + .type = POWER_SUPPLY_TYPE_USB, + .gpio = JZ_GPIO_PORTD(28), + .gpio_active_low = 1, + .supplied_to = qi_lb60_batteries, + .num_supplicants = ARRAY_SIZE(qi_lb60_batteries), +}; + +static struct platform_device qi_lb60_charger_device = { + .name = "gpio-charger", + .dev = { + .platform_data = &qi_lb60_charger_pdata, + }, +}; + + static struct platform_device *jz_platform_devices[] __initdata = { &jz4740_udc_device, &jz4740_mmc_device, @@ -410,12 +433,13 @@ static struct platform_device *jz_platform_devices[] __initdata = { &jz4740_adc_device, &qi_lb60_gpio_keys, &qi_lb60_pwm_beeper, + &qi_lb60_charger_device, }; static void __init board_gpio_setup(void) { /* We only need to enable/disable pullup here for pins used in generic - * drivers. Everything else is done by the drivers themselfs. */ + * drivers. Everything else is done by the drivers themselves. */ jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N); jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD); } diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 88e6aeda5bf1..73031f7fc827 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c @@ -86,7 +86,6 @@ struct jz_gpio_chip { spinlock_t lock; struct gpio_chip gpio_chip; - struct irq_chip irq_chip; struct sys_device sysdev; }; @@ -102,9 +101,9 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip); } -static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq) +static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) { - return get_irq_chip_data(irq); + return irq_data_get_irq_chip_data(data); } static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) @@ -307,7 +306,7 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) uint32_t flag; unsigned int gpio_irq; unsigned int gpio_bank; - struct jz_gpio_chip *chip = get_irq_desc_data(desc); + struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc); gpio_bank = JZ4740_IRQ_GPIO0 - irq; @@ -325,62 +324,52 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) generic_handle_irq(gpio_irq); }; -static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg) +static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg) { - struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); - writel(IRQ_TO_BIT(irq), chip->base + reg); + struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); + writel(IRQ_TO_BIT(data->irq), chip->base + reg); } -static void jz_gpio_irq_mask(unsigned int irq) +static void jz_gpio_irq_mask(struct irq_data *data) { - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET); }; -static void jz_gpio_irq_unmask(unsigned int irq) +static void jz_gpio_irq_unmask(struct irq_data *data) { - struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); + struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); - jz_gpio_check_trigger_both(chip, irq); + jz_gpio_check_trigger_both(chip, data->irq); - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR); }; /* TODO: Check if function is gpio */ -static unsigned int jz_gpio_irq_startup(unsigned int irq) +static unsigned int jz_gpio_irq_startup(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(irq); - - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET); - - desc->status &= ~IRQ_MASKED; - jz_gpio_irq_unmask(irq); - + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET); + jz_gpio_irq_unmask(data); return 0; } -static void jz_gpio_irq_shutdown(unsigned int irq) +static void jz_gpio_irq_shutdown(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(irq); - - jz_gpio_irq_mask(irq); - desc->status |= IRQ_MASKED; + jz_gpio_irq_mask(data); /* Set direction to input */ - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR); } -static void jz_gpio_irq_ack(unsigned int irq) +static void jz_gpio_irq_ack(struct irq_data *data) { - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR); }; -static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) +static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) { - struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); - struct irq_desc *desc = irq_to_desc(irq); - - jz_gpio_irq_mask(irq); + struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); + unsigned int irq = data->irq; if (flow_type == IRQ_TYPE_EDGE_BOTH) { uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN); @@ -395,45 +384,54 @@ static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) switch (flow_type) { case IRQ_TYPE_EDGE_RISING: - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET); - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET); break; case IRQ_TYPE_EDGE_FALLING: - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET); break; case IRQ_TYPE_LEVEL_HIGH: - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET); - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR); break; case IRQ_TYPE_LEVEL_LOW: - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); - jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); + jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR); break; default: return -EINVAL; } - if (!(desc->status & IRQ_MASKED)) - jz_gpio_irq_unmask(irq); - return 0; } -static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on) +static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) { - struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); + struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); spin_lock(&chip->lock); if (on) - chip->wakeup |= IRQ_TO_BIT(irq); + chip->wakeup |= IRQ_TO_BIT(data->irq); else - chip->wakeup &= ~IRQ_TO_BIT(irq); + chip->wakeup &= ~IRQ_TO_BIT(data->irq); spin_unlock(&chip->lock); - set_irq_wake(chip->irq, on); + irq_set_irq_wake(chip->irq, on); return 0; } +static struct irq_chip jz_gpio_irq_chip = { + .name = "GPIO", + .irq_mask = jz_gpio_irq_mask, + .irq_unmask = jz_gpio_irq_unmask, + .irq_ack = jz_gpio_irq_ack, + .irq_startup = jz_gpio_irq_startup, + .irq_shutdown = jz_gpio_irq_shutdown, + .irq_set_type = jz_gpio_irq_set_type, + .irq_set_wake = jz_gpio_irq_set_wake, + .flags = IRQCHIP_SET_TYPE_MASKED, +}; + /* * This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. @@ -452,16 +450,6 @@ static struct lock_class_key gpio_lock_class; .base = JZ4740_GPIO_BASE_ ## _bank, \ .ngpio = JZ4740_GPIO_NUM_ ## _bank, \ }, \ - .irq_chip = { \ - .name = "GPIO Bank " # _bank, \ - .mask = jz_gpio_irq_mask, \ - .unmask = jz_gpio_irq_unmask, \ - .ack = jz_gpio_irq_ack, \ - .startup = jz_gpio_irq_startup, \ - .shutdown = jz_gpio_irq_shutdown, \ - .set_type = jz_gpio_irq_set_type, \ - .set_wake = jz_gpio_irq_set_wake, \ - }, \ } static struct jz_gpio_chip jz4740_gpio_chips[] = { @@ -522,13 +510,14 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) gpiochip_add(&chip->gpio_chip); chip->irq = JZ4740_IRQ_INTC_GPIO(id); - set_irq_data(chip->irq, chip); - set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler); + irq_set_handler_data(chip->irq, chip); + irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler); for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { - lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class); - set_irq_chip_data(irq, chip); - set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq); + irq_set_lockdep_class(irq, &gpio_lock_class); + irq_set_chip_data(irq, chip); + irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, + handle_level_irq); } return 0; diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c index 7d33ff83580f..d82c0c430e03 100644 --- a/arch/mips/jz4740/irq.c +++ b/arch/mips/jz4740/irq.c @@ -43,32 +43,37 @@ static uint32_t jz_intc_saved; #define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE) -static void intc_irq_unmask(unsigned int irq) +static inline unsigned long intc_irq_bit(struct irq_data *data) { - writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); + return (unsigned long)irq_data_get_irq_chip_data(data); } -static void intc_irq_mask(unsigned int irq) +static void intc_irq_unmask(struct irq_data *data) { - writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK); + writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); } -static int intc_irq_set_wake(unsigned int irq, unsigned int on) +static void intc_irq_mask(struct irq_data *data) +{ + writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK); +} + +static int intc_irq_set_wake(struct irq_data *data, unsigned int on) { if (on) - jz_intc_wakeup |= IRQ_BIT(irq); + jz_intc_wakeup |= intc_irq_bit(data); else - jz_intc_wakeup &= ~IRQ_BIT(irq); + jz_intc_wakeup &= ~intc_irq_bit(data); return 0; } static struct irq_chip intc_irq_type = { .name = "INTC", - .mask = intc_irq_mask, - .mask_ack = intc_irq_mask, - .unmask = intc_irq_unmask, - .set_wake = intc_irq_set_wake, + .irq_mask = intc_irq_mask, + .irq_mask_ack = intc_irq_mask, + .irq_unmask = intc_irq_unmask, + .irq_set_wake = intc_irq_set_wake, }; static irqreturn_t jz4740_cascade(int irq, void *data) @@ -95,9 +100,12 @@ void __init arch_init_irq(void) jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); + /* Mask all irqs */ + writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK); + for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { - intc_irq_mask(i); - set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); + irq_set_chip_data(i, (void *)IRQ_BIT(i)); + irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq); } setup_irq(2, &jz4740_cascade_action); diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 1cc9e544d16b..10929e2bc6d8 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c @@ -289,3 +289,19 @@ void jz4740_serial_device_register(void) platform_device_register(&jz4740_uart_device); } + +/* Watchdog */ +static struct resource jz4740_wdt_resources[] = { + { + .start = JZ4740_WDT_BASE_ADDR, + .end = JZ4740_WDT_BASE_ADDR + 0x10 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device jz4740_wdt_device = { + .name = "jz4740-wdt", + .id = -1, + .num_resources = ARRAY_SIZE(jz4740_wdt_resources), + .resource = jz4740_wdt_resources, +}; diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index b8bb8ba60869..f305ca14351b 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -73,7 +73,7 @@ static inline void mult_sh_align_mod(long *v1, long *v2, long *w, : "0" (5), "1" (8), "2" (5)); align_mod(align, mod); /* - * The trailing nop is needed to fullfill the two-instruction + * The trailing nop is needed to fulfill the two-instruction * requirement between reading hi/lo and staring a mult/div. * Leaving it out may cause gas insert a nop itself breaking * the desired alignment of the next chunk. diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 5a84a1f11231..94ca2b018af7 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -17,29 +17,13 @@ #include <asm/cacheflush.h> #include <asm/uasm.h> -/* - * If the Instruction Pointer is in module space (0xc0000000), return true; - * otherwise, it is in kernel space (0x80000000), return false. - * - * FIXME: This will not work when the kernel space and module space are the - * same. If they are the same, we need to modify scripts/recordmcount.pl, - * ftrace_make_nop/call() and the other related parts to ensure the - * enabling/disabling of the calling site to _mcount is right for both kernel - * and module. - */ - -static inline int in_module(unsigned long ip) -{ - return ip & 0x40000000; -} +#include <asm-generic/sections.h> #ifdef CONFIG_DYNAMIC_FTRACE #define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ #define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */ -#define INSN_B_1F_4 0x10000004 /* b 1f; offset = 4 */ -#define INSN_B_1F_5 0x10000005 /* b 1f; offset = 5 */ #define INSN_NOP 0x00000000 /* nop */ #define INSN_JAL(addr) \ ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK))) @@ -69,6 +53,20 @@ static inline void ftrace_dyn_arch_init_insns(void) #endif } +/* + * Check if the address is in kernel space + * + * Clone core_kernel_text() from kernel/extable.c, but doesn't call + * init_kernel_text() for Ftrace doesn't trace functions in init sections. + */ +static inline int in_kernel_space(unsigned long ip) +{ + if (ip >= (unsigned long)_stext && + ip <= (unsigned long)_etext) + return 1; + return 0; +} + static int ftrace_modify_code(unsigned long ip, unsigned int new_code) { int faulted; @@ -84,6 +82,42 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code) return 0; } +/* + * The details about the calling site of mcount on MIPS + * + * 1. For kernel: + * + * move at, ra + * jal _mcount --> nop + * + * 2. For modules: + * + * 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT + * + * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) + * addiu v1, v1, low_16bit_of_mcount + * move at, ra + * move $12, ra_address + * jalr v1 + * sub sp, sp, 8 + * 1: offset = 5 instructions + * 2.2 For the Other situations + * + * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) + * addiu v1, v1, low_16bit_of_mcount + * move at, ra + * jalr v1 + * nop | move $12, ra_address | sub sp, sp, 8 + * 1: offset = 4 instructions + */ + +#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) +#define MCOUNT_OFFSET_INSNS 5 +#else +#define MCOUNT_OFFSET_INSNS 4 +#endif +#define INSN_B_1F (0x10000000 | MCOUNT_OFFSET_INSNS) + int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { @@ -91,39 +125,11 @@ int ftrace_make_nop(struct module *mod, unsigned long ip = rec->ip; /* - * We have compiled module with -mlong-calls, but compiled the kernel - * without it, we need to cope with them respectively. + * If ip is in kernel space, no long call, otherwise, long call is + * needed. */ - if (in_module(ip)) { -#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) - /* - * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) - * addiu v1, v1, low_16bit_of_mcount - * move at, ra - * move $12, ra_address - * jalr v1 - * sub sp, sp, 8 - * 1: offset = 5 instructions - */ - new = INSN_B_1F_5; -#else - /* - * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) - * addiu v1, v1, low_16bit_of_mcount - * move at, ra - * jalr v1 - * nop | move $12, ra_address | sub sp, sp, 8 - * 1: offset = 4 instructions - */ - new = INSN_B_1F_4; -#endif - } else { - /* - * move at, ra - * jal _mcount --> nop - */ - new = INSN_NOP; - } + new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F; + return ftrace_modify_code(ip, new); } @@ -132,8 +138,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) unsigned int new; unsigned long ip = rec->ip; - /* ip, module: 0xc0000000, kernel: 0x80000000 */ - new = in_module(ip) ? insn_lui_v1_hi16_mcount : insn_jal_ftrace_caller; + new = in_kernel_space(ip) ? insn_jal_ftrace_caller : + insn_lui_v1_hi16_mcount; return ftrace_modify_code(ip, new); } @@ -190,29 +196,25 @@ int ftrace_disable_ftrace_graph_caller(void) #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ -unsigned long ftrace_get_parent_addr(unsigned long self_addr, - unsigned long parent, - unsigned long parent_addr, - unsigned long fp) +unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long + old_parent_ra, unsigned long parent_ra_addr, unsigned long fp) { - unsigned long sp, ip, ra; + unsigned long sp, ip, tmp; unsigned int code; int faulted; /* - * For module, move the ip from calling site of mcount to the - * instruction "lui v1, hi_16bit_of_mcount"(offset is 20), but for - * kernel, move to the instruction "move ra, at"(offset is 12) + * For module, move the ip from the return address after the + * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for + * kernel, move after the instruction "move ra, at"(offset is 16) */ - ip = self_addr - (in_module(self_addr) ? 20 : 12); + ip = self_ra - (in_kernel_space(self_ra) ? 16 : 24); /* * search the text until finding the non-store instruction or "s{d,w} * ra, offset(sp)" instruction */ do { - ip -= 4; - /* get the code at "ip": code = *(unsigned int *)ip; */ safe_load_code(code, ip, faulted); @@ -224,18 +226,20 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, * store the ra on the stack */ if ((code & S_R_SP) != S_R_SP) - return parent_addr; + return parent_ra_addr; - } while (((code & S_RA_SP) != S_RA_SP)); + /* Move to the next instruction */ + ip -= 4; + } while ((code & S_RA_SP) != S_RA_SP); sp = fp + (code & OFFSET_MASK); - /* ra = *(unsigned long *)sp; */ - safe_load_stack(ra, sp, faulted); + /* tmp = *(unsigned long *)sp; */ + safe_load_stack(tmp, sp, faulted); if (unlikely(faulted)) return 0; - if (ra == parent) + if (tmp == old_parent_ra) return sp; return 0; } @@ -246,21 +250,21 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr, * Hook the return address and push it in the stack of return addrs * in current thread info. */ -void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, +void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra, unsigned long fp) { - unsigned long old; + unsigned long old_parent_ra; struct ftrace_graph_ent trace; unsigned long return_hooker = (unsigned long) &return_to_handler; - int faulted; + int faulted, insns; if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; /* - * "parent" is the stack address saved the return address of the caller - * of _mcount. + * "parent_ra_addr" is the stack address saved the return address of + * the caller of _mcount. * * if the gcc < 4.5, a leaf function does not save the return address * in the stack address, so, we "emulate" one in _mcount's stack space, @@ -275,37 +279,44 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, * do it in ftrace_graph_caller of mcount.S. */ - /* old = *parent; */ - safe_load_stack(old, parent, faulted); + /* old_parent_ra = *parent_ra_addr; */ + safe_load_stack(old_parent_ra, parent_ra_addr, faulted); if (unlikely(faulted)) goto out; #ifndef KBUILD_MCOUNT_RA_ADDRESS - parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old, - (unsigned long)parent, fp); + parent_ra_addr = (unsigned long *)ftrace_get_parent_ra_addr(self_ra, + old_parent_ra, (unsigned long)parent_ra_addr, fp); /* * If fails when getting the stack address of the non-leaf function's * ra, stop function graph tracer and return */ - if (parent == 0) + if (parent_ra_addr == 0) goto out; #endif - /* *parent = return_hooker; */ - safe_store_stack(return_hooker, parent, faulted); + /* *parent_ra_addr = return_hooker; */ + safe_store_stack(return_hooker, parent_ra_addr, faulted); if (unlikely(faulted)) goto out; - if (ftrace_push_return_trace(old, self_addr, &trace.depth, fp) == - -EBUSY) { - *parent = old; + if (ftrace_push_return_trace(old_parent_ra, self_ra, &trace.depth, fp) + == -EBUSY) { + *parent_ra_addr = old_parent_ra; return; } - trace.func = self_addr; + /* + * Get the recorded ip of the current mcount calling site in the + * __mcount_loc section, which will be used to filter the function + * entries configured through the tracing/set_graph_function interface. + */ + + insns = in_kernel_space(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1; + trace.func = self_ra - (MCOUNT_INSN_SIZE * insns); /* Only trace if the calling function expects to */ if (!ftrace_graph_entry(&trace)) { current->curr_ret_stack--; - *parent = old; + *parent_ra_addr = old_parent_ra; } return; out: diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index 9fadd17888d9..391221b6a6aa 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -125,84 +125,11 @@ void __init setup_pit_timer(void) setup_irq(0, &irq0); } -/* - * Since the PIT overflows every tick, its not very useful - * to just read by itself. So use jiffies to emulate a free - * running counter: - */ -static cycle_t pit_read(struct clocksource *cs) -{ - unsigned long flags; - int count; - u32 jifs; - static int old_count; - static u32 old_jifs; - - raw_spin_lock_irqsave(&i8253_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - count = inb_p(PIT_CH0); /* read the latched count */ - count |= inb_p(PIT_CH0) << 8; - - /* VIA686a test code... reset the latch if count > max + 1 */ - if (count > LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(LATCH & 0xff, PIT_CH0); - outb(LATCH >> 8, PIT_CH0); - count = LATCH - 1; - } - - /* - * It's possible for count to appear to go the wrong way for a - * couple of reasons: - * - * 1. The timer counter underflows, but we haven't handled the - * resulting interrupt and incremented jiffies yet. - * 2. Hardware problem with the timer, not giving us continuous time, - * the counter does small "jumps" upwards on some Pentium systems, - * (see c't 95/10 page 335 for Neptun bug.) - * - * Previous attempts to handle these cases intelligently were - * buggy, so we just do the simple thing now. - */ - if (count > old_count && jifs == old_jifs) { - count = old_count; - } - old_count = count; - old_jifs = jifs; - - raw_spin_unlock_irqrestore(&i8253_lock, flags); - - count = (LATCH - 1) - count; - - return (cycle_t)(jifs * LATCH) + count; -} - -static struct clocksource clocksource_pit = { - .name = "pit", - .rating = 110, - .read = pit_read, - .mask = CLOCKSOURCE_MASK(32), -}; - static int __init init_pit_clocksource(void) { if (num_possible_cpus() > 1) /* PIT does not scale! */ return 0; - return clocksource_register_hz(&clocksource_pit, CLOCK_TICK_RATE); + return clocksource_i8253_init(); } arch_initcall(init_pit_clocksource); diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index c58176cc796b..c018696765d4 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -31,19 +31,19 @@ static int i8259A_auto_eoi = -1; DEFINE_RAW_SPINLOCK(i8259A_lock); -static void disable_8259A_irq(unsigned int irq); -static void enable_8259A_irq(unsigned int irq); -static void mask_and_ack_8259A(unsigned int irq); +static void disable_8259A_irq(struct irq_data *d); +static void enable_8259A_irq(struct irq_data *d); +static void mask_and_ack_8259A(struct irq_data *d); static void init_8259A(int auto_eoi); static struct irq_chip i8259A_chip = { - .name = "XT-PIC", - .mask = disable_8259A_irq, - .disable = disable_8259A_irq, - .unmask = enable_8259A_irq, - .mask_ack = mask_and_ack_8259A, + .name = "XT-PIC", + .irq_mask = disable_8259A_irq, + .irq_disable = disable_8259A_irq, + .irq_unmask = enable_8259A_irq, + .irq_mask_ack = mask_and_ack_8259A, #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF - .set_affinity = plat_set_irq_affinity, + .irq_set_affinity = plat_set_irq_affinity, #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ }; @@ -59,12 +59,11 @@ static unsigned int cached_irq_mask = 0xffff; #define cached_master_mask (cached_irq_mask) #define cached_slave_mask (cached_irq_mask >> 8) -static void disable_8259A_irq(unsigned int irq) +static void disable_8259A_irq(struct irq_data *d) { - unsigned int mask; + unsigned int mask, irq = d->irq - I8259A_IRQ_BASE; unsigned long flags; - irq -= I8259A_IRQ_BASE; mask = 1 << irq; raw_spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask |= mask; @@ -75,12 +74,11 @@ static void disable_8259A_irq(unsigned int irq) raw_spin_unlock_irqrestore(&i8259A_lock, flags); } -static void enable_8259A_irq(unsigned int irq) +static void enable_8259A_irq(struct irq_data *d) { - unsigned int mask; + unsigned int mask, irq = d->irq - I8259A_IRQ_BASE; unsigned long flags; - irq -= I8259A_IRQ_BASE; mask = ~(1 << irq); raw_spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask &= mask; @@ -112,7 +110,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); + irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); enable_irq(irq); } @@ -145,12 +143,11 @@ static inline int i8259A_irq_real(unsigned int irq) * first, _then_ send the EOI, and the order of EOI * to the two 8259s is important! */ -static void mask_and_ack_8259A(unsigned int irq) +static void mask_and_ack_8259A(struct irq_data *d) { - unsigned int irqmask; + unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE; unsigned long flags; - irq -= I8259A_IRQ_BASE; irqmask = 1 << irq; raw_spin_lock_irqsave(&i8259A_lock, flags); /* @@ -290,9 +287,9 @@ static void init_8259A(int auto_eoi) * In AEOI mode we just have to mask the interrupt * when acking. */ - i8259A_chip.mask_ack = disable_8259A_irq; + i8259A_chip.irq_mask_ack = disable_8259A_irq; else - i8259A_chip.mask_ack = mask_and_ack_8259A; + i8259A_chip.irq_mask_ack = mask_and_ack_8259A; udelay(100); /* wait for 8259A to initialize */ @@ -339,8 +336,8 @@ void __init init_i8259_irqs(void) init_8259A(0); for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { - set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); - set_irq_probe(i); + irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); + irq_set_probe(i); } setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 1774271af848..0c527f652196 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c @@ -87,17 +87,10 @@ unsigned int gic_get_int(void) return i; } -static unsigned int gic_irq_startup(unsigned int irq) +static void gic_irq_ack(struct irq_data *d) { - irq -= _irqbase; - pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); - GIC_SET_INTR_MASK(irq); - return 0; -} + unsigned int irq = d->irq - _irqbase; -static void gic_irq_ack(unsigned int irq) -{ - irq -= _irqbase; pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); GIC_CLR_INTR_MASK(irq); @@ -105,16 +98,16 @@ static void gic_irq_ack(unsigned int irq) GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); } -static void gic_mask_irq(unsigned int irq) +static void gic_mask_irq(struct irq_data *d) { - irq -= _irqbase; + unsigned int irq = d->irq - _irqbase; pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); GIC_CLR_INTR_MASK(irq); } -static void gic_unmask_irq(unsigned int irq) +static void gic_unmask_irq(struct irq_data *d) { - irq -= _irqbase; + unsigned int irq = d->irq - _irqbase; pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); GIC_SET_INTR_MASK(irq); } @@ -123,13 +116,14 @@ static void gic_unmask_irq(unsigned int irq) static DEFINE_SPINLOCK(gic_lock); -static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) +static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, + bool force) { + unsigned int irq = d->irq - _irqbase; cpumask_t tmp = CPU_MASK_NONE; unsigned long flags; int i; - irq -= _irqbase; pr_debug("%s(%d) called\n", __func__, irq); cpumask_and(&tmp, cpumask, cpu_online_mask); if (cpus_empty(tmp)) @@ -147,23 +141,22 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); } - cpumask_copy(irq_desc[irq].affinity, cpumask); + cpumask_copy(d->affinity, cpumask); spin_unlock_irqrestore(&gic_lock, flags); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif static struct irq_chip gic_irq_controller = { - .name = "MIPS GIC", - .startup = gic_irq_startup, - .ack = gic_irq_ack, - .mask = gic_mask_irq, - .mask_ack = gic_mask_irq, - .unmask = gic_unmask_irq, - .eoi = gic_unmask_irq, + .name = "MIPS GIC", + .irq_ack = gic_irq_ack, + .irq_mask = gic_mask_irq, + .irq_mask_ack = gic_mask_irq, + .irq_unmask = gic_unmask_irq, + .irq_eoi = gic_unmask_irq, #ifdef CONFIG_SMP - .set_affinity = gic_set_affinity, + .irq_set_affinity = gic_set_affinity, #endif }; @@ -236,7 +229,7 @@ static void __init gic_basic_init(int numintrs, int numvpes, vpe_local_setup(numvpes); for (i = _irqbase; i < (_irqbase + numintrs); i++) - set_irq_chip(i, &gic_irq_controller); + irq_set_chip(i, &gic_irq_controller); } void __init gic_init(unsigned long gic_base_addr, diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c index 42ef81461bfc..883fc6cead36 100644 --- a/arch/mips/kernel/irq-gt641xx.c +++ b/arch/mips/kernel/irq-gt641xx.c @@ -29,64 +29,64 @@ static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock); -static void ack_gt641xx_irq(unsigned int irq) +static void ack_gt641xx_irq(struct irq_data *d) { unsigned long flags; u32 cause; raw_spin_lock_irqsave(>641xx_irq_lock, flags); cause = GT_READ(GT_INTRCAUSE_OFS); - cause &= ~GT641XX_IRQ_TO_BIT(irq); + cause &= ~GT641XX_IRQ_TO_BIT(d->irq); GT_WRITE(GT_INTRCAUSE_OFS, cause); raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); } -static void mask_gt641xx_irq(unsigned int irq) +static void mask_gt641xx_irq(struct irq_data *d) { unsigned long flags; u32 mask; raw_spin_lock_irqsave(>641xx_irq_lock, flags); mask = GT_READ(GT_INTRMASK_OFS); - mask &= ~GT641XX_IRQ_TO_BIT(irq); + mask &= ~GT641XX_IRQ_TO_BIT(d->irq); GT_WRITE(GT_INTRMASK_OFS, mask); raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); } -static void mask_ack_gt641xx_irq(unsigned int irq) +static void mask_ack_gt641xx_irq(struct irq_data *d) { unsigned long flags; u32 cause, mask; raw_spin_lock_irqsave(>641xx_irq_lock, flags); mask = GT_READ(GT_INTRMASK_OFS); - mask &= ~GT641XX_IRQ_TO_BIT(irq); + mask &= ~GT641XX_IRQ_TO_BIT(d->irq); GT_WRITE(GT_INTRMASK_OFS, mask); cause = GT_READ(GT_INTRCAUSE_OFS); - cause &= ~GT641XX_IRQ_TO_BIT(irq); + cause &= ~GT641XX_IRQ_TO_BIT(d->irq); GT_WRITE(GT_INTRCAUSE_OFS, cause); raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); } -static void unmask_gt641xx_irq(unsigned int irq) +static void unmask_gt641xx_irq(struct irq_data *d) { unsigned long flags; u32 mask; raw_spin_lock_irqsave(>641xx_irq_lock, flags); mask = GT_READ(GT_INTRMASK_OFS); - mask |= GT641XX_IRQ_TO_BIT(irq); + mask |= GT641XX_IRQ_TO_BIT(d->irq); GT_WRITE(GT_INTRMASK_OFS, mask); raw_spin_unlock_irqrestore(>641xx_irq_lock, flags); } static struct irq_chip gt641xx_irq_chip = { .name = "GT641xx", - .ack = ack_gt641xx_irq, - .mask = mask_gt641xx_irq, - .mask_ack = mask_ack_gt641xx_irq, - .unmask = unmask_gt641xx_irq, + .irq_ack = ack_gt641xx_irq, + .irq_mask = mask_gt641xx_irq, + .irq_mask_ack = mask_ack_gt641xx_irq, + .irq_unmask = unmask_gt641xx_irq, }; void gt641xx_irq_dispatch(void) @@ -126,6 +126,6 @@ void __init gt641xx_irq_init(void) * bit31: logical or of bits[25:1]. */ for (i = 1; i < 30; i++) - set_irq_chip_and_handler(GT641XX_IRQ_BASE + i, - >641xx_irq_chip, handle_level_irq); + irq_set_chip_and_handler(GT641XX_IRQ_BASE + i, + >641xx_irq_chip, handle_level_irq); } diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 6a8cd28133d5..0c6afeed89d2 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -28,8 +28,10 @@ static unsigned long _icctrl_msc; static unsigned int irq_base; /* mask off an interrupt */ -static inline void mask_msc_irq(unsigned int irq) +static inline void mask_msc_irq(struct irq_data *d) { + unsigned int irq = d->irq; + if (irq < (irq_base + 32)) MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base)); else @@ -37,8 +39,10 @@ static inline void mask_msc_irq(unsigned int irq) } /* unmask an interrupt */ -static inline void unmask_msc_irq(unsigned int irq) +static inline void unmask_msc_irq(struct irq_data *d) { + unsigned int irq = d->irq; + if (irq < (irq_base + 32)) MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base)); else @@ -48,9 +52,11 @@ static inline void unmask_msc_irq(unsigned int irq) /* * Masks and ACKs an IRQ */ -static void level_mask_and_ack_msc_irq(unsigned int irq) +static void level_mask_and_ack_msc_irq(struct irq_data *d) { - mask_msc_irq(irq); + unsigned int irq = d->irq; + + mask_msc_irq(d); if (!cpu_has_veic) MSCIC_WRITE(MSC01_IC_EOI, 0); /* This actually needs to be a call into platform code */ @@ -60,9 +66,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq) /* * Masks and ACKs an IRQ */ -static void edge_mask_and_ack_msc_irq(unsigned int irq) +static void edge_mask_and_ack_msc_irq(struct irq_data *d) { - mask_msc_irq(irq); + unsigned int irq = d->irq; + + mask_msc_irq(d); if (!cpu_has_veic) MSCIC_WRITE(MSC01_IC_EOI, 0); else { @@ -75,15 +83,6 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq) } /* - * End IRQ processing - */ -static void end_msc_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_msc_irq(irq); -} - -/* * Interrupt handler for interrupts coming from SOC-it. */ void ll_msc_irq(void) @@ -107,22 +106,20 @@ static void msc_bind_eic_interrupt(int irq, int set) static struct irq_chip msc_levelirq_type = { .name = "SOC-it-Level", - .ack = level_mask_and_ack_msc_irq, - .mask = mask_msc_irq, - .mask_ack = level_mask_and_ack_msc_irq, - .unmask = unmask_msc_irq, - .eoi = unmask_msc_irq, - .end = end_msc_irq, + .irq_ack = level_mask_and_ack_msc_irq, + .irq_mask = mask_msc_irq, + .irq_mask_ack = level_mask_and_ack_msc_irq, + .irq_unmask = unmask_msc_irq, + .irq_eoi = unmask_msc_irq, }; static struct irq_chip msc_edgeirq_type = { .name = "SOC-it-Edge", - .ack = edge_mask_and_ack_msc_irq, - .mask = mask_msc_irq, - .mask_ack = edge_mask_and_ack_msc_irq, - .unmask = unmask_msc_irq, - .eoi = unmask_msc_irq, - .end = end_msc_irq, + .irq_ack = edge_mask_and_ack_msc_irq, + .irq_mask = mask_msc_irq, + .irq_mask_ack = edge_mask_and_ack_msc_irq, + .irq_unmask = unmask_msc_irq, + .irq_eoi = unmask_msc_irq, }; @@ -140,16 +137,20 @@ void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqma switch (imp->im_type) { case MSC01_IRQ_EDGE: - set_irq_chip_and_handler_name(irqbase + n, - &msc_edgeirq_type, handle_edge_irq, "edge"); + irq_set_chip_and_handler_name(irqbase + n, + &msc_edgeirq_type, + handle_edge_irq, + "edge"); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - set_irq_chip_and_handler_name(irqbase+n, - &msc_levelirq_type, handle_level_irq, "level"); + irq_set_chip_and_handler_name(irqbase + n, + &msc_levelirq_type, + handle_level_irq, + "level"); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 9731e8b47862..a8a8977d5887 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -18,23 +18,23 @@ #include <asm/mipsregs.h> #include <asm/system.h> -static inline void unmask_rm7k_irq(unsigned int irq) +static inline void unmask_rm7k_irq(struct irq_data *d) { - set_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE)); + set_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE)); } -static inline void mask_rm7k_irq(unsigned int irq) +static inline void mask_rm7k_irq(struct irq_data *d) { - clear_c0_intcontrol(0x100 << (irq - RM7K_CPU_IRQ_BASE)); + clear_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE)); } static struct irq_chip rm7k_irq_controller = { .name = "RM7000", - .ack = mask_rm7k_irq, - .mask = mask_rm7k_irq, - .mask_ack = mask_rm7k_irq, - .unmask = unmask_rm7k_irq, - .eoi = unmask_rm7k_irq + .irq_ack = mask_rm7k_irq, + .irq_mask = mask_rm7k_irq, + .irq_mask_ack = mask_rm7k_irq, + .irq_unmask = unmask_rm7k_irq, + .irq_eoi = unmask_rm7k_irq }; void __init rm7k_cpu_irq_init(void) @@ -45,6 +45,6 @@ void __init rm7k_cpu_irq_init(void) clear_c0_intcontrol(0x00000f00); /* Mask all */ for (i = base; i < base + 4; i++) - set_irq_chip_and_handler(i, &rm7k_irq_controller, + irq_set_chip_and_handler(i, &rm7k_irq_controller, handle_percpu_irq); } diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index b7e4025b58a8..38874a4b9255 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -19,22 +19,22 @@ #include <asm/mipsregs.h> #include <asm/system.h> -static inline void unmask_rm9k_irq(unsigned int irq) +static inline void unmask_rm9k_irq(struct irq_data *d) { - set_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE)); + set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE)); } -static inline void mask_rm9k_irq(unsigned int irq) +static inline void mask_rm9k_irq(struct irq_data *d) { - clear_c0_intcontrol(0x1000 << (irq - RM9K_CPU_IRQ_BASE)); + clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE)); } -static inline void rm9k_cpu_irq_enable(unsigned int irq) +static inline void rm9k_cpu_irq_enable(struct irq_data *d) { unsigned long flags; local_irq_save(flags); - unmask_rm9k_irq(irq); + unmask_rm9k_irq(d); local_irq_restore(flags); } @@ -43,50 +43,47 @@ static inline void rm9k_cpu_irq_enable(unsigned int irq) */ static void local_rm9k_perfcounter_irq_startup(void *args) { - unsigned int irq = (unsigned int) args; - - rm9k_cpu_irq_enable(irq); + rm9k_cpu_irq_enable(args); } -static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq) +static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d) { - on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 1); + on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1); return 0; } static void local_rm9k_perfcounter_irq_shutdown(void *args) { - unsigned int irq = (unsigned int) args; unsigned long flags; local_irq_save(flags); - mask_rm9k_irq(irq); + mask_rm9k_irq(args); local_irq_restore(flags); } -static void rm9k_perfcounter_irq_shutdown(unsigned int irq) +static void rm9k_perfcounter_irq_shutdown(struct irq_data *d) { - on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 1); + on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1); } static struct irq_chip rm9k_irq_controller = { .name = "RM9000", - .ack = mask_rm9k_irq, - .mask = mask_rm9k_irq, - .mask_ack = mask_rm9k_irq, - .unmask = unmask_rm9k_irq, - .eoi = unmask_rm9k_irq + .irq_ack = mask_rm9k_irq, + .irq_mask = mask_rm9k_irq, + .irq_mask_ack = mask_rm9k_irq, + .irq_unmask = unmask_rm9k_irq, + .irq_eoi = unmask_rm9k_irq }; static struct irq_chip rm9k_perfcounter_irq = { .name = "RM9000", - .startup = rm9k_perfcounter_irq_startup, - .shutdown = rm9k_perfcounter_irq_shutdown, - .ack = mask_rm9k_irq, - .mask = mask_rm9k_irq, - .mask_ack = mask_rm9k_irq, - .unmask = unmask_rm9k_irq, + .irq_startup = rm9k_perfcounter_irq_startup, + .irq_shutdown = rm9k_perfcounter_irq_shutdown, + .irq_ack = mask_rm9k_irq, + .irq_mask = mask_rm9k_irq, + .irq_mask_ack = mask_rm9k_irq, + .irq_unmask = unmask_rm9k_irq, }; unsigned int rm9000_perfcount_irq; @@ -101,10 +98,10 @@ void __init rm9k_cpu_irq_init(void) clear_c0_intcontrol(0x0000f000); /* Mask all */ for (i = base; i < base + 4; i++) - set_irq_chip_and_handler(i, &rm9k_irq_controller, + irq_set_chip_and_handler(i, &rm9k_irq_controller, handle_level_irq); rm9000_perfcount_irq = base + 1; - set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, + irq_set_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, handle_percpu_irq); } diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 4f93db58a79e..9b734d74ae8e 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -81,48 +81,9 @@ void ack_bad_irq(unsigned int irq) atomic_t irq_err_count; -/* - * Generic, controller-independent functions: - */ - -int show_interrupts(struct seq_file *p, void *v) +int arch_show_interrupts(struct seq_file *p, int prec) { - int i = *(loff_t *) v, j; - struct irqaction * action; - unsigned long flags; - - if (i == 0) { - seq_printf(p, " "); - for_each_online_cpu(j) - seq_printf(p, "CPU%d ", j); - seq_putc(p, '\n'); - } - - if (i < NR_IRQS) { - raw_spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto skip; - seq_printf(p, "%3d: ", i); -#ifndef CONFIG_SMP - seq_printf(p, "%10u ", kstat_irqs(i)); -#else - for_each_online_cpu(j) - seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); -#endif - seq_printf(p, " %14s", irq_desc[i].chip->name); - seq_printf(p, " %s", action->name); - - for (action=action->next; action; action = action->next) - seq_printf(p, ", %s", action->name); - - seq_putc(p, '\n'); -skip: - raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { - seq_putc(p, '\n'); - seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); - } + seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); return 0; } @@ -141,7 +102,7 @@ void __init init_IRQ(void) #endif for (i = 0; i < NR_IRQS; i++) - set_irq_noprobe(i); + irq_set_noprobe(i); arch_init_irq(); @@ -183,8 +144,8 @@ void __irq_entry do_IRQ(unsigned int irq) { irq_enter(); check_stack_overflow(); - __DO_IRQ_SMTC_HOOK(irq); - generic_handle_irq(irq); + if (!smtc_handle_on_other_cpu(irq)) + generic_handle_irq(irq); irq_exit(); } @@ -197,7 +158,7 @@ void __irq_entry do_IRQ(unsigned int irq) void __irq_entry do_IRQ_no_affinity(unsigned int irq) { irq_enter(); - __NO_AFFINITY_IRQ_SMTC_HOOK(irq); + smtc_im_backstop(irq); generic_handle_irq(irq); irq_exit(); } diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 0262abe09121..6e71b284f6c9 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -37,42 +37,38 @@ #include <asm/mipsmtregs.h> #include <asm/system.h> -static inline void unmask_mips_irq(unsigned int irq) +static inline void unmask_mips_irq(struct irq_data *d) { - set_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE)); + set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); irq_enable_hazard(); } -static inline void mask_mips_irq(unsigned int irq) +static inline void mask_mips_irq(struct irq_data *d) { - clear_c0_status(0x100 << (irq - MIPS_CPU_IRQ_BASE)); + clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); irq_disable_hazard(); } static struct irq_chip mips_cpu_irq_controller = { .name = "MIPS", - .ack = mask_mips_irq, - .mask = mask_mips_irq, - .mask_ack = mask_mips_irq, - .unmask = unmask_mips_irq, - .eoi = unmask_mips_irq, + .irq_ack = mask_mips_irq, + .irq_mask = mask_mips_irq, + .irq_mask_ack = mask_mips_irq, + .irq_unmask = unmask_mips_irq, + .irq_eoi = unmask_mips_irq, }; /* * Basically the same as above but taking care of all the MT stuff */ -#define unmask_mips_mt_irq unmask_mips_irq -#define mask_mips_mt_irq mask_mips_irq - -static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) +static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) { unsigned int vpflags = dvpe(); - clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE)); + clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); evpe(vpflags); - unmask_mips_mt_irq(irq); - + unmask_mips_irq(d); return 0; } @@ -80,22 +76,22 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) * While we ack the interrupt interrupts are disabled and thus we don't need * to deal with concurrency issues. Same for mips_cpu_irq_end. */ -static void mips_mt_cpu_irq_ack(unsigned int irq) +static void mips_mt_cpu_irq_ack(struct irq_data *d) { unsigned int vpflags = dvpe(); - clear_c0_cause(0x100 << (irq - MIPS_CPU_IRQ_BASE)); + clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); evpe(vpflags); - mask_mips_mt_irq(irq); + mask_mips_irq(d); } static struct irq_chip mips_mt_cpu_irq_controller = { .name = "MIPS", - .startup = mips_mt_cpu_irq_startup, - .ack = mips_mt_cpu_irq_ack, - .mask = mask_mips_mt_irq, - .mask_ack = mips_mt_cpu_irq_ack, - .unmask = unmask_mips_mt_irq, - .eoi = unmask_mips_mt_irq, + .irq_startup = mips_mt_cpu_irq_startup, + .irq_ack = mips_mt_cpu_irq_ack, + .irq_mask = mask_mips_irq, + .irq_mask_ack = mips_mt_cpu_irq_ack, + .irq_unmask = unmask_mips_irq, + .irq_eoi = unmask_mips_irq, }; void __init mips_cpu_irq_init(void) @@ -113,10 +109,10 @@ void __init mips_cpu_irq_init(void) */ if (cpu_has_mipsmt) for (i = irq_base; i < irq_base + 2; i++) - set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller, + irq_set_chip_and_handler(i, &mips_mt_cpu_irq_controller, handle_percpu_irq); for (i = irq_base + 2; i < irq_base + 8; i++) - set_irq_chip_and_handler(i, &mips_cpu_irq_controller, + irq_set_chip_and_handler(i, &mips_cpu_irq_controller, handle_percpu_irq); } diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c index 95a96f69172d..b0c55b50218e 100644 --- a/arch/mips/kernel/irq_txx9.c +++ b/arch/mips/kernel/irq_txx9.c @@ -63,9 +63,9 @@ static struct { unsigned char mode; } txx9irq[TXx9_MAX_IR] __read_mostly; -static void txx9_irq_unmask(unsigned int irq) +static void txx9_irq_unmask(struct irq_data *d) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2]; int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8; @@ -79,9 +79,9 @@ static void txx9_irq_unmask(unsigned int irq) #endif } -static inline void txx9_irq_mask(unsigned int irq) +static inline void txx9_irq_mask(struct irq_data *d) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2]; int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8; @@ -99,19 +99,19 @@ static inline void txx9_irq_mask(unsigned int irq) #endif } -static void txx9_irq_mask_ack(unsigned int irq) +static void txx9_irq_mask_ack(struct irq_data *d) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; - txx9_irq_mask(irq); + txx9_irq_mask(d); /* clear edge detection */ if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode))) __raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr); } -static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type) +static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; u32 cr; u32 __iomem *crp; int ofs; @@ -139,11 +139,11 @@ static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type) static struct irq_chip txx9_irq_chip = { .name = "TXX9", - .ack = txx9_irq_mask_ack, - .mask = txx9_irq_mask, - .mask_ack = txx9_irq_mask_ack, - .unmask = txx9_irq_unmask, - .set_type = txx9_irq_set_type, + .irq_ack = txx9_irq_mask_ack, + .irq_mask = txx9_irq_mask, + .irq_mask_ack = txx9_irq_mask_ack, + .irq_unmask = txx9_irq_unmask, + .irq_set_type = txx9_irq_set_type, }; void __init txx9_irq_init(unsigned long baseaddr) @@ -154,8 +154,8 @@ void __init txx9_irq_init(unsigned long baseaddr) for (i = 0; i < TXx9_MAX_IR; i++) { txx9irq[i].level = 4; /* middle level */ txx9irq[i].mode = TXx9_IRCR_LOW; - set_irq_chip_and_handler(TXX9_IRQ_BASE + i, - &txx9_irq_chip, handle_level_irq); + irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &txx9_irq_chip, + handle_level_irq); } /* mask all IRC interrupts */ diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c index 2b7f3f703b83..a8244854d3dc 100644 --- a/arch/mips/kernel/perf_event.c +++ b/arch/mips/kernel/perf_event.c @@ -161,41 +161,6 @@ mipspmu_event_set_period(struct perf_event *event, return ret; } -static int mipspmu_enable(struct perf_event *event) -{ - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct hw_perf_event *hwc = &event->hw; - int idx; - int err = 0; - - /* To look for a free counter for this event. */ - idx = mipspmu->alloc_counter(cpuc, hwc); - if (idx < 0) { - err = idx; - goto out; - } - - /* - * If there is an event in the counter we are going to use then - * make sure it is disabled. - */ - event->hw.idx = idx; - mipspmu->disable_event(idx); - cpuc->events[idx] = event; - - /* Set the period for the event. */ - mipspmu_event_set_period(event, hwc, idx); - - /* Enable the event. */ - mipspmu->enable_event(hwc, idx); - - /* Propagate our changes to the userspace mapping. */ - perf_event_update_userpage(event); - -out: - return err; -} - static void mipspmu_event_update(struct perf_event *event, struct hw_perf_event *hwc, int idx) @@ -204,7 +169,7 @@ static void mipspmu_event_update(struct perf_event *event, unsigned long flags; int shift = 64 - TOTAL_BITS; s64 prev_raw_count, new_raw_count; - s64 delta; + u64 delta; again: prev_raw_count = local64_read(&hwc->prev_count); @@ -231,32 +196,90 @@ again: return; } -static void mipspmu_disable(struct perf_event *event) +static void mipspmu_start(struct perf_event *event, int flags) +{ + struct hw_perf_event *hwc = &event->hw; + + if (!mipspmu) + return; + + if (flags & PERF_EF_RELOAD) + WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); + + hwc->state = 0; + + /* Set the period for the event. */ + mipspmu_event_set_period(event, hwc, hwc->idx); + + /* Enable the event. */ + mipspmu->enable_event(hwc, hwc->idx); +} + +static void mipspmu_stop(struct perf_event *event, int flags) +{ + struct hw_perf_event *hwc = &event->hw; + + if (!mipspmu) + return; + + if (!(hwc->state & PERF_HES_STOPPED)) { + /* We are working on a local event. */ + mipspmu->disable_event(hwc->idx); + barrier(); + mipspmu_event_update(event, hwc, hwc->idx); + hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; + } +} + +static int mipspmu_add(struct perf_event *event, int flags) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx; + int idx; + int err = 0; + perf_pmu_disable(event->pmu); - WARN_ON(idx < 0 || idx >= mipspmu->num_counters); + /* To look for a free counter for this event. */ + idx = mipspmu->alloc_counter(cpuc, hwc); + if (idx < 0) { + err = idx; + goto out; + } - /* We are working on a local event. */ + /* + * If there is an event in the counter we are going to use then + * make sure it is disabled. + */ + event->hw.idx = idx; mipspmu->disable_event(idx); + cpuc->events[idx] = event; - barrier(); - - mipspmu_event_update(event, hwc, idx); - cpuc->events[idx] = NULL; - clear_bit(idx, cpuc->used_mask); + hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; + if (flags & PERF_EF_START) + mipspmu_start(event, PERF_EF_RELOAD); + /* Propagate our changes to the userspace mapping. */ perf_event_update_userpage(event); + +out: + perf_pmu_enable(event->pmu); + return err; } -static void mipspmu_unthrottle(struct perf_event *event) +static void mipspmu_del(struct perf_event *event, int flags) { + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; - mipspmu->enable_event(hwc, hwc->idx); + WARN_ON(idx < 0 || idx >= mipspmu->num_counters); + + mipspmu_stop(event, PERF_EF_UPDATE); + cpuc->events[idx] = NULL; + clear_bit(idx, cpuc->used_mask); + + perf_event_update_userpage(event); } static void mipspmu_read(struct perf_event *event) @@ -270,12 +293,17 @@ static void mipspmu_read(struct perf_event *event) mipspmu_event_update(event, hwc, hwc->idx); } -static struct pmu pmu = { - .enable = mipspmu_enable, - .disable = mipspmu_disable, - .unthrottle = mipspmu_unthrottle, - .read = mipspmu_read, -}; +static void mipspmu_enable(struct pmu *pmu) +{ + if (mipspmu) + mipspmu->start(); +} + +static void mipspmu_disable(struct pmu *pmu) +{ + if (mipspmu) + mipspmu->stop(); +} static atomic_t active_events = ATOMIC_INIT(0); static DEFINE_MUTEX(pmu_reserve_mutex); @@ -318,6 +346,82 @@ static void mipspmu_free_irq(void) perf_irq = save_perf_irq; } +/* + * mipsxx/rm9000/loongson2 have different performance counters, they have + * specific low-level init routines. + */ +static void reset_counters(void *arg); +static int __hw_perf_event_init(struct perf_event *event); + +static void hw_perf_event_destroy(struct perf_event *event) +{ + if (atomic_dec_and_mutex_lock(&active_events, + &pmu_reserve_mutex)) { + /* + * We must not call the destroy function with interrupts + * disabled. + */ + on_each_cpu(reset_counters, + (void *)(long)mipspmu->num_counters, 1); + mipspmu_free_irq(); + mutex_unlock(&pmu_reserve_mutex); + } +} + +static int mipspmu_event_init(struct perf_event *event) +{ + int err = 0; + + switch (event->attr.type) { + case PERF_TYPE_RAW: + case PERF_TYPE_HARDWARE: + case PERF_TYPE_HW_CACHE: + break; + + default: + return -ENOENT; + } + + if (!mipspmu || event->cpu >= nr_cpumask_bits || + (event->cpu >= 0 && !cpu_online(event->cpu))) + return -ENODEV; + + if (!atomic_inc_not_zero(&active_events)) { + if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { + atomic_dec(&active_events); + return -ENOSPC; + } + + mutex_lock(&pmu_reserve_mutex); + if (atomic_read(&active_events) == 0) + err = mipspmu_get_irq(); + + if (!err) + atomic_inc(&active_events); + mutex_unlock(&pmu_reserve_mutex); + } + + if (err) + return err; + + err = __hw_perf_event_init(event); + if (err) + hw_perf_event_destroy(event); + + return err; +} + +static struct pmu pmu = { + .pmu_enable = mipspmu_enable, + .pmu_disable = mipspmu_disable, + .event_init = mipspmu_event_init, + .add = mipspmu_add, + .del = mipspmu_del, + .start = mipspmu_start, + .stop = mipspmu_stop, + .read = mipspmu_read, +}; + static inline unsigned int mipspmu_perf_event_encode(const struct mips_perf_event *pev) { @@ -382,8 +486,9 @@ static int validate_event(struct cpu_hw_events *cpuc, { struct hw_perf_event fake_hwc = event->hw; - if (event->pmu && event->pmu != &pmu) - return 0; + /* Allow mixed event group. So return 1 to pass validation. */ + if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) + return 1; return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0; } @@ -409,73 +514,6 @@ static int validate_group(struct perf_event *event) return 0; } -/* - * mipsxx/rm9000/loongson2 have different performance counters, they have - * specific low-level init routines. - */ -static void reset_counters(void *arg); -static int __hw_perf_event_init(struct perf_event *event); - -static void hw_perf_event_destroy(struct perf_event *event) -{ - if (atomic_dec_and_mutex_lock(&active_events, - &pmu_reserve_mutex)) { - /* - * We must not call the destroy function with interrupts - * disabled. - */ - on_each_cpu(reset_counters, - (void *)(long)mipspmu->num_counters, 1); - mipspmu_free_irq(); - mutex_unlock(&pmu_reserve_mutex); - } -} - -const struct pmu *hw_perf_event_init(struct perf_event *event) -{ - int err = 0; - - if (!mipspmu || event->cpu >= nr_cpumask_bits || - (event->cpu >= 0 && !cpu_online(event->cpu))) - return ERR_PTR(-ENODEV); - - if (!atomic_inc_not_zero(&active_events)) { - if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { - atomic_dec(&active_events); - return ERR_PTR(-ENOSPC); - } - - mutex_lock(&pmu_reserve_mutex); - if (atomic_read(&active_events) == 0) - err = mipspmu_get_irq(); - - if (!err) - atomic_inc(&active_events); - mutex_unlock(&pmu_reserve_mutex); - } - - if (err) - return ERR_PTR(err); - - err = __hw_perf_event_init(event); - if (err) - hw_perf_event_destroy(event); - - return err ? ERR_PTR(err) : &pmu; -} - -void hw_perf_enable(void) -{ - if (mipspmu) - mipspmu->start(); -} - -void hw_perf_disable(void) -{ - if (mipspmu) - mipspmu->stop(); -} - /* This is needed by specific irq handlers in perf_event_*.c */ static void handle_associated_event(struct cpu_hw_events *cpuc, @@ -496,21 +534,13 @@ handle_associated_event(struct cpu_hw_events *cpuc, #include "perf_event_mipsxx.c" /* Callchain handling code. */ -static inline void -callchain_store(struct perf_callchain_entry *entry, - u64 ip) -{ - if (entry->nr < PERF_MAX_STACK_DEPTH) - entry->ip[entry->nr++] = ip; -} /* * Leave userspace callchain empty for now. When we find a way to trace * the user stack callchains, we add here. */ -static void -perf_callchain_user(struct pt_regs *regs, - struct perf_callchain_entry *entry) +void perf_callchain_user(struct perf_callchain_entry *entry, + struct pt_regs *regs) { } @@ -523,23 +553,21 @@ static void save_raw_perf_callchain(struct perf_callchain_entry *entry, while (!kstack_end(sp)) { addr = *sp++; if (__kernel_text_address(addr)) { - callchain_store(entry, addr); + perf_callchain_store(entry, addr); if (entry->nr >= PERF_MAX_STACK_DEPTH) break; } } } -static void -perf_callchain_kernel(struct pt_regs *regs, - struct perf_callchain_entry *entry) +void perf_callchain_kernel(struct perf_callchain_entry *entry, + struct pt_regs *regs) { unsigned long sp = regs->regs[29]; #ifdef CONFIG_KALLSYMS unsigned long ra = regs->regs[31]; unsigned long pc = regs->cp0_epc; - callchain_store(entry, PERF_CONTEXT_KERNEL); if (raw_show_trace || !__kernel_text_address(pc)) { unsigned long stack_page = (unsigned long)task_stack_page(current); @@ -549,53 +577,12 @@ perf_callchain_kernel(struct pt_regs *regs, return; } do { - callchain_store(entry, pc); + perf_callchain_store(entry, pc); if (entry->nr >= PERF_MAX_STACK_DEPTH) break; pc = unwind_stack(current, &sp, pc, &ra); } while (pc); #else - callchain_store(entry, PERF_CONTEXT_KERNEL); save_raw_perf_callchain(entry, sp); #endif } - -static void -perf_do_callchain(struct pt_regs *regs, - struct perf_callchain_entry *entry) -{ - int is_user; - - if (!regs) - return; - - is_user = user_mode(regs); - - if (!current || !current->pid) - return; - - if (is_user && current->state != TASK_RUNNING) - return; - - if (!is_user) { - perf_callchain_kernel(regs, entry); - if (current->mm) - regs = task_pt_regs(current); - else - regs = NULL; - } - if (regs) - perf_callchain_user(regs, entry); -} - -static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); - -struct perf_callchain_entry * -perf_callchain(struct pt_regs *regs) -{ - struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry); - - entry->nr = 0; - perf_do_callchain(regs, entry); - return entry; -} diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 183e0d226669..75266ff4cc33 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -696,7 +696,7 @@ static int mipsxx_pmu_handle_shared_irq(void) * interrupt, not NMI. */ if (handled == IRQ_HANDLED) - perf_event_do_pending(); + irq_work_run(); #ifdef CONFIG_MIPS_MT_SMP read_unlock(&pmuint_rwlock); @@ -721,7 +721,7 @@ static void mipsxx_pmu_start(void) /* * MIPS performance counters can be per-TC. The control registers can - * not be directly accessed accross CPUs. Hence if we want to do global + * not be directly accessed across CPUs. Hence if we want to do global * control, we need cross CPU calls. on_each_cpu() can help us, but we * can not make sure this function is called with interrupts enabled. So * here we pause local counters and then grab a rwlock and leave the @@ -1045,6 +1045,8 @@ init_hw_perf_events(void) "CPU, irq %d%s\n", mipspmu->name, counters, irq, irq < 0 ? " (share with timer interrupt)" : ""); + perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); + return 0; } early_initcall(init_hw_perf_events); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index ae167df73ddd..d2112d3cf115 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -410,7 +410,7 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) return 0; /* - * Return ra if an exception occured at the first instruction + * Return ra if an exception occurred at the first instruction */ if (unlikely(ofs == 0)) { pc = *ra; diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index fbaabad0e6e2..7f5468b38d4c 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -586,6 +586,10 @@ einval: li v0, -ENOSYS sys sys_fanotify_init 2 sys sys_fanotify_mark 6 sys sys_prlimit64 4 + sys sys_name_to_handle_at 5 + sys sys_open_by_handle_at 3 /* 4340 */ + sys sys_clock_adjtime 2 + sys sys_syncfs 1 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3f4179283207..a2e1fcbc41dc 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -425,4 +425,8 @@ sys_call_table: PTR sys_fanotify_init /* 5295 */ PTR sys_fanotify_mark PTR sys_prlimit64 + PTR sys_name_to_handle_at + PTR sys_open_by_handle_at + PTR sys_clock_adjtime /* 5300 */ + PTR sys_syncfs .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f08ece6d8acc..b2c7624995b8 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -425,4 +425,8 @@ EXPORT(sysn32_call_table) PTR sys_fanotify_init /* 6300 */ PTR sys_fanotify_mark PTR sys_prlimit64 + PTR sys_name_to_handle_at + PTR sys_open_by_handle_at + PTR compat_sys_clock_adjtime /* 6305 */ + PTR sys_syncfs .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 78d768a3e19d..049a9c8c49a0 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -543,4 +543,8 @@ sys_call_table: PTR sys_fanotify_init PTR sys_32_fanotify_mark PTR sys_prlimit64 + PTR sys_name_to_handle_at + PTR compat_sys_open_by_handle_at /* 4340 */ + PTR compat_sys_clock_adjtime + PTR sys_syncfs .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 5922342bca39..dbbe0ce48d89 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -84,7 +84,7 @@ static int protected_save_fp_context(struct sigcontext __user *sc) static int protected_restore_fp_context(struct sigcontext __user *sc) { - int err, tmp; + int err, tmp __maybe_unused; while (1) { lock_fpu_owner(); own_fpu_inatomic(0); diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index a0ed0e052b2e..aae986613795 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -115,7 +115,7 @@ static int protected_save_fp_context32(struct sigcontext32 __user *sc) static int protected_restore_fp_context32(struct sigcontext32 __user *sc) { - int err, tmp; + int err, tmp __maybe_unused; while (1) { lock_fpu_owner(); own_fpu_inatomic(0); diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index c0e81418ba21..1ec56e635d04 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -120,7 +120,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) local_irq_save(flags); - vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */ + vpflags = dvpe(); /* can't access the other CPU's registers whilst MVPE enabled */ switch (action) { case SMP_CALL_FUNCTION: diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 383aeb95cb49..32a256101082 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -193,6 +193,22 @@ void __devinit smp_prepare_boot_cpu(void) */ static struct task_struct *cpu_idle_thread[NR_CPUS]; +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +static void __cpuinit do_fork_idle(struct work_struct *work) +{ + struct create_idle *c_idle = + container_of(work, struct create_idle, work); + + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + int __cpuinit __cpu_up(unsigned int cpu) { struct task_struct *idle; @@ -203,8 +219,19 @@ int __cpuinit __cpu_up(unsigned int cpu) * Linux can schedule processes on this slave. */ if (!cpu_idle_thread[cpu]) { - idle = fork_idle(cpu); - cpu_idle_thread[cpu] = idle; + /* + * Schedule work item to avoid forking user task + * Ported from arch/x86/kernel/smpboot.c + */ + struct create_idle c_idle = { + .cpu = cpu, + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + }; + + INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle); + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + idle = cpu_idle_thread[cpu] = c_idle.idle; if (IS_ERR(idle)) panic(KERN_ERR "Fork failed for CPU %d", cpu); diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 39c08254b0f1..5a88cc4ccd5a 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -677,8 +677,9 @@ void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity) */ } -void smtc_forward_irq(unsigned int irq) +void smtc_forward_irq(struct irq_data *d) { + unsigned int irq = d->irq; int target; /* @@ -692,7 +693,7 @@ void smtc_forward_irq(unsigned int irq) * and efficiency, we just pick the easiest one to find. */ - target = cpumask_first(irq_desc[irq].affinity); + target = cpumask_first(d->affinity); /* * We depend on the platform code to have correctly processed @@ -707,12 +708,10 @@ void smtc_forward_irq(unsigned int irq) */ /* If no one is eligible, service locally */ - if (target >= NR_CPUS) { + if (target >= NR_CPUS) do_IRQ_no_affinity(irq); - return; - } - - smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq); + else + smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq); } #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ @@ -1147,7 +1146,7 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe) setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); - set_irq_handler(cpu_ipi_irq, handle_percpu_irq); + irq_set_handler(cpu_ipi_irq, handle_percpu_irq); } /* diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 1dc6edff45e0..58beabf50b3c 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -383,12 +383,11 @@ save_static_function(sys_sysmips); static int __used noinline _sys_sysmips(nabi_no_regargs struct pt_regs regs) { - long cmd, arg1, arg2, arg3; + long cmd, arg1, arg2; cmd = regs.regs[4]; arg1 = regs.regs[5]; arg2 = regs.regs[6]; - arg3 = regs.regs[7]; switch (cmd) { case MIPS_ATOMIC_SET: @@ -405,7 +404,7 @@ _sys_sysmips(nabi_no_regargs struct pt_regs regs) if (arg1 & 2) set_thread_flag(TIF_LOGADE); else - clear_thread_flag(TIF_FIXADE); + clear_thread_flag(TIF_LOGADE); return 0; diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index fb7497405510..1083ad4e1017 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -102,7 +102,7 @@ static __init int cpu_has_mfc0_count_bug(void) case CPU_R4400SC: case CPU_R4400MC: /* - * The published errata for the R4400 upto 3.0 say the CPU + * The published errata for the R4400 up to 3.0 say the CPU * has the mfc0 from count bug. */ if ((current_cpu_data.processor_id & 0xff) <= 0x30) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 570607b376b5..832afbb87588 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -115,7 +115,7 @@ SECTIONS EXIT_DATA } - PERCPU(PAGE_SIZE) + PERCPU(1 << CONFIG_MIPS_L1_CACHE_SHIFT, PAGE_SIZE) . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 6a1fdfef8fde..dbb6b408f001 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -19,7 +19,7 @@ * VPE support module * * Provides support for loading a MIPS SP program on VPE1. - * The SP enviroment is rather simple, no tlb's. It needs to be relocatable + * The SP environment is rather simple, no tlb's. It needs to be relocatable * (or partially linked). You should initialise your stack in the startup * code. This loader looks for the symbol __start and sets up * execution to resume from there. The MIPS SDE kit contains suitable examples. @@ -148,9 +148,9 @@ struct { spinlock_t tc_list_lock; struct list_head tc_list; /* Thread contexts */ } vpecontrol = { - .vpe_list_lock = SPIN_LOCK_UNLOCKED, + .vpe_list_lock = __SPIN_LOCK_UNLOCKED(vpe_list_lock), .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), - .tc_list_lock = SPIN_LOCK_UNLOCKED, + .tc_list_lock = __SPIN_LOCK_UNLOCKED(tc_list_lock), .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) }; diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 1353fb135ed3..de4c165515d7 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -32,24 +32,24 @@ static volatile int *lasat_int_status; static volatile int *lasat_int_mask; static volatile int lasat_int_mask_shift; -void disable_lasat_irq(unsigned int irq_nr) +void disable_lasat_irq(struct irq_data *d) { - irq_nr -= LASAT_IRQ_BASE; + unsigned int irq_nr = d->irq - LASAT_IRQ_BASE; + *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; } -void enable_lasat_irq(unsigned int irq_nr) +void enable_lasat_irq(struct irq_data *d) { - irq_nr -= LASAT_IRQ_BASE; + unsigned int irq_nr = d->irq - LASAT_IRQ_BASE; + *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; } static struct irq_chip lasat_irq_type = { .name = "Lasat", - .ack = disable_lasat_irq, - .mask = disable_lasat_irq, - .mask_ack = disable_lasat_irq, - .unmask = enable_lasat_irq, + .irq_mask = disable_lasat_irq, + .irq_unmask = enable_lasat_irq, }; static inline int ls1bit32(unsigned int x) @@ -128,7 +128,7 @@ void __init arch_init_irq(void) mips_cpu_irq_init(); for (i = LASAT_IRQ_BASE; i <= LASAT_IRQ_END; i++) - set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &lasat_irq_type, handle_level_irq); setup_irq(LASAT_CASCADE_IRQ, &cascade); } diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S index c768e3000616..64457162f7e0 100644 --- a/arch/mips/lib/strnlen_user.S +++ b/arch/mips/lib/strnlen_user.S @@ -17,7 +17,7 @@ .previous /* - * Return the size of a string including the ending NUL character upto a + * Return the size of a string including the ending NUL character up to a * maximum of a1 or 0 in case of error. * * Note: for performance reasons we deliberately accept that a user may diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 6e1b77fec7ea..aca93eed8779 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -1,6 +1,7 @@ +if MACH_LOONGSON + choice prompt "Machine Type" - depends on MACH_LOONGSON config LEMOTE_FULOONG2E bool "Lemote Fuloong(2e) mini-PC" @@ -87,3 +88,5 @@ config LOONGSON_UART_BASE config LOONGSON_MC146818 bool default n + +endif # MACH_LOONGSON diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c index 2dc2a4cc632a..f27d7ccca92a 100644 --- a/arch/mips/loongson/common/bonito-irq.c +++ b/arch/mips/loongson/common/bonito-irq.c @@ -16,24 +16,22 @@ #include <loongson.h> -static inline void bonito_irq_enable(unsigned int irq) +static inline void bonito_irq_enable(struct irq_data *d) { - LOONGSON_INTENSET = (1 << (irq - LOONGSON_IRQ_BASE)); + LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE)); mmiowb(); } -static inline void bonito_irq_disable(unsigned int irq) +static inline void bonito_irq_disable(struct irq_data *d) { - LOONGSON_INTENCLR = (1 << (irq - LOONGSON_IRQ_BASE)); + LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE)); mmiowb(); } static struct irq_chip bonito_irq_type = { - .name = "bonito_irq", - .ack = bonito_irq_disable, - .mask = bonito_irq_disable, - .mask_ack = bonito_irq_disable, - .unmask = bonito_irq_enable, + .name = "bonito_irq", + .irq_mask = bonito_irq_disable, + .irq_unmask = bonito_irq_enable, }; static struct irqaction __maybe_unused dma_timeout_irqaction = { @@ -46,7 +44,8 @@ void bonito_irq_init(void) u32 i; for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) - set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &bonito_irq_type, + handle_level_irq); #ifdef CONFIG_CPU_LOONGSON2E setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c index 1a06defc4f7f..353e1d2e41a5 100644 --- a/arch/mips/loongson/common/cmdline.c +++ b/arch/mips/loongson/common/cmdline.c @@ -44,10 +44,5 @@ void __init prom_init_cmdline(void) strcat(arcs_cmdline, " "); } - if ((strstr(arcs_cmdline, "console=")) == NULL) - strcat(arcs_cmdline, " console=ttyS0,115200"); - if ((strstr(arcs_cmdline, "root=")) == NULL) - strcat(arcs_cmdline, " root=/dev/hda1"); - prom_init_machtype(); } diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 81fbe6b73f91..2efd5d9dee27 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c @@ -41,7 +41,7 @@ void __weak __init mach_prom_init_machtype(void) void __init prom_init_machtype(void) { - char *p, str[MACHTYPE_LEN]; + char *p, str[MACHTYPE_LEN + 1]; int machtype = MACH_LEMOTE_FL2E; mips_machtype = LOONGSON_MACHTYPE; @@ -53,6 +53,7 @@ void __init prom_init_machtype(void) } p += strlen("machtype="); strncpy(str, p, MACHTYPE_LEN); + str[MACHTYPE_LEN] = '\0'; p = strstr(str, " "); if (p) *p = '\0'; diff --git a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c index 1dfbd92ba9d0..daed6834dc15 100644 --- a/arch/mips/math-emu/dp_fsp.c +++ b/arch/mips/math-emu/dp_fsp.c @@ -62,7 +62,7 @@ ieee754dp ieee754dp_fsp(ieee754sp x) break; } - /* CANT possibly overflow,underflow, or need rounding + /* CAN'T possibly overflow,underflow, or need rounding */ /* drop the hidden bit */ diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c index aa566e785f5a..09175f461920 100644 --- a/arch/mips/math-emu/dp_mul.c +++ b/arch/mips/math-emu/dp_mul.c @@ -104,7 +104,7 @@ ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): break; } - /* rm = xm * ym, re = xe+ye basicly */ + /* rm = xm * ym, re = xe+ye basically */ assert(xm & DP_HIDDEN_BIT); assert(ym & DP_HIDDEN_BIT); { diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 36d975ae08f8..3c4a8c5ba7f2 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -32,7 +32,7 @@ * not change cp0_epc due to the instruction * * According to the spec: - * 1) it shouldnt be a branch :-) + * 1) it shouldn't be a branch :-) * 2) it can be a COP instruction :-( * 3) if we are tring to run a protected memory space we must take * special care on memory access instructions :-( diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h index 2701d9500959..2a7d43f4f161 100644 --- a/arch/mips/math-emu/ieee754int.h +++ b/arch/mips/math-emu/ieee754int.h @@ -70,7 +70,7 @@ #define COMPXSP \ - unsigned xm; int xe; int xs; int xc + unsigned xm; int xe; int xs __maybe_unused; int xc #define COMPYSP \ unsigned ym; int ye; int ys; int yc @@ -104,7 +104,7 @@ #define COMPXDP \ -u64 xm; int xe; int xs; int xc +u64 xm; int xe; int xs __maybe_unused; int xc #define COMPYDP \ u64 ym; int ye; int ys; int yc diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c index c06bb4022be5..2722a2570ea4 100644 --- a/arch/mips/math-emu/sp_mul.c +++ b/arch/mips/math-emu/sp_mul.c @@ -104,7 +104,7 @@ ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): break; } - /* rm = xm * ym, re = xe+ye basicly */ + /* rm = xm * ym, re = xe+ye basically */ assert(xm & SP_HIDDEN_BIT); assert(ym & SP_HIDDEN_BIT); diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c index 5da30b6a65b7..30df47258c2c 100644 --- a/arch/mips/mipssim/sim_smtc.c +++ b/arch/mips/mipssim/sim_smtc.c @@ -27,6 +27,7 @@ #include <asm/atomic.h> #include <asm/cpu.h> #include <asm/processor.h> +#include <asm/smtc.h> #include <asm/system.h> #include <asm/mmu_context.h> #include <asm/smtc_ipi.h> @@ -57,8 +58,6 @@ static inline void ssmtc_send_ipi_mask(const struct cpumask *mask, */ static void __cpuinit ssmtc_init_secondary(void) { - void smtc_init_secondary(void); - smtc_init_secondary(); } diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S index 2d08268bb705..89c412bc4b64 100644 --- a/arch/mips/mm/cex-sb1.S +++ b/arch/mips/mm/cex-sb1.S @@ -79,7 +79,7 @@ LEAF(except_vec2_sb1) recovered_dcache: /* * Unlock CacheErr-D (which in turn unlocks CacheErr-DPA). - * Ought to log the occurence of this recovered dcache error. + * Ought to log the occurrence of this recovered dcache error. */ b recovered mtc0 $0,C0_CERR_D diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 2efcbd24c82f..279599e9a779 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -324,7 +324,7 @@ int page_is_ram(unsigned long pagenr) void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; - unsigned long lastpfn; + unsigned long lastpfn __maybe_unused; pagetable_init(); diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 083d3412d0bc..5ef294fbb6e7 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -109,6 +109,8 @@ static bool scratchpad_available(void) static int scratchpad_offset(int i) { BUG(); + /* Really unreachable, but evidently some GCC want this. */ + return 0; } #endif /* @@ -350,7 +352,7 @@ static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p) /* * Write random or indexed TLB entry, and care about the hazards from - * the preceeding mtc0 and for the following eret. + * the preceding mtc0 and for the following eret. */ enum tlb_write_entry { tlb_random, tlb_indexed }; diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index b79b24afe3a2..9027061f0ead 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -472,7 +472,7 @@ static void __init fill_ipi_map(void) void __init arch_init_ipiirq(int irq, struct irqaction *action) { setup_irq(irq, action); - set_irq_handler(irq, handle_percpu_irq); + irq_set_handler(irq, handle_percpu_irq); } void __init arch_init_irq(void) diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c index 192cfd2a539c..49a38b09a488 100644 --- a/arch/mips/mti-malta/malta-smtc.c +++ b/arch/mips/mti-malta/malta-smtc.c @@ -34,7 +34,6 @@ static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action) */ static void __cpuinit msmtc_init_secondary(void) { - void smtc_init_secondary(void); int myvpe; /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ @@ -114,7 +113,8 @@ struct plat_smp_ops msmtc_smp_ops = { */ -int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) +int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, + bool force) { cpumask_t tmask; int cpu = 0; @@ -130,7 +130,7 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) * cleared in the affinity mask, there will never be any * interrupt forwarding. But as soon as a program or operator * sets affinity for one of the related IRQs, we need to make - * sure that we don't ever try to forward across the VPE boundry, + * sure that we don't ever try to forward across the VPE boundary, * at least not until we engineer a system where the interrupt * _ack() or _end() function can somehow know that it corresponds * to an interrupt taken on another VPE, and perform the appropriate @@ -144,7 +144,7 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu)) cpu_clear(cpu, tmask); } - cpumask_copy(irq_desc[irq].affinity, &tmask); + cpumask_copy(d->affinity, &tmask); if (cpus_empty(tmask)) /* @@ -155,8 +155,8 @@ int plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) "IRQ affinity leaves no legal CPU for IRQ %d\n", irq); /* Do any generic SMTC IRQ affinity setup */ - smtc_set_irq_affinity(irq, tmask); + smtc_set_irq_affinity(d->irq, tmask); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 3c6f190aa61c..1620b83cd13e 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -119,7 +119,7 @@ static void __init plat_perf_setup(void) set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; #ifdef CONFIG_SMP - set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq); + irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); #endif } } diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 02cc65e52d11..4b9d7044e26c 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -1,4 +1,4 @@ -EXTRA_CFLAGS := -Werror +ccflags-y := -Werror obj-$(CONFIG_OPROFILE) += oprofile.o diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c index d8080499872a..5d530f89d872 100644 --- a/arch/mips/pci/msi-octeon.c +++ b/arch/mips/pci/msi-octeon.c @@ -172,7 +172,7 @@ msi_irq_allocated: pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control); - set_irq_msi(irq, desc); + irq_set_msi_desc(irq, desc); write_msi_msg(irq, &msg); return 0; } @@ -259,11 +259,11 @@ static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock); static u64 msi_rcv_reg[4]; static u64 mis_ena_reg[4]; -static void octeon_irq_msi_enable_pcie(unsigned int irq) +static void octeon_irq_msi_enable_pcie(struct irq_data *data) { u64 en; unsigned long flags; - int msi_number = irq - OCTEON_IRQ_MSI_BIT0; + int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0; int irq_index = msi_number >> 6; int irq_bit = msi_number & 0x3f; @@ -275,11 +275,11 @@ static void octeon_irq_msi_enable_pcie(unsigned int irq) raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags); } -static void octeon_irq_msi_disable_pcie(unsigned int irq) +static void octeon_irq_msi_disable_pcie(struct irq_data *data) { u64 en; unsigned long flags; - int msi_number = irq - OCTEON_IRQ_MSI_BIT0; + int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0; int irq_index = msi_number >> 6; int irq_bit = msi_number & 0x3f; @@ -293,11 +293,11 @@ static void octeon_irq_msi_disable_pcie(unsigned int irq) static struct irq_chip octeon_irq_chip_msi_pcie = { .name = "MSI", - .enable = octeon_irq_msi_enable_pcie, - .disable = octeon_irq_msi_disable_pcie, + .irq_enable = octeon_irq_msi_enable_pcie, + .irq_disable = octeon_irq_msi_disable_pcie, }; -static void octeon_irq_msi_enable_pci(unsigned int irq) +static void octeon_irq_msi_enable_pci(struct irq_data *data) { /* * Octeon PCI doesn't have the ability to mask/unmask MSI @@ -308,15 +308,15 @@ static void octeon_irq_msi_enable_pci(unsigned int irq) */ } -static void octeon_irq_msi_disable_pci(unsigned int irq) +static void octeon_irq_msi_disable_pci(struct irq_data *data) { /* See comment in enable */ } static struct irq_chip octeon_irq_chip_msi_pci = { .name = "MSI", - .enable = octeon_irq_msi_enable_pci, - .disable = octeon_irq_msi_disable_pci, + .irq_enable = octeon_irq_msi_enable_pci, + .irq_disable = octeon_irq_msi_disable_pci, }; /* @@ -388,7 +388,7 @@ int __init octeon_msi_initialize(void) } for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_LAST; irq++) - set_irq_chip_and_handler(irq, msi, handle_simple_irq); + irq_set_chip_and_handler(irq, msi, handle_simple_irq); if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0, diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index b7c03d80c88c..8fbfbf2b931c 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -308,7 +308,7 @@ static struct resource pci_mem_resource = { * RETURNS: PCIBIOS_SUCCESSFUL - success * ****************************************************************************/ -static int bpci_interrupt(int irq, void *dev_id) +static irqreturn_t bpci_interrupt(int irq, void *dev_id) { struct msp_pci_regs *preg = (void *)PCI_BASE_REG; unsigned int stat = preg->if_status; @@ -326,7 +326,7 @@ static int bpci_interrupt(int irq, void *dev_id) /* write to clear all asserted interrupts */ preg->if_status = stat; - return PCIBIOS_SUCCESSFUL; + return IRQ_HANDLED; } /***************************************************************************** @@ -344,7 +344,7 @@ static int bpci_interrupt(int irq, void *dev_id) * PCI_ACCESS_WRITE and PCI_ACCESS_READ. * * bus - pointer to the bus number of the device to - * be targetted for the configuration cycle. + * be targeted for the configuration cycle. * The only element of the pci_bus structure * used is bus->number. This argument determines * if the configuration access will be Type 0 or @@ -354,7 +354,7 @@ static int bpci_interrupt(int irq, void *dev_id) * * devfn - this is an 8-bit field. The lower three bits * specify the function number of the device to - * be targetted for the configuration cycle, with + * be targeted for the configuration cycle, with * all three-bit combinations being legal. The * upper five bits specify the device number, * with legal values being 10 to 31. diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index 6f5e24c6ae67..af8c31996965 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -210,7 +210,7 @@ static int __init bcm1480_pcibios_init(void) PCIBIOS_MIN_IO = 0x00008000UL; PCIBIOS_MIN_MEM = 0x01000000UL; - /* Set I/O resource limits. - unlimited for now to accomodate HT */ + /* Set I/O resource limits. - unlimited for now to accommodate HT */ ioport_resource.end = 0xffffffffUL; iomem_resource.end = 0xffffffffUL; diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 2d74fc9ae3ba..ed1c54284b8f 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -441,7 +441,7 @@ static void octeon_pci_initialize(void) /* * TDOMC must be set to one in PCI mode. TDOMC should be set to 4 - * in PCI-X mode to allow four oustanding splits. Otherwise, + * in PCI-X mode to allow four outstanding splits. Otherwise, * should not change from its reset value. Don't write PCI_CFG19 * in PCI mode (0x82000001 reset value), write it to 0x82000004 * after PCI-X mode is known. MRBCI,MDWE,MDRE -> must be zero. @@ -515,7 +515,7 @@ static void octeon_pci_initialize(void) #endif /* USE_OCTEON_INTERNAL_ARBITER */ /* - * Preferrably written to 1 to set MLTD. [RDSATI,TRTAE, + * Preferably written to 1 to set MLTD. [RDSATI,TRTAE, * TWTAE,TMAE,DPPMR -> must be zero. TILT -> must not be set to * 1..7. */ diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 38bc28005b4a..33bba7bff258 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -125,7 +125,7 @@ void __devinit register_pci_controller(struct pci_controller *hose) hose_tail = &hose->next; /* - * Do not panic here but later - this might hapen before console init. + * Do not panic here but later - this might happen before console init. */ if (!hose->io_map_base) { printk(KERN_WARNING diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig index c139988bb85d..bbd76082fa8c 100644 --- a/arch/mips/pmc-sierra/Kconfig +++ b/arch/mips/pmc-sierra/Kconfig @@ -4,15 +4,11 @@ choice config PMC_MSP4200_EVAL bool "PMC-Sierra MSP4200 Eval Board" - select CEVT_R4K - select CSRC_R4K select IRQ_MSP_SLP select HW_HAS_PCI config PMC_MSP4200_GW bool "PMC-Sierra MSP4200 VoIP Gateway" - select CEVT_R4K - select CSRC_R4K select IRQ_MSP_SLP select HW_HAS_PCI @@ -27,6 +23,8 @@ config PMC_MSP7120_GW select SYS_SUPPORTS_MULTITHREADING select IRQ_MSP_CIC select HW_HAS_PCI + select MSP_HAS_USB + select MSP_ETH config PMC_MSP7120_FPGA bool "PMC-Sierra MSP7120 FPGA" @@ -39,3 +37,16 @@ endchoice config HYPERTRANSPORT bool "Hypertransport Support for PMC-Sierra Yosemite" depends on PMC_YOSEMITE + +config MSP_HAS_USB + boolean + depends on PMC_MSP + +config MSP_ETH + boolean + select MSP_HAS_MAC + depends on PMC_MSP + +config MSP_HAS_MAC + boolean + depends on PMC_MSP diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile index e107f79b1491..cefba7733b73 100644 --- a/arch/mips/pmc-sierra/msp71xx/Makefile +++ b/arch/mips/pmc-sierra/msp71xx/Makefile @@ -6,7 +6,9 @@ obj-y += msp_prom.o msp_setup.o msp_irq.o \ obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o -obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o +obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o obj-$(CONFIG_PCI) += msp_pci.o -obj-$(CONFIG_MSPETH) += msp_eth.o -obj-$(CONFIG_USB_MSP71XX) += msp_usb.o +obj-$(CONFIG_MSP_HAS_MAC) += msp_eth.o +obj-$(CONFIG_MSP_HAS_USB) += msp_usb.o +obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o +obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o diff --git a/arch/mips/pmc-sierra/msp71xx/msp_eth.c b/arch/mips/pmc-sierra/msp71xx/msp_eth.c new file mode 100644 index 000000000000..c584df393de2 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_eth.c @@ -0,0 +1,187 @@ +/* + * The setup file for ethernet related hardware on PMC-Sierra MSP processors. + * + * Copyright 2010 PMC-Sierra, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <msp_regs.h> +#include <msp_int.h> +#include <msp_gpio_macros.h> + + +#define MSP_ETHERNET_GPIO0 14 +#define MSP_ETHERNET_GPIO1 15 +#define MSP_ETHERNET_GPIO2 16 + +#ifdef CONFIG_MSP_HAS_TSMAC +#define MSP_TSMAC_SIZE 0x10020 +#define MSP_TSMAC_ID "pmc_tsmac" + +static struct resource msp_tsmac0_resources[] = { + [0] = { + .start = MSP_MAC0_BASE, + .end = MSP_MAC0_BASE + MSP_TSMAC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_MAC0, + .end = MSP_INT_MAC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msp_tsmac1_resources[] = { + [0] = { + .start = MSP_MAC1_BASE, + .end = MSP_MAC1_BASE + MSP_TSMAC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_MAC1, + .end = MSP_INT_MAC1, + .flags = IORESOURCE_IRQ, + }, +}; +static struct resource msp_tsmac2_resources[] = { + [0] = { + .start = MSP_MAC2_BASE, + .end = MSP_MAC2_BASE + MSP_TSMAC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_SAR, + .end = MSP_INT_SAR, + .flags = IORESOURCE_IRQ, + }, +}; + + +static struct platform_device tsmac_device[] = { + [0] = { + .name = MSP_TSMAC_ID, + .id = 0, + .num_resources = ARRAY_SIZE(msp_tsmac0_resources), + .resource = msp_tsmac0_resources, + }, + [1] = { + .name = MSP_TSMAC_ID, + .id = 1, + .num_resources = ARRAY_SIZE(msp_tsmac1_resources), + .resource = msp_tsmac1_resources, + }, + [2] = { + .name = MSP_TSMAC_ID, + .id = 2, + .num_resources = ARRAY_SIZE(msp_tsmac2_resources), + .resource = msp_tsmac2_resources, + }, +}; +#define msp_eth_devs tsmac_device + +#else +/* If it is not TSMAC assume MSP_ETH (100Mbps) */ +#define MSP_ETH_ID "pmc_mspeth" +#define MSP_ETH_SIZE 0xE0 +static struct resource msp_eth0_resources[] = { + [0] = { + .start = MSP_MAC0_BASE, + .end = MSP_MAC0_BASE + MSP_ETH_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_MAC0, + .end = MSP_INT_MAC0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msp_eth1_resources[] = { + [0] = { + .start = MSP_MAC1_BASE, + .end = MSP_MAC1_BASE + MSP_ETH_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_MAC1, + .end = MSP_INT_MAC1, + .flags = IORESOURCE_IRQ, + }, +}; + + + +static struct platform_device mspeth_device[] = { + [0] = { + .name = MSP_ETH_ID, + .id = 0, + .num_resources = ARRAY_SIZE(msp_eth0_resources), + .resource = msp_eth0_resources, + }, + [1] = { + .name = MSP_ETH_ID, + .id = 1, + .num_resources = ARRAY_SIZE(msp_eth1_resources), + .resource = msp_eth1_resources, + }, + +}; +#define msp_eth_devs mspeth_device + +#endif +int __init msp_eth_setup(void) +{ + int i, ret = 0; + + /* Configure the GPIO and take the ethernet PHY out of reset */ + msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO0); + msp_gpio_pin_hi(MSP_ETHERNET_GPIO0); + +#ifdef CONFIG_MSP_HAS_TSMAC + /* 3 phys on boards with TSMAC */ + msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO1); + msp_gpio_pin_hi(MSP_ETHERNET_GPIO1); + + msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO2); + msp_gpio_pin_hi(MSP_ETHERNET_GPIO2); +#endif + for (i = 0; i < ARRAY_SIZE(msp_eth_devs); i++) { + ret = platform_device_register(&msp_eth_devs[i]); + printk(KERN_INFO "device: %d, return value = %d\n", i, ret); + if (ret) { + platform_device_unregister(&msp_eth_devs[i]); + break; + } + } + + if (ret) + printk(KERN_WARNING "Could not initialize " + "MSPETH device structures.\n"); + + return ret; +} +subsys_initcall(msp_eth_setup); diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c index 734d598a2e3a..4531c4a514bc 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c @@ -19,8 +19,6 @@ #include <msp_int.h> -extern void msp_int_handle(void); - /* SLP bases systems */ extern void msp_slp_irq_init(void); extern void msp_slp_irq_dispatch(void); @@ -29,6 +27,18 @@ extern void msp_slp_irq_dispatch(void); extern void msp_cic_irq_init(void); extern void msp_cic_irq_dispatch(void); +/* VSMP support init */ +extern void msp_vsmp_int_init(void); + +/* vectored interrupt implementation */ + +/* SW0/1 interrupts are used for SMP/SMTC */ +static inline void mac0_int_dispatch(void) { do_IRQ(MSP_INT_MAC0); } +static inline void mac1_int_dispatch(void) { do_IRQ(MSP_INT_MAC1); } +static inline void mac2_int_dispatch(void) { do_IRQ(MSP_INT_SAR); } +static inline void usb_int_dispatch(void) { do_IRQ(MSP_INT_USB); } +static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); } + /* * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded * hierarchical system. The first level are the direct MIPS interrupts @@ -96,29 +106,57 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) do_IRQ(MSP_INT_SW1); } -static struct irqaction cascade_msp = { +static struct irqaction cic_cascade_msp = { .handler = no_action, - .name = "MSP cascade" + .name = "MSP CIC cascade" }; +static struct irqaction per_cascade_msp = { + .handler = no_action, + .name = "MSP PER cascade" +}; void __init arch_init_irq(void) { + /* assume we'll be using vectored interrupt mode except in UP mode*/ +#ifdef CONFIG_MIPS_MT + BUG_ON(!cpu_has_vint); +#endif /* initialize the 1st-level CPU based interrupt controller */ mips_cpu_irq_init(); #ifdef CONFIG_IRQ_MSP_CIC msp_cic_irq_init(); - +#ifdef CONFIG_MIPS_MT + set_vi_handler(MSP_INT_CIC, msp_cic_irq_dispatch); + set_vi_handler(MSP_INT_MAC0, mac0_int_dispatch); + set_vi_handler(MSP_INT_MAC1, mac1_int_dispatch); + set_vi_handler(MSP_INT_SAR, mac2_int_dispatch); + set_vi_handler(MSP_INT_USB, usb_int_dispatch); + set_vi_handler(MSP_INT_SEC, sec_int_dispatch); +#ifdef CONFIG_MIPS_MT_SMP + msp_vsmp_int_init(); +#elif defined CONFIG_MIPS_MT_SMTC + /*Set hwmask for all platform devices */ + irq_hwmask[MSP_INT_MAC0] = C_IRQ0; + irq_hwmask[MSP_INT_MAC1] = C_IRQ1; + irq_hwmask[MSP_INT_USB] = C_IRQ2; + irq_hwmask[MSP_INT_SAR] = C_IRQ3; + irq_hwmask[MSP_INT_SEC] = C_IRQ5; + +#endif /* CONFIG_MIPS_MT_SMP */ +#endif /* CONFIG_MIPS_MT */ /* setup the cascaded interrupts */ - setup_irq(MSP_INT_CIC, &cascade_msp); - setup_irq(MSP_INT_PER, &cascade_msp); + setup_irq(MSP_INT_CIC, &cic_cascade_msp); + setup_irq(MSP_INT_PER, &per_cascade_msp); + #else /* setup the 2nd-level SLP register based interrupt controller */ + /* VSMP /SMTC support support is not enabled for SLP */ msp_slp_irq_init(); /* setup the cascaded SLP/PER interrupts */ - setup_irq(MSP_INT_SLP, &cascade_msp); - setup_irq(MSP_INT_PER, &cascade_msp); + setup_irq(MSP_INT_SLP, &cic_cascade_msp); + setup_irq(MSP_INT_PER, &per_cascade_msp); #endif } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c index 07e71ff2433f..c4fa2d775d8b 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c @@ -1,8 +1,7 @@ /* - * This file define the irq handler for MSP SLM subsystem interrupts. + * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c * - * Copyright 2005-2007 PMC-Sierra, Inc, derived from irq_cpu.c - * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com + * This file define the irq handler for MSP CIC subsystem interrupts. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,119 +15,203 @@ #include <linux/bitops.h> #include <linux/irq.h> +#include <asm/mipsregs.h> #include <asm/system.h> #include <msp_cic_int.h> #include <msp_regs.h> /* - * NOTE: We are only enabling support for VPE0 right now. + * External API */ +extern void msp_per_irq_init(void); +extern void msp_per_irq_dispatch(void); -static inline void unmask_msp_cic_irq(unsigned int irq) + +/* + * Convenience Macro. Should be somewhere generic. + */ +#define get_current_vpe() \ + ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) + +#ifdef CONFIG_SMP + +#define LOCK_VPE(flags, mtflags) \ +do { \ + local_irq_save(flags); \ + mtflags = dmt(); \ +} while (0) + +#define UNLOCK_VPE(flags, mtflags) \ +do { \ + emt(mtflags); \ + local_irq_restore(flags);\ +} while (0) + +#define LOCK_CORE(flags, mtflags) \ +do { \ + local_irq_save(flags); \ + mtflags = dvpe(); \ +} while (0) + +#define UNLOCK_CORE(flags, mtflags) \ +do { \ + evpe(mtflags); \ + local_irq_restore(flags);\ +} while (0) + +#else + +#define LOCK_VPE(flags, mtflags) +#define UNLOCK_VPE(flags, mtflags) +#endif + +/* ensure writes to cic are completed */ +static inline void cic_wmb(void) { + const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG; + volatile u32 dummy_read; - /* check for PER interrupt range */ - if (irq < MSP_PER_INTBASE) - *CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE)); - else - *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); + wmb(); + dummy_read = __raw_readl(cic_mem); + dummy_read++; } -static inline void mask_msp_cic_irq(unsigned int irq) +static void unmask_cic_irq(struct irq_data *d) { - /* check for PER interrupt range */ - if (irq < MSP_PER_INTBASE) - *CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE)); - else - *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE)); + volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; + int vpe; +#ifdef CONFIG_SMP + unsigned int mtflags; + unsigned long flags; + + /* + * Make sure we have IRQ affinity. It may have changed while + * we were processing the IRQ. + */ + if (!cpumask_test_cpu(smp_processor_id(), d->affinity)) + return; +#endif + + vpe = get_current_vpe(); + LOCK_VPE(flags, mtflags); + cic_msk_reg[vpe] |= (1 << (d->irq - MSP_CIC_INTBASE)); + UNLOCK_VPE(flags, mtflags); + cic_wmb(); } -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for msp_cic_irq_end. - */ -static inline void ack_msp_cic_irq(unsigned int irq) +static void mask_cic_irq(struct irq_data *d) { - mask_msp_cic_irq(irq); - + volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG; + int vpe = get_current_vpe(); +#ifdef CONFIG_SMP + unsigned long flags, mtflags; +#endif + LOCK_VPE(flags, mtflags); + cic_msk_reg[vpe] &= ~(1 << (d->irq - MSP_CIC_INTBASE)); + UNLOCK_VPE(flags, mtflags); + cic_wmb(); +} +static void msp_cic_irq_ack(struct irq_data *d) +{ + mask_cic_irq(d); /* - * only really necessary for 18, 16-14 and sometimes 3:0 (since - * these can be edge sensitive) but it doesn't hurt for the others. - */ - - /* check for PER interrupt range */ - if (irq < MSP_PER_INTBASE) - *CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE)); - else - *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE)); + * Only really necessary for 18, 16-14 and sometimes 3:0 + * (since these can be edge sensitive) but it doesn't + * hurt for the others + */ + *CIC_STS_REG = (1 << (d->irq - MSP_CIC_INTBASE)); + smtc_im_ack_irq(d->irq); } +/*Note: Limiting to VSMP . Not tested in SMTC */ + +#ifdef CONFIG_MIPS_MT_SMP +static int msp_cic_irq_set_affinity(struct irq_data *d, + const struct cpumask *cpumask, bool force) +{ + int cpu; + unsigned long flags; + unsigned int mtflags; + unsigned long imask = (1 << (irq - MSP_CIC_INTBASE)); + volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG; + + /* timer balancing should be disabled in kernel code */ + BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER); + + LOCK_CORE(flags, mtflags); + /* enable if any of each VPE's TCs require this IRQ */ + for_each_online_cpu(cpu) { + if (cpumask_test_cpu(cpu, cpumask)) + cic_mask[cpu] |= imask; + else + cic_mask[cpu] &= ~imask; + + } + + UNLOCK_CORE(flags, mtflags); + return 0; + +} +#endif + static struct irq_chip msp_cic_irq_controller = { .name = "MSP_CIC", - .ack = ack_msp_cic_irq, - .mask = ack_msp_cic_irq, - .mask_ack = ack_msp_cic_irq, - .unmask = unmask_msp_cic_irq, + .irq_mask = mask_cic_irq, + .irq_mask_ack = msp_cic_irq_ack, + .irq_unmask = unmask_cic_irq, + .irq_ack = msp_cic_irq_ack, +#ifdef CONFIG_MIPS_MT_SMP + .irq_set_affinity = msp_cic_irq_set_affinity, +#endif }; - void __init msp_cic_irq_init(void) { int i; - /* Mask/clear interrupts. */ *CIC_VPE0_MSK_REG = 0x00000000; - *PER_INT_MSK_REG = 0x00000000; + *CIC_VPE1_MSK_REG = 0x00000000; *CIC_STS_REG = 0xFFFFFFFF; - *PER_INT_STS_REG = 0xFFFFFFFF; - -#if defined(CONFIG_PMC_MSP7120_GW) || \ - defined(CONFIG_PMC_MSP7120_EVAL) /* - * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI. - * These inputs map to EXT_INT_POL[6:4] inside the CIC. - * They are to be active low, level sensitive. - */ + * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI. + * These inputs map to EXT_INT_POL[6:4] inside the CIC. + * They are to be active low, level sensitive. + */ *CIC_EXT_CFG_REG &= 0xFFFF8F8F; -#endif /* initialize all the IRQ descriptors */ - for (i = MSP_CIC_INTBASE; i < MSP_PER_INTBASE + 32; i++) - set_irq_chip_and_handler(i, &msp_cic_irq_controller, + for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) { + irq_set_chip_and_handler(i, &msp_cic_irq_controller, handle_level_irq); +#ifdef CONFIG_MIPS_MT_SMTC + /* Mask of CIC interrupt */ + irq_hwmask[i] = C_IRQ4; +#endif + } + + /* Initialize the PER interrupt sub-system */ + msp_per_irq_init(); } +/* CIC masked by CIC vector processing before dispatch called */ void msp_cic_irq_dispatch(void) { - u32 pending; - int intbase; - - intbase = MSP_CIC_INTBASE; - pending = *CIC_STS_REG & *CIC_VPE0_MSK_REG; - - /* check for PER interrupt */ - if (pending == (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) { - intbase = MSP_PER_INTBASE; - pending = *PER_INT_STS_REG & *PER_INT_MSK_REG; - } - - /* check for spurious interrupt */ - if (pending == 0x00000000) { - printk(KERN_ERR - "Spurious %s interrupt? status %08x, mask %08x\n", - (intbase == MSP_CIC_INTBASE) ? "CIC" : "PER", - (intbase == MSP_CIC_INTBASE) ? - *CIC_STS_REG : *PER_INT_STS_REG, - (intbase == MSP_CIC_INTBASE) ? - *CIC_VPE0_MSK_REG : *PER_INT_MSK_REG); - return; - } - - /* check for the timer and dispatch it first */ - if ((intbase == MSP_CIC_INTBASE) && - (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE)))) + volatile u32 *cic_msk_reg = (volatile u32 *)CIC_VPE0_MSK_REG; + u32 cic_mask; + u32 pending; + int cic_status = *CIC_STS_REG; + cic_mask = cic_msk_reg[get_current_vpe()]; + pending = cic_status & cic_mask; + if (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))) { do_IRQ(MSP_INT_VPE0_TIMER); - else - do_IRQ(ffs(pending) + intbase - 1); + } else if (pending & (1 << (MSP_INT_VPE1_TIMER - MSP_CIC_INTBASE))) { + do_IRQ(MSP_INT_VPE1_TIMER); + } else if (pending & (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) { + msp_per_irq_dispatch(); + } else if (pending) { + do_IRQ(ffs(pending) + MSP_CIC_INTBASE - 1); + } else{ + spurious_interrupt(); + } } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c new file mode 100644 index 000000000000..f9b9dcdfa9dd --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c @@ -0,0 +1,135 @@ +/* + * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c + * + * This file define the irq handler for MSP PER subsystem interrupts. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/bitops.h> + +#include <asm/mipsregs.h> +#include <asm/system.h> + +#include <msp_cic_int.h> +#include <msp_regs.h> + + +/* + * Convenience Macro. Should be somewhere generic. + */ +#define get_current_vpe() \ + ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) + +#ifdef CONFIG_SMP +/* + * The PER registers must be protected from concurrent access. + */ + +static DEFINE_SPINLOCK(per_lock); +#endif + +/* ensure writes to per are completed */ + +static inline void per_wmb(void) +{ + const volatile void __iomem *per_mem = PER_INT_MSK_REG; + volatile u32 dummy_read; + + wmb(); + dummy_read = __raw_readl(per_mem); + dummy_read++; +} + +static inline void unmask_per_irq(struct irq_data *d) +{ +#ifdef CONFIG_SMP + unsigned long flags; + spin_lock_irqsave(&per_lock, flags); + *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE)); + spin_unlock_irqrestore(&per_lock, flags); +#else + *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE)); +#endif + per_wmb(); +} + +static inline void mask_per_irq(struct irq_data *d) +{ +#ifdef CONFIG_SMP + unsigned long flags; + spin_lock_irqsave(&per_lock, flags); + *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE)); + spin_unlock_irqrestore(&per_lock, flags); +#else + *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE)); +#endif + per_wmb(); +} + +static inline void msp_per_irq_ack(struct irq_data *d) +{ + mask_per_irq(d); + /* + * In the PER interrupt controller, only bits 11 and 10 + * are write-to-clear, (SPI TX complete, SPI RX complete). + * It does nothing for any others. + */ + *PER_INT_STS_REG = (1 << (d->irq - MSP_PER_INTBASE)); +} + +#ifdef CONFIG_SMP +static int msp_per_irq_set_affinity(struct irq_data *d, + const struct cpumask *affinity, bool force) +{ + /* WTF is this doing ????? */ + unmask_per_irq(d); + return 0; +} +#endif + +static struct irq_chip msp_per_irq_controller = { + .name = "MSP_PER", + .irq_enable = unmask_per_irq. + .irq_disable = mask_per_irq, + .irq_ack = msp_per_irq_ack, +#ifdef CONFIG_SMP + .irq_set_affinity = msp_per_irq_set_affinity, +#endif +}; + +void __init msp_per_irq_init(void) +{ + int i; + /* Mask/clear interrupts. */ + *PER_INT_MSK_REG = 0x00000000; + *PER_INT_STS_REG = 0xFFFFFFFF; + /* initialize all the IRQ descriptors */ + for (i = MSP_PER_INTBASE; i < MSP_PER_INTBASE + 32; i++) { + irq_set_chip(i, &msp_per_irq_controller); +#ifdef CONFIG_MIPS_MT_SMTC + irq_hwmask[i] = C_IRQ4; +#endif + } +} + +void msp_per_irq_dispatch(void) +{ + u32 per_mask = *PER_INT_MSK_REG; + u32 per_status = *PER_INT_STS_REG; + u32 pending; + + pending = per_status & per_mask; + if (pending) { + do_IRQ(ffs(pending) + MSP_PER_INTBASE - 1); + } else { + spurious_interrupt(); + } +} diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c index 61f390232346..5bbcc47da6b9 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c @@ -21,8 +21,10 @@ #include <msp_slp_int.h> #include <msp_regs.h> -static inline void unmask_msp_slp_irq(unsigned int irq) +static inline void unmask_msp_slp_irq(struct irq_data *d) { + unsigned int irq = d->irq; + /* check for PER interrupt range */ if (irq < MSP_PER_INTBASE) *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE)); @@ -30,8 +32,10 @@ static inline void unmask_msp_slp_irq(unsigned int irq) *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE)); } -static inline void mask_msp_slp_irq(unsigned int irq) +static inline void mask_msp_slp_irq(struct irq_data *d) { + unsigned int irq = d->irq; + /* check for PER interrupt range */ if (irq < MSP_PER_INTBASE) *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE)); @@ -43,8 +47,10 @@ static inline void mask_msp_slp_irq(unsigned int irq) * While we ack the interrupt interrupts are disabled and thus we don't need * to deal with concurrency issues. Same for msp_slp_irq_end. */ -static inline void ack_msp_slp_irq(unsigned int irq) +static inline void ack_msp_slp_irq(struct irq_data *d) { + unsigned int irq = d->irq; + /* check for PER interrupt range */ if (irq < MSP_PER_INTBASE) *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE)); @@ -54,9 +60,9 @@ static inline void ack_msp_slp_irq(unsigned int irq) static struct irq_chip msp_slp_irq_controller = { .name = "MSP_SLP", - .ack = ack_msp_slp_irq, - .mask = mask_msp_slp_irq, - .unmask = unmask_msp_slp_irq, + .irq_ack = ack_msp_slp_irq, + .irq_mask = mask_msp_slp_irq, + .irq_unmask = unmask_msp_slp_irq, }; void __init msp_slp_irq_init(void) @@ -71,7 +77,7 @@ void __init msp_slp_irq_init(void) /* initialize all the IRQ descriptors */ for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++) - set_irq_chip_and_handler(i, &msp_slp_irq_controller, + irq_set_chip_and_handler(i, &msp_slp_irq_controller, handle_level_irq); } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index a54e85b3cf29..2413ea67877e 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c @@ -146,6 +146,8 @@ void __init plat_mem_setup(void) pm_power_off = msp_power_off; } +extern struct plat_smp_ops msp_smtc_smp_ops; + void __init prom_init(void) { unsigned long family; @@ -226,10 +228,18 @@ void __init prom_init(void) */ msp_serial_setup(); +#ifdef CONFIG_MIPS_MT_SMP + register_smp_ops(&vsmp_smp_ops); +#endif + +#ifdef CONFIG_MIPS_MT_SMTC + register_smp_ops(&msp_smtc_smp_ops); +#endif + #ifdef CONFIG_PMCTWILED /* * Setup LED states before the subsys_initcall loads other - * dependant drivers/modules. + * dependent drivers/modules. */ pmctwiled_setup(); #endif diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c new file mode 100644 index 000000000000..bec17901ff03 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. + * Copyright (C) 2001 Ralf Baechle + * Copyright (C) 2010 PMC-Sierra, Inc. + * + * VSMP support for MSP platforms . Derived from malta vsmp support. + * + * This program is free software; you can distribute 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 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. + * + */ +#include <linux/smp.h> +#include <linux/interrupt.h> + +#ifdef CONFIG_MIPS_MT_SMP +#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ +#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */ + + +static void ipi_resched_dispatch(void) +{ + do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ); +} + +static void ipi_call_dispatch(void) +{ + do_IRQ(MIPS_CPU_IPI_CALL_IRQ); +} + +static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) +{ + smp_call_function_interrupt(); + + return IRQ_HANDLED; +} + +static struct irqaction irq_resched = { + .handler = ipi_resched_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "IPI_resched" +}; + +static struct irqaction irq_call = { + .handler = ipi_call_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "IPI_call" +}; + +void __init arch_init_ipiirq(int irq, struct irqaction *action) +{ + setup_irq(irq, action); + irq_set_handler(irq, handle_percpu_irq); +} + +void __init msp_vsmp_int_init(void) +{ + set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); + set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); + arch_init_ipiirq(MIPS_CPU_IPI_RESCHED_IRQ, &irq_resched); + arch_init_ipiirq(MIPS_CPU_IPI_CALL_IRQ, &irq_call); +} +#endif /* CONFIG_MIPS_MT_SMP */ diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smtc.c b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c new file mode 100644 index 000000000000..c8dcc1c01e18 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c @@ -0,0 +1,105 @@ +/* + * MSP71xx Platform-specific hooks for SMP operation + */ +#include <linux/irq.h> +#include <linux/init.h> + +#include <asm/mipsmtregs.h> +#include <asm/mipsregs.h> +#include <asm/smtc.h> +#include <asm/smtc_ipi.h> + +/* VPE/SMP Prototype implements platform interfaces directly */ + +/* + * Cause the specified action to be performed on a targeted "CPU" + */ + +static void msp_smtc_send_ipi_single(int cpu, unsigned int action) +{ + /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ + smtc_send_ipi(cpu, LINUX_SMP_IPI, action); +} + +static void msp_smtc_send_ipi_mask(const struct cpumask *mask, + unsigned int action) +{ + unsigned int i; + + for_each_cpu(i, mask) + msp_smtc_send_ipi_single(i, action); +} + +/* + * Post-config but pre-boot cleanup entry point + */ +static void __cpuinit msp_smtc_init_secondary(void) +{ + int myvpe; + + /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ + myvpe = read_c0_tcbind() & TCBIND_CURVPE; + if (myvpe > 0) + change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | + STATUSF_IP6 | STATUSF_IP7); + smtc_init_secondary(); +} + +/* + * Platform "CPU" startup hook + */ +static void __cpuinit msp_smtc_boot_secondary(int cpu, + struct task_struct *idle) +{ + smtc_boot_secondary(cpu, idle); +} + +/* + * SMP initialization finalization entry point + */ +static void __cpuinit msp_smtc_smp_finish(void) +{ + smtc_smp_finish(); +} + +/* + * Hook for after all CPUs are online + */ + +static void msp_smtc_cpus_done(void) +{ +} + +/* + * Platform SMP pre-initialization + * + * As noted above, we can assume a single CPU for now + * but it may be multithreaded. + */ + +static void __init msp_smtc_smp_setup(void) +{ + /* + * we won't get the definitive value until + * we've run smtc_prepare_cpus later, but + */ + + if (read_c0_config3() & (1 << 2)) + smp_num_siblings = smtc_build_cpu_map(0); +} + +static void __init msp_smtc_prepare_cpus(unsigned int max_cpus) +{ + smtc_prepare_cpus(max_cpus); +} + +struct plat_smp_ops msp_smtc_smp_ops = { + .send_ipi_single = msp_smtc_send_ipi_single, + .send_ipi_mask = msp_smtc_send_ipi_mask, + .init_secondary = msp_smtc_init_secondary, + .smp_finish = msp_smtc_smp_finish, + .cpus_done = msp_smtc_cpus_done, + .boot_secondary = msp_smtc_boot_secondary, + .smp_setup = msp_smtc_smp_setup, + .prepare_cpus = msp_smtc_prepare_cpus, +}; diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c index cca64e15f57f..8b42f307a7a7 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_time.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c @@ -29,6 +29,7 @@ #include <linux/module.h> #include <linux/ptrace.h> +#include <asm/cevt-r4k.h> #include <asm/mipsregs.h> #include <asm/time.h> @@ -36,6 +37,12 @@ #include <msp_int.h> #include <msp_regs.h> +#define get_current_vpe() \ + ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE) + +static struct irqaction timer_vpe1; +static int tim_installed; + void __init plat_time_init(void) { char *endp, *s; @@ -81,7 +88,14 @@ void __init plat_time_init(void) mips_hpt_frequency = cpu_rate/2; } -unsigned int __init get_c0_compare_int(void) +unsigned int __cpuinit get_c0_compare_int(void) { - return MSP_INT_VPE0_TIMER; + /* MIPS_MT modes may want timer for second VPE */ + if ((get_current_vpe()) && !tim_installed) { + memcpy(&timer_vpe1, &c0_compare_irqaction, sizeof(timer_vpe1)); + setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1); + tim_installed++; + } + + return get_current_vpe() ? MSP_INT_VPE1_TIMER : MSP_INT_VPE0_TIMER; } diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c index 0ee01e359dd8..9a1aef89bd4c 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_usb.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c @@ -1,7 +1,7 @@ /* * The setup file for USB related hardware on PMC-Sierra MSP processors. * - * Copyright 2006-2007 PMC-Sierra, Inc. + * Copyright 2006 PMC-Sierra, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -23,8 +23,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) -#include <linux/dma-mapping.h> #include <linux/init.h> #include <linux/ioport.h> #include <linux/platform_device.h> @@ -34,40 +34,56 @@ #include <msp_regs.h> #include <msp_int.h> #include <msp_prom.h> +#include <msp_usb.h> + #if defined(CONFIG_USB_EHCI_HCD) -static struct resource msp_usbhost_resources [] = { - [0] = { - .start = MSP_USB_BASE_START, - .end = MSP_USB_BASE_END, - .flags = IORESOURCE_MEM, +static struct resource msp_usbhost0_resources[] = { + [0] = { /* EHCI-HS operational and capabilities registers */ + .start = MSP_USB0_HS_START, + .end = MSP_USB0_HS_END, + .flags = IORESOURCE_MEM, }, [1] = { - .start = MSP_INT_USB, - .end = MSP_INT_USB, - .flags = IORESOURCE_IRQ, + .start = MSP_INT_USB, + .end = MSP_INT_USB, + .flags = IORESOURCE_IRQ, + }, + [2] = { /* MSBus-to-AMBA bridge register space */ + .start = MSP_USB0_MAB_START, + .end = MSP_USB0_MAB_END, + .flags = IORESOURCE_MEM, + }, + [3] = { /* Identification and general hardware parameters */ + .start = MSP_USB0_ID_START, + .end = MSP_USB0_ID_END, + .flags = IORESOURCE_MEM, }, }; -static u64 msp_usbhost_dma_mask = DMA_BIT_MASK(32); +static u64 msp_usbhost0_dma_mask = 0xffffffffUL; -static struct platform_device msp_usbhost_device = { - .name = "pmcmsp-ehci", - .id = 0, +static struct mspusb_device msp_usbhost0_device = { .dev = { - .dma_mask = &msp_usbhost_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), + .name = "pmcmsp-ehci", + .id = 0, + .dev = { + .dma_mask = &msp_usbhost0_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE(msp_usbhost0_resources), + .resource = msp_usbhost0_resources, }, - .num_resources = ARRAY_SIZE(msp_usbhost_resources), - .resource = msp_usbhost_resources, }; -#endif /* CONFIG_USB_EHCI_HCD */ -#if defined(CONFIG_USB_GADGET) -static struct resource msp_usbdev_resources [] = { - [0] = { - .start = MSP_USB_BASE, - .end = MSP_USB_BASE_END, +/* MSP7140/MSP82XX has two USB2 hosts. */ +#ifdef CONFIG_MSP_HAS_DUAL_USB +static u64 msp_usbhost1_dma_mask = 0xffffffffUL; + +static struct resource msp_usbhost1_resources[] = { + [0] = { /* EHCI-HS operational and capabilities registers */ + .start = MSP_USB1_HS_START, + .end = MSP_USB1_HS_END, .flags = IORESOURCE_MEM, }, [1] = { @@ -75,76 +91,173 @@ static struct resource msp_usbdev_resources [] = { .end = MSP_INT_USB, .flags = IORESOURCE_IRQ, }, + [2] = { /* MSBus-to-AMBA bridge register space */ + .start = MSP_USB1_MAB_START, + .end = MSP_USB1_MAB_END, + .flags = IORESOURCE_MEM, + }, + [3] = { /* Identification and general hardware parameters */ + .start = MSP_USB1_ID_START, + .end = MSP_USB1_ID_END, + .flags = IORESOURCE_MEM, + }, +}; + +static struct mspusb_device msp_usbhost1_device = { + .dev = { + .name = "pmcmsp-ehci", + .id = 1, + .dev = { + .dma_mask = &msp_usbhost1_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE(msp_usbhost1_resources), + .resource = msp_usbhost1_resources, + }, }; +#endif /* CONFIG_MSP_HAS_DUAL_USB */ +#endif /* CONFIG_USB_EHCI_HCD */ -static u64 msp_usbdev_dma_mask = DMA_BIT_MASK(32); +#if defined(CONFIG_USB_GADGET) +static struct resource msp_usbdev0_resources[] = { + [0] = { /* EHCI-HS operational and capabilities registers */ + .start = MSP_USB0_HS_START, + .end = MSP_USB0_HS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_USB, + .end = MSP_INT_USB, + .flags = IORESOURCE_IRQ, + }, + [2] = { /* MSBus-to-AMBA bridge register space */ + .start = MSP_USB0_MAB_START, + .end = MSP_USB0_MAB_END, + .flags = IORESOURCE_MEM, + }, + [3] = { /* Identification and general hardware parameters */ + .start = MSP_USB0_ID_START, + .end = MSP_USB0_ID_END, + .flags = IORESOURCE_MEM, + }, +}; -static struct platform_device msp_usbdev_device = { - .name = "msp71xx_udc", - .id = 0, +static u64 msp_usbdev_dma_mask = 0xffffffffUL; + +/* This may need to be converted to a mspusb_device, too. */ +static struct mspusb_device msp_usbdev0_device = { .dev = { - .dma_mask = &msp_usbdev_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), + .name = "msp71xx_udc", + .id = 0, + .dev = { + .dma_mask = &msp_usbdev_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE(msp_usbdev0_resources), + .resource = msp_usbdev0_resources, }, - .num_resources = ARRAY_SIZE(msp_usbdev_resources), - .resource = msp_usbdev_resources, }; -#endif /* CONFIG_USB_GADGET */ -#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) -static struct platform_device *msp_devs[1]; -#endif +#ifdef CONFIG_MSP_HAS_DUAL_USB +static struct resource msp_usbdev1_resources[] = { + [0] = { /* EHCI-HS operational and capabilities registers */ + .start = MSP_USB1_HS_START, + .end = MSP_USB1_HS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MSP_INT_USB, + .end = MSP_INT_USB, + .flags = IORESOURCE_IRQ, + }, + [2] = { /* MSBus-to-AMBA bridge register space */ + .start = MSP_USB1_MAB_START, + .end = MSP_USB1_MAB_END, + .flags = IORESOURCE_MEM, + }, + [3] = { /* Identification and general hardware parameters */ + .start = MSP_USB1_ID_START, + .end = MSP_USB1_ID_END, + .flags = IORESOURCE_MEM, + }, +}; +/* This may need to be converted to a mspusb_device, too. */ +static struct mspusb_device msp_usbdev1_device = { + .dev = { + .name = "msp71xx_udc", + .id = 0, + .dev = { + .dma_mask = &msp_usbdev_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE(msp_usbdev1_resources), + .resource = msp_usbdev1_resources, + }, +}; + +#endif /* CONFIG_MSP_HAS_DUAL_USB */ +#endif /* CONFIG_USB_GADGET */ static int __init msp_usb_setup(void) { -#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET) - char *strp; - char envstr[32]; - unsigned int val = 0; - int result = 0; + char *strp; + char envstr[32]; + struct platform_device *msp_devs[NUM_USB_DEVS]; + unsigned int val; + /* construct environment name usbmode */ + /* set usbmode <host/device> as pmon environment var */ /* - * construct environment name usbmode - * set usbmode <host/device> as pmon environment var + * Could this perhaps be integrated into the "features" env var? + * Use the features key "U", and follow with "H" for host-mode, + * "D" for device-mode. If it works for Ethernet, why not USB... + * -- hammtrev, 2007/03/22 */ snprintf((char *)&envstr[0], sizeof(envstr), "usbmode"); -#if defined(CONFIG_USB_EHCI_HCD) - /* default to host mode */ + /* set default host mode */ val = 1; -#endif /* get environment string */ strp = prom_getenv((char *)&envstr[0]); if (strp) { + /* compare string */ if (!strcmp(strp, "device")) val = 0; } if (val) { #if defined(CONFIG_USB_EHCI_HCD) - /* get host mode device */ - msp_devs[0] = &msp_usbhost_device; - ppfinit("platform add USB HOST done %s.\n", - msp_devs[0]->name); - - result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs)); -#endif /* CONFIG_USB_EHCI_HCD */ - } + msp_devs[0] = &msp_usbhost0_device.dev; + ppfinit("platform add USB HOST done %s.\n", msp_devs[0]->name); +#ifdef CONFIG_MSP_HAS_DUAL_USB + msp_devs[1] = &msp_usbhost1_device.dev; + ppfinit("platform add USB HOST done %s.\n", msp_devs[1]->name); +#endif +#else + ppfinit("%s: echi_hcd not supported\n", __FILE__); +#endif /* CONFIG_USB_EHCI_HCD */ + } else { #if defined(CONFIG_USB_GADGET) - else { /* get device mode structure */ - msp_devs[0] = &msp_usbdev_device; - ppfinit("platform add USB DEVICE done %s.\n", - msp_devs[0]->name); - - result = platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs)); + msp_devs[0] = &msp_usbdev0_device.dev; + ppfinit("platform add USB DEVICE done %s.\n" + , msp_devs[0]->name); +#ifdef CONFIG_MSP_HAS_DUAL_USB + msp_devs[1] = &msp_usbdev1_device.dev; + ppfinit("platform add USB DEVICE done %s.\n" + , msp_devs[1]->name); +#endif +#else + ppfinit("%s: usb_gadget not supported\n", __FILE__); +#endif /* CONFIG_USB_GADGET */ } -#endif /* CONFIG_USB_GADGET */ -#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */ + /* add device */ + platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs)); - return result; + return 0; } subsys_initcall(msp_usb_setup); +#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */ diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile index b16f95c3df65..02f5fb94ea28 100644 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ b/arch/mips/pmc-sierra/yosemite/Makefile @@ -6,4 +6,4 @@ obj-y += irq.o prom.o py-console.o setup.o obj-$(CONFIG_SMP) += smp.o -EXTRA_CFLAGS += -Werror +ccflags-y := -Werror diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c index 941916f8aaff..adc171c8846f 100644 --- a/arch/mips/pnx833x/common/interrupts.c +++ b/arch/mips/pnx833x/common/interrupts.c @@ -152,10 +152,6 @@ static inline void pnx833x_hard_disable_pic_irq(unsigned int irq) PNX833X_PIC_INT_REG(irq) = 0; } -static int irqflags[PNX833X_PIC_NUM_IRQ]; /* initialized by zeroes */ -#define IRQFLAG_STARTED 1 -#define IRQFLAG_DISABLED 2 - static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock); static unsigned int pnx833x_startup_pic_irq(unsigned int irq) @@ -164,108 +160,54 @@ static unsigned int pnx833x_startup_pic_irq(unsigned int irq) unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - - irqflags[pic_irq] = IRQFLAG_STARTED; /* started, not disabled */ pnx833x_hard_enable_pic_irq(pic_irq); - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); return 0; } -static void pnx833x_shutdown_pic_irq(unsigned int irq) -{ - unsigned long flags; - unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; - - raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - - irqflags[pic_irq] = 0; /* not started */ - pnx833x_hard_disable_pic_irq(pic_irq); - - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); -} - -static void pnx833x_enable_pic_irq(unsigned int irq) +static void pnx833x_enable_pic_irq(struct irq_data *d) { unsigned long flags; - unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; + unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE; raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - - irqflags[pic_irq] &= ~IRQFLAG_DISABLED; - if (irqflags[pic_irq] == IRQFLAG_STARTED) - pnx833x_hard_enable_pic_irq(pic_irq); - + pnx833x_hard_enable_pic_irq(pic_irq); raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); } -static void pnx833x_disable_pic_irq(unsigned int irq) +static void pnx833x_disable_pic_irq(struct irq_data *d) { unsigned long flags; - unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; + unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE; raw_spin_lock_irqsave(&pnx833x_irq_lock, flags); - - irqflags[pic_irq] |= IRQFLAG_DISABLED; pnx833x_hard_disable_pic_irq(pic_irq); - raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags); } -static void pnx833x_ack_pic_irq(unsigned int irq) -{ -} - -static void pnx833x_end_pic_irq(unsigned int irq) -{ -} - static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock); -static unsigned int pnx833x_startup_gpio_irq(unsigned int irq) -{ - int pin = irq - PNX833X_GPIO_IRQ_BASE; - unsigned long flags; - raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); - pnx833x_gpio_enable_irq(pin); - raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); - return 0; -} - -static void pnx833x_enable_gpio_irq(unsigned int irq) +static void pnx833x_enable_gpio_irq(struct irq_data *d) { - int pin = irq - PNX833X_GPIO_IRQ_BASE; + int pin = d->irq - PNX833X_GPIO_IRQ_BASE; unsigned long flags; raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); pnx833x_gpio_enable_irq(pin); raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); } -static void pnx833x_disable_gpio_irq(unsigned int irq) +static void pnx833x_disable_gpio_irq(struct irq_data *d) { - int pin = irq - PNX833X_GPIO_IRQ_BASE; + int pin = d->irq - PNX833X_GPIO_IRQ_BASE; unsigned long flags; raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); pnx833x_gpio_disable_irq(pin); raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); } -static void pnx833x_ack_gpio_irq(unsigned int irq) -{ -} - -static void pnx833x_end_gpio_irq(unsigned int irq) -{ - int pin = irq - PNX833X_GPIO_IRQ_BASE; - unsigned long flags; - raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); - pnx833x_gpio_clear_irq(pin); - raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); -} - -static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type) +static int pnx833x_set_type_gpio_irq(struct irq_data *d, unsigned int flow_type) { - int pin = irq - PNX833X_GPIO_IRQ_BASE; + int pin = d->irq - PNX833X_GPIO_IRQ_BASE; int gpio_mode; switch (flow_type) { @@ -296,23 +238,15 @@ static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type) static struct irq_chip pnx833x_pic_irq_type = { .name = "PNX-PIC", - .startup = pnx833x_startup_pic_irq, - .shutdown = pnx833x_shutdown_pic_irq, - .enable = pnx833x_enable_pic_irq, - .disable = pnx833x_disable_pic_irq, - .ack = pnx833x_ack_pic_irq, - .end = pnx833x_end_pic_irq + .irq_enable = pnx833x_enable_pic_irq, + .irq_disable = pnx833x_disable_pic_irq, }; static struct irq_chip pnx833x_gpio_irq_type = { .name = "PNX-GPIO", - .startup = pnx833x_startup_gpio_irq, - .shutdown = pnx833x_disable_gpio_irq, - .enable = pnx833x_enable_gpio_irq, - .disable = pnx833x_disable_gpio_irq, - .ack = pnx833x_ack_gpio_irq, - .end = pnx833x_end_gpio_irq, - .set_type = pnx833x_set_type_gpio_irq + .irq_enable = pnx833x_enable_gpio_irq, + .irq_disable = pnx833x_disable_gpio_irq, + .irq_set_type = pnx833x_set_type_gpio_irq, }; void __init arch_init_irq(void) @@ -325,11 +259,13 @@ void __init arch_init_irq(void) /* Set IRQ information in irq_desc */ for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) { pnx833x_hard_disable_pic_irq(irq); - set_irq_chip_and_handler(irq, &pnx833x_pic_irq_type, handle_simple_irq); + irq_set_chip_and_handler(irq, &pnx833x_pic_irq_type, + handle_simple_irq); } for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++) - set_irq_chip_and_handler(irq, &pnx833x_gpio_irq_type, handle_simple_irq); + irq_set_chip_and_handler(irq, &pnx833x_gpio_irq_type, + handle_simple_irq); /* Set PIC priority limiter register to 0 */ PNX833X_PIC_INT_PRIORITY = 0; diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index ce45df17fd09..87167dcc79fa 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -165,7 +165,7 @@ static struct i2c_pnx0105_dev pnx833x_i2c_dev[] = { { .base = PNX833X_I2C0_PORTS_START, .irq = -1, /* should be PNX833X_PIC_I2C0_INT but polling is faster */ - .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Prefered HDCP) */ + .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Preferred HDCP) */ .bus_addr = 0, /* no slave support */ }, { diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c index cfed5051dc6d..6b93c81779c1 100644 --- a/arch/mips/pnx8550/common/int.c +++ b/arch/mips/pnx8550/common/int.c @@ -114,8 +114,10 @@ static inline void unmask_gic_int(unsigned int irq_nr) PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr]; } -static inline void mask_irq(unsigned int irq_nr) +static inline void mask_irq(struct irq_data *d) { + unsigned int irq_nr = d->irq; + if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { modify_cp0_intmask(1 << irq_nr, 0); } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && @@ -129,8 +131,10 @@ static inline void mask_irq(unsigned int irq_nr) } } -static inline void unmask_irq(unsigned int irq_nr) +static inline void unmask_irq(struct irq_data *d) { + unsigned int irq_nr = d->irq; + if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) { modify_cp0_intmask(0, 1 << irq_nr); } else if ((PNX8550_INT_GIC_MIN <= irq_nr) && @@ -157,10 +161,8 @@ int pnx8550_set_gic_priority(int irq, int priority) static struct irq_chip level_irq_type = { .name = "PNX Level IRQ", - .ack = mask_irq, - .mask = mask_irq, - .mask_ack = mask_irq, - .unmask = unmask_irq, + .irq_mask = mask_irq, + .irq_unmask = unmask_irq, }; static struct irqaction gic_action = { @@ -180,10 +182,8 @@ void __init arch_init_irq(void) int i; int configPR; - for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { - set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); - mask_irq(i); /* mask the irq just in case */ - } + for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) + irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq); /* init of GIC/IPC interrupts */ /* should be done before cp0 since cp0 init enables the GIC int */ @@ -206,7 +206,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq); } /* Priority level 0 */ @@ -215,20 +215,20 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - set_irq_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type, + irq_set_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type, handle_level_irq); setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) - set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq); /* Stop Timer 1-3 */ configPR = read_c0_config7(); configPR |= 0x00000038; write_c0_config7(configPR); - set_irq_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type, + irq_set_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type, handle_level_irq); setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile index baf6e9092a9f..348d2e850ef5 100644 --- a/arch/mips/powertv/Makefile +++ b/arch/mips/powertv/Makefile @@ -28,4 +28,4 @@ obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \ obj-$(CONFIG_USB) += powertv-usb.o -EXTRA_CFLAGS += -Wall +ccflags-y := -Wall diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile index f0e95dc0ac97..d810a33182a4 100644 --- a/arch/mips/powertv/asic/Makefile +++ b/arch/mips/powertv/asic/Makefile @@ -20,4 +20,4 @@ obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \ asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \ prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o -EXTRA_CFLAGS += -Wall -Werror +ccflags-y := -Wall -Werror diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c index e55382434155..7fb97fb0931e 100644 --- a/arch/mips/powertv/asic/irq_asic.c +++ b/arch/mips/powertv/asic/irq_asic.c @@ -21,9 +21,10 @@ #include <asm/mach-powertv/asic_regs.h> -static inline void unmask_asic_irq(unsigned int irq) +static inline void unmask_asic_irq(struct irq_data *d) { unsigned long enable_bit; + unsigned int irq = d->irq; enable_bit = (1 << (irq & 0x1f)); @@ -45,9 +46,10 @@ static inline void unmask_asic_irq(unsigned int irq) } } -static inline void mask_asic_irq(unsigned int irq) +static inline void mask_asic_irq(struct irq_data *d) { unsigned long disable_mask; + unsigned int irq = d->irq; disable_mask = ~(1 << (irq & 0x1f)); @@ -71,11 +73,8 @@ static inline void mask_asic_irq(unsigned int irq) static struct irq_chip asic_irq_chip = { .name = "ASIC Level", - .ack = mask_asic_irq, - .mask = mask_asic_irq, - .mask_ack = mask_asic_irq, - .unmask = unmask_asic_irq, - .eoi = unmask_asic_irq, + .irq_mask = mask_asic_irq, + .irq_unmask = unmask_asic_irq, }; void __init asic_irq_init(void) @@ -113,5 +112,5 @@ void __init asic_irq_init(void) * Initialize interrupt handlers. */ for (i = 0; i < NR_IRQS; i++) - set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq); + irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq); } diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile index f5c62462fc9d..5783201cd2c8 100644 --- a/arch/mips/powertv/pci/Makefile +++ b/arch/mips/powertv/pci/Makefile @@ -18,4 +18,4 @@ obj-$(CONFIG_PCI) += fixup-powertv.o -EXTRA_CFLAGS += -Wall -Werror +ccflags-y := -Wall -Werror diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c index ea6cec3c1e0d..7c6db74e3fad 100644 --- a/arch/mips/rb532/irq.c +++ b/arch/mips/rb532/irq.c @@ -111,10 +111,10 @@ static inline void ack_local_irq(unsigned int ip) clear_c0_cause(ipnum); } -static void rb532_enable_irq(unsigned int irq_nr) +static void rb532_enable_irq(struct irq_data *d) { + unsigned int group, intr_bit, irq_nr = d->irq; int ip = irq_nr - GROUP0_IRQ_BASE; - unsigned int group, intr_bit; volatile unsigned int *addr; if (ip < 0) @@ -132,10 +132,10 @@ static void rb532_enable_irq(unsigned int irq_nr) } } -static void rb532_disable_irq(unsigned int irq_nr) +static void rb532_disable_irq(struct irq_data *d) { + unsigned int group, intr_bit, mask, irq_nr = d->irq; int ip = irq_nr - GROUP0_IRQ_BASE; - unsigned int group, intr_bit, mask; volatile unsigned int *addr; if (ip < 0) { @@ -163,18 +163,18 @@ static void rb532_disable_irq(unsigned int irq_nr) } } -static void rb532_mask_and_ack_irq(unsigned int irq_nr) +static void rb532_mask_and_ack_irq(struct irq_data *d) { - rb532_disable_irq(irq_nr); - ack_local_irq(group_to_ip(irq_to_group(irq_nr))); + rb532_disable_irq(d); + ack_local_irq(group_to_ip(irq_to_group(d->irq))); } -static int rb532_set_type(unsigned int irq_nr, unsigned type) +static int rb532_set_type(struct irq_data *d, unsigned type) { - int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE; - int group = irq_to_group(irq_nr); + int gpio = d->irq - GPIO_MAPPED_IRQ_BASE; + int group = irq_to_group(d->irq); - if (group != GPIO_MAPPED_IRQ_GROUP || irq_nr > (GROUP4_IRQ_BASE + 13)) + if (group != GPIO_MAPPED_IRQ_GROUP || d->irq > (GROUP4_IRQ_BASE + 13)) return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL; switch (type) { @@ -193,11 +193,11 @@ static int rb532_set_type(unsigned int irq_nr, unsigned type) static struct irq_chip rc32434_irq_type = { .name = "RB532", - .ack = rb532_disable_irq, - .mask = rb532_disable_irq, - .mask_ack = rb532_mask_and_ack_irq, - .unmask = rb532_enable_irq, - .set_type = rb532_set_type, + .irq_ack = rb532_disable_irq, + .irq_mask = rb532_disable_irq, + .irq_mask_ack = rb532_mask_and_ack_irq, + .irq_unmask = rb532_enable_irq, + .irq_set_type = rb532_set_type, }; void __init arch_init_irq(void) @@ -207,8 +207,8 @@ void __init arch_init_irq(void) pr_info("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS); for (i = 0; i < RC32434_NR_IRQS; i++) - set_irq_chip_and_handler(i, &rc32434_irq_type, - handle_level_irq); + irq_set_chip_and_handler(i, &rc32434_irq_type, + handle_level_irq); } /* Main Interrupt dispatcher */ diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 383f11d7f442..476423a01296 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -31,88 +31,80 @@ static char lc3msk_to_irqnr[256]; extern int ip22_eisa_init(void); -static void enable_local0_irq(unsigned int irq) +static void enable_local0_irq(struct irq_data *d) { /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ - if (irq != SGI_MAP_0_IRQ) - sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); + if (d->irq != SGI_MAP_0_IRQ) + sgint->imask0 |= (1 << (d->irq - SGINT_LOCAL0)); } -static void disable_local0_irq(unsigned int irq) +static void disable_local0_irq(struct irq_data *d) { - sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); + sgint->imask0 &= ~(1 << (d->irq - SGINT_LOCAL0)); } static struct irq_chip ip22_local0_irq_type = { .name = "IP22 local 0", - .ack = disable_local0_irq, - .mask = disable_local0_irq, - .mask_ack = disable_local0_irq, - .unmask = enable_local0_irq, + .irq_mask = disable_local0_irq, + .irq_unmask = enable_local0_irq, }; -static void enable_local1_irq(unsigned int irq) +static void enable_local1_irq(struct irq_data *d) { /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ - if (irq != SGI_MAP_1_IRQ) - sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); + if (d->irq != SGI_MAP_1_IRQ) + sgint->imask1 |= (1 << (d->irq - SGINT_LOCAL1)); } -static void disable_local1_irq(unsigned int irq) +static void disable_local1_irq(struct irq_data *d) { - sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); + sgint->imask1 &= ~(1 << (d->irq - SGINT_LOCAL1)); } static struct irq_chip ip22_local1_irq_type = { .name = "IP22 local 1", - .ack = disable_local1_irq, - .mask = disable_local1_irq, - .mask_ack = disable_local1_irq, - .unmask = enable_local1_irq, + .irq_mask = disable_local1_irq, + .irq_unmask = enable_local1_irq, }; -static void enable_local2_irq(unsigned int irq) +static void enable_local2_irq(struct irq_data *d) { sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); - sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); + sgint->cmeimask0 |= (1 << (d->irq - SGINT_LOCAL2)); } -static void disable_local2_irq(unsigned int irq) +static void disable_local2_irq(struct irq_data *d) { - sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); + sgint->cmeimask0 &= ~(1 << (d->irq - SGINT_LOCAL2)); if (!sgint->cmeimask0) sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); } static struct irq_chip ip22_local2_irq_type = { .name = "IP22 local 2", - .ack = disable_local2_irq, - .mask = disable_local2_irq, - .mask_ack = disable_local2_irq, - .unmask = enable_local2_irq, + .irq_mask = disable_local2_irq, + .irq_unmask = enable_local2_irq, }; -static void enable_local3_irq(unsigned int irq) +static void enable_local3_irq(struct irq_data *d) { sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); - sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); + sgint->cmeimask1 |= (1 << (d->irq - SGINT_LOCAL3)); } -static void disable_local3_irq(unsigned int irq) +static void disable_local3_irq(struct irq_data *d) { - sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); + sgint->cmeimask1 &= ~(1 << (d->irq - SGINT_LOCAL3)); if (!sgint->cmeimask1) sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); } static struct irq_chip ip22_local3_irq_type = { .name = "IP22 local 3", - .ack = disable_local3_irq, - .mask = disable_local3_irq, - .mask_ack = disable_local3_irq, - .unmask = enable_local3_irq, + .irq_mask = disable_local3_irq, + .irq_unmask = enable_local3_irq, }; static void indy_local0_irqdispatch(void) @@ -320,7 +312,7 @@ void __init arch_init_irq(void) else handler = &ip22_local3_irq_type; - set_irq_chip_and_handler(i, handler, handle_level_irq); + irq_set_chip_and_handler(i, handler, handle_level_irq); } /* vector handler. this register the IRQ as non-sharable */ diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig index 5e960ae9735a..bc5e9769bb73 100644 --- a/arch/mips/sgi-ip27/Kconfig +++ b/arch/mips/sgi-ip27/Kconfig @@ -1,7 +1,7 @@ #config SGI_SN0_XXL # bool "IP27 XXL" # depends on SGI_IP27 -# This options adds support for userspace processes upto 16TB size. +# This options adds support for userspace processes up to 16TB size. # Normally the limit is just .5TB. choice diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO index 19f1512c8f2e..160857ff1483 100644 --- a/arch/mips/sgi-ip27/TODO +++ b/arch/mips/sgi-ip27/TODO @@ -13,7 +13,7 @@ being invoked on all nodes in ip27-memory.c. 9. start_thread must turn off UX64 ... and define tlb_refill_debug. 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable does not agree with pgd_bad/pmd_bad. -11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node. +11. All intrs (ip27_do_irq handlers) are targeted at cpu A on the node. This might need to change later. Only the timer intr is set up to be received on both Cpu A and B. (ip27_do_irq()/bridge_startup()) 13. Cache flushing (specially the SMP version) has to be investigated. diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c index 51d3a4f2d7e1..923c080f77bd 100644 --- a/arch/mips/sgi-ip27/ip27-init.c +++ b/arch/mips/sgi-ip27/ip27-init.c @@ -93,7 +93,7 @@ static void __cpuinit per_hub_init(cnodeid_t cnode) /* * Some interrupts are reserved by hardware or by software convention. - * Mark these as reserved right away so they won't be used accidently + * Mark these as reserved right away so they won't be used accidentally * later. */ for (i = 0; i <= BASE_PCI_IRQ; i++) { diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 6a123ea72de5..0a04603d577c 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -41,7 +41,7 @@ * Linux has a controller-independent x86 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 + * interrupt source is transparently wired to the appropriate * controller. Thus drivers need not be aware of the * interrupt-controller. * @@ -240,7 +240,7 @@ static int intr_disconnect_level(int cpu, int bit) } /* Startup one of the (PCI ...) IRQs routes over a bridge. */ -static unsigned int startup_bridge_irq(unsigned int irq) +static unsigned int startup_bridge_irq(struct irq_data *d) { struct bridge_controller *bc; bridgereg_t device; @@ -248,16 +248,16 @@ static unsigned int startup_bridge_irq(unsigned int irq) int pin, swlevel; cpuid_t cpu; - pin = SLOT_FROM_PCI_IRQ(irq); - bc = IRQ_TO_BRIDGE(irq); + pin = SLOT_FROM_PCI_IRQ(d->irq); + bc = IRQ_TO_BRIDGE(d->irq); bridge = bc->base; - pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); + pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin); /* * "map" irq to a swlevel greater than 6 since the first 6 bits * of INT_PEND0 are taken */ - swlevel = find_level(&cpu, irq); + swlevel = find_level(&cpu, d->irq); bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); bridge->b_int_enable |= (1 << pin); bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ @@ -288,58 +288,56 @@ static unsigned int startup_bridge_irq(unsigned int irq) } /* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ -static void shutdown_bridge_irq(unsigned int irq) +static void shutdown_bridge_irq(struct irq_data *d) { - struct bridge_controller *bc = IRQ_TO_BRIDGE(irq); + struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq); bridge_t *bridge = bc->base; int pin, swlevel; cpuid_t cpu; - pr_debug("bridge_shutdown: irq 0x%x\n", irq); - pin = SLOT_FROM_PCI_IRQ(irq); + pr_debug("bridge_shutdown: irq 0x%x\n", d->irq); + pin = SLOT_FROM_PCI_IRQ(d->irq); /* * map irq to a swlevel greater than 6 since the first 6 bits * of INT_PEND0 are taken */ - swlevel = find_level(&cpu, irq); + swlevel = find_level(&cpu, d->irq); intr_disconnect_level(cpu, swlevel); bridge->b_int_enable &= ~(1 << pin); bridge->b_wid_tflush; } -static inline void enable_bridge_irq(unsigned int irq) +static inline void enable_bridge_irq(struct irq_data *d) { cpuid_t cpu; int swlevel; - swlevel = find_level(&cpu, irq); /* Criminal offence */ + swlevel = find_level(&cpu, d->irq); /* Criminal offence */ intr_connect_level(cpu, swlevel); } -static inline void disable_bridge_irq(unsigned int irq) +static inline void disable_bridge_irq(struct irq_data *d) { cpuid_t cpu; int swlevel; - swlevel = find_level(&cpu, irq); /* Criminal offence */ + swlevel = find_level(&cpu, d->irq); /* Criminal offence */ intr_disconnect_level(cpu, swlevel); } static struct irq_chip bridge_irq_type = { .name = "bridge", - .startup = startup_bridge_irq, - .shutdown = shutdown_bridge_irq, - .ack = disable_bridge_irq, - .mask = disable_bridge_irq, - .mask_ack = disable_bridge_irq, - .unmask = enable_bridge_irq, + .irq_startup = startup_bridge_irq, + .irq_shutdown = shutdown_bridge_irq, + .irq_mask = disable_bridge_irq, + .irq_unmask = enable_bridge_irq, }; void __devinit register_bridge_irq(unsigned int irq) { - set_irq_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); + irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); } int __devinit request_bridge_irq(struct bridge_controller *bc) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 3cac88382d4c..8d0d2690e962 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -36,21 +36,18 @@ #include <asm/sn/sn0/hubio.h> #include <asm/pci/bridge.h> -static void enable_rt_irq(unsigned int irq) +static void enable_rt_irq(struct irq_data *d) { } -static void disable_rt_irq(unsigned int irq) +static void disable_rt_irq(struct irq_data *d) { } static struct irq_chip rt_irq_type = { .name = "SN HUB RT timer", - .ack = disable_rt_irq, - .mask = disable_rt_irq, - .mask_ack = disable_rt_irq, - .unmask = enable_rt_irq, - .eoi = enable_rt_irq, + .irq_mask = disable_rt_irq, + .irq_unmask = enable_rt_irq, }; static int rt_next_event(unsigned long delta, struct clock_event_device *evt) @@ -156,7 +153,7 @@ static void __init hub_rt_clock_event_global_init(void) panic("Allocation of irq number for timer failed"); } while (xchg(&rt_timer_irq, irq)); - set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); + irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); setup_irq(irq, &hub_rt_irqaction); } diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index eb40824b172a..c65ea76d56c7 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -130,70 +130,48 @@ static struct irqaction cpuerr_irq = { static uint64_t crime_mask; -static inline void crime_enable_irq(unsigned int irq) +static inline void crime_enable_irq(struct irq_data *d) { - unsigned int bit = irq - CRIME_IRQ_BASE; + unsigned int bit = d->irq - CRIME_IRQ_BASE; crime_mask |= 1 << bit; crime->imask = crime_mask; } -static inline void crime_disable_irq(unsigned int irq) +static inline void crime_disable_irq(struct irq_data *d) { - unsigned int bit = irq - CRIME_IRQ_BASE; + unsigned int bit = d->irq - CRIME_IRQ_BASE; crime_mask &= ~(1 << bit); crime->imask = crime_mask; flush_crime_bus(); } -static void crime_level_mask_and_ack_irq(unsigned int irq) -{ - crime_disable_irq(irq); -} - -static void crime_level_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - crime_enable_irq(irq); -} - static struct irq_chip crime_level_interrupt = { .name = "IP32 CRIME", - .ack = crime_level_mask_and_ack_irq, - .mask = crime_disable_irq, - .mask_ack = crime_level_mask_and_ack_irq, - .unmask = crime_enable_irq, - .end = crime_level_end_irq, + .irq_mask = crime_disable_irq, + .irq_unmask = crime_enable_irq, }; -static void crime_edge_mask_and_ack_irq(unsigned int irq) +static void crime_edge_mask_and_ack_irq(struct irq_data *d) { - unsigned int bit = irq - CRIME_IRQ_BASE; + unsigned int bit = d->irq - CRIME_IRQ_BASE; uint64_t crime_int; /* Edge triggered interrupts must be cleared. */ - crime_int = crime->hard_int; crime_int &= ~(1 << bit); crime->hard_int = crime_int; - crime_disable_irq(irq); -} - -static void crime_edge_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - crime_enable_irq(irq); + crime_disable_irq(d); } static struct irq_chip crime_edge_interrupt = { .name = "IP32 CRIME", - .ack = crime_edge_mask_and_ack_irq, - .mask = crime_disable_irq, - .mask_ack = crime_edge_mask_and_ack_irq, - .unmask = crime_enable_irq, - .end = crime_edge_end_irq, + .irq_ack = crime_edge_mask_and_ack_irq, + .irq_mask = crime_disable_irq, + .irq_mask_ack = crime_edge_mask_and_ack_irq, + .irq_unmask = crime_enable_irq, }; /* @@ -204,37 +182,28 @@ static struct irq_chip crime_edge_interrupt = { static unsigned long macepci_mask; -static void enable_macepci_irq(unsigned int irq) +static void enable_macepci_irq(struct irq_data *d) { - macepci_mask |= MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ); + macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ); mace->pci.control = macepci_mask; - crime_mask |= 1 << (irq - CRIME_IRQ_BASE); + crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE); crime->imask = crime_mask; } -static void disable_macepci_irq(unsigned int irq) +static void disable_macepci_irq(struct irq_data *d) { - crime_mask &= ~(1 << (irq - CRIME_IRQ_BASE)); + crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE)); crime->imask = crime_mask; flush_crime_bus(); - macepci_mask &= ~MACEPCI_CONTROL_INT(irq - MACEPCI_SCSI0_IRQ); + macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ); mace->pci.control = macepci_mask; flush_mace_bus(); } -static void end_macepci_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_macepci_irq(irq); -} - static struct irq_chip ip32_macepci_interrupt = { .name = "IP32 MACE PCI", - .ack = disable_macepci_irq, - .mask = disable_macepci_irq, - .mask_ack = disable_macepci_irq, - .unmask = enable_macepci_irq, - .end = end_macepci_irq, + .irq_mask = disable_macepci_irq, + .irq_unmask = enable_macepci_irq, }; /* This is used for MACE ISA interrupts. That means bits 4-6 in the @@ -276,13 +245,13 @@ static struct irq_chip ip32_macepci_interrupt = { static unsigned long maceisa_mask; -static void enable_maceisa_irq(unsigned int irq) +static void enable_maceisa_irq(struct irq_data *d) { unsigned int crime_int = 0; - pr_debug("maceisa enable: %u\n", irq); + pr_debug("maceisa enable: %u\n", d->irq); - switch (irq) { + switch (d->irq) { case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: crime_int = MACE_AUDIO_INT; break; @@ -296,15 +265,15 @@ static void enable_maceisa_irq(unsigned int irq) pr_debug("crime_int %08x enabled\n", crime_int); crime_mask |= crime_int; crime->imask = crime_mask; - maceisa_mask |= 1 << (irq - MACEISA_AUDIO_SW_IRQ); + maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ); mace->perif.ctrl.imask = maceisa_mask; } -static void disable_maceisa_irq(unsigned int irq) +static void disable_maceisa_irq(struct irq_data *d) { unsigned int crime_int = 0; - maceisa_mask &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); + maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ)); if (!(maceisa_mask & MACEISA_AUDIO_INT)) crime_int |= MACE_AUDIO_INT; if (!(maceisa_mask & MACEISA_MISC_INT)) @@ -318,76 +287,57 @@ static void disable_maceisa_irq(unsigned int irq) flush_mace_bus(); } -static void mask_and_ack_maceisa_irq(unsigned int irq) +static void mask_and_ack_maceisa_irq(struct irq_data *d) { unsigned long mace_int; /* edge triggered */ mace_int = mace->perif.ctrl.istat; - mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ)); + mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ)); mace->perif.ctrl.istat = mace_int; - disable_maceisa_irq(irq); -} - -static void end_maceisa_irq(unsigned irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_maceisa_irq(irq); + disable_maceisa_irq(d); } static struct irq_chip ip32_maceisa_level_interrupt = { .name = "IP32 MACE ISA", - .ack = disable_maceisa_irq, - .mask = disable_maceisa_irq, - .mask_ack = disable_maceisa_irq, - .unmask = enable_maceisa_irq, - .end = end_maceisa_irq, + .irq_mask = disable_maceisa_irq, + .irq_unmask = enable_maceisa_irq, }; static struct irq_chip ip32_maceisa_edge_interrupt = { .name = "IP32 MACE ISA", - .ack = mask_and_ack_maceisa_irq, - .mask = disable_maceisa_irq, - .mask_ack = mask_and_ack_maceisa_irq, - .unmask = enable_maceisa_irq, - .end = end_maceisa_irq, + .irq_ack = mask_and_ack_maceisa_irq, + .irq_mask = disable_maceisa_irq, + .irq_mask_ack = mask_and_ack_maceisa_irq, + .irq_unmask = enable_maceisa_irq, }; /* This is used for regular non-ISA, non-PCI MACE interrupts. That means * bits 0-3 and 7 in the CRIME register. */ -static void enable_mace_irq(unsigned int irq) +static void enable_mace_irq(struct irq_data *d) { - unsigned int bit = irq - CRIME_IRQ_BASE; + unsigned int bit = d->irq - CRIME_IRQ_BASE; crime_mask |= (1 << bit); crime->imask = crime_mask; } -static void disable_mace_irq(unsigned int irq) +static void disable_mace_irq(struct irq_data *d) { - unsigned int bit = irq - CRIME_IRQ_BASE; + unsigned int bit = d->irq - CRIME_IRQ_BASE; crime_mask &= ~(1 << bit); crime->imask = crime_mask; flush_crime_bus(); } -static void end_mace_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_mace_irq(irq); -} - static struct irq_chip ip32_mace_interrupt = { .name = "IP32 MACE", - .ack = disable_mace_irq, - .mask = disable_mace_irq, - .mask_ack = disable_mace_irq, - .unmask = enable_mace_irq, - .end = end_mace_irq, + .irq_mask = disable_mace_irq, + .irq_unmask = enable_mace_irq, }; static void ip32_unknown_interrupt(void) @@ -501,43 +451,51 @@ void __init arch_init_irq(void) for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) { switch (irq) { case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: - set_irq_chip_and_handler_name(irq,&ip32_mace_interrupt, - handle_level_irq, "level"); + irq_set_chip_and_handler_name(irq, + &ip32_mace_interrupt, + handle_level_irq, + "level"); break; case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: - set_irq_chip_and_handler_name(irq, - &ip32_macepci_interrupt, handle_level_irq, - "level"); + irq_set_chip_and_handler_name(irq, + &ip32_macepci_interrupt, + handle_level_irq, + "level"); break; case CRIME_CPUERR_IRQ: case CRIME_MEMERR_IRQ: - set_irq_chip_and_handler_name(irq, - &crime_level_interrupt, handle_level_irq, - "level"); + irq_set_chip_and_handler_name(irq, + &crime_level_interrupt, + handle_level_irq, + "level"); break; case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ: case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ: case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ: case CRIME_VICE_IRQ: - set_irq_chip_and_handler_name(irq, - &crime_edge_interrupt, handle_edge_irq, "edge"); + irq_set_chip_and_handler_name(irq, + &crime_edge_interrupt, + handle_edge_irq, + "edge"); break; case MACEISA_PARALLEL_IRQ: case MACEISA_SERIAL1_TDMAPR_IRQ: case MACEISA_SERIAL2_TDMAPR_IRQ: - set_irq_chip_and_handler_name(irq, - &ip32_maceisa_edge_interrupt, handle_edge_irq, - "edge"); + irq_set_chip_and_handler_name(irq, + &ip32_maceisa_edge_interrupt, + handle_edge_irq, + "edge"); break; default: - set_irq_chip_and_handler_name(irq, - &ip32_maceisa_level_interrupt, handle_level_irq, - "level"); + irq_set_chip_and_handler_name(irq, + &ip32_maceisa_level_interrupt, + handle_level_irq, + "level"); break; } } diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 044bbe462c2c..09740d60e187 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -44,31 +44,10 @@ * for interrupt lines */ - -static void end_bcm1480_irq(unsigned int irq); -static void enable_bcm1480_irq(unsigned int irq); -static void disable_bcm1480_irq(unsigned int irq); -static void ack_bcm1480_irq(unsigned int irq); -#ifdef CONFIG_SMP -static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask); -#endif - #ifdef CONFIG_PCI extern unsigned long ht_eoi_space; #endif -static struct irq_chip bcm1480_irq_type = { - .name = "BCM1480-IMR", - .ack = ack_bcm1480_irq, - .mask = disable_bcm1480_irq, - .mask_ack = ack_bcm1480_irq, - .unmask = enable_bcm1480_irq, - .end = end_bcm1480_irq, -#ifdef CONFIG_SMP - .set_affinity = bcm1480_set_affinity -#endif -}; - /* Store the CPU id (not the logical number) */ int bcm1480_irq_owner[BCM1480_NR_IRQS]; @@ -109,12 +88,13 @@ void bcm1480_unmask_irq(int cpu, int irq) } #ifdef CONFIG_SMP -static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask) +static int bcm1480_set_affinity(struct irq_data *d, const struct cpumask *mask, + bool force) { + unsigned int irq_dirty, irq = d->irq; int i = 0, old_cpu, cpu, int_on, k; u64 cur_ints; unsigned long flags; - unsigned int irq_dirty; i = cpumask_first(mask); @@ -156,21 +136,25 @@ static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask) /*****************************************************************************/ -static void disable_bcm1480_irq(unsigned int irq) +static void disable_bcm1480_irq(struct irq_data *d) { + unsigned int irq = d->irq; + bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); } -static void enable_bcm1480_irq(unsigned int irq) +static void enable_bcm1480_irq(struct irq_data *d) { + unsigned int irq = d->irq; + bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); } -static void ack_bcm1480_irq(unsigned int irq) +static void ack_bcm1480_irq(struct irq_data *d) { + unsigned int irq_dirty, irq = d->irq; u64 pending; - unsigned int irq_dirty; int k; /* @@ -217,21 +201,23 @@ static void ack_bcm1480_irq(unsigned int irq) bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); } - -static void end_bcm1480_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); - } -} - +static struct irq_chip bcm1480_irq_type = { + .name = "BCM1480-IMR", + .irq_mask_ack = ack_bcm1480_irq, + .irq_mask = disable_bcm1480_irq, + .irq_unmask = enable_bcm1480_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = bcm1480_set_affinity +#endif +}; void __init init_bcm1480_irqs(void) { int i; for (i = 0; i < BCM1480_NR_IRQS; i++) { - set_irq_chip_and_handler(i, &bcm1480_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &bcm1480_irq_type, + handle_level_irq); bcm1480_irq_owner[i] = 0; } } diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 12ac04a658ee..be4460a5f6a8 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -43,31 +43,10 @@ * for interrupt lines */ - -static void end_sb1250_irq(unsigned int irq); -static void enable_sb1250_irq(unsigned int irq); -static void disable_sb1250_irq(unsigned int irq); -static void ack_sb1250_irq(unsigned int irq); -#ifdef CONFIG_SMP -static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask); -#endif - #ifdef CONFIG_SIBYTE_HAS_LDT extern unsigned long ldt_eoi_space; #endif -static struct irq_chip sb1250_irq_type = { - .name = "SB1250-IMR", - .ack = ack_sb1250_irq, - .mask = disable_sb1250_irq, - .mask_ack = ack_sb1250_irq, - .unmask = enable_sb1250_irq, - .end = end_sb1250_irq, -#ifdef CONFIG_SMP - .set_affinity = sb1250_set_affinity -#endif -}; - /* Store the CPU id (not the logical number) */ int sb1250_irq_owner[SB1250_NR_IRQS]; @@ -102,9 +81,11 @@ void sb1250_unmask_irq(int cpu, int irq) } #ifdef CONFIG_SMP -static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask) +static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask, + bool force) { int i = 0, old_cpu, cpu, int_on; + unsigned int irq = d->irq; u64 cur_ints; unsigned long flags; @@ -142,21 +123,17 @@ static int sb1250_set_affinity(unsigned int irq, const struct cpumask *mask) } #endif -/*****************************************************************************/ - -static void disable_sb1250_irq(unsigned int irq) +static void enable_sb1250_irq(struct irq_data *d) { - sb1250_mask_irq(sb1250_irq_owner[irq], irq); -} + unsigned int irq = d->irq; -static void enable_sb1250_irq(unsigned int irq) -{ sb1250_unmask_irq(sb1250_irq_owner[irq], irq); } -static void ack_sb1250_irq(unsigned int irq) +static void ack_sb1250_irq(struct irq_data *d) { + unsigned int irq = d->irq; #ifdef CONFIG_SIBYTE_HAS_LDT u64 pending; @@ -199,21 +176,22 @@ static void ack_sb1250_irq(unsigned int irq) sb1250_mask_irq(sb1250_irq_owner[irq], irq); } - -static void end_sb1250_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - sb1250_unmask_irq(sb1250_irq_owner[irq], irq); - } -} - +static struct irq_chip sb1250_irq_type = { + .name = "SB1250-IMR", + .irq_mask_ack = ack_sb1250_irq, + .irq_unmask = enable_sb1250_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = sb1250_set_affinity +#endif +}; void __init init_sb1250_irqs(void) { int i; for (i = 0; i < SB1250_NR_IRQS; i++) { - set_irq_chip_and_handler(i, &sb1250_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &sb1250_irq_type, + handle_level_irq); sb1250_irq_owner[i] = 0; } } diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index bbe7187879fa..c48194c3073b 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c @@ -168,33 +168,22 @@ static u32 a20r_ack_hwint(void) return status; } -static inline void unmask_a20r_irq(unsigned int irq) +static inline void unmask_a20r_irq(struct irq_data *d) { - set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE)); + set_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE)); irq_enable_hazard(); } -static inline void mask_a20r_irq(unsigned int irq) +static inline void mask_a20r_irq(struct irq_data *d) { - clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE)); + clear_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE)); irq_disable_hazard(); } -static void end_a20r_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - a20r_ack_hwint(); - unmask_a20r_irq(irq); - } -} - static struct irq_chip a20r_irq_type = { .name = "A20R", - .ack = mask_a20r_irq, - .mask = mask_a20r_irq, - .mask_ack = mask_a20r_irq, - .unmask = unmask_a20r_irq, - .end = end_a20r_irq, + .irq_mask = mask_a20r_irq, + .irq_unmask = unmask_a20r_irq, }; /* @@ -220,7 +209,7 @@ void __init sni_a20r_irq_init(void) int i; for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++) - set_irq_chip_and_handler(i, &a20r_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &a20r_irq_type, handle_level_irq); sni_hwint = a20r_hwint; change_c0_status(ST0_IM, IE_IRQ0); setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq); diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 8c92c73bc717..ed3b3d317358 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c @@ -194,33 +194,24 @@ static struct pci_controller sni_controller = { .io_map_base = SNI_PORT_BASE }; -static void enable_pcimt_irq(unsigned int irq) +static void enable_pcimt_irq(struct irq_data *d) { - unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); + unsigned int mask = 1 << (d->irq - PCIMT_IRQ_INT2); *(volatile u8 *) PCIMT_IRQSEL |= mask; } -void disable_pcimt_irq(unsigned int irq) +void disable_pcimt_irq(struct irq_data *d) { - unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); + unsigned int mask = ~(1 << (d->irq - PCIMT_IRQ_INT2)); *(volatile u8 *) PCIMT_IRQSEL &= mask; } -static void end_pcimt_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_pcimt_irq(irq); -} - static struct irq_chip pcimt_irq_type = { .name = "PCIMT", - .ack = disable_pcimt_irq, - .mask = disable_pcimt_irq, - .mask_ack = disable_pcimt_irq, - .unmask = enable_pcimt_irq, - .end = end_pcimt_irq, + .irq_mask = disable_pcimt_irq, + .irq_unmask = enable_pcimt_irq, }; /* @@ -305,7 +296,7 @@ void __init sni_pcimt_irq_init(void) mips_cpu_irq_init(); /* Actually we've got more interrupts to handle ... */ for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++) - set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &pcimt_irq_type, handle_level_irq); sni_hwint = sni_pcimt_hwint; change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); } diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c index dc9874553bec..b5246373d16b 100644 --- a/arch/mips/sni/pcit.c +++ b/arch/mips/sni/pcit.c @@ -156,33 +156,24 @@ static struct pci_controller sni_pcit_controller = { .io_map_base = SNI_PORT_BASE }; -static void enable_pcit_irq(unsigned int irq) +static void enable_pcit_irq(struct irq_data *d) { - u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24); + u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24); *(volatile u32 *)SNI_PCIT_INT_REG |= mask; } -void disable_pcit_irq(unsigned int irq) +void disable_pcit_irq(struct irq_data *d) { - u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24); + u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24); *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask; } -void end_pcit_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_pcit_irq(irq); -} - static struct irq_chip pcit_irq_type = { .name = "PCIT", - .ack = disable_pcit_irq, - .mask = disable_pcit_irq, - .mask_ack = disable_pcit_irq, - .unmask = enable_pcit_irq, - .end = end_pcit_irq, + .irq_mask = disable_pcit_irq, + .irq_unmask = enable_pcit_irq, }; static void pcit_hwint1(void) @@ -247,7 +238,7 @@ void __init sni_pcit_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) - set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq); *(volatile u32 *)SNI_PCIT_INT_REG = 0; sni_hwint = sni_pcit_hwint; change_c0_status(ST0_IM, IE_IRQ1); @@ -260,7 +251,7 @@ void __init sni_pcit_cplus_irq_init(void) mips_cpu_irq_init(); for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) - set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq); *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000; sni_hwint = sni_pcit_hwint_cplus; change_c0_status(ST0_IM, IE_IRQ0); diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c index 0e6f42c2bbc8..a7e5a6d917b1 100644 --- a/arch/mips/sni/rm200.c +++ b/arch/mips/sni/rm200.c @@ -155,12 +155,11 @@ static __iomem u8 *rm200_pic_slave; #define cached_master_mask (rm200_cached_irq_mask) #define cached_slave_mask (rm200_cached_irq_mask >> 8) -static void sni_rm200_disable_8259A_irq(unsigned int irq) +static void sni_rm200_disable_8259A_irq(struct irq_data *d) { - unsigned int mask; + unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE; unsigned long flags; - irq -= RM200_I8259A_IRQ_BASE; mask = 1 << irq; raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); rm200_cached_irq_mask |= mask; @@ -171,12 +170,11 @@ static void sni_rm200_disable_8259A_irq(unsigned int irq) raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags); } -static void sni_rm200_enable_8259A_irq(unsigned int irq) +static void sni_rm200_enable_8259A_irq(struct irq_data *d) { - unsigned int mask; + unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE; unsigned long flags; - irq -= RM200_I8259A_IRQ_BASE; mask = ~(1 << irq); raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); rm200_cached_irq_mask &= mask; @@ -210,12 +208,11 @@ static inline int sni_rm200_i8259A_irq_real(unsigned int irq) * first, _then_ send the EOI, and the order of EOI * to the two 8259s is important! */ -void sni_rm200_mask_and_ack_8259A(unsigned int irq) +void sni_rm200_mask_and_ack_8259A(struct irq_data *d) { - unsigned int irqmask; + unsigned int irqmask, irq = d->irq - RM200_I8259A_IRQ_BASE; unsigned long flags; - irq -= RM200_I8259A_IRQ_BASE; irqmask = 1 << irq; raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags); /* @@ -285,9 +282,9 @@ spurious_8259A_irq: static struct irq_chip sni_rm200_i8259A_chip = { .name = "RM200-XT-PIC", - .mask = sni_rm200_disable_8259A_irq, - .unmask = sni_rm200_enable_8259A_irq, - .mask_ack = sni_rm200_mask_and_ack_8259A, + .irq_mask = sni_rm200_disable_8259A_irq, + .irq_unmask = sni_rm200_enable_8259A_irq, + .irq_mask_ack = sni_rm200_mask_and_ack_8259A, }; /* @@ -416,7 +413,7 @@ void __init sni_rm200_i8259_irqs(void) sni_rm200_init_8259A(); for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++) - set_irq_chip_and_handler(i, &sni_rm200_i8259A_chip, + irq_set_chip_and_handler(i, &sni_rm200_i8259A_chip, handle_level_irq); setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2); @@ -429,33 +426,24 @@ void __init sni_rm200_i8259_irqs(void) #define SNI_RM200_INT_START 24 #define SNI_RM200_INT_END 28 -static void enable_rm200_irq(unsigned int irq) +static void enable_rm200_irq(struct irq_data *d) { - unsigned int mask = 1 << (irq - SNI_RM200_INT_START); + unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START); *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask; } -void disable_rm200_irq(unsigned int irq) +void disable_rm200_irq(struct irq_data *d) { - unsigned int mask = 1 << (irq - SNI_RM200_INT_START); + unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START); *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask; } -void end_rm200_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_rm200_irq(irq); -} - static struct irq_chip rm200_irq_type = { .name = "RM200", - .ack = disable_rm200_irq, - .mask = disable_rm200_irq, - .mask_ack = disable_rm200_irq, - .unmask = enable_rm200_irq, - .end = end_rm200_irq, + .irq_mask = disable_rm200_irq, + .irq_unmask = enable_rm200_irq, }; static void sni_rm200_hwint(void) @@ -489,7 +477,7 @@ void __init sni_rm200_irq_init(void) mips_cpu_irq_init(); /* Actually we've got more interrupts to handle ... */ for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) - set_irq_chip_and_handler(i, &rm200_irq_type, handle_level_irq); + irq_set_chip_and_handler(i, &rm200_irq_type, handle_level_irq); sni_hwint = sni_rm200_hwint; change_c0_status(ST0_IM, IE_IRQ0); setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq); diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c index e1828e8bcaef..7e3ac5782da4 100644 --- a/arch/mips/txx9/generic/irq_tx4927.c +++ b/arch/mips/txx9/generic/irq_tx4927.c @@ -35,7 +35,7 @@ void __init tx4927_irq_init(void) mips_cpu_irq_init(); txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL); - set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, + irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT, handle_simple_irq); /* raise priority for errors, timers, SIO */ txx9_irq_set_pri(TX4927_IR_ECCERR, 7); diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c index a6e6e805097a..aace85653329 100644 --- a/arch/mips/txx9/generic/irq_tx4938.c +++ b/arch/mips/txx9/generic/irq_tx4938.c @@ -23,7 +23,7 @@ void __init tx4938_irq_init(void) mips_cpu_irq_init(); txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL); - set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, + irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT, handle_simple_irq); /* raise priority for errors, timers, SIO */ txx9_irq_set_pri(TX4938_IR_ECCERR, 7); diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c index 3886ad77cbad..6b067dbd2ae1 100644 --- a/arch/mips/txx9/generic/irq_tx4939.c +++ b/arch/mips/txx9/generic/irq_tx4939.c @@ -50,9 +50,9 @@ static struct { unsigned char mode; } tx4939irq[TX4939_NUM_IR] __read_mostly; -static void tx4939_irq_unmask(unsigned int irq) +static void tx4939_irq_unmask(struct irq_data *d) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; u32 __iomem *lvlp; int ofs; if (irq_nr < 32) { @@ -68,9 +68,9 @@ static void tx4939_irq_unmask(unsigned int irq) lvlp); } -static inline void tx4939_irq_mask(unsigned int irq) +static inline void tx4939_irq_mask(struct irq_data *d) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; u32 __iomem *lvlp; int ofs; if (irq_nr < 32) { @@ -87,11 +87,11 @@ static inline void tx4939_irq_mask(unsigned int irq) mmiowb(); } -static void tx4939_irq_mask_ack(unsigned int irq) +static void tx4939_irq_mask_ack(struct irq_data *d) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; - tx4939_irq_mask(irq); + tx4939_irq_mask(d); if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) { irq_nr--; /* clear edge detection */ @@ -101,9 +101,9 @@ static void tx4939_irq_mask_ack(unsigned int irq) } } -static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type) +static int tx4939_irq_set_type(struct irq_data *d, unsigned int flow_type) { - unsigned int irq_nr = irq - TXX9_IRQ_BASE; + unsigned int irq_nr = d->irq - TXX9_IRQ_BASE; u32 cr; u32 __iomem *crp; int ofs; @@ -145,11 +145,11 @@ static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type) static struct irq_chip tx4939_irq_chip = { .name = "TX4939", - .ack = tx4939_irq_mask_ack, - .mask = tx4939_irq_mask, - .mask_ack = tx4939_irq_mask_ack, - .unmask = tx4939_irq_unmask, - .set_type = tx4939_irq_set_type, + .irq_ack = tx4939_irq_mask_ack, + .irq_mask = tx4939_irq_mask, + .irq_mask_ack = tx4939_irq_mask_ack, + .irq_unmask = tx4939_irq_unmask, + .irq_set_type = tx4939_irq_set_type, }; static int tx4939_irq_set_pri(int irc_irq, int new_pri) @@ -176,8 +176,8 @@ void __init tx4939_irq_init(void) for (i = 1; i < TX4939_NUM_IR; i++) { tx4939irq[i].level = 4; /* middle level */ tx4939irq[i].mode = TXx9_IRCR_LOW; - set_irq_chip_and_handler(TXX9_IRQ_BASE + i, - &tx4939_irq_chip, handle_level_irq); + irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &tx4939_irq_chip, + handle_level_irq); } /* mask all IRC interrupts */ @@ -193,7 +193,7 @@ void __init tx4939_irq_init(void) __raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r); __raw_writel(irc_elevel, &tx4939_ircptr->msk.r); - set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT, + irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT, handle_simple_irq); /* raise priority for errors, timers, sio */ diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c index 0a7f8e3b9fd7..c22c859a2c49 100644 --- a/arch/mips/txx9/jmr3927/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c @@ -47,20 +47,20 @@ * CP0_STATUS is a thread's resource (saved/restored on context switch). * So disable_irq/enable_irq MUST handle IOC/IRC registers. */ -static void mask_irq_ioc(unsigned int irq) +static void mask_irq_ioc(struct irq_data *d) { /* 0: mask */ - unsigned int irq_nr = irq - JMR3927_IRQ_IOC; + unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC; unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); /* flush write buffer */ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } -static void unmask_irq_ioc(unsigned int irq) +static void unmask_irq_ioc(struct irq_data *d) { /* 0: mask */ - unsigned int irq_nr = irq - JMR3927_IRQ_IOC; + unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC; unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); @@ -95,10 +95,8 @@ static int jmr3927_irq_dispatch(int pending) static struct irq_chip jmr3927_irq_ioc = { .name = "jmr3927_ioc", - .ack = mask_irq_ioc, - .mask = mask_irq_ioc, - .mask_ack = mask_irq_ioc, - .unmask = unmask_irq_ioc, + .irq_mask = mask_irq_ioc, + .irq_unmask = unmask_irq_ioc, }; void __init jmr3927_irq_setup(void) @@ -122,8 +120,9 @@ void __init jmr3927_irq_setup(void) tx3927_irq_init(); for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++) - set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq); + irq_set_chip_and_handler(i, &jmr3927_irq_ioc, + handle_level_irq); /* setup IOC interrupt 1 (PCI, MODEM) */ - set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq); + irq_set_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq); } diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index c4b54d20efd3..6c22c496090b 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -117,18 +117,6 @@ #include <asm/txx9/generic.h> #include <asm/txx9/rbtx4927.h> -static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); -static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); - -#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" -static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { - .name = TOSHIBA_RBTX4927_IOC_NAME, - .ack = toshiba_rbtx4927_irq_ioc_disable, - .mask = toshiba_rbtx4927_irq_ioc_disable, - .mask_ack = toshiba_rbtx4927_irq_ioc_disable, - .unmask = toshiba_rbtx4927_irq_ioc_enable, -}; - static int toshiba_rbtx4927_irq_nested(int sw_irq) { u8 level3; @@ -139,41 +127,47 @@ static int toshiba_rbtx4927_irq_nested(int sw_irq) return RBTX4927_IRQ_IOC + __fls8(level3); } -static void __init toshiba_rbtx4927_irq_ioc_init(void) -{ - int i; - - /* mask all IOC interrupts */ - writeb(0, rbtx4927_imask_addr); - /* clear SoftInt interrupts */ - writeb(0, rbtx4927_softint_addr); - - for (i = RBTX4927_IRQ_IOC; - i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, - handle_level_irq); - set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); -} - -static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d) { unsigned char v; v = readb(rbtx4927_imask_addr); - v |= (1 << (irq - RBTX4927_IRQ_IOC)); + v |= (1 << (d->irq - RBTX4927_IRQ_IOC)); writeb(v, rbtx4927_imask_addr); } -static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d) { unsigned char v; v = readb(rbtx4927_imask_addr); - v &= ~(1 << (irq - RBTX4927_IRQ_IOC)); + v &= ~(1 << (d->irq - RBTX4927_IRQ_IOC)); writeb(v, rbtx4927_imask_addr); mmiowb(); } +#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" +static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { + .name = TOSHIBA_RBTX4927_IOC_NAME, + .irq_mask = toshiba_rbtx4927_irq_ioc_disable, + .irq_unmask = toshiba_rbtx4927_irq_ioc_enable, +}; + +static void __init toshiba_rbtx4927_irq_ioc_init(void) +{ + int i; + + /* mask all IOC interrupts */ + writeb(0, rbtx4927_imask_addr); + /* clear SoftInt interrupts */ + writeb(0, rbtx4927_softint_addr); + + for (i = RBTX4927_IRQ_IOC; + i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++) + irq_set_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, + handle_level_irq); + irq_set_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq); +} static int rbtx4927_irq_dispatch(int pending) { @@ -200,5 +194,5 @@ void __init rbtx4927_irq_setup(void) tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); /* Onboard 10M Ether: High Active */ - set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); + irq_set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); } diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c index 67a73a8065ec..58cd7a9272cc 100644 --- a/arch/mips/txx9/rbtx4938/irq.c +++ b/arch/mips/txx9/rbtx4938/irq.c @@ -69,18 +69,6 @@ #include <asm/txx9/generic.h> #include <asm/txx9/rbtx4938.h> -static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); -static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); - -#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" -static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { - .name = TOSHIBA_RBTX4938_IOC_NAME, - .ack = toshiba_rbtx4938_irq_ioc_disable, - .mask = toshiba_rbtx4938_irq_ioc_disable, - .mask_ack = toshiba_rbtx4938_irq_ioc_disable, - .unmask = toshiba_rbtx4938_irq_ioc_enable, -}; - static int toshiba_rbtx4938_irq_nested(int sw_irq) { u8 level3; @@ -92,41 +80,33 @@ static int toshiba_rbtx4938_irq_nested(int sw_irq) return RBTX4938_IRQ_IOC + __fls8(level3); } -static void __init -toshiba_rbtx4938_irq_ioc_init(void) -{ - int i; - - for (i = RBTX4938_IRQ_IOC; - i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) - set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, - handle_level_irq); - - set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); -} - -static void -toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) +static void toshiba_rbtx4938_irq_ioc_enable(struct irq_data *d) { unsigned char v; v = readb(rbtx4938_imask_addr); - v |= (1 << (irq - RBTX4938_IRQ_IOC)); + v |= (1 << (d->irq - RBTX4938_IRQ_IOC)); writeb(v, rbtx4938_imask_addr); mmiowb(); } -static void -toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) +static void toshiba_rbtx4938_irq_ioc_disable(struct irq_data *d) { unsigned char v; v = readb(rbtx4938_imask_addr); - v &= ~(1 << (irq - RBTX4938_IRQ_IOC)); + v &= ~(1 << (d->irq - RBTX4938_IRQ_IOC)); writeb(v, rbtx4938_imask_addr); mmiowb(); } +#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" +static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { + .name = TOSHIBA_RBTX4938_IOC_NAME, + .irq_mask = toshiba_rbtx4938_irq_ioc_disable, + .irq_unmask = toshiba_rbtx4938_irq_ioc_enable, +}; + static int rbtx4938_irq_dispatch(int pending) { int irq; @@ -146,6 +126,18 @@ static int rbtx4938_irq_dispatch(int pending) return irq; } +static void __init toshiba_rbtx4938_irq_ioc_init(void) +{ + int i; + + for (i = RBTX4938_IRQ_IOC; + i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++) + irq_set_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, + handle_level_irq); + + irq_set_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq); +} + void __init rbtx4938_irq_setup(void) { txx9_irq_dispatch = rbtx4938_irq_dispatch; @@ -161,5 +153,5 @@ void __init rbtx4938_irq_setup(void) tx4938_irq_init(); toshiba_rbtx4938_irq_ioc_init(); /* Onboard 10M Ether: High Active */ - set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); + irq_set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH); } diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c index 57fa740a7205..69a80616f0c9 100644 --- a/arch/mips/txx9/rbtx4939/irq.c +++ b/arch/mips/txx9/rbtx4939/irq.c @@ -19,16 +19,16 @@ * RBTX4939 IOC controller definition */ -static void rbtx4939_ioc_irq_unmask(unsigned int irq) +static void rbtx4939_ioc_irq_unmask(struct irq_data *d) { - int ioc_nr = irq - RBTX4939_IRQ_IOC; + int ioc_nr = d->irq - RBTX4939_IRQ_IOC; writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr); } -static void rbtx4939_ioc_irq_mask(unsigned int irq) +static void rbtx4939_ioc_irq_mask(struct irq_data *d) { - int ioc_nr = irq - RBTX4939_IRQ_IOC; + int ioc_nr = d->irq - RBTX4939_IRQ_IOC; writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr); mmiowb(); @@ -36,10 +36,8 @@ static void rbtx4939_ioc_irq_mask(unsigned int irq) static struct irq_chip rbtx4939_ioc_irq_chip = { .name = "IOC", - .ack = rbtx4939_ioc_irq_mask, - .mask = rbtx4939_ioc_irq_mask, - .mask_ack = rbtx4939_ioc_irq_mask, - .unmask = rbtx4939_ioc_irq_unmask, + .irq_mask = rbtx4939_ioc_irq_mask, + .irq_unmask = rbtx4939_ioc_irq_unmask, }; @@ -90,8 +88,8 @@ void __init rbtx4939_irq_setup(void) tx4939_irq_init(); for (i = RBTX4939_IRQ_IOC; i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++) - set_irq_chip_and_handler(i, &rbtx4939_ioc_irq_chip, + irq_set_chip_and_handler(i, &rbtx4939_ioc_irq_chip, handle_level_irq); - set_irq_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq); + irq_set_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq); } diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 6153b6a05ccf..a39ef3207d71 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -154,7 +154,7 @@ static inline uint16_t icu2_clear(uint8_t offset, uint16_t clear) void vr41xx_enable_piuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + PIU_IRQ; + struct irq_desc *desc = irq_to_desc(PIU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4111 || @@ -169,7 +169,7 @@ EXPORT_SYMBOL(vr41xx_enable_piuint); void vr41xx_disable_piuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + PIU_IRQ; + struct irq_desc *desc = irq_to_desc(PIU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4111 || @@ -184,7 +184,7 @@ EXPORT_SYMBOL(vr41xx_disable_piuint); void vr41xx_enable_aiuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + AIU_IRQ; + struct irq_desc *desc = irq_to_desc(AIU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4111 || @@ -199,7 +199,7 @@ EXPORT_SYMBOL(vr41xx_enable_aiuint); void vr41xx_disable_aiuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + AIU_IRQ; + struct irq_desc *desc = irq_to_desc(AIU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4111 || @@ -214,7 +214,7 @@ EXPORT_SYMBOL(vr41xx_disable_aiuint); void vr41xx_enable_kiuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + KIU_IRQ; + struct irq_desc *desc = irq_to_desc(KIU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4111 || @@ -229,7 +229,7 @@ EXPORT_SYMBOL(vr41xx_enable_kiuint); void vr41xx_disable_kiuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + KIU_IRQ; + struct irq_desc *desc = irq_to_desc(KIU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4111 || @@ -244,7 +244,7 @@ EXPORT_SYMBOL(vr41xx_disable_kiuint); void vr41xx_enable_macint(uint16_t mask) { - struct irq_desc *desc = irq_desc + ETHERNET_IRQ; + struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ); unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -256,7 +256,7 @@ EXPORT_SYMBOL(vr41xx_enable_macint); void vr41xx_disable_macint(uint16_t mask) { - struct irq_desc *desc = irq_desc + ETHERNET_IRQ; + struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ); unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -268,7 +268,7 @@ EXPORT_SYMBOL(vr41xx_disable_macint); void vr41xx_enable_dsiuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + DSIU_IRQ; + struct irq_desc *desc = irq_to_desc(DSIU_IRQ); unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -280,7 +280,7 @@ EXPORT_SYMBOL(vr41xx_enable_dsiuint); void vr41xx_disable_dsiuint(uint16_t mask) { - struct irq_desc *desc = irq_desc + DSIU_IRQ; + struct irq_desc *desc = irq_to_desc(DSIU_IRQ); unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -292,7 +292,7 @@ EXPORT_SYMBOL(vr41xx_disable_dsiuint); void vr41xx_enable_firint(uint16_t mask) { - struct irq_desc *desc = irq_desc + FIR_IRQ; + struct irq_desc *desc = irq_to_desc(FIR_IRQ); unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -304,7 +304,7 @@ EXPORT_SYMBOL(vr41xx_enable_firint); void vr41xx_disable_firint(uint16_t mask) { - struct irq_desc *desc = irq_desc + FIR_IRQ; + struct irq_desc *desc = irq_to_desc(FIR_IRQ); unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -316,7 +316,7 @@ EXPORT_SYMBOL(vr41xx_disable_firint); void vr41xx_enable_pciint(void) { - struct irq_desc *desc = irq_desc + PCI_IRQ; + struct irq_desc *desc = irq_to_desc(PCI_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -332,7 +332,7 @@ EXPORT_SYMBOL(vr41xx_enable_pciint); void vr41xx_disable_pciint(void) { - struct irq_desc *desc = irq_desc + PCI_IRQ; + struct irq_desc *desc = irq_to_desc(PCI_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -348,7 +348,7 @@ EXPORT_SYMBOL(vr41xx_disable_pciint); void vr41xx_enable_scuint(void) { - struct irq_desc *desc = irq_desc + SCU_IRQ; + struct irq_desc *desc = irq_to_desc(SCU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -364,7 +364,7 @@ EXPORT_SYMBOL(vr41xx_enable_scuint); void vr41xx_disable_scuint(void) { - struct irq_desc *desc = irq_desc + SCU_IRQ; + struct irq_desc *desc = irq_to_desc(SCU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -380,7 +380,7 @@ EXPORT_SYMBOL(vr41xx_disable_scuint); void vr41xx_enable_csiint(uint16_t mask) { - struct irq_desc *desc = irq_desc + CSI_IRQ; + struct irq_desc *desc = irq_to_desc(CSI_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -396,7 +396,7 @@ EXPORT_SYMBOL(vr41xx_enable_csiint); void vr41xx_disable_csiint(uint16_t mask) { - struct irq_desc *desc = irq_desc + CSI_IRQ; + struct irq_desc *desc = irq_to_desc(CSI_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -412,7 +412,7 @@ EXPORT_SYMBOL(vr41xx_disable_csiint); void vr41xx_enable_bcuint(void) { - struct irq_desc *desc = irq_desc + BCU_IRQ; + struct irq_desc *desc = irq_to_desc(BCU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -428,7 +428,7 @@ EXPORT_SYMBOL(vr41xx_enable_bcuint); void vr41xx_disable_bcuint(void) { - struct irq_desc *desc = irq_desc + BCU_IRQ; + struct irq_desc *desc = irq_to_desc(BCU_IRQ); unsigned long flags; if (current_cpu_type() == CPU_VR4122 || @@ -442,45 +442,41 @@ void vr41xx_disable_bcuint(void) EXPORT_SYMBOL(vr41xx_disable_bcuint); -static void disable_sysint1_irq(unsigned int irq) +static void disable_sysint1_irq(struct irq_data *d) { - icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); + icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq)); } -static void enable_sysint1_irq(unsigned int irq) +static void enable_sysint1_irq(struct irq_data *d) { - icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); + icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq)); } static struct irq_chip sysint1_irq_type = { .name = "SYSINT1", - .ack = disable_sysint1_irq, - .mask = disable_sysint1_irq, - .mask_ack = disable_sysint1_irq, - .unmask = enable_sysint1_irq, + .irq_mask = disable_sysint1_irq, + .irq_unmask = enable_sysint1_irq, }; -static void disable_sysint2_irq(unsigned int irq) +static void disable_sysint2_irq(struct irq_data *d) { - icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); + icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq)); } -static void enable_sysint2_irq(unsigned int irq) +static void enable_sysint2_irq(struct irq_data *d) { - icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); + icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq)); } static struct irq_chip sysint2_irq_type = { .name = "SYSINT2", - .ack = disable_sysint2_irq, - .mask = disable_sysint2_irq, - .mask_ack = disable_sysint2_irq, - .unmask = enable_sysint2_irq, + .irq_mask = disable_sysint2_irq, + .irq_unmask = enable_sysint2_irq, }; static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) { - struct irq_desc *desc = irq_desc + irq; + struct irq_desc *desc = irq_to_desc(irq); uint16_t intassign0, intassign1; unsigned int pin; @@ -540,7 +536,7 @@ static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) static inline int set_sysint2_assign(unsigned int irq, unsigned char assign) { - struct irq_desc *desc = irq_desc + irq; + struct irq_desc *desc = irq_to_desc(irq); uint16_t intassign2, intassign3; unsigned int pin; @@ -714,11 +710,11 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - set_irq_chip_and_handler(i, &sysint1_irq_type, + irq_set_chip_and_handler(i, &sysint1_irq_type, handle_level_irq); for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - set_irq_chip_and_handler(i, &sysint2_irq_type, + irq_set_chip_and_handler(i, &sysint2_irq_type, handle_level_irq); cascade_irq(INT0_IRQ, icu_get_irq); diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 0975eb72d385..70a3b85f3757 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c @@ -62,7 +62,6 @@ EXPORT_SYMBOL_GPL(cascade_irq); static void irq_dispatch(unsigned int irq) { irq_cascade_t *cascade; - struct irq_desc *desc; if (irq >= NR_IRQS) { atomic_inc(&irq_err_count); @@ -71,14 +70,16 @@ static void irq_dispatch(unsigned int irq) cascade = irq_cascade + irq; if (cascade->get_irq != NULL) { - unsigned int source_irq = irq; + struct irq_desc *desc = irq_to_desc(irq); + struct irq_data *idata = irq_desc_get_irq_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); int ret; - desc = irq_desc + source_irq; - if (desc->chip->mask_ack) - desc->chip->mask_ack(source_irq); + + if (chip->irq_mask_ack) + chip->irq_mask_ack(idata); else { - desc->chip->mask(source_irq); - desc->chip->ack(source_irq); + chip->irq_mask(idata); + chip->irq_ack(idata); } ret = cascade->get_irq(irq); irq = ret; @@ -86,8 +87,8 @@ static void irq_dispatch(unsigned int irq) atomic_inc(&irq_err_count); else irq_dispatch(irq); - if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) - desc->chip->unmask(source_irq); + if (!irqd_irq_disabled(idata) && chip->irq_unmask) + chip->irq_unmask(idata); } else do_IRQ(irq); } |