Commit 9ddfd929 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (38 commits)
  MIPS: O32: Fix ppoll
  MIPS: Oprofile: Rename cpu_type from godson2 to loongson2
  MIPS: Alchemy: Fix hang with high-frequency edge interrupts
  MIPS: TXx9: Fix spi-baseclk value
  MIPS: bcm63xx: Set the correct BCM3302 CPU name
  MIPS: Loongson 2: Set cpu_has_dc_aliases and cpu_icache_snoops_remote_store
  MIPS: Avoid potential hazard on Context register
  MIPS: Octeon: Use lockless interrupt controller operations when possible.
  MIPS: Octeon: Use write_{un,}lock_irq{restore,save} to set irq affinity
  MIPS: Set S-cache linesize to 64-bytes for MTI's S-cache
  MIPS: SMTC: Avoid queing multiple reschedule IPIs
  MIPS: GCMP: Avoid accessing registers when they are not present
  MIPS: GIC: Random fixes and enhancements.
  MIPS: CMP: Fix memory barriers for correct operation of amon_cpu_start
  MIPS: Fix abs.[sd] and neg.[sd] emulation for NaN operands
  MIPS: SPRAM: Clean up support code a little
  MIPS: 1004K: Enable SPRAM support.
  MIPS: Malta: Enable PCI 2.1 compatibility in PIIX4
  MIPS: Kconfig: Fix duplicate default value for MIPS_L1_CACHE_SHIFT.
  MIPS: MTI: Fix accesses to device registers on MIPS boards
  ...
parents 38dc6345 049a31af
...@@ -1012,9 +1012,9 @@ config BOOT_ELF32 ...@@ -1012,9 +1012,9 @@ config BOOT_ELF32
config MIPS_L1_CACHE_SHIFT config MIPS_L1_CACHE_SHIFT
int int
default "4" if MACH_DECSTATION || MIKROTIK_RB532 default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL
default "6" if MIPS_CPU_SCACHE
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
default "4" if PMC_MSP4200_EVAL
default "5" default "5"
config HAVE_STD_PC_SERIAL_PORT config HAVE_STD_PC_SERIAL_PORT
......
...@@ -354,6 +354,28 @@ static void au1x_ic1_ack(unsigned int irq_nr) ...@@ -354,6 +354,28 @@ static void au1x_ic1_ack(unsigned int irq_nr)
au_sync(); au_sync();
} }
static void au1x_ic0_maskack(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_WAKECLR);
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_RISINGCLR);
au_writel(1 << bit, IC0_FALLINGCLR);
au_sync();
}
static void au1x_ic1_maskack(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_WAKECLR);
au_writel(1 << bit, IC1_MASKCLR);
au_writel(1 << bit, IC1_RISINGCLR);
au_writel(1 << bit, IC1_FALLINGCLR);
au_sync();
}
static int au1x_ic1_setwake(unsigned int irq, unsigned int on) static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
{ {
unsigned int bit = irq - AU1000_INTC1_INT_BASE; unsigned int bit = irq - AU1000_INTC1_INT_BASE;
...@@ -379,25 +401,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on) ...@@ -379,25 +401,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
/* /*
* irq_chips for both ICs; this way the mask handlers can be * irq_chips for both ICs; this way the mask handlers can be
* as short as possible. * as short as possible.
*
* NOTE: the ->ack() callback is used by the handle_edge_irq
* flowhandler only, the ->mask_ack() one by handle_level_irq,
* so no need for an irq_chip for each type of irq (level/edge).
*/ */
static struct irq_chip au1x_ic0_chip = { static struct irq_chip au1x_ic0_chip = {
.name = "Alchemy-IC0", .name = "Alchemy-IC0",
.ack = au1x_ic0_ack, /* edge */ .ack = au1x_ic0_ack,
.mask = au1x_ic0_mask, .mask = au1x_ic0_mask,
.mask_ack = au1x_ic0_mask, /* level */ .mask_ack = au1x_ic0_maskack,
.unmask = au1x_ic0_unmask, .unmask = au1x_ic0_unmask,
.set_type = au1x_ic_settype, .set_type = au1x_ic_settype,
}; };
static struct irq_chip au1x_ic1_chip = { static struct irq_chip au1x_ic1_chip = {
.name = "Alchemy-IC1", .name = "Alchemy-IC1",
.ack = au1x_ic1_ack, /* edge */ .ack = au1x_ic1_ack,
.mask = au1x_ic1_mask, .mask = au1x_ic1_mask,
.mask_ack = au1x_ic1_mask, /* level */ .mask_ack = au1x_ic1_maskack,
.unmask = au1x_ic1_unmask, .unmask = au1x_ic1_unmask,
.set_type = au1x_ic_settype, .set_type = au1x_ic_settype,
.set_wake = au1x_ic1_setwake, .set_wake = au1x_ic1_setwake,
......
...@@ -69,6 +69,7 @@ void __init board_setup(void) ...@@ -69,6 +69,7 @@ void __init board_setup(void)
#else #else
au_writel(0xf, Au1500_PCI_CFG); au_writel(0xf, Au1500_PCI_CFG);
#endif #endif
board_pci_idsel = mtx1_pci_idsel;
#endif #endif
/* Initialize sys_pinfunc */ /* Initialize sys_pinfunc */
...@@ -85,8 +86,6 @@ void __init board_setup(void) ...@@ -85,8 +86,6 @@ void __init board_setup(void)
alchemy_gpio_direction_output(211, 1); /* green on */ alchemy_gpio_direction_output(211, 1); /* green on */
alchemy_gpio_direction_output(212, 0); /* red off */ alchemy_gpio_direction_output(212, 0); /* red off */
board_pci_idsel = mtx1_pci_idsel;
printk(KERN_INFO "4G Systems MTX-1 Board\n"); printk(KERN_INFO "4G Systems MTX-1 Board\n");
} }
......
...@@ -503,6 +503,7 @@ static int __init ar7_register_devices(void) ...@@ -503,6 +503,7 @@ static int __init ar7_register_devices(void)
{ {
u16 chip_id; u16 chip_id;
int res; int res;
u32 *bootcr, val;
#ifdef CONFIG_SERIAL_8250 #ifdef CONFIG_SERIAL_8250
static struct uart_port uart_port[2]; static struct uart_port uart_port[2];
...@@ -595,7 +596,13 @@ static int __init ar7_register_devices(void) ...@@ -595,7 +596,13 @@ static int __init ar7_register_devices(void)
ar7_wdt_res.end = ar7_wdt_res.start + 0x20; ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
res = platform_device_register(&ar7_wdt); bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
val = *bootcr;
iounmap(bootcr);
/* Register watchdog only if enabled in hardware */
if (val & AR7_WDT_HW_ENA)
res = platform_device_register(&ar7_wdt);
return res; return res;
} }
......
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/ obj-y += boards/
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <bcm63xx_dev_enet.h> #include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h> #include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_pcmcia.h> #include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_uart.h>
#include <board_bcm963xx.h> #include <board_bcm963xx.h>
#define PFX "board_bcm963xx: " #define PFX "board_bcm963xx: "
...@@ -794,8 +793,6 @@ int __init board_register_devices(void) ...@@ -794,8 +793,6 @@ int __init board_register_devices(void)
{ {
u32 val; u32 val;
bcm63xx_uart_register();
if (board.has_pccard) if (board.has_pccard)
bcm63xx_pcmcia_register(); bcm63xx_pcmcia_register();
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <asm/cpu-info.h>
#include <bcm63xx_cpu.h> #include <bcm63xx_cpu.h>
#include <bcm63xx_regs.h> #include <bcm63xx_regs.h>
#include <bcm63xx_io.h> #include <bcm63xx_io.h>
...@@ -284,6 +285,7 @@ void __init bcm63xx_cpu_init(void) ...@@ -284,6 +285,7 @@ void __init bcm63xx_cpu_init(void)
{ {
unsigned int tmp, expected_cpu_id; unsigned int tmp, expected_cpu_id;
struct cpuinfo_mips *c = &current_cpu_data; struct cpuinfo_mips *c = &current_cpu_data;
unsigned int cpu = smp_processor_id();
/* soc registers location depends on cpu type */ /* soc registers location depends on cpu type */
expected_cpu_id = 0; expected_cpu_id = 0;
...@@ -293,6 +295,7 @@ void __init bcm63xx_cpu_init(void) ...@@ -293,6 +295,7 @@ void __init bcm63xx_cpu_init(void)
* BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
*/ */
case CPU_BCM3302: case CPU_BCM3302:
__cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID; expected_cpu_id = BCM6338_CPU_ID;
bcm63xx_regs_base = bcm96338_regs_base; bcm63xx_regs_base = bcm96338_regs_base;
bcm63xx_irqs = bcm96338_irqs; bcm63xx_irqs = bcm96338_irqs;
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <bcm63xx_cpu.h> #include <bcm63xx_cpu.h>
#include <bcm63xx_dev_uart.h>
static struct resource uart_resources[] = { static struct resource uart_resources[] = {
{ {
...@@ -39,3 +38,4 @@ int __init bcm63xx_uart_register(void) ...@@ -39,3 +38,4 @@ int __init bcm63xx_uart_register(void)
uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
return platform_device_register(&bcm63xx_uart_device); return platform_device_register(&bcm63xx_uart_device);
} }
arch_initcall(bcm63xx_uart_register);
/*
* 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) 2008 Florian Fainelli <florian@openwrt.org>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <bcm63xx_cpu.h>
static struct resource wdt_resources[] = {
{
.start = -1, /* filled at runtime */
.end = -1, /* filled at runtime */
.flags = IORESOURCE_MEM,
},
};
static struct platform_device bcm63xx_wdt_device = {
.name = "bcm63xx-wdt",
.id = 0,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
int __init bcm63xx_wdt_register(void)
{
wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT);
wdt_resources[0].end = wdt_resources[0].start;
wdt_resources[0].end += RSET_WDT_SIZE - 1;
return platform_device_register(&bcm63xx_wdt_device);
}
arch_initcall(bcm63xx_wdt_register);
...@@ -75,7 +75,9 @@ void bcm63xx_machine_reboot(void) ...@@ -75,7 +75,9 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot(); bcm6348_a1_reboot();
printk(KERN_INFO "triggering watchdog soft-reset...\n"); printk(KERN_INFO "triggering watchdog soft-reset...\n");
bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG); reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
reg |= SYS_PLL_SOFT_RESET;
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
while (1) while (1)
; ;
} }
......
...@@ -17,6 +17,15 @@ DEFINE_RWLOCK(octeon_irq_ciu0_rwlock); ...@@ -17,6 +17,15 @@ DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
DEFINE_RWLOCK(octeon_irq_ciu1_rwlock); DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
DEFINE_SPINLOCK(octeon_irq_msi_lock); DEFINE_SPINLOCK(octeon_irq_msi_lock);
static int octeon_coreid_for_cpu(int cpu)
{
#ifdef CONFIG_SMP
return cpu_logical_map(cpu);
#else
return cvmx_get_core_num();
#endif
}
static void octeon_irq_core_ack(unsigned int irq) static void octeon_irq_core_ack(unsigned int irq)
{ {
unsigned int bit = irq - OCTEON_IRQ_SW0; unsigned int bit = irq - OCTEON_IRQ_SW0;
...@@ -152,11 +161,10 @@ static void octeon_irq_ciu0_disable(unsigned int irq) ...@@ -152,11 +161,10 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
unsigned long flags; unsigned long flags;
uint64_t en0; uint64_t en0;
#ifdef CONFIG_SMP
int cpu; int cpu;
write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags); write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
en0 &= ~(1ull << bit); en0 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
...@@ -167,26 +175,57 @@ static void octeon_irq_ciu0_disable(unsigned int irq) ...@@ -167,26 +175,57 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags); write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
#else }
int coreid = cvmx_get_core_num();
local_irq_save(flags); /*
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); * Enable the irq on the current core for chips that have the EN*_W1{S,C}
en0 &= ~(1ull << bit); * registers.
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); */
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); static void octeon_irq_ciu0_enable_v2(unsigned int irq)
local_irq_restore(flags); {
#endif int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
}
/*
* Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu0_disable_v2(unsigned int irq)
{
int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}
/*
* Disable 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)
{
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);
}
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest) static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
{ {
int cpu; int cpu;
unsigned long flags;
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
write_lock(&octeon_irq_ciu0_rwlock); write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
uint64_t en0 = uint64_t en0 =
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
if (cpumask_test_cpu(cpu, dest)) if (cpumask_test_cpu(cpu, dest))
...@@ -200,11 +239,45 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask * ...@@ -200,11 +239,45 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
* of them are done. * of them are done.
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock(&octeon_irq_ciu0_rwlock); write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
return 0; return 0;
} }
/*
* 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)
{
int cpu;
int index;
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))
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
else
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}
return 0;
}
#endif
/*
* 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,
.ack = octeon_irq_ciu0_disable_v2,
.eoi = octeon_irq_ciu0_enable_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity_v2,
#endif #endif
};
static struct irq_chip octeon_irq_chip_ciu0 = { static struct irq_chip octeon_irq_chip_ciu0 = {
.name = "CIU0", .name = "CIU0",
...@@ -269,11 +342,10 @@ static void octeon_irq_ciu1_disable(unsigned int irq) ...@@ -269,11 +342,10 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
unsigned long flags; unsigned long flags;
uint64_t en1; uint64_t en1;
#ifdef CONFIG_SMP
int cpu; int cpu;
write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags); write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
en1 &= ~(1ull << bit); en1 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
...@@ -284,26 +356,58 @@ static void octeon_irq_ciu1_disable(unsigned int irq) ...@@ -284,26 +356,58 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags); write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
#else }
int coreid = cvmx_get_core_num();
local_irq_save(flags); /*
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); * Enable the irq on the current core for chips that have the EN*_W1{S,C}
en1 &= ~(1ull << bit); * registers.
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); */
cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); static void octeon_irq_ciu1_enable_v2(unsigned int irq)
local_irq_restore(flags); {
#endif int index = cvmx_get_core_num() * 2 + 1;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
}
/*
* Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu1_disable_v2(unsigned int irq)
{
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);
}
/*
* 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)
{
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);
}
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest) static int octeon_irq_ciu1_set_affinity(unsigned int irq,
const struct cpumask *dest)
{ {
int cpu; int cpu;
unsigned long flags;
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
write_lock(&octeon_irq_ciu1_rwlock); write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
uint64_t en1 = uint64_t en1 =
cvmx_read_csr(CVMX_CIU_INTX_EN1 cvmx_read_csr(CVMX_CIU_INTX_EN1
(coreid * 2 + 1)); (coreid * 2 + 1));
...@@ -318,12 +422,46 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask * ...@@ -318,12 +422,46 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *
* of them are done. * of them are done.
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock(&octeon_irq_ciu1_rwlock); write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
return 0;
}
/*
* 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)
{
int cpu;
int index;
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))
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
else
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
}
return 0; return 0;
} }
#endif #endif
/*
* Newer octeon chips have support for lockless CIU operation.
*/
static struct irq_chip octeon_irq_chip_ciu1_v2 = {
.name = "CIU0",
.enable = octeon_irq_ciu1_enable_v2,
.disable = octeon_irq_ciu1_disable_all_v2,
.ack = octeon_irq_ciu1_disable_v2,
.eoi = octeon_irq_ciu1_enable_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu1_set_affinity_v2,
#endif
};
static struct irq_chip octeon_irq_chip_ciu1 = { static struct irq_chip octeon_irq_chip_ciu1 = {
.name = "CIU1", .name = "CIU1",
.enable = octeon_irq_ciu1_enable, .enable = octeon_irq_ciu1_enable,
...@@ -420,6 +558,8 @@ static struct irq_chip octeon_irq_chip_msi = { ...@@ -420,6 +558,8 @@ static struct irq_chip octeon_irq_chip_msi = {
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
int irq; int irq;
struct irq_chip *chip0;
struct irq_chip *chip1;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Set the default affinity to the boot cpu. */ /* Set the default affinity to the boot cpu. */
...@@ -430,6 +570,16 @@ void __init arch_init_irq(void) ...@@ -430,6 +570,16 @@ void __init arch_init_irq(void)
if (NR_IRQS < OCTEON_IRQ_LAST) if (NR_IRQS < OCTEON_IRQ_LAST)
pr_err("octeon_irq_init: NR_IRQS is set too low\n"); 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)) {
chip0 = &octeon_irq_chip_ciu0_v2;
chip1 = &octeon_irq_chip_ciu1_v2;
} else {
chip0 = &octeon_irq_chip_ciu0;
chip1 = &octeon_irq_chip_ciu1;
}
/* 0 - 15 reserved for i8259 master and slave controller. */ /* 0 - 15 reserved for i8259 master and slave controller. */
/* 17 - 23 Mips internal */ /* 17 - 23 Mips internal */
...@@ -440,14 +590,12 @@ void __init arch_init_irq(void) ...@@ -440,14 +590,12 @@ void __init arch_init_irq(void)
/* 24 - 87 CIU_INT_SUM0 */ /* 24 - 87 CIU_INT_SUM0 */
for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu0, set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
handle_percpu_irq);
} }
/* 88 - 151 CIU_INT_SUM1 */ /* 88 - 151 CIU_INT_SUM1 */
for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) { for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu1, set_irq_chip_and_handler(irq, chip1, handle_percpu_irq);
handle_percpu_irq);
} }
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
...@@ -505,14 +653,10 @@ asmlinkage void plat_irq_dispatch(void) ...@@ -505,14 +653,10 @@ asmlinkage void plat_irq_dispatch(void)
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu) static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu)
{ {
unsigned int isset; unsigned int isset;
#ifdef CONFIG_SMP int coreid = octeon_coreid_for_cpu(cpu);
int coreid = cpu_logical_map(cpu);
#else
int coreid = cvmx_get_core_num();
#endif
int bit = (irq < OCTEON_IRQ_WDOG0) ? int bit = (irq < OCTEON_IRQ_WDOG0) ?
irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0; irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0;
if (irq < 64) { if (irq < 64) {
isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) & isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) &
(1ull << bit)) >> bit; (1ull << bit)) >> bit;
......
...@@ -65,11 +65,12 @@ void octeon_send_ipi_single(int cpu, unsigned int action) ...@@ -65,11 +65,12 @@ void octeon_send_ipi_single(int cpu, unsigned int action)
cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action); cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action);
} }
static inline void octeon_send_ipi_mask(cpumask_t mask, unsigned int action) static inline void octeon_send_ipi_mask(const struct cpumask *mask,
unsigned int action)
{ {
unsigned int i; unsigned int i;
for_each_cpu_mask(i, mask) for_each_cpu_mask(i, *mask)
octeon_send_ipi_single(i, action); octeon_send_ipi_single(i, action);
} }
......
...@@ -48,9 +48,9 @@ enum fixed_addresses { ...@@ -48,9 +48,9 @@ enum fixed_addresses {
#define FIX_N_COLOURS 8 #define FIX_N_COLOURS 8
FIX_CMAP_BEGIN, FIX_CMAP_BEGIN,
#ifdef CONFIG_MIPS_MT_SMTC #ifdef CONFIG_MIPS_MT_SMTC
FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS), FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS * 2),
#else #else
FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS, FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2),
#endif #endif
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
/* reserved pte's for temporary kernel mappings */ /* reserved pte's for temporary kernel mappings */
......
...@@ -19,15 +19,20 @@ ...@@ -19,15 +19,20 @@
#define GCMP_GDB_OFS 0x8000 /* Global Debug Block */ #define GCMP_GDB_OFS 0x8000 /* Global Debug Block */
/* Offsets to individual GCMP registers from GCMP base */ /* Offsets to individual GCMP registers from GCMP base */
#define GCMPOFS(block, tag, reg) (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS) #define GCMPOFS(block, tag, reg) \
(GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS)
#define GCMPOFSn(block, tag, reg, n) \
(GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS(n))
#define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg) #define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg)
#define GCMPGCBOFSn(reg, n) GCMPOFSn(GCB, GCB, reg, n)
#define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg) #define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg)
#define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg) #define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg)
#define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg) #define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg)
/* GCMP register access */ /* GCMP register access */
#define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg)) #define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg))
#define GCMPGCBn(reg, n) REGP(_gcmp_base, GCMPGCBOFSn(reg, n))
#define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg)) #define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg))
#define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg)) #define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg))
#define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg)) #define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg))
...@@ -49,10 +54,10 @@ ...@@ -49,10 +54,10 @@
#define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17) #define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17)
#define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0 #define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0
#define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2) #define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2)
#define GCMP_GCB_GCMPB_CMDEFTGT_MEM 0 #define GCMP_GCB_GCMPB_CMDEFTGT_DISABLED 0
#define GCMP_GCB_GCMPB_CMDEFTGT_MEM1 1 #define GCMP_GCB_GCMPB_CMDEFTGT_MEM 1
#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2 #define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2
#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3 #define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3
#define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */ #define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */
#define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */ #define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */
#define GCMP_GCB_GCSRAP_CMACCESS_SHF 0 #define GCMP_GCB_GCSRAP_CMACCESS_SHF 0
...@@ -115,5 +120,6 @@ ...@@ -115,5 +120,6 @@
#define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */ #define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */
extern int __init gcmp_probe(unsigned long, unsigned long); extern int __init gcmp_probe(unsigned long, unsigned long);
extern int __init gcmp_niocu(void);
extern void __init gcmp_setregion(int, unsigned long, unsigned long, int);
#endif /* _ASM_GCMPREGS_H */ #endif /* _ASM_GCMPREGS_H */
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#define _ASM_GICREGS_H #define _ASM_GICREGS_H
#undef GICISBYTELITTLEENDIAN #undef GICISBYTELITTLEENDIAN
#define GICISWORDLITTLEENDIAN
/* Constants */ /* Constants */
#define GIC_POL_POS 1 #define GIC_POL_POS 1
...@@ -20,11 +19,7 @@ ...@@ -20,11 +19,7 @@
#define GIC_TRIG_EDGE 1 #define GIC_TRIG_EDGE 1
#define GIC_TRIG_LEVEL 0 #define GIC_TRIG_LEVEL 0
#ifdef CONFIG_SMP
#define GIC_NUM_INTRS (24 + NR_CPUS * 2) #define GIC_NUM_INTRS (24 + NR_CPUS * 2)
#else
#define GIC_NUM_INTRS 32
#endif
#define MSK(n) ((1 << (n)) - 1) #define MSK(n) ((1 << (n)) - 1)
#define REG32(addr) (*(volatile unsigned int *) (addr)) #define REG32(addr) (*(volatile unsigned int *) (addr))
...@@ -70,13 +65,13 @@ ...@@ -70,13 +65,13 @@
#define USM_VISIBLE_SECTION_SIZE 0x10000 #define USM_VISIBLE_SECTION_SIZE 0x10000
/* Register Map for Shared Section */ /* Register Map for Shared Section */
#if defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(GICISWORDLITTLEENDIAN)
#define GIC_SH_CONFIG_OFS 0x0000 #define GIC_SH_CONFIG_OFS 0x0000
/* Shared Global Counter */ /* Shared Global Counter */
#define GIC_SH_COUNTER_31_00_OFS 0x0010 #define GIC_SH_COUNTER_31_00_OFS 0x0010
#define GIC_SH_COUNTER_63_32_OFS 0x0014 #define GIC_SH_COUNTER_63_32_OFS 0x0014
#define GIC_SH_REVISIONID_OFS 0x0020
/* Interrupt Polarity */ /* Interrupt Polarity */
#define GIC_SH_POL_31_0_OFS 0x0100 #define GIC_SH_POL_31_0_OFS 0x0100
...@@ -164,24 +159,31 @@ ...@@ -164,24 +159,31 @@
(GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4))
#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
/* Convert an interrupt number to a byte offset/bit for multi-word registers */
#define GIC_INTR_OFS(intr) (((intr) / 32)*4)
#define GIC_INTR_BIT(intr) ((intr) % 32)
/* Polarity : Reset Value is always 0 */ /* Polarity : Reset Value is always 0 */
#define GIC_SH_SET_POLARITY_OFS 0x0100 #define GIC_SH_SET_POLARITY_OFS 0x0100
#define GIC_SET_POLARITY(intr, pol) \ #define GIC_SET_POLARITY(intr, pol) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + (((intr) / 32) * 4)), (pol) << ((intr) % 32)) GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr))
/* Triggering : Reset Value is always 0 */ /* Triggering : Reset Value is always 0 */
#define GIC_SH_SET_TRIGGER_OFS 0x0180 #define GIC_SH_SET_TRIGGER_OFS 0x0180
#define GIC_SET_TRIGGER(intr, trig) \ #define GIC_SET_TRIGGER(intr, trig) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + (((intr) / 32) * 4)), (trig) << ((intr) % 32)) GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr))
/* Mask manipulation */ /* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380 #define GIC_SH_SMASK_OFS 0x0380
#define GIC_SET_INTR_MASK(intr, val) \ #define GIC_SET_INTR_MASK(intr) \
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32))) GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \
GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
#define GIC_SH_RMASK_OFS 0x0300 #define GIC_SH_RMASK_OFS 0x0300
#define GIC_CLR_INTR_MASK(intr, val) \ #define GIC_CLR_INTR_MASK(intr) \
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + (((intr) / 32) * 4)), ((val) << ((intr) % 32))) GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \
GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
/* Register Map for Local Section */ /* Register Map for Local Section */
#define GIC_VPE_CTL_OFS 0x0000 #define GIC_VPE_CTL_OFS 0x0000
...@@ -219,161 +221,6 @@ ...@@ -219,161 +221,6 @@
#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000
#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004
#else /* CONFIG_CPU_BIG_ENDIAN */
#define GIC_SH_CONFIG_OFS 0x0000
/* Shared Global Counter */
#define GIC_SH_COUNTER_31_00_OFS 0x0014
#define GIC_SH_COUNTER_63_32_OFS 0x0010
/* Interrupt Polarity */
#define GIC_SH_POL_31_0_OFS 0x0104
#define GIC_SH_POL_63_32_OFS 0x0100
#define GIC_SH_POL_95_64_OFS 0x010c
#define GIC_SH_POL_127_96_OFS 0x0108
#define GIC_SH_POL_159_128_OFS 0x0114
#define GIC_SH_POL_191_160_OFS 0x0110
#define GIC_SH_POL_223_192_OFS 0x011c
#define GIC_SH_POL_255_224_OFS 0x0118
/* Edge/Level Triggering */
#define GIC_SH_TRIG_31_0_OFS 0x0184
#define GIC_SH_TRIG_63_32_OFS 0x0180
#define GIC_SH_TRIG_95_64_OFS 0x018c
#define GIC_SH_TRIG_127_96_OFS 0x0188
#define GIC_SH_TRIG_159_128_OFS 0x0194
#define GIC_SH_TRIG_191_160_OFS 0x0190
#define GIC_SH_TRIG_223_192_OFS 0x019c
#define GIC_SH_TRIG_255_224_OFS 0x0198
/* Dual Edge Triggering */
#define GIC_SH_DUAL_31_0_OFS 0x0204
#define GIC_SH_DUAL_63_32_OFS 0x0200
#define GIC_SH_DUAL_95_64_OFS 0x020c
#define GIC_SH_DUAL_127_96_OFS 0x0208
#define GIC_SH_DUAL_159_128_OFS 0x0214
#define GIC_SH_DUAL_191_160_OFS 0x0210
#define GIC_SH_DUAL_223_192_OFS 0x021c
#define GIC_SH_DUAL_255_224_OFS 0x0218
/* Set/Clear corresponding bit in Edge Detect Register */
#define GIC_SH_WEDGE_OFS 0x0280
/* Reset Mask - Disables Interrupt */
#define GIC_SH_RMASK_31_0_OFS 0x0304
#define GIC_SH_RMASK_63_32_OFS 0x0300
#define GIC_SH_RMASK_95_64_OFS 0x030c
#define GIC_SH_RMASK_127_96_OFS 0x0308
#define GIC_SH_RMASK_159_128_OFS 0x0314
#define GIC_SH_RMASK_191_160_OFS 0x0310
#define GIC_SH_RMASK_223_192_OFS 0x031c
#define GIC_SH_RMASK_255_224_OFS 0x0318
/* Set Mask (WO) - Enables Interrupt */
#define GIC_SH_SMASK_31_0_OFS 0x0384
#define GIC_SH_SMASK_63_32_OFS 0x0380
#define GIC_SH_SMASK_95_64_OFS 0x038c
#define GIC_SH_SMASK_127_96_OFS 0x0388
#define GIC_SH_SMASK_159_128_OFS 0x0394
#define GIC_SH_SMASK_191_160_OFS 0x0390
#define GIC_SH_SMASK_223_192_OFS 0x039c
#define GIC_SH_SMASK_255_224_OFS 0x0398
/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
#define GIC_SH_MASK_31_0_OFS 0x0404
#define GIC_SH_MASK_63_32_OFS 0x0400
#define GIC_SH_MASK_95_64_OFS 0x040c
#define GIC_SH_MASK_127_96_OFS 0x0408
#define GIC_SH_MASK_159_128_OFS 0x0414
#define GIC_SH_MASK_191_160_OFS 0x0410
#define GIC_SH_MASK_223_192_OFS 0x041c
#define GIC_SH_MASK_255_224_OFS 0x0418
/* Pending Global Interrupts (RO) */
#define GIC_SH_PEND_31_0_OFS 0x0484
#define GIC_SH_PEND_63_32_OFS 0x0480
#define GIC_SH_PEND_95_64_OFS 0x048c
#define GIC_SH_PEND_127_96_OFS 0x0488
#define GIC_SH_PEND_159_128_OFS 0x0494
#define GIC_SH_PEND_191_160_OFS 0x0490
#define GIC_SH_PEND_223_192_OFS 0x049c
#define GIC_SH_PEND_255_224_OFS 0x0498
#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
/* Maps Interrupt X to a Pin */
#define GIC_SH_MAP_TO_PIN(intr) \
(GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr))
#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2004
/*
* Maps Interrupt X to a VPE. This is more complex than the LE case, as
* odd and even registers need to be transposed. It does work - trust me!
*/
#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
(GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + \
(((((vpe) / 32) ^ 1) - 1) * 4))
#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
/* Polarity */
#define GIC_SH_SET_POLARITY_OFS 0x0100
#define GIC_SET_POLARITY(intr, pol) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (pol) << ((intr) % 32))
/* Triggering */
#define GIC_SH_SET_TRIGGER_OFS 0x0180
#define GIC_SET_TRIGGER(intr, trig) \
GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), (trig) << ((intr) % 32))
/* Mask manipulation */
#define GIC_SH_SMASK_OFS 0x0380
#define GIC_SET_INTR_MASK(intr, val) \
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32)))
#define GIC_SH_RMASK_OFS 0x0300
#define GIC_CLR_INTR_MASK(intr, val) \
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + 4 + (((((intr) / 32) ^ 1) - 1) * 4)), ((val) << ((intr) % 32)))
/* Register Map for Local Section */
#define GIC_VPE_CTL_OFS 0x0000
#define GIC_VPE_PEND_OFS 0x0004
#define GIC_VPE_MASK_OFS 0x0008
#define GIC_VPE_RMASK_OFS 0x000c
#define GIC_VPE_SMASK_OFS 0x0010
#define GIC_VPE_WD_MAP_OFS 0x0040
#define GIC_VPE_COMPARE_MAP_OFS 0x0044
#define GIC_VPE_TIMER_MAP_OFS 0x0048
#define GIC_VPE_PERFCTR_MAP_OFS 0x0050
#define GIC_VPE_SWINT0_MAP_OFS 0x0054
#define GIC_VPE_SWINT1_MAP_OFS 0x0058
#define GIC_VPE_OTHER_ADDR_OFS 0x0080
#define GIC_VPE_WD_CONFIG0_OFS 0x0090
#define GIC_VPE_WD_COUNT0_OFS 0x0094
#define GIC_VPE_WD_INITIAL0_OFS 0x0098
#define GIC_VPE_COMPARE_LO_OFS 0x00a4
#define GIC_VPE_COMPARE_HI_OFS 0x00a0
#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
#define GIC_VPE_EIC_SS(intr) \
(GIC_EIC_SHADOW_SET_BASE + (4 * intr))
#define GIC_VPE_EIC_VEC_BASE 0x0800
#define GIC_VPE_EIC_VEC(intr) \
(GIC_VPE_EIC_VEC_BASE + (4 * intr))
#define GIC_VPE_TENABLE_NMI_OFS 0x1000
#define GIC_VPE_TENABLE_YQ_OFS 0x1004
#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080
#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084
/* User Mode Visible Section Register Map */
#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0004
#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0000
#endif /* !LE */
/* Masks */ /* Masks */
#define GIC_SH_CONFIG_COUNTSTOP_SHF 28 #define GIC_SH_CONFIG_COUNTSTOP_SHF 28
#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) #define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
...@@ -473,12 +320,13 @@ struct gic_intrmask_regs { ...@@ -473,12 +320,13 @@ struct gic_intrmask_regs {
* in building ipi_map. * in building ipi_map.
*/ */
struct gic_intr_map { struct gic_intr_map {
unsigned int intrnum; /* Ext Intr Num */
unsigned int cpunum; /* Directed to this CPU */ unsigned int cpunum; /* Directed to this CPU */
unsigned int pin; /* Directed to this Pin */ unsigned int pin; /* Directed to this Pin */
unsigned int polarity; /* Polarity : +/- */ unsigned int polarity; /* Polarity : +/- */
unsigned int trigtype; /* Trigger : Edge/Levl */ unsigned int trigtype; /* Trigger : Edge/Levl */
unsigned int ipiflag; /* Is used for IPI ? */ unsigned int flags; /* Misc flags */
#define GIC_FLAG_IPI 0x01
#define GIC_FLAG_TRANSPARENT 0x02
}; };
extern void gic_init(unsigned long gic_base_addr, extern void gic_init(unsigned long gic_base_addr,
......
...@@ -78,6 +78,9 @@ ...@@ -78,6 +78,9 @@
#define AR7_REF_CLOCK 25000000 #define AR7_REF_CLOCK 25000000
#define AR7_XTAL_CLOCK 24000000 #define AR7_XTAL_CLOCK 24000000
/* DCL */
#define AR7_WDT_HW_ENA 0x10
struct plat_cpmac_data { struct plat_cpmac_data {
int reset_bit; int reset_bit;
int power_bit; int power_bit;
......
...@@ -104,6 +104,8 @@ static inline int au1100_gpio2_to_irq(int gpio) ...@@ -104,6 +104,8 @@ static inline int au1100_gpio2_to_irq(int gpio)
if ((gpio >= 8) && (gpio <= 15)) if ((gpio >= 8) && (gpio <= 15))
return MAKE_IRQ(0, 29); /* shared GPIO208_215 */ return MAKE_IRQ(0, 29); /* shared GPIO208_215 */
return -ENXIO;
} }
#ifdef CONFIG_SOC_AU1100 #ifdef CONFIG_SOC_AU1100
......
#ifndef BCM63XX_DEV_UART_H_
#define BCM63XX_DEV_UART_H_
int bcm63xx_uart_register(void);
#endif /* BCM63XX_DEV_UART_H_ */
...@@ -44,8 +44,8 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; ...@@ -44,8 +44,8 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
.busy_factor = 32, \ .busy_factor = 32, \
.imbalance_pct = 125, \ .imbalance_pct = 125, \
.cache_nice_tries = 1, \ .cache_nice_tries = 1, \
.flags = SD_LOAD_BALANCE \ .flags = SD_LOAD_BALANCE | \
| SD_BALANCE_EXEC \ SD_BALANCE_EXEC, \
.last_balance = jiffies, \ .last_balance = jiffies, \
.balance_interval = 1, \ .balance_interval = 1, \
.nr_balance_failed = 0, \ .nr_balance_failed = 0, \
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define cpu_has_cache_cdex_p 0 #define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0 #define cpu_has_cache_cdex_s 0
#define cpu_has_counter 1 #define cpu_has_counter 1
#define cpu_has_dc_aliases 1 #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
#define cpu_has_divec 0 #define cpu_has_divec 0
#define cpu_has_dsp 0 #define cpu_has_dsp 0
#define cpu_has_ejtag 0 #define cpu_has_ejtag 0
...@@ -54,6 +54,5 @@ ...@@ -54,6 +54,5 @@
#define cpu_has_vce 0 #define cpu_has_vce 0
#define cpu_has_vtag_icache 0 #define cpu_has_vtag_icache 0
#define cpu_has_watch 1 #define cpu_has_watch 1
#define cpu_icache_snoops_remote_store 1
#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */ #endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/hazards.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#ifdef CONFIG_MIPS_MT_SMTC #ifdef CONFIG_MIPS_MT_SMTC
#include <asm/mipsmtregs.h> #include <asm/mipsmtregs.h>
...@@ -36,11 +37,13 @@ extern unsigned long pgd_current[]; ...@@ -36,11 +37,13 @@ extern unsigned long pgd_current[];
#ifdef CONFIG_32BIT #ifdef CONFIG_32BIT
#define TLBMISS_HANDLER_SETUP() \ #define TLBMISS_HANDLER_SETUP() \
write_c0_context((unsigned long) smp_processor_id() << 25); \ write_c0_context((unsigned long) smp_processor_id() << 25); \
back_to_back_c0_hazard(); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif #endif
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define TLBMISS_HANDLER_SETUP() \ #define TLBMISS_HANDLER_SETUP() \
write_c0_context((unsigned long) smp_processor_id() << 26); \ write_c0_context((unsigned long) smp_processor_id() << 26); \
back_to_back_c0_hazard(); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif #endif
...@@ -165,12 +168,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, ...@@ -165,12 +168,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* having ASID_MASK smaller than the hardware maximum, * having ASID_MASK smaller than the hardware maximum,
* make sure no "soft" bits become "hard"... * make sure no "soft" bits become "hard"...
*/ */
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
| (cpu_context(cpu, next) & ASID_MASK)); cpu_asid(cpu, next));
ehb(); /* Make sure it propagates to TCStatus */ ehb(); /* Make sure it propagates to TCStatus */
evpe(mtflags); evpe(mtflags);
#else #else
write_c0_entryhi(cpu_context(cpu, next)); write_c0_entryhi(cpu_asid(cpu, next));
#endif /* CONFIG_MIPS_MT_SMTC */ #endif /* CONFIG_MIPS_MT_SMTC */
TLBMISS_HANDLER_SETUP_PGD(next->pgd); TLBMISS_HANDLER_SETUP_PGD(next->pgd);
...@@ -226,11 +229,11 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) ...@@ -226,11 +229,11 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
} }
/* See comments for similar code above */ /* See comments for similar code above */
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
(cpu_context(cpu, next) & ASID_MASK)); cpu_asid(cpu, next));
ehb(); /* Make sure it propagates to TCStatus */ ehb(); /* Make sure it propagates to TCStatus */
evpe(mtflags); evpe(mtflags);
#else #else
write_c0_entryhi(cpu_context(cpu, next)); write_c0_entryhi(cpu_asid(cpu, next));
#endif /* CONFIG_MIPS_MT_SMTC */ #endif /* CONFIG_MIPS_MT_SMTC */
TLBMISS_HANDLER_SETUP_PGD(next->pgd); TLBMISS_HANDLER_SETUP_PGD(next->pgd);
......
#ifndef _MIPS_SETUP_H #ifndef _MIPS_SETUP_H
#define _MIPS_SETUP_H #define _MIPS_SETUP_H
#define COMMAND_LINE_SIZE 256 #define COMMAND_LINE_SIZE 4096
#ifdef __KERNEL__ #ifdef __KERNEL__
extern void setup_early_printk(void); extern void setup_early_printk(void);
......
...@@ -45,6 +45,7 @@ struct smtc_ipi_q { ...@@ -45,6 +45,7 @@ struct smtc_ipi_q {
spinlock_t lock; spinlock_t lock;
struct smtc_ipi *tail; struct smtc_ipi *tail;
int depth; int depth;
int resched_flag; /* reschedule already queued */
}; };
static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p) static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
......
#ifndef _MIPS_SPRAM_H
#define _MIPS_SPRAM_H
#ifdef CONFIG_CPU_MIPSR2
extern __init void spram_config(void);
#else
static inline void spram_config(void) { };
#endif /* CONFIG_CPU_MIPSR2 */
#endif /* _MIPS_SPRAM_H */
...@@ -86,14 +86,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); ...@@ -86,14 +86,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#ifdef CONFIG_DEBUG_STACK_USAGE #ifdef CONFIG_DEBUG_STACK_USAGE
#define alloc_thread_info(tsk) \ #define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
({ \
struct thread_info *ret; \
\
ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \
\
ret; \
})
#else #else
#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) #define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
#endif #endif
......
...@@ -134,7 +134,7 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) ...@@ -134,7 +134,7 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
static struct irqaction r4030_timer_irqaction = { static struct irqaction r4030_timer_irqaction = {
.handler = r4030_timer_interrupt, .handler = r4030_timer_interrupt,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED | IRQF_TIMER,
.name = "R4030 timer", .name = "R4030 timer",
}; };
......
...@@ -144,7 +144,7 @@ void __cpuinit sb1480_clockevent_init(void) ...@@ -144,7 +144,7 @@ void __cpuinit sb1480_clockevent_init(void)
bcm1480_unmask_irq(cpu, irq); bcm1480_unmask_irq(cpu, irq);
action->handler = sibyte_counter_handler; action->handler = sibyte_counter_handler;
action->flags = IRQF_DISABLED | IRQF_PERCPU; action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
action->name = name; action->name = name;
action->dev_id = cd; action->dev_id = cd;
......
...@@ -107,7 +107,7 @@ static irqreturn_t ds1287_interrupt(int irq, void *dev_id) ...@@ -107,7 +107,7 @@ static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
static struct irqaction ds1287_irqaction = { static struct irqaction ds1287_irqaction = {
.handler = ds1287_interrupt, .handler = ds1287_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "ds1287", .name = "ds1287",
}; };
......
...@@ -113,7 +113,7 @@ static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id) ...@@ -113,7 +113,7 @@ static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
static struct irqaction gt641xx_timer0_irqaction = { static struct irqaction gt641xx_timer0_irqaction = {
.handler = gt641xx_timer0_interrupt, .handler = gt641xx_timer0_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "gt641xx_timer0", .name = "gt641xx_timer0",
}; };
......
...@@ -83,7 +83,7 @@ irqreturn_t c0_compare_interrupt(int irq, void *dev_id) ...@@ -83,7 +83,7 @@ irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
struct irqaction c0_compare_irqaction = { struct irqaction c0_compare_irqaction = {
.handler = c0_compare_interrupt, .handler = c0_compare_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "timer", .name = "timer",
}; };
......
...@@ -143,7 +143,7 @@ void __cpuinit sb1250_clockevent_init(void) ...@@ -143,7 +143,7 @@ void __cpuinit sb1250_clockevent_init(void)
sb1250_unmask_irq(cpu, irq); sb1250_unmask_irq(cpu, irq);
action->handler = sibyte_counter_handler; action->handler = sibyte_counter_handler;
action->flags = IRQF_DISABLED | IRQF_PERCPU; action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
action->name = name; action->name = name;
action->dev_id = cd; action->dev_id = cd;
......
...@@ -146,7 +146,7 @@ static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) ...@@ -146,7 +146,7 @@ static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
static struct irqaction txx9tmr_irq = { static struct irqaction txx9tmr_irq = {
.handler = txx9tmr_interrupt, .handler = txx9tmr_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "txx9tmr", .name = "txx9tmr",
.dev_id = &txx9_clock_event_device, .dev_id = &txx9_clock_event_device,
}; };
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/watch.h> #include <asm/watch.h>
#include <asm/spram.h>
/* /*
* Not all of the MIPS CPUs have the "wait" instruction available. Moreover, * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
* the implementation of the "wait" feature differs between CPU families. This * the implementation of the "wait" feature differs between CPU families. This
...@@ -711,12 +711,6 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c) ...@@ -711,12 +711,6 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
mips_probe_watch_registers(c); mips_probe_watch_registers(c);
} }
#ifdef CONFIG_CPU_MIPSR2
extern void spram_config(void);
#else
static inline void spram_config(void) {}
#endif
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
{ {
decode_configs(c); decode_configs(c);
......
...@@ -191,6 +191,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point ...@@ -191,6 +191,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
/* Set the SP after an empty pt_regs. */ /* Set the SP after an empty pt_regs. */
PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE
PTR_ADDU sp, $28 PTR_ADDU sp, $28
back_to_back_c0_hazard
set_saved_sp sp, t0, t1 set_saved_sp sp, t0, t1
PTR_SUBU sp, 4 * SZREG # init stack pointer PTR_SUBU sp, 4 * SZREG # init stack pointer
......
...@@ -98,7 +98,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) ...@@ -98,7 +98,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq0 = { static struct irqaction irq0 = {
.handler = timer_interrupt, .handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING, .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
.name = "timer" .name = "timer"
}; };
......
...@@ -14,38 +14,23 @@ ...@@ -14,38 +14,23 @@
static unsigned long _gic_base; static unsigned long _gic_base;
static unsigned int _irqbase, _mapsize, numvpes, numintrs; static unsigned int _irqbase;
static struct gic_intr_map *_intrmap; static unsigned int gic_irq_flags[GIC_NUM_INTRS];
#define GIC_IRQ_FLAG_EDGE 0x0001
static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
#define gic_wedgeb2bok 0 /*
* Can GIC handle b2b writes to wedge register?
*/
#if gic_wedgeb2bok == 0
static DEFINE_SPINLOCK(gic_wedgeb2b_lock);
#endif
void gic_send_ipi(unsigned int intr) void gic_send_ipi(unsigned int intr)
{ {
#if gic_wedgeb2bok == 0
unsigned long flags;
#endif
pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
read_c0_status()); read_c0_status());
if (!gic_wedgeb2bok)
spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
if (!gic_wedgeb2bok) {
(void) GIC_REG(SHARED, GIC_SH_CONFIG);
spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
}
} }
/* This is Malta specific and needs to be exported */ /* This is Malta specific and needs to be exported */
static void vpe_local_setup(unsigned int numvpes) static void __init vpe_local_setup(unsigned int numvpes)
{ {
int i; int i;
unsigned long timer_interrupt = 5, perf_interrupt = 5; unsigned long timer_interrupt = 5, perf_interrupt = 5;
...@@ -105,44 +90,34 @@ unsigned int gic_get_int(void) ...@@ -105,44 +90,34 @@ unsigned int gic_get_int(void)
static unsigned int gic_irq_startup(unsigned int irq) static unsigned int gic_irq_startup(unsigned int irq)
{ {
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase; irq -= _irqbase;
GIC_SET_INTR_MASK(irq, 1); pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_SET_INTR_MASK(irq);
return 0; return 0;
} }
static void gic_irq_ack(unsigned int irq) static void gic_irq_ack(unsigned int irq)
{ {
#if gic_wedgeb2bok == 0
unsigned long flags;
#endif
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase; irq -= _irqbase;
GIC_CLR_INTR_MASK(irq, 1); pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_CLR_INTR_MASK(irq);
if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE)
if (!gic_wedgeb2bok)
spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
if (!gic_wedgeb2bok) {
(void) GIC_REG(SHARED, GIC_SH_CONFIG);
spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
}
}
} }
static void gic_mask_irq(unsigned int irq) static void gic_mask_irq(unsigned int irq)
{ {
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase; irq -= _irqbase;
GIC_CLR_INTR_MASK(irq, 1); 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(unsigned int irq)
{ {
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase; irq -= _irqbase;
GIC_SET_INTR_MASK(irq, 1); pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
GIC_SET_INTR_MASK(irq);
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -155,9 +130,8 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) ...@@ -155,9 +130,8 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
unsigned long flags; unsigned long flags;
int i; int i;
pr_debug(KERN_DEBUG "%s called\n", __func__);
irq -= _irqbase; irq -= _irqbase;
pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq);
cpumask_and(&tmp, cpumask, cpu_online_mask); cpumask_and(&tmp, cpumask, cpu_online_mask);
if (cpus_empty(tmp)) if (cpus_empty(tmp))
return -1; return -1;
...@@ -168,13 +142,6 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) ...@@ -168,13 +142,6 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
/* Re-route this IRQ */ /* Re-route this IRQ */
GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
/*
* FIXME: assumption that _intrmap is ordered and has no holes
*/
/* Update the intr_map */
_intrmap[irq].cpunum = first_cpu(tmp);
/* Update the pcpu_masks */ /* Update the pcpu_masks */
for (i = 0; i < NR_CPUS; i++) for (i = 0; i < NR_CPUS; i++)
clear_bit(irq, pcpu_masks[i].pcpu_mask); clear_bit(irq, pcpu_masks[i].pcpu_mask);
...@@ -201,8 +168,9 @@ static struct irq_chip gic_irq_controller = { ...@@ -201,8 +168,9 @@ static struct irq_chip gic_irq_controller = {
#endif #endif
}; };
static void __init setup_intr(unsigned int intr, unsigned int cpu, static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
unsigned int pin, unsigned int polarity, unsigned int trigtype) unsigned int pin, unsigned int polarity, unsigned int trigtype,
unsigned int flags)
{ {
/* Setup Intr to Pin mapping */ /* Setup Intr to Pin mapping */
if (pin & GIC_MAP_TO_NMI_MSK) { if (pin & GIC_MAP_TO_NMI_MSK) {
...@@ -227,38 +195,43 @@ static void __init setup_intr(unsigned int intr, unsigned int cpu, ...@@ -227,38 +195,43 @@ static void __init setup_intr(unsigned int intr, unsigned int cpu,
GIC_SET_TRIGGER(intr, trigtype); GIC_SET_TRIGGER(intr, trigtype);
/* Init Intr Masks */ /* Init Intr Masks */
GIC_SET_INTR_MASK(intr, 0); GIC_CLR_INTR_MASK(intr);
/* Initialise per-cpu Interrupt software masks */
if (flags & GIC_FLAG_IPI)
set_bit(intr, pcpu_masks[cpu].pcpu_mask);
if (flags & GIC_FLAG_TRANSPARENT)
GIC_SET_INTR_MASK(intr);
if (trigtype == GIC_TRIG_EDGE)
gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
} }
static void __init gic_basic_init(void) static void __init gic_basic_init(int numintrs, int numvpes,
struct gic_intr_map *intrmap, int mapsize)
{ {
unsigned int i, cpu; unsigned int i, cpu;
/* Setup defaults */ /* Setup defaults */
for (i = 0; i < GIC_NUM_INTRS; i++) { for (i = 0; i < numintrs; i++) {
GIC_SET_POLARITY(i, GIC_POL_POS); GIC_SET_POLARITY(i, GIC_POL_POS);
GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
GIC_SET_INTR_MASK(i, 0); GIC_CLR_INTR_MASK(i);
if (i < GIC_NUM_INTRS)
gic_irq_flags[i] = 0;
} }
/* Setup specifics */ /* Setup specifics */
for (i = 0; i < _mapsize; i++) { for (i = 0; i < mapsize; i++) {
cpu = _intrmap[i].cpunum; cpu = intrmap[i].cpunum;
if (cpu == X) if (cpu == X)
continue; continue;
if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 &&
_intrmap[i].ipiflag == 0)
continue; continue;
gic_setup_intr(i,
setup_intr(_intrmap[i].intrnum, intrmap[i].cpunum,
_intrmap[i].cpunum, intrmap[i].pin,
_intrmap[i].pin, intrmap[i].polarity,
_intrmap[i].polarity, intrmap[i].trigtype,
_intrmap[i].trigtype); intrmap[i].flags);
/* Initialise per-cpu Interrupt software masks */
if (_intrmap[i].ipiflag)
set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask);
} }
vpe_local_setup(numvpes); vpe_local_setup(numvpes);
...@@ -273,12 +246,11 @@ void __init gic_init(unsigned long gic_base_addr, ...@@ -273,12 +246,11 @@ void __init gic_init(unsigned long gic_base_addr,
unsigned int irqbase) unsigned int irqbase)
{ {
unsigned int gicconfig; unsigned int gicconfig;
int numvpes, numintrs;
_gic_base = (unsigned long) ioremap_nocache(gic_base_addr, _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
gic_addrspace_size); gic_addrspace_size);
_irqbase = irqbase; _irqbase = irqbase;
_intrmap = intr_map;
_mapsize = intr_map_size;
GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
...@@ -290,5 +262,5 @@ void __init gic_init(unsigned long gic_base_addr, ...@@ -290,5 +262,5 @@ void __init gic_init(unsigned long gic_base_addr,
pr_debug("%s called\n", __func__); pr_debug("%s called\n", __func__);
gic_basic_init(); gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
} }
...@@ -428,3 +428,9 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) ...@@ -428,3 +428,9 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
return do_fork(clone_flags, newsp, &regs, 0, return do_fork(clone_flags, newsp, &regs, 0,
parent_tidptr, child_tidptr); parent_tidptr, child_tidptr);
} }
asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf,
size_t len)
{
return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
}
...@@ -450,7 +450,7 @@ sys_call_table: ...@@ -450,7 +450,7 @@ sys_call_table:
PTR sys_io_submit PTR sys_io_submit
PTR sys_io_cancel /* 4245 */ PTR sys_io_cancel /* 4245 */
PTR sys_exit_group PTR sys_exit_group
PTR sys_lookup_dcookie PTR sys32_lookup_dcookie
PTR sys_epoll_create PTR sys_epoll_create
PTR sys_epoll_ctl PTR sys_epoll_ctl
PTR sys_epoll_wait /* 4250 */ PTR sys_epoll_wait /* 4250 */
...@@ -505,7 +505,7 @@ sys_call_table: ...@@ -505,7 +505,7 @@ sys_call_table:
PTR sys_fchmodat PTR sys_fchmodat
PTR sys_faccessat /* 4300 */ PTR sys_faccessat /* 4300 */
PTR compat_sys_pselect6 PTR compat_sys_pselect6
PTR sys_ppoll PTR compat_sys_ppoll
PTR sys_unshare PTR sys_unshare
PTR sys_splice PTR sys_splice
PTR sys32_sync_file_range /* 4305 */ PTR sys32_sync_file_range /* 4305 */
......
...@@ -75,7 +75,6 @@ unsigned long irq_hwmask[NR_IRQS]; ...@@ -75,7 +75,6 @@ unsigned long irq_hwmask[NR_IRQS];
asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
/* /*
* Number of InterProcessor Interrupt (IPI) message buffers to allocate * Number of InterProcessor Interrupt (IPI) message buffers to allocate
*/ */
...@@ -388,6 +387,7 @@ void smtc_prepare_cpus(int cpus) ...@@ -388,6 +387,7 @@ void smtc_prepare_cpus(int cpus)
IPIQ[i].head = IPIQ[i].tail = NULL; IPIQ[i].head = IPIQ[i].tail = NULL;
spin_lock_init(&IPIQ[i].lock); spin_lock_init(&IPIQ[i].lock);
IPIQ[i].depth = 0; IPIQ[i].depth = 0;
IPIQ[i].resched_flag = 0; /* No reschedules queued initially */
} }
/* cpu_data index starts at zero */ /* cpu_data index starts at zero */
...@@ -741,11 +741,24 @@ void smtc_forward_irq(unsigned int irq) ...@@ -741,11 +741,24 @@ void smtc_forward_irq(unsigned int irq)
static void smtc_ipi_qdump(void) static void smtc_ipi_qdump(void)
{ {
int i; int i;
struct smtc_ipi *temp;
for (i = 0; i < NR_CPUS ;i++) { for (i = 0; i < NR_CPUS ;i++) {
printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail, i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
IPIQ[i].depth); IPIQ[i].depth);
temp = IPIQ[i].head;
while (temp != IPIQ[i].tail) {
pr_debug("%d %d %d: ", temp->type, temp->dest,
(int)temp->arg);
#ifdef SMTC_IPI_DEBUG
pr_debug("%u %lu\n", temp->sender, temp->stamp);
#else
pr_debug("\n");
#endif
temp = temp->flink;
}
} }
} }
...@@ -784,11 +797,16 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) ...@@ -784,11 +797,16 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
int mtflags; int mtflags;
unsigned long tcrestart; unsigned long tcrestart;
extern void r4k_wait_irqoff(void), __pastwait(void); extern void r4k_wait_irqoff(void), __pastwait(void);
int set_resched_flag = (type == LINUX_SMP_IPI &&
action == SMP_RESCHEDULE_YOURSELF);
if (cpu == smp_processor_id()) { if (cpu == smp_processor_id()) {
printk("Cannot Send IPI to self!\n"); printk("Cannot Send IPI to self!\n");
return; return;
} }
if (set_resched_flag && IPIQ[cpu].resched_flag != 0)
return; /* There is a reschedule queued already */
/* Set up a descriptor, to be delivered either promptly or queued */ /* Set up a descriptor, to be delivered either promptly or queued */
pipi = smtc_ipi_dq(&freeIPIq); pipi = smtc_ipi_dq(&freeIPIq);
if (pipi == NULL) { if (pipi == NULL) {
...@@ -801,6 +819,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) ...@@ -801,6 +819,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
pipi->dest = cpu; pipi->dest = cpu;
if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
/* If not on same VPE, enqueue and send cross-VPE interrupt */ /* If not on same VPE, enqueue and send cross-VPE interrupt */
IPIQ[cpu].resched_flag |= set_resched_flag;
smtc_ipi_nq(&IPIQ[cpu], pipi); smtc_ipi_nq(&IPIQ[cpu], pipi);
LOCK_CORE_PRA(); LOCK_CORE_PRA();
settc(cpu_data[cpu].tc_id); settc(cpu_data[cpu].tc_id);
...@@ -847,6 +866,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) ...@@ -847,6 +866,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
*/ */
write_tc_c0_tchalt(0); write_tc_c0_tchalt(0);
UNLOCK_CORE_PRA(); UNLOCK_CORE_PRA();
IPIQ[cpu].resched_flag |= set_resched_flag;
smtc_ipi_nq(&IPIQ[cpu], pipi); smtc_ipi_nq(&IPIQ[cpu], pipi);
} else { } else {
postdirect: postdirect:
...@@ -996,12 +1016,15 @@ void deferred_smtc_ipi(void) ...@@ -996,12 +1016,15 @@ void deferred_smtc_ipi(void)
* already enabled. * already enabled.
*/ */
local_irq_save(flags); local_irq_save(flags);
spin_lock(&q->lock); spin_lock(&q->lock);
pipi = __smtc_ipi_dq(q); pipi = __smtc_ipi_dq(q);
spin_unlock(&q->lock); spin_unlock(&q->lock);
if (pipi != NULL) if (pipi != NULL) {
if (pipi->type == LINUX_SMP_IPI &&
(int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
IPIQ[cpu].resched_flag = 0;
ipi_decode(pipi); ipi_decode(pipi);
}
/* /*
* The use of the __raw_local restore isn't * The use of the __raw_local restore isn't
* as obviously necessary here as in smtc_ipi_replay(), * as obviously necessary here as in smtc_ipi_replay(),
...@@ -1082,6 +1105,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) ...@@ -1082,6 +1105,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
* with interrupts off * with interrupts off
*/ */
local_irq_save(flags); local_irq_save(flags);
if (pipi->type == LINUX_SMP_IPI &&
(int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
IPIQ[cpu].resched_flag = 0;
ipi_decode(pipi); ipi_decode(pipi);
local_irq_restore(flags); local_irq_restore(flags);
} }
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <asm/cpu.h>
#include <asm/fpu.h> #include <asm/fpu.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -198,8 +197,7 @@ static __cpuinit void probe_spram(char *type, ...@@ -198,8 +197,7 @@ static __cpuinit void probe_spram(char *type,
offset += 2 * SPRAM_TAG_STRIDE; offset += 2 * SPRAM_TAG_STRIDE;
} }
} }
void __cpuinit spram_config(void)
__cpuinit void spram_config(void)
{ {
struct cpuinfo_mips *c = &current_cpu_data; struct cpuinfo_mips *c = &current_cpu_data;
unsigned int config0; unsigned int config0;
...@@ -208,6 +206,7 @@ __cpuinit void spram_config(void) ...@@ -208,6 +206,7 @@ __cpuinit void spram_config(void)
case CPU_24K: case CPU_24K:
case CPU_34K: case CPU_34K:
case CPU_74K: case CPU_74K:
case CPU_1004K:
config0 = read_c0_config(); config0 = read_c0_config();
/* FIXME: addresses are Malta specific */ /* FIXME: addresses are Malta specific */
if (config0 & (1<<24)) { if (config0 & (1<<24)) {
......
...@@ -1116,8 +1116,6 @@ static int vpe_open(struct inode *inode, struct file *filp) ...@@ -1116,8 +1116,6 @@ static int vpe_open(struct inode *inode, struct file *filp)
v->shared_ptr = NULL; v->shared_ptr = NULL;
v->__start = 0; v->__start = 0;
unlock_kernel();
return 0; return 0;
} }
......
...@@ -55,7 +55,6 @@ void __init arch_init_irq(void) ...@@ -55,7 +55,6 @@ void __init arch_init_irq(void)
* int-handler is not on bootstrap * int-handler is not on bootstrap
*/ */
clear_c0_status(ST0_IM | ST0_BEV); clear_c0_status(ST0_IM | ST0_BEV);
local_irq_disable();
/* setting irq trigger mode */ /* setting irq trigger mode */
set_irq_trigger_mode(); set_irq_trigger_mode();
......
...@@ -62,8 +62,6 @@ ieee754dp ieee754dp_neg(ieee754dp x) ...@@ -62,8 +62,6 @@ ieee754dp ieee754dp_neg(ieee754dp x)
return ieee754dp_nanxcpt(y, "neg"); return ieee754dp_nanxcpt(y, "neg");
} }
if (ieee754dp_isnan(x)) /* but not infinity */
return ieee754dp_nanxcpt(x, "neg", x);
return x; return x;
} }
...@@ -76,15 +74,12 @@ ieee754dp ieee754dp_abs(ieee754dp x) ...@@ -76,15 +74,12 @@ ieee754dp ieee754dp_abs(ieee754dp x)
CLEARCX; CLEARCX;
FLUSHXDP; FLUSHXDP;
/* Clear sign ALWAYS, irrespective of NaN */
DPSIGN(x) = 0;
if (xc == IEEE754_CLASS_SNAN) { if (xc == IEEE754_CLASS_SNAN) {
SETCX(IEEE754_INVALID_OPERATION); return ieee754dp_nanxcpt(ieee754dp_indef(), "abs");
return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
} }
if (ieee754dp_isnan(x)) /* but not infinity */
return ieee754dp_nanxcpt(x, "abs", x);
/* quick fix up */
DPSIGN(x) = 0;
return x; return x;
} }
...@@ -62,8 +62,6 @@ ieee754sp ieee754sp_neg(ieee754sp x) ...@@ -62,8 +62,6 @@ ieee754sp ieee754sp_neg(ieee754sp x)
return ieee754sp_nanxcpt(y, "neg"); return ieee754sp_nanxcpt(y, "neg");
} }
if (ieee754sp_isnan(x)) /* but not infinity */
return ieee754sp_nanxcpt(x, "neg", x);
return x; return x;
} }
...@@ -76,15 +74,12 @@ ieee754sp ieee754sp_abs(ieee754sp x) ...@@ -76,15 +74,12 @@ ieee754sp ieee754sp_abs(ieee754sp x)
CLEARCX; CLEARCX;
FLUSHXSP; FLUSHXSP;
/* Clear sign ALWAYS, irrespective of NaN */
SPSIGN(x) = 0;
if (xc == IEEE754_CLASS_SNAN) { if (xc == IEEE754_CLASS_SNAN) {
SETCX(IEEE754_INVALID_OPERATION);
return ieee754sp_nanxcpt(ieee754sp_indef(), "abs"); return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
} }
if (ieee754sp_isnan(x)) /* but not infinity */
return ieee754sp_nanxcpt(x, "abs", x);
/* quick fix up */
SPSIGN(x) = 0;
return x; return x;
} }
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/pfn.h> #include <linux/pfn.h>
#include <linux/hardirq.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
...@@ -132,7 +133,10 @@ void *kmap_coherent(struct page *page, unsigned long addr) ...@@ -132,7 +133,10 @@ void *kmap_coherent(struct page *page, unsigned long addr)
inc_preempt_count(); inc_preempt_count();
idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
#ifdef CONFIG_MIPS_MT_SMTC #ifdef CONFIG_MIPS_MT_SMTC
idx += FIX_N_COLOURS * smp_processor_id(); idx += FIX_N_COLOURS * smp_processor_id() +
(in_interrupt() ? (FIX_N_COLOURS * NR_CPUS) : 0);
#else
idx += in_interrupt() ? FIX_N_COLOURS : 0;
#endif #endif
vaddr = __fix_to_virt(FIX_CMAP_END - idx); vaddr = __fix_to_virt(FIX_CMAP_END - idx);
pte = mk_pte(page, PAGE_KERNEL); pte = mk_pte(page, PAGE_KERNEL);
......
...@@ -70,11 +70,12 @@ void amon_cpu_start(int cpu, ...@@ -70,11 +70,12 @@ void amon_cpu_start(int cpu,
launch->sp = sp; launch->sp = sp;
launch->a0 = a0; launch->a0 = a0;
/* Make sure target sees parameters before the go bit */ smp_wmb(); /* Target must see parameters before go */
smp_mb();
launch->flags |= LAUNCH_FGO; launch->flags |= LAUNCH_FGO;
smp_wmb(); /* Target must see go before we poll */
while ((launch->flags & LAUNCH_FGONE) == 0) while ((launch->flags & LAUNCH_FGONE) == 0)
; ;
smp_rmb(); /* Target will be updating flags soon */
pr_debug("launch: cpu%d gone!\n", cpu); pr_debug("launch: cpu%d gone!\n", cpu);
} }
...@@ -87,7 +87,7 @@ static inline int mips_pcibios_iack(void) ...@@ -87,7 +87,7 @@ static inline int mips_pcibios_iack(void)
dummy = BONITO_PCIMAP_CFG; dummy = BONITO_PCIMAP_CFG;
iob(); /* sync */ iob(); /* sync */
irq = readl((u32 *)_pcictrl_bonito_pcicfg); irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg);
iob(); /* sync */ iob(); /* sync */
irq &= 0xff; irq &= 0xff;
BONITO_PCIMAP_CFG = 0; BONITO_PCIMAP_CFG = 0;
...@@ -379,38 +379,43 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = { ...@@ -379,38 +379,43 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = {
static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
#if defined(CONFIG_MIPS_MT_SMP)
/* /*
* This GIC specific tabular array defines the association between External * This GIC specific tabular array defines the association between External
* Interrupts and CPUs/Core Interrupts. The nature of the External * Interrupts and CPUs/Core Interrupts. The nature of the External
* Interrupts is also defined here - polarity/trigger. * Interrupts is also defined here - polarity/trigger.
*/ */
#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
{ GIC_EXT_INTR(0), X, X, X, X, 0 }, { X, X, X, X, 0 },
{ GIC_EXT_INTR(1), X, X, X, X, 0 }, { X, X, X, X, 0 },
{ GIC_EXT_INTR(2), X, X, X, X, 0 }, { X, X, X, X, 0 },
{ GIC_EXT_INTR(3), 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(4), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(5), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(6), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(7), 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(8), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(9), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(10), X, X, X, X, 0 }, { X, X, X, X, 0 },
{ GIC_EXT_INTR(11), X, X, X, X, 0 }, { X, X, X, X, 0 },
{ GIC_EXT_INTR(12), 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
{ GIC_EXT_INTR(15), X, X, X, X, 0 }, { X, X, X, X, 0 },
/* This is the end of the general interrupts now we do IPI ones */ /* The remainder of this table is initialised by fill_ipi_map */
}; };
#endif
/* /*
* GCMP needs to be detected before any SMP initialisation * GCMP needs to be detected before any SMP initialisation
*/ */
int __init gcmp_probe(unsigned long addr, unsigned long size) int __init gcmp_probe(unsigned long addr, unsigned long size)
{ {
if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) {
gcmp_present = 0;
return gcmp_present;
}
if (gcmp_present >= 0) if (gcmp_present >= 0)
return gcmp_present; return gcmp_present;
...@@ -419,20 +424,35 @@ int __init gcmp_probe(unsigned long addr, unsigned long size) ...@@ -419,20 +424,35 @@ int __init gcmp_probe(unsigned long addr, unsigned long size)
gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR; gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
if (gcmp_present) if (gcmp_present)
printk(KERN_DEBUG "GCMP present\n"); pr_debug("GCMP present\n");
return gcmp_present; return gcmp_present;
} }
/* Return the number of IOCU's present */
int __init gcmp_niocu(void)
{
return gcmp_present ?
(GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF :
0;
}
/* Set GCMP region attributes */
void __init gcmp_setregion(int region, unsigned long base,
unsigned long mask, int type)
{
GCMPGCBn(CMxBASE, region) = base;
GCMPGCBn(CMxMASK, region) = mask | type;
}
#if defined(CONFIG_MIPS_MT_SMP) #if defined(CONFIG_MIPS_MT_SMP)
static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
{ {
int intr = baseintr + cpu; int intr = baseintr + cpu;
gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr);
gic_intr_map[intr].cpunum = cpu; gic_intr_map[intr].cpunum = cpu;
gic_intr_map[intr].pin = cpupin; gic_intr_map[intr].pin = cpupin;
gic_intr_map[intr].polarity = GIC_POL_POS; gic_intr_map[intr].polarity = GIC_POL_POS;
gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
gic_intr_map[intr].ipiflag = 1; gic_intr_map[intr].flags = GIC_FLAG_IPI;
ipi_map[cpu] |= (1 << (cpupin + 2)); ipi_map[cpu] |= (1 << (cpupin + 2));
} }
...@@ -447,6 +467,12 @@ static void __init fill_ipi_map(void) ...@@ -447,6 +467,12 @@ static void __init fill_ipi_map(void)
} }
#endif #endif
void __init arch_init_ipiirq(int irq, struct irqaction *action)
{
setup_irq(irq, action);
set_irq_handler(irq, handle_percpu_irq);
}
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
init_i8259_irqs(); init_i8259_irqs();
...@@ -458,12 +484,17 @@ void __init arch_init_irq(void) ...@@ -458,12 +484,17 @@ void __init arch_init_irq(void)
GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK;
gic_present = 1; gic_present = 1;
} else { } else {
_msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ); if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) {
gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & _msc01_biu_base = (unsigned long)
MSC01_SC_CFG_GICPRES_MSK) >> MSC01_SC_CFG_GICPRES_SHF; ioremap_nocache(MSC01_BIU_REG_BASE,
MSC01_BIU_ADDRSPACE_SZ);
gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) &
MSC01_SC_CFG_GICPRES_MSK) >>
MSC01_SC_CFG_GICPRES_SHF;
}
} }
if (gic_present) if (gic_present)
printk(KERN_DEBUG "GIC present\n"); pr_debug("GIC present\n");
switch (mips_revision_sconid) { switch (mips_revision_sconid) {
case MIPS_REVISION_SCON_SOCIT: case MIPS_REVISION_SCON_SOCIT:
...@@ -526,16 +557,16 @@ void __init arch_init_irq(void) ...@@ -526,16 +557,16 @@ void __init arch_init_irq(void)
&corehi_irqaction); &corehi_irqaction);
} }
#if defined(CONFIG_MIPS_MT_SMP)
if (gic_present) { if (gic_present) {
/* FIXME */ /* FIXME */
int i; int i;
#if defined(CONFIG_MIPS_MT_SMP)
gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
gic_resched_int_base = gic_call_int_base - NR_CPUS; gic_resched_int_base = gic_call_int_base - NR_CPUS;
fill_ipi_map(); fill_ipi_map();
gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); #endif
gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
if (!gcmp_present) { if (!gcmp_present) {
/* Enable the GIC */ /* Enable the GIC */
i = REG(_msc01_biu_base, MSC01_SC_CFG); i = REG(_msc01_biu_base, MSC01_SC_CFG);
...@@ -543,7 +574,7 @@ void __init arch_init_irq(void) ...@@ -543,7 +574,7 @@ void __init arch_init_irq(void)
(i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); (i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
pr_debug("GIC Enabled\n"); pr_debug("GIC Enabled\n");
} }
#if defined(CONFIG_MIPS_MT_SMP)
/* set up ipi interrupts */ /* set up ipi interrupts */
if (cpu_has_vint) { if (cpu_has_vint) {
set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
...@@ -556,16 +587,14 @@ void __init arch_init_irq(void) ...@@ -556,16 +587,14 @@ void __init arch_init_irq(void)
write_c0_status(0x1100dc00); write_c0_status(0x1100dc00);
printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
setup_irq(MIPS_GIC_IRQ_BASE + arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
GIC_RESCHED_INT(i), &irq_resched); GIC_RESCHED_INT(i), &irq_resched);
setup_irq(MIPS_GIC_IRQ_BASE + arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
GIC_CALL_INT(i), &irq_call); GIC_CALL_INT(i), &irq_call);
set_irq_handler(MIPS_GIC_IRQ_BASE +
GIC_RESCHED_INT(i), handle_percpu_irq);
set_irq_handler(MIPS_GIC_IRQ_BASE +
GIC_CALL_INT(i), handle_percpu_irq);
} }
#endif
} else { } else {
#if defined(CONFIG_MIPS_MT_SMP)
/* set up ipi interrupts */ /* set up ipi interrupts */
if (cpu_has_veic) { if (cpu_has_veic) {
set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch); set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
...@@ -580,14 +609,10 @@ void __init arch_init_irq(void) ...@@ -580,14 +609,10 @@ void __init arch_init_irq(void)
cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
} }
arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
setup_irq(cpu_ipi_resched_irq, &irq_resched); arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
setup_irq(cpu_ipi_call_irq, &irq_call);
set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
}
#endif #endif
}
} }
void malta_be_init(void) void malta_be_init(void)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/gt64120.h> #include <asm/gt64120.h>
#include <asm/gcmpregs.h>
#include <asm/mips-boards/generic.h> #include <asm/mips-boards/generic.h>
#include <asm/mips-boards/bonito64.h> #include <asm/mips-boards/bonito64.h>
#include <asm/mips-boards/msc01_pci.h> #include <asm/mips-boards/msc01_pci.h>
...@@ -201,7 +201,11 @@ void __init mips_pcibios_init(void) ...@@ -201,7 +201,11 @@ void __init mips_pcibios_init(void)
msc_mem_resource.start = start & mask; msc_mem_resource.start = start & mask;
msc_mem_resource.end = (start & mask) | ~mask; msc_mem_resource.end = (start & mask) | ~mask;
msc_controller.mem_offset = (start & mask) - (map & mask); msc_controller.mem_offset = (start & mask) - (map & mask);
#ifdef CONFIG_MIPS_CMP
if (gcmp_niocu())
gcmp_setregion(0, start, mask,
GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
#endif
MSC_READ(MSC01_PCI_SC2PIOBASL, start); MSC_READ(MSC01_PCI_SC2PIOBASL, start);
MSC_READ(MSC01_PCI_SC2PIOMSKL, mask); MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
MSC_READ(MSC01_PCI_SC2PIOMAPL, map); MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
...@@ -209,7 +213,11 @@ void __init mips_pcibios_init(void) ...@@ -209,7 +213,11 @@ void __init mips_pcibios_init(void)
msc_io_resource.end = (map & mask) | ~mask; msc_io_resource.end = (map & mask) | ~mask;
msc_controller.io_offset = 0; msc_controller.io_offset = 0;
ioport_resource.end = ~mask; ioport_resource.end = ~mask;
#ifdef CONFIG_MIPS_CMP
if (gcmp_niocu())
gcmp_setregion(1, start, mask,
GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
#endif
/* If ranges overlap I/O takes precedence. */ /* If ranges overlap I/O takes precedence. */
start = start & mask; start = start & mask;
end = start | ~mask; end = start | ~mask;
...@@ -241,3 +249,16 @@ void __init mips_pcibios_init(void) ...@@ -241,3 +249,16 @@ void __init mips_pcibios_init(void)
register_pci_controller(controller); register_pci_controller(controller);
} }
/* Enable PCI 2.1 compatibility in PIIX4 */
static void __init quirk_dlcsetup(struct pci_dev *dev)
{
u8 odlc, ndlc;
(void) pci_read_config_byte(dev, 0x82, &odlc);
/* Enable passive releases and delayed transaction */
ndlc = odlc | 7;
(void) pci_write_config_byte(dev, 0x82, ndlc);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
quirk_dlcsetup);
...@@ -172,7 +172,7 @@ static struct irqaction gic_action = { ...@@ -172,7 +172,7 @@ static struct irqaction gic_action = {
static struct irqaction timer_action = { static struct irqaction timer_action = {
.handler = no_action, .handler = no_action,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED | IRQF_TIMER,
.name = "Timer", .name = "Timer",
}; };
......
...@@ -59,7 +59,7 @@ static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id) ...@@ -59,7 +59,7 @@ static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id)
static struct irqaction pnx8xxx_timer_irq = { static struct irqaction pnx8xxx_timer_irq = {
.handler = pnx8xxx_timer_interrupt, .handler = pnx8xxx_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "pnx8xxx_timer", .name = "pnx8xxx_timer",
}; };
...@@ -72,7 +72,7 @@ static irqreturn_t monotonic_interrupt(int irq, void *dev_id) ...@@ -72,7 +72,7 @@ static irqreturn_t monotonic_interrupt(int irq, void *dev_id)
static struct irqaction monotonic_irqaction = { static struct irqaction monotonic_irqaction = {
.handler = monotonic_interrupt, .handler = monotonic_interrupt,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED | IRQF_TIMER,
.name = "Monotonic timer", .name = "Monotonic timer",
}; };
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* otherwise, the oprofile tool will not recognize this and complain about * otherwise, the oprofile tool will not recognize this and complain about
* "cpu_type 'unset' is not valid". * "cpu_type 'unset' is not valid".
*/ */
#define LOONGSON2_CPU_TYPE "mips/godson2" #define LOONGSON2_CPU_TYPE "mips/loongson2"
#define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5) #define LOONGSON2_COUNTER1_EVENT(event) ((event & 0x0f) << 5)
#define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9) #define LOONGSON2_COUNTER2_EVENT(event) ((event & 0x0f) << 9)
......
...@@ -105,7 +105,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) ...@@ -105,7 +105,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
struct irqaction hub_rt_irqaction = { struct irqaction hub_rt_irqaction = {
.handler = hub_rt_counter_handler, .handler = hub_rt_counter_handler,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "hub-rt", .name = "hub-rt",
}; };
......
...@@ -67,7 +67,7 @@ static irqreturn_t a20r_interrupt(int irq, void *dev_id) ...@@ -67,7 +67,7 @@ static irqreturn_t a20r_interrupt(int irq, void *dev_id)
static struct irqaction a20r_irqaction = { static struct irqaction a20r_irqaction = {
.handler = a20r_interrupt, .handler = a20r_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU, .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
.name = "a20r-timer", .name = "a20r-timer",
}; };
......
...@@ -85,7 +85,7 @@ int txx9_ccfg_toeon __initdata = 1; ...@@ -85,7 +85,7 @@ int txx9_ccfg_toeon __initdata = 1;
struct clk *clk_get(struct device *dev, const char *id) struct clk *clk_get(struct device *dev, const char *id)
{ {
if (!strcmp(id, "spi-baseclk")) if (!strcmp(id, "spi-baseclk"))
return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 4); return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2);
if (!strcmp(id, "imbus_clk")) if (!strcmp(id, "imbus_clk"))
return (struct clk *)((unsigned long)txx9_gbus_clock / 2); return (struct clk *)((unsigned long)txx9_gbus_clock / 2);
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
...@@ -817,7 +817,8 @@ void __init txx9_iocled_init(unsigned long baseaddr, ...@@ -817,7 +817,8 @@ void __init txx9_iocled_init(unsigned long baseaddr,
out_pdev: out_pdev:
platform_device_put(pdev); platform_device_put(pdev);
out_gpio: out_gpio:
gpio_remove(&iocled->chip); if (gpiochip_remove(&iocled->chip))
return;
out_unmap: out_unmap:
iounmap(iocled->mmioaddr); iounmap(iocled->mmioaddr);
out_free: out_free:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment