diff options
Diffstat (limited to 'arch')
44 files changed, 573 insertions, 294 deletions
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index b5d387ef37e..bff7ddd06a5 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -76,8 +76,8 @@ static struct map_desc anubis_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (u32)ANUBIS_VA_CTRL2, - .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2), + .virtual = (u32)ANUBIS_VA_IDREG, + .pfn = __phys_to_pfn(ANUBIS_PA_IDREG), .length = SZ_4K, .type = MT_DEVICE, }, diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 4d6c7a574c1..15811601f03 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -16,6 +16,7 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/device.h> +#include <linux/sysdev.h> #include <linux/serial_core.h> #include <asm/mach/arch.h> @@ -65,6 +66,11 @@ static struct map_desc osiris_iodesc[] __initdata = { /* CPLD control registers */ { + .virtual = (u32)OSIRIS_VA_CTRL0, + .pfn = __phys_to_pfn(OSIRIS_PA_CTRL0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { .virtual = (u32)OSIRIS_VA_CTRL1, .pfn = __phys_to_pfn(OSIRIS_PA_CTRL1), .length = SZ_16K, @@ -74,6 +80,11 @@ static struct map_desc osiris_iodesc[] __initdata = { .pfn = __phys_to_pfn(OSIRIS_PA_CTRL2), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (u32)OSIRIS_VA_IDREG, + .pfn = __phys_to_pfn(OSIRIS_PA_IDREG), + .length = SZ_16K, + .type = MT_DEVICE, }, }; @@ -195,13 +206,13 @@ static void osiris_nand_select(struct s3c2410_nand_set *set, int slot) pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n", slot, set, set->nr_map); - tmp = __raw_readb(OSIRIS_VA_CTRL1); - tmp &= ~OSIRIS_CTRL1_NANDSEL; + tmp = __raw_readb(OSIRIS_VA_CTRL0); + tmp &= ~OSIRIS_CTRL0_NANDSEL; tmp |= slot; - pr_debug("osiris_nand: ctrl1 now %02x\n", tmp); + pr_debug("osiris_nand: ctrl0 now %02x\n", tmp); - __raw_writeb(tmp, OSIRIS_VA_CTRL1); + __raw_writeb(tmp, OSIRIS_VA_CTRL0); } static struct s3c2410_platform_nand osiris_nand_info = { @@ -235,10 +246,45 @@ static struct platform_device osiris_pcmcia = { .resource = osiris_pcmcia_resource, }; +/* Osiris power management device */ + +#ifdef CONFIG_PM +static unsigned char pm_osiris_ctrl0; + +static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state) +{ + pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0); + return 0; +} + +static int osiris_pm_resume(struct sys_device *sd) +{ + if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8) + __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1); + + return 0; +} + +#else +#define osiris_pm_suspend NULL +#define osiris_pm_resume NULL +#endif + +static struct sysdev_class osiris_pm_sysclass = { + set_kset_name("mach-osiris"), + .suspend = osiris_pm_suspend, + .resume = osiris_pm_resume, +}; + +static struct sys_device osiris_pm_sysdev = { + .cls = &osiris_pm_sysclass, +}; + /* Standard Osiris devices */ static struct platform_device *osiris_devices[] __initdata = { &s3c_device_i2c, + &s3c_device_wdt, &s3c_device_nand, &osiris_pcmcia, }; @@ -288,6 +334,9 @@ static void __init osiris_map_io(void) static void __init osiris_init(void) { + sysdev_class_register(&osiris_pm_sysclass); + sysdev_register(&osiris_pm_sysdev); + platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices)); }; @@ -299,5 +348,6 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS") .map_io = osiris_map_io, .init_machine = osiris_init, .init_irq = s3c24xx_init_irq, + .init_machine = osiris_init, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index ca2a5ad19ea..806ce26d524 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -29,6 +29,10 @@ do_vfp: add r10, r10, #TI_VFPSTATE @ r10 = workspace ldr pc, [r4] @ call VFP entry point +ENTRY(vfp_null_entry) + mov pc, lr +ENDPROC(vfp_null_entry) + .LCvfp: .word vfp_vector diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index f1e5951dc72..1106b5f9cf1 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -26,8 +26,9 @@ */ void vfp_testing_entry(void); void vfp_support_entry(void); +void vfp_null_entry(void); -void (*vfp_vector)(void) = vfp_testing_entry; +void (*vfp_vector)(void) = vfp_null_entry; union vfp_state *last_VFP_context[NR_CPUS]; /* @@ -321,8 +322,10 @@ static int __init vfp_init(void) * The handler is already setup to just log calls, so * we just need to read the VFPSID register. */ + vfp_vector = vfp_testing_entry; vfpsid = fmrx(FPSID); barrier(); + vfp_vector = vfp_null_entry; printk(KERN_INFO "VFP support v0.3: "); if (VFP_arch) { diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index fe1dbe2e28f..e253e86a1a3 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -42,6 +42,7 @@ static struct spi_board_info spi0_board_info[] __initdata = { .modalias = "ltv350qv", .max_speed_hz = 16000000, .chip_select = 1, + .mode = SPI_MODE_3, }, }; diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index e011f1ce187..4b2495285d9 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -158,7 +158,7 @@ bad_area: up_read(&mm->mmap_sem); if (user_mode(regs)) { - if (exception_trace) + if (exception_trace && printk_ratelimit()) printk("%s%s[%d]: segfault at %08lx pc %08lx " "sp %08lx ecr %lu\n", is_init(tsk) ? KERN_EMERG : KERN_INFO, diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 64b62bdfb4f..b8fa7ddd78f 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -129,13 +129,13 @@ static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) static struct irqaction irq_resched = { .handler = ipi_resched_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED|IRQF_PERCPU, .name = "IPI_resched" }; static struct irqaction irq_call = { .handler = ipi_call_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED|IRQF_PERCPU, .name = "IPI_call" }; @@ -275,10 +275,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus) setup_irq(cpu_ipi_resched_irq, &irq_resched); setup_irq(cpu_ipi_call_irq, &irq_call); - /* need to mark IPI's as IRQ_PER_CPU */ - irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU; set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); - irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU; set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); } @@ -326,8 +323,11 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) void prom_init_secondary(void) { + /* Enable per-cpu interrupts */ + + /* This is Malta specific: IPI,performance and timer inetrrupts */ write_c0_status((read_c0_status() & ~ST0_IM ) | - (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7)); + (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); } void prom_smp_finish(void) diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 751b4a18b13..7def1ff3da9 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -199,6 +199,30 @@ int (*perf_irq)(void) = null_perf_irq; EXPORT_SYMBOL(null_perf_irq); EXPORT_SYMBOL(perf_irq); +/* + * Performance counter IRQ or -1 if shared with timer + */ +int mipsxx_perfcount_irq; +EXPORT_SYMBOL(mipsxx_perfcount_irq); + +/* + * Possibly handle a performance counter interrupt. + * Return true if the timer interrupt should not be checked + */ +static inline int handle_perf_irq (int r2) +{ + /* + * The performance counter overflow interrupt may be shared with the + * timer interrupt (mipsxx_perfcount_irq < 0). If it is and a + * performance counter has overflowed (perf_irq() == IRQ_HANDLED) + * and we can't reliably determine if a counter interrupt has also + * happened (!r2) then don't check for a timer interrupt. + */ + return (mipsxx_perfcount_irq < 0) && + perf_irq() == IRQ_HANDLED && + !r2; +} + asmlinkage void ll_timer_interrupt(int irq) { int r2 = cpu_has_mips_r2; @@ -206,19 +230,13 @@ asmlinkage void ll_timer_interrupt(int irq) irq_enter(); kstat_this_cpu.irqs[irq]++; - /* - * Suckage alert: - * Before R2 of the architecture there was no way to see if a - * performance counter interrupt was pending, so we have to run the - * performance counter interrupt handler anyway. - */ - if (!r2 || (read_c0_cause() & (1 << 26))) - if (perf_irq()) - goto out; + if (handle_perf_irq(r2)) + goto out; - /* we keep interrupt disabled all the time */ - if (!r2 || (read_c0_cause() & (1 << 30))) - timer_interrupt(irq, NULL); + if (r2 && ((read_c0_cause() & (1 << 30)) == 0)) + goto out; + + timer_interrupt(irq, NULL); out: irq_exit(); @@ -258,7 +276,7 @@ unsigned int mips_hpt_frequency; static struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "timer", }; diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index 88e9c2a7a2f..4eabc1eadd2 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c @@ -57,7 +57,8 @@ int *_prom_argv, *_prom_envp; int init_debug = 0; -unsigned int mips_revision_corid; +int mips_revision_corid; +int mips_revision_sconid; /* Bonito64 system controller register base. */ unsigned long _pcictrl_bonito; @@ -275,13 +276,38 @@ void __init prom_init(void) else mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; } - switch(mips_revision_corid) { + + mips_revision_sconid = MIPS_REVISION_SCONID; + if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) { + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_FPGAR2: + mips_revision_sconid = MIPS_REVISION_SCON_GT64120; + break; + case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + mips_revision_sconid = MIPS_REVISION_SCON_BONITO; + break; + case MIPS_REVISION_CORID_CORE_MSC: + case MIPS_REVISION_CORID_CORE_FPGA2: + case MIPS_REVISION_CORID_CORE_FPGA3: + case MIPS_REVISION_CORID_CORE_24K: + case MIPS_REVISION_CORID_CORE_EMUL_MSC: + mips_revision_sconid = MIPS_REVISION_SCON_SOCIT; + break; + default: + mips_display_message("CC Error"); + while (1); /* We die here... */ + } + } + + switch (mips_revision_sconid) { u32 start, map, mask, data; - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_FPGAR2: + case MIPS_REVISION_SCON_GT64120: /* * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. @@ -305,9 +331,7 @@ void __init prom_init(void) set_io_port_base(MALTA_GT_PORT_BASE); break; - case MIPS_REVISION_CORID_CORE_EMUL_BON: - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: + case MIPS_REVISION_SCON_BONITO: _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); /* @@ -334,13 +358,10 @@ void __init prom_init(void) set_io_port_base(MALTA_BONITO_PORT_BASE); break; - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); - + mips_pci_controller: mb(); MSC_READ(MSC01_PCI_CFG, data); MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); @@ -374,10 +395,15 @@ void __init prom_init(void) set_io_port_base(MALTA_MSC_PORT_BASE); break; + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: + _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000); + goto mips_pci_controller; + default: - /* Unknown Core card */ - mips_display_message("CC Error"); - while(1); /* We die here... */ + /* Unknown system controller */ + mips_display_message("SC Error"); + while (1); /* We die here... */ } #endif board_nmi_handler_setup = mips_nmi_setup; diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c index f98d60f7865..c9852206890 100644 --- a/arch/mips/mips-boards/generic/pci.c +++ b/arch/mips/mips-boards/generic/pci.c @@ -92,11 +92,8 @@ void __init mips_pcibios_init(void) struct pci_controller *controller; resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; - switch (mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_FPGAR2: + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_GT64120: /* * Due to a bug in the Galileo system controller, we need * to setup the PCI BAR for the Galileo internal registers. @@ -161,9 +158,7 @@ void __init mips_pcibios_init(void) controller = >64120_controller; break; - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_SCON_BONITO: /* Set up resource ranges from the controller's registers. */ map = BONITO_PCIMAP; map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >> @@ -195,11 +190,10 @@ void __init mips_pcibios_init(void) controller = &bonito64_controller; break; - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: /* Set up resource ranges from the controller's registers. */ MSC_READ(MSC01_PCI_SC2PMBASL, start); MSC_READ(MSC01_PCI_SC2PMMSKL, mask); diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index b41db9e7ab1..8f1000f51b3 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -53,9 +53,8 @@ unsigned long cpu_khz; -#define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) - static int mips_cpu_timer_irq; +extern int mipsxx_perfcount_irq; extern void smtc_timer_broadcast(int); static void mips_timer_dispatch(void) @@ -63,6 +62,11 @@ static void mips_timer_dispatch(void) do_IRQ(mips_cpu_timer_irq); } +static void mips_perf_dispatch(void) +{ + do_IRQ(mipsxx_perfcount_irq); +} + /* * Redeclare until I get around mopping the timer code insanity on MIPS. */ @@ -70,6 +74,24 @@ extern int null_perf_irq(void); extern int (*perf_irq)(void); +/* + * Possibly handle a performance counter interrupt. + * Return true if the timer interrupt should not be checked + */ +static inline int handle_perf_irq (int r2) +{ + /* + * The performance counter overflow interrupt may be shared with the + * timer interrupt (mipsxx_perfcount_irq < 0). If it is and a + * performance counter has overflowed (perf_irq() == IRQ_HANDLED) + * and we can't reliably determine if a counter interrupt has also + * happened (!r2) then don't check for a timer interrupt. + */ + return (mipsxx_perfcount_irq < 0) && + perf_irq() == IRQ_HANDLED && + !r2; +} + irqreturn_t mips_timer_interrupt(int irq, void *dev_id) { int cpu = smp_processor_id(); @@ -92,8 +114,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) * We could be here due to timer interrupt, * perf counter overflow, or both. */ - if (read_c0_cause() & (1 << 26)) - perf_irq(); + (void) handle_perf_irq(1); if (read_c0_cause() & (1 << 30)) { /* @@ -115,19 +136,19 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) #else /* CONFIG_MIPS_MT_SMTC */ int r2 = cpu_has_mips_r2; + if (handle_perf_irq(r2)) + goto out; + + if (r2 && ((read_c0_cause() & (1 << 30)) == 0)) + goto out; + if (cpu == 0) { /* * CPU 0 handles the global timer interrupt job and process * accounting resets count/compare registers to trigger next * timer int. */ - if (!r2 || (read_c0_cause() & (1 << 26))) - if (perf_irq()) - goto out; - - /* we keep interrupt disabled all the time */ - if (!r2 || (read_c0_cause() & (1 << 30))) - timer_interrupt(irq, NULL); + timer_interrupt(irq, NULL); } else { /* Everyone else needs to reset the timer int here as ll_local_timer_interrupt doesn't */ @@ -225,35 +246,85 @@ void __init mips_time_init(void) mips_scroll_message(); } +irqreturn_t mips_perf_interrupt(int irq, void *dev_id) +{ + return perf_irq(); +} + +static struct irqaction perf_irqaction = { + .handler = mips_perf_interrupt, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "performance", +}; + +void __init plat_perf_setup(struct irqaction *irq) +{ + int hwint = 0; + mipsxx_perfcount_irq = -1; + +#ifdef MSC01E_INT_BASE + if (cpu_has_veic) { + set_vi_handler (MSC01E_INT_PERFCTR, mips_perf_dispatch); + mipsxx_perfcount_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; + } else +#endif + if (cpu_has_mips_r2) { + /* + * Read IntCtl.IPPCI to determine the performance + * counter interrupt + */ + hwint = (read_c0_intctl () >> 26) & 7; + if (hwint != MIPSCPU_INT_CPUCTR) { + if (cpu_has_vint) + set_vi_handler (hwint, mips_perf_dispatch); + mipsxx_perfcount_irq = MIPSCPU_INT_BASE + hwint; + } + } + if (mipsxx_perfcount_irq >= 0) { +#ifdef CONFIG_MIPS_MT_SMTC + setup_irq_smtc(mipsxx_perfcount_irq, irq, 0x100 << hwint); +#else + setup_irq(mipsxx_perfcount_irq, irq); +#endif /* CONFIG_MIPS_MT_SMTC */ +#ifdef CONFIG_SMP + set_irq_handler(mipsxx_perfcount_irq, handle_percpu_irq); +#endif + } +} + void __init plat_timer_setup(struct irqaction *irq) { + int hwint = 0; #ifdef MSC01E_INT_BASE if (cpu_has_veic) { set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } else + } + else #endif { + if (cpu_has_mips_r2) + /* + * Read IntCtl.IPTI to determine the timer interrupt + */ + hwint = (read_c0_intctl () >> 29) & 7; + else + hwint = MIPSCPU_INT_CPUCTR; if (cpu_has_vint) - set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch); - mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR; + set_vi_handler (hwint, mips_timer_dispatch); + mips_cpu_timer_irq = MIPSCPU_INT_BASE + hwint; } - /* we are using the cpu counter for timer interrupts */ irq->handler = mips_timer_interrupt; /* we use our own handler */ #ifdef CONFIG_MIPS_MT_SMTC - setup_irq_smtc(mips_cpu_timer_irq, irq, CPUCTR_IMASKBIT); + setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << hwint); #else setup_irq(mips_cpu_timer_irq, irq); #endif /* CONFIG_MIPS_MT_SMTC */ - #ifdef CONFIG_SMP - /* irq_desc(riptor) is a global resource, when the interrupt overlaps - on seperate cpu's the first one tries to handle the second interrupt. - The effect is that the int remains disabled on the second cpu. - Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ - irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); #endif + + plat_perf_setup(&perf_irqaction); } diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 1cd830e3d93..1668cc21d5b 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -53,25 +53,19 @@ static inline int mips_pcibios_iack(void) * Determine highest priority pending interrupt by performing * a PCI Interrupt Acknowledge cycle. */ - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: MSC_READ(MSC01_PCI_IACK, irq); irq &= 0xff; break; - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_FPGAR2: + case MIPS_REVISION_SCON_GT64120: irq = GT_READ(GT_PCI0_IACK_OFS); irq &= 0xff; break; - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_SCON_BONITO: /* The following will generate a PCI IACK cycle on the * Bonito controller. It's a little bit kludgy, but it * was the easiest way to implement it in hardware at @@ -89,7 +83,7 @@ static inline int mips_pcibios_iack(void) BONITO_PCIMAP_CFG = 0; break; default: - printk("Unknown Core card, don't know the system controller.\n"); + printk("Unknown system controller.\n"); return -1; } return irq; @@ -144,27 +138,21 @@ static void corehi_irqdispatch(void) Do it for the others too. */ - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: + switch (mips_revision_sconid) { + case MIPS_REVISION_SCON_SOCIT: + case MIPS_REVISION_SCON_ROCIT: + case MIPS_REVISION_SCON_SOCITSC: + case MIPS_REVISION_SCON_SOCITSCP: ll_msc_irq(); break; - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_FPGAR2: + case MIPS_REVISION_SCON_GT64120: intrcause = GT_READ(GT_INTRCAUSE_OFS); datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); printk("GT_INTRCAUSE = %08x\n", intrcause); printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); break; - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_SCON_BONITO: pcibadaddr = BONITO_PCIBADADDR; pcimstat = BONITO_PCIMSTAT; intisr = BONITO_INTISR; diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index c14b7bf8995..8f1b78dfd89 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c @@ -103,9 +103,7 @@ void __init plat_mem_setup(void) kgdb_config (); #endif - if ((mips_revision_corid == MIPS_REVISION_CORID_BONITO64) || - (mips_revision_corid == MIPS_REVISION_CORID_CORE_20K) || - (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL_BON)) { + if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) { char *argptr; argptr = prom_getcmdline(); diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 4f94fa261aa..1ea5c9c1010 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -177,7 +177,10 @@ static int mipsxx_perfcount_handler(void) unsigned int counters = op_model_mipsxx_ops.num_counters; unsigned int control; unsigned int counter; - int handled = 0; + int handled = IRQ_NONE; + + if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26))) + return handled; switch (counters) { #define HANDLE_COUNTER(n) \ @@ -188,7 +191,7 @@ static int mipsxx_perfcount_handler(void) (counter & M_COUNTER_OVERFLOW)) { \ oprofile_add_sample(get_irq_regs(), n); \ w_c0_perfcntr ## n(reg.counter[n]); \ - handled = 1; \ + handled = IRQ_HANDLED; \ } HANDLE_COUNTER(3) HANDLE_COUNTER(2) diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index d86e1577677..f2042e6466a 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c @@ -21,6 +21,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/kernel.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/file.h> @@ -69,7 +70,6 @@ struct getdents_callback { }; #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) static int filldir(void * __buf, const char * name, int namlen, loff_t offset, u64 ino, unsigned d_type) @@ -77,7 +77,7 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, struct hpux_dirent __user * dirent; struct getdents_callback * buf = (struct getdents_callback *) __buf; ino_t d_ino; - int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); + int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(long)); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) @@ -102,7 +102,6 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, } #undef NAME_OFFSET -#undef ROUND_UP int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count) { diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 8474f9e5ca1..42598abf457 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -954,21 +954,6 @@ intr_return: /* NOTE: Need to enable interrupts incase we schedule. */ ssm PSW_SM_I, %r0 - /* Check for software interrupts */ - - .import irq_stat,data - - load32 irq_stat,%r19 -#ifdef CONFIG_SMP - mfctl %cr30,%r1 - ldw TI_CPU(%r1),%r1 /* get cpu # - int */ - /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount - ** irq_stat[] is defined using ____cacheline_aligned. - */ - SHLREG %r1,L1_CACHE_SHIFT,%r20 - add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ -#endif /* CONFIG_SMP */ - intr_check_resched: /* check for reschedule */ @@ -2034,10 +2019,9 @@ ENTRY(syscall_exit) STREG %r28,TASK_PT_GR28(%r1) #ifdef CONFIG_HPUX - /* <linux/personality.h> cannot be easily included */ #define PER_HPUX 0x10 - LDREG TASK_PERSONALITY(%r1),%r19 + ldw TASK_PERSONALITY(%r1),%r19 /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */ ldo -PER_HPUX(%r19), %r19 @@ -2055,24 +2039,6 @@ ENTRY(syscall_exit) */ loadgp -syscall_check_bh: - - /* Check for software interrupts */ - - .import irq_stat,data - - load32 irq_stat,%r19 - -#ifdef CONFIG_SMP - /* sched.h: int processor */ - /* %r26 is used as scratch register to index into irq_stat[] */ - ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */ - - /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */ - SHLREG %r26,L1_CACHE_SHIFT,%r20 - add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ -#endif /* CONFIG_SMP */ - syscall_check_resched: /* check for reschedule */ @@ -2114,7 +2080,7 @@ syscall_restore: /* Are we being ptraced? */ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - LDREG TASK_PTRACE(%r1), %r19 + ldw TASK_PTRACE(%r1), %r19 bb,< %r19,31,syscall_restore_rfi nop @@ -2244,7 +2210,7 @@ syscall_do_resched: #else nop #endif - b syscall_check_bh /* if resched, we start over again */ + b syscall_check_resched /* if resched, we start over again */ nop ENDPROC(syscall_exit) diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 39dc835bf89..fd6552c4c08 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -634,7 +634,7 @@ EXPORT_SYMBOL(pdc_lan_station_id); * pdc_stable_read - Read data from Stable Storage. * @staddr: Stable Storage address to access. * @memaddr: The memory address where Stable Storage data shall be copied. - * @count: number of bytes to transfert. count is multiple of 4. + * @count: number of bytes to transfer. count is multiple of 4. * * This PDC call reads from the Stable Storage address supplied in staddr * and copies count bytes to the memory address memaddr. @@ -660,7 +660,7 @@ EXPORT_SYMBOL(pdc_stable_read); * pdc_stable_write - Write data to Stable Storage. * @staddr: Stable Storage address to access. * @memaddr: The memory address where Stable Storage data shall be read from. - * @count: number of bytes to transfert. count is multiple of 4. + * @count: number of bytes to transfer. count is multiple of 4. * * This PDC call reads count bytes from the supplied memaddr address, * and copies count bytes to the Stable Storage address staddr. diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index 18ba4cb9159..04848b2b381 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c @@ -38,7 +38,7 @@ * so don't reference this table after starting the init process */ -static struct hp_hardware hp_hardware_list[] __initdata = { +static struct hp_hardware hp_hardware_list[] __devinitdata = { {HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"}, {HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"}, {HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"}, @@ -1219,7 +1219,7 @@ static struct hp_cpu_type_mask { unsigned short model; unsigned short mask; enum cpu_type cpu; -} hp_cpu_type_mask_list[] __initdata = { +} hp_cpu_type_mask_list[] __devinitdata = { { 0x0000, 0x0ff0, pcx }, /* 0x0000 - 0x000f */ { 0x0048, 0x0ff0, pcxl }, /* 0x0040 - 0x004f */ @@ -1296,10 +1296,11 @@ static struct hp_cpu_type_mask { { 0x05f0, 0x0ff0, pcxw2 }, /* 0x05f0 - 0x05ff */ { 0x0600, 0x0fe0, pcxl }, /* 0x0600 - 0x061f */ { 0x0880, 0x0ff0, mako }, /* 0x0880 - 0x088f */ + { 0x0890, 0x0ff0, mako2 }, /* 0x0890 - 0x089f */ { 0x0000, 0x0000, pcx } /* terminate table */ }; -char *cpu_name_version[][2] = { +const char * const cpu_name_version[][2] = { [pcx] = { "PA7000 (PCX)", "1.0" }, [pcxs] = { "PA7000 (PCX-S)", "1.1a" }, [pcxt] = { "PA7100 (PCX-T)", "1.1b" }, @@ -1311,10 +1312,11 @@ char *cpu_name_version[][2] = { [pcxw] = { "PA8500 (PCX-W)", "2.0" }, [pcxw_] = { "PA8600 (PCX-W+)", "2.0" }, [pcxw2] = { "PA8700 (PCX-W2)", "2.0" }, - [mako] = { "PA8800 (Mako)", "2.0" } + [mako] = { "PA8800 (Mako)", "2.0" }, + [mako2] = { "PA8900 (Shortfin)", "2.0" } }; -const char * __init +const char * __devinit parisc_hardware_description(struct parisc_device_id *id) { struct hp_hardware *listptr; @@ -1353,7 +1355,7 @@ parisc_hardware_description(struct parisc_device_id *id) /* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */ -enum cpu_type __init +enum cpu_type __cpuinit parisc_get_cpu_type(unsigned long hversion) { struct hp_cpu_type_mask *ptr; diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S index d8baa158d8a..43b41df0b54 100644 --- a/arch/parisc/kernel/hpmc.S +++ b/arch/parisc/kernel/hpmc.S @@ -295,8 +295,5 @@ os_hpmc_6: b . nop ENDPROC(os_hpmc) - - /* this label used to compute os_hpmc checksum */ -ENTRY(os_hpmc_end) - +ENTRY(os_hpmc_end) /* this label used to compute os_hpmc checksum */ nop diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index c5c9125dace..76ce5e3b005 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -46,14 +46,10 @@ extern irqreturn_t ipi_interrupt(int, void *); static volatile unsigned long cpu_eiem = 0; /* -** ack bitmap ... habitually set to 1, but reset to zero +** local ACK bitmap ... habitually set to 1, but reset to zero ** between ->ack() and ->end() of the interrupt to prevent ** re-interruption of a processing interrupt. */ -static volatile unsigned long global_ack_eiem = ~0UL; -/* -** Local bitmap, same as above but for per-cpu interrupts -*/ static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL; static void cpu_disable_irq(unsigned int irq) @@ -94,13 +90,11 @@ void cpu_ack_irq(unsigned int irq) int cpu = smp_processor_id(); /* Clear in EIEM so we can no longer process */ - if (CHECK_IRQ_PER_CPU(irq_desc[irq].status)) - per_cpu(local_ack_eiem, cpu) &= ~mask; - else - global_ack_eiem &= ~mask; + per_cpu(local_ack_eiem, cpu) &= ~mask; /* disable the interrupt */ - set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu)); + set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu)); + /* and now ack it */ mtctl(mask, 23); } @@ -111,13 +105,10 @@ void cpu_end_irq(unsigned int irq) int cpu = smp_processor_id(); /* set it in the eiems---it's no longer in process */ - if (CHECK_IRQ_PER_CPU(irq_desc[irq].status)) - per_cpu(local_ack_eiem, cpu) |= mask; - else - global_ack_eiem |= mask; + per_cpu(local_ack_eiem, cpu) |= mask; /* enable the interrupt */ - set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu)); + set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu)); } #ifdef CONFIG_SMP @@ -354,8 +345,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) local_irq_disable(); irq_enter(); - eirr_val = mfctl(23) & cpu_eiem & global_ack_eiem & - per_cpu(local_ack_eiem, cpu); + eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu); if (!eirr_val) goto set_out; irq = eirr_to_irq(eirr_val); @@ -381,7 +371,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) return; set_out: - set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu)); + set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu)); goto out; } diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 0c3aecb85a5..23c1388df1f 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -21,6 +21,7 @@ #include <linux/mm.h> #include <linux/pci.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/types.h> @@ -34,7 +35,6 @@ #include <asm/tlbflush.h> /* for purge_tlb_*() macros */ static struct proc_dir_entry * proc_gsc_root __read_mostly = NULL; -static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length); static unsigned long pcxl_used_bytes __read_mostly = 0; static unsigned long pcxl_used_pages __read_mostly = 0; @@ -330,6 +330,54 @@ pcxl_free_range(unsigned long vaddr, size_t size) dump_resmap(); } +static int proc_pcxl_dma_show(struct seq_file *m, void *v) +{ +#if 0 + u_long i = 0; + unsigned long *res_ptr = (u_long *)pcxl_res_map; +#endif + unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */ + + seq_printf(m, "\nDMA Mapping Area size : %d bytes (%ld pages)\n", + PCXL_DMA_MAP_SIZE, total_pages); + + seq_printf(m, "Resource bitmap : %d bytes\n", pcxl_res_size); + + seq_puts(m, " total: free: used: % used:\n"); + seq_printf(m, "blocks %8d %8ld %8ld %8ld%%\n", pcxl_res_size, + pcxl_res_size - pcxl_used_bytes, pcxl_used_bytes, + (pcxl_used_bytes * 100) / pcxl_res_size); + + seq_printf(m, "pages %8ld %8ld %8ld %8ld%%\n", total_pages, + total_pages - pcxl_used_pages, pcxl_used_pages, + (pcxl_used_pages * 100 / total_pages)); + +#if 0 + seq_puts(m, "\nResource bitmap:"); + + for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) { + if ((i & 7) == 0) + seq_puts(m,"\n "); + seq_printf(m, "%s %08lx", buf, *res_ptr); + } +#endif + seq_putc(m, '\n'); + return 0; +} + +static int proc_pcxl_dma_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_pcxl_dma_show, NULL); +} + +static const struct file_operations proc_pcxl_dma_ops = { + .owner = THIS_MODULE, + .open = proc_pcxl_dma_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int __init pcxl_dma_init(void) { @@ -348,9 +396,10 @@ pcxl_dma_init(void) "pcxl_dma_init: Unable to create gsc /proc dir entry\n"); else { struct proc_dir_entry* ent; - ent = create_proc_info_entry("pcxl_dma", 0, - proc_gsc_root, pcxl_proc_info); - if (!ent) + ent = create_proc_entry("pcxl_dma", 0, proc_gsc_root); + if (ent) + ent->proc_fops = &proc_pcxl_dma_ops; + else printk(KERN_WARNING "pci-dma.c: Unable to create pcxl_dma /proc entry.\n"); } @@ -551,40 +600,3 @@ struct hppa_dma_ops pcx_dma_ops = { .dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu, .dma_sync_sg_for_device = pa11_dma_sync_sg_for_device, }; - - -static int pcxl_proc_info(char *buf, char **start, off_t offset, int len) -{ -#if 0 - u_long i = 0; - unsigned long *res_ptr = (u_long *)pcxl_res_map; -#endif - unsigned long total_pages = pcxl_res_size << 3; /* 8 bits per byte */ - - sprintf(buf, "\nDMA Mapping Area size : %d bytes (%ld pages)\n", - PCXL_DMA_MAP_SIZE, total_pages); - - sprintf(buf, "%sResource bitmap : %d bytes\n", buf, pcxl_res_size); - - strcat(buf, " total: free: used: % used:\n"); - sprintf(buf, "%sblocks %8d %8ld %8ld %8ld%%\n", buf, pcxl_res_size, - pcxl_res_size - pcxl_used_bytes, pcxl_used_bytes, - (pcxl_used_bytes * 100) / pcxl_res_size); - - sprintf(buf, "%spages %8ld %8ld %8ld %8ld%%\n", buf, total_pages, - total_pages - pcxl_used_pages, pcxl_used_pages, - (pcxl_used_pages * 100 / total_pages)); - -#if 0 - strcat(buf, "\nResource bitmap:"); - - for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) { - if ((i & 7) == 0) - strcat(buf,"\n "); - sprintf(buf, "%s %08lx", buf, *res_ptr); - } -#endif - strcat(buf, "\n"); - return strlen(buf); -} - diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index a46bc62b643..89d6d5ad44b 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -171,7 +171,7 @@ static const uint64_t perf_bitmasks[] = { /* * Write control bitmasks for Pa-8700 processor given - * somethings have changed slightly. + * some things have changed slightly. */ static const uint64_t perf_bitmasks_piranha[] = { 0x0000000000000000ul, /* first dbl word must be zero */ @@ -511,10 +511,12 @@ static int __init perf_init(void) } else if (boot_cpu_data.cpu_type == pcxw || boot_cpu_data.cpu_type == pcxw_ || boot_cpu_data.cpu_type == pcxw2 || - boot_cpu_data.cpu_type == mako) { + boot_cpu_data.cpu_type == mako || + boot_cpu_data.cpu_type == mako2) { perf_processor_interface = CUDA_INTF; if (boot_cpu_data.cpu_type == pcxw2 || - boot_cpu_data.cpu_type == mako) + boot_cpu_data.cpu_type == mako || + boot_cpu_data.cpu_type == mako2) bitmask_array = perf_bitmasks_piranha; } else { perf_processor_interface = UNKNOWN_INTF; @@ -574,27 +576,27 @@ static int perf_stop_counters(uint32_t *raddr) if (!perf_rdr_read_ubuf(16, userbuf)) return -13; - /* Counter0 is bits 1398 thru 1429 */ + /* Counter0 is bits 1398 to 1429 */ tmp64 = (userbuf[21] << 22) & 0x00000000ffc00000; tmp64 |= (userbuf[22] >> 42) & 0x00000000003fffff; /* OR sticky0 (bit 1430) to counter0 bit 32 */ tmp64 |= (userbuf[22] >> 10) & 0x0000000080000000; raddr[0] = (uint32_t)tmp64; - /* Counter1 is bits 1431 thru 1462 */ + /* Counter1 is bits 1431 to 1462 */ tmp64 = (userbuf[22] >> 9) & 0x00000000ffffffff; /* OR sticky1 (bit 1463) to counter1 bit 32 */ tmp64 |= (userbuf[22] << 23) & 0x0000000080000000; raddr[1] = (uint32_t)tmp64; - /* Counter2 is bits 1464 thru 1495 */ + /* Counter2 is bits 1464 to 1495 */ tmp64 = (userbuf[22] << 24) & 0x00000000ff000000; tmp64 |= (userbuf[23] >> 40) & 0x0000000000ffffff; /* OR sticky2 (bit 1496) to counter2 bit 32 */ tmp64 |= (userbuf[23] >> 8) & 0x0000000080000000; raddr[2] = (uint32_t)tmp64; - /* Counter3 is bits 1497 thru 1528 */ + /* Counter3 is bits 1497 to 1528 */ tmp64 = (userbuf[23] >> 7) & 0x00000000ffffffff; /* OR sticky3 (bit 1529) to counter3 bit 32 */ tmp64 |= (userbuf[23] << 25) & 0x0000000080000000; @@ -616,7 +618,7 @@ static int perf_stop_counters(uint32_t *raddr) userbuf[23] = 0; /* - * Write back the zero'ed bytes + the image given + * Write back the zeroed bytes + the image given * the read was destructive. */ perf_rdr_write(16, userbuf); diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 0dd3847f494..355664812b8 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -381,6 +381,10 @@ get_wchan(struct task_struct *p) struct unwind_frame_info info; unsigned long ip; int count = 0; + + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + /* * These bracket the sleeping functions.. */ diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 566226d78bc..549f5484342 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -63,7 +63,7 @@ extern int update_cr16_clocksource(void); /* from time.c */ ** will call register_parisc_driver(&cpu_driver) before calling do_inventory(). ** ** The goal of consolidating CPU initialization into one place is -** to make sure all CPU's get initialized the same way. +** to make sure all CPUs get initialized the same way. ** The code path not shared is how PDC hands control of the CPU to the OS. ** The initialization of OS data structures is the same (done below). */ @@ -76,7 +76,7 @@ extern int update_cr16_clocksource(void); /* from time.c */ * (return 1). If so, initialize the chip and tell other partners in crime * they have work to do. */ -static int __init processor_probe(struct parisc_device *dev) +static int __cpuinit processor_probe(struct parisc_device *dev) { unsigned long txn_addr; unsigned long cpuid; @@ -166,7 +166,7 @@ static int __init processor_probe(struct parisc_device *dev) #endif /* - ** CONFIG_SMP: init_smp_config() will attempt to get CPU's into + ** CONFIG_SMP: init_smp_config() will attempt to get CPUs into ** OS control. RENDEZVOUS is the default state - see mem_set above. ** p->state = STATE_RENDEZVOUS; */ @@ -334,7 +334,7 @@ int __init init_per_cpu(int cpunum) } /* - * Display cpu info for all cpu's. + * Display CPU info for all CPUs. */ int show_cpuinfo (struct seq_file *m, void *v) @@ -381,19 +381,19 @@ show_cpuinfo (struct seq_file *m, void *v) return 0; } -static struct parisc_device_id processor_tbl[] __read_mostly = { +static const struct parisc_device_id processor_tbl[] = { { HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID }, { 0, } }; -static struct parisc_driver cpu_driver __read_mostly = { +static struct parisc_driver cpu_driver = { .name = "CPU", .id_table = processor_tbl, .probe = processor_probe }; /** - * processor_init - Processor initalization procedure. + * processor_init - Processor initialization procedure. * * Register this driver. */ diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 9818919571f..c44b8c51f5d 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -45,7 +45,7 @@ #include <asm/io.h> #include <asm/setup.h> -char __initdata command_line[COMMAND_LINE_SIZE]; +static char __initdata command_line[COMMAND_LINE_SIZE]; /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ struct proc_dir_entry * proc_runway_root __read_mostly = NULL; @@ -162,7 +162,7 @@ void __init setup_arch(char **cmdline_p) } /* - * Display cpu info for all cpu's. + * Display CPU info for all CPUs. * for parisc this is in processor.c */ extern int show_cpuinfo (struct seq_file *m, void *v); @@ -225,6 +225,7 @@ static void __init parisc_proc_mkdir(void) } break; case mako: + case mako2: if (NULL == proc_mckinley_root) { proc_mckinley_root = proc_mkdir("bus/mckinley", NULL); diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index e39b38a67a8..c7800846422 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -113,7 +113,7 @@ int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); /* In a deft move of uber-hackery, we decide to carry the top half of all * 64-bit registers in a non-portable, non-ABI, hidden structure. * Userspace can read the hidden structure if it *wants* but is never - * guaranteed to be in the same place. Infact the uc_sigmask from the + * guaranteed to be in the same place. In fact the uc_sigmask from the * ucontext_t structure may push the hidden register file downards */ struct compat_regfile { diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 6ba9257fdb7..04c7e1d36ce 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -8,7 +8,7 @@ ** Lots of stuff stolen from arch/alpha/kernel/smp.c ** ...and then parisc stole from arch/ia64/kernel/smp.c. Thanks David! :^) ** -** Thanks to John Curry and Ullas Ponnadi. I learned alot from their work. +** Thanks to John Curry and Ullas Ponnadi. I learned a lot from their work. ** -grant (1/12/2001) ** ** This program is free software; you can redistribute it and/or modify @@ -419,7 +419,7 @@ smp_cpu_init(int cpunum) BUG(); enter_lazy_tlb(&init_mm, current); - init_IRQ(); /* make sure no IRQ's are enabled or pending */ + init_IRQ(); /* make sure no IRQs are enabled or pending */ start_cpu_itimer(); } @@ -461,7 +461,7 @@ void __init smp_callin(void) /* * Bring one cpu online. */ -int __init smp_boot_one_cpu(int cpuid) +int __cpuinit smp_boot_one_cpu(int cpuid) { struct task_struct *idle; long timeout; @@ -552,7 +552,7 @@ void __devinit smp_prepare_boot_cpu(void) /* ** inventory.c:do_inventory() hasn't yet been run and thus we -** don't 'discover' the additional CPU's until later. +** don't 'discover' the additional CPUs until later. */ void __init smp_prepare_cpus(unsigned int max_cpus) { diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index ce3245f87fd..bb23ff71c28 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -311,14 +311,13 @@ struct readdir32_callback { int count; }; -#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) static int filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino, unsigned int d_type) { struct linux32_dirent __user * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; - int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); + int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, 4); u32 d_ino; buf->error = -EINVAL; /* only used if we fail.. */ @@ -350,6 +349,10 @@ sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) struct getdents32_callback buf; int error; + error = -EFAULT; + if (!access_ok(VERIFY_WRITE, dirent, count)) + goto out; + error = -EBADF; file = fget(fd); if (!file) @@ -366,8 +369,10 @@ sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) error = buf.error; lastdirent = buf.previous; if (lastdirent) { - put_user(file->f_pos, &lastdirent->d_off); - error = count - buf.count; + if (put_user(file->f_pos, &lastdirent->d_off)) + error = -EFAULT; + else + error = count - buf.count; } out_putf: diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 10859f53e94..56f6231cb86 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -181,7 +181,7 @@ linux_gateway_entry: /* Are we being ptraced? */ mfctl %cr30, %r1 LDREG TI_TASK(%r1),%r1 - LDREG TASK_PTRACE(%r1), %r1 + ldw TASK_PTRACE(%r1), %r1 bb,<,n %r1,31,.Ltracesys /* Note! We cannot use the syscall table that is mapped @@ -198,7 +198,7 @@ linux_gateway_entry: ldil L%sys_call_table, %r1 ldo R%sys_call_table(%r1), %r19 #endif - comiclr,>>= __NR_Linux_syscalls, %r20, %r0 + comiclr,>> __NR_Linux_syscalls, %r20, %r0 b,n .Lsyscall_nosys LDREGX %r20(%r19), %r19 @@ -501,7 +501,7 @@ lws_compare_and_swap: shlw %r20, 4, %r20 add %r20, %r28, %r20 -# ifdef ENABLE_LWS_DEBUG +# if ENABLE_LWS_DEBUG /* DEBUG, check for deadlock! If the thread register values are the same @@ -550,7 +550,7 @@ cas_wouldblock: perspective */ cas_action: -#if defined CONFIG_SMP && defined ENABLE_LWS_DEBUG +#if defined CONFIG_SMP && ENABLE_LWS_DEBUG /* DEBUG */ mfctl %cr27, %r1 stw %r1, 4(%sr2,%r20) @@ -562,7 +562,7 @@ cas_action: #ifdef CONFIG_SMP /* Free lock */ stw %r20, 0(%sr2,%r20) -# ifdef ENABLE_LWS_DEBUG +# if ENABLE_LWS_DEBUG /* Clear thread register indicator */ stw %r0, 4(%sr2,%r20) # endif @@ -576,7 +576,7 @@ cas_action: #ifdef CONFIG_SMP /* Free lock */ stw %r20, 0(%sr2,%r20) -# ifdef ENABLE_LWS_DEBUG +# if ENABLE_LWS_DEBUG stw %r0, 4(%sr2,%r20) # endif #endif diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 8bf87e5d9c3..627f3c28ad8 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -30,11 +30,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#undef ENTRY_SAME -#undef ENTRY_DIFF -#undef ENTRY_UHOH -#undef ENTRY_COMP -#undef ENTRY_OURS #if defined(CONFIG_64BIT) && !defined(SYSCALL_TABLE_64BIT) /* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific @@ -405,5 +400,16 @@ ENTRY_SAME(epoll_pwait) ENTRY_COMP(statfs64) ENTRY_COMP(fstatfs64) + ENTRY_COMP(kexec_load) /* 300 */ + ENTRY_COMP(utimensat) + ENTRY_COMP(signalfd) + ENTRY_COMP(timerfd) + ENTRY_SAME(eventfd) + /* Nothing yet */ +#undef ENTRY_SAME +#undef ENTRY_DIFF +#undef ENTRY_UHOH +#undef ENTRY_COMP +#undef ENTRY_OURS diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 07a991aa9b0..8b3062a5c81 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -191,7 +191,7 @@ int update_cr16_clocksource(void) { int change = 0; - /* since the cr16 cycle counters are not syncronized across CPUs, + /* since the cr16 cycle counters are not synchronized across CPUs, we'll check if we should switch to a safe clocksource: */ if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) { clocksource_change_rating(&clocksource_cr16, 0); diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 745ff741490..c3ec9f1ec0f 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -615,7 +615,7 @@ void handle_interruption(int code, struct pt_regs *regs) case 13: /* Conditional Trap - The condition succees in an instruction which traps + The condition succeeds in an instruction which traps on condition */ if(user_mode(regs)){ si.si_signo = SIGFPE; @@ -802,13 +802,14 @@ void handle_interruption(int code, struct pt_regs *regs) int __init check_ivt(void *iva) { + extern const u32 os_hpmc[]; + extern const u32 os_hpmc_end[]; + int i; u32 check = 0; u32 *ivap; u32 *hpmcp; u32 length; - extern void os_hpmc(void); - extern void os_hpmc_end(void); if (strcmp((char *)iva, "cows can fly")) return -1; @@ -820,7 +821,7 @@ int __init check_ivt(void *iva) /* Compute Checksum for HPMC handler */ - length = (u32)((unsigned long)os_hpmc_end - (unsigned long)os_hpmc); + length = os_hpmc_end - os_hpmc; ivap[7] = length; hpmcp = (u32 *)os_hpmc; diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 89c03707ecc..e70f57e2764 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -216,8 +216,10 @@ static void unwind_frame_regs(struct unwind_frame_info *info) /* Handle some frequent special cases.... */ { char symname[KSYM_NAME_LEN+1]; + char *modname; - kallsyms_lookup(info->ip, NULL, NULL, NULL, symname); + kallsyms_lookup(info->ip, NULL, NULL, &modname, + symname); dbg("info->ip = 0x%lx, name = %s\n", info->ip, symname); diff --git a/arch/parisc/math-emu/dbl_float.h b/arch/parisc/math-emu/dbl_float.h index 1570e2e0a32..0c2fa9a951b 100644 --- a/arch/parisc/math-emu/dbl_float.h +++ b/arch/parisc/math-emu/dbl_float.h @@ -22,7 +22,7 @@ PA header file -- do not include this header file for non-PA builds. #endif -/* 32-bit word grabing functions */ +/* 32-bit word grabbing functions */ #define Dbl_firstword(value) Dallp1(value) #define Dbl_secondword(value) Dallp2(value) #define Dbl_thirdword(value) dummy_location @@ -37,7 +37,7 @@ #define Dbl_allp1(object) Dallp1(object) #define Dbl_allp2(object) Dallp2(object) -/* dbl_and_signs ands the sign bits of each argument and puts the result +/* dbl_and_signs ANDs the sign bits of each argument and puts the result * into the first argument. dbl_or_signs ors those same sign bits */ #define Dbl_and_signs( src1dst, src2) \ Dallp1(src1dst) = (Dallp1(src2)|~((unsigned int)1<<31)) & Dallp1(src1dst) diff --git a/arch/parisc/math-emu/dfsqrt.c b/arch/parisc/math-emu/dfsqrt.c index b6ed1066f1e..9542c6d281a 100644 --- a/arch/parisc/math-emu/dfsqrt.c +++ b/arch/parisc/math-emu/dfsqrt.c @@ -76,7 +76,7 @@ dbl_fsqrt( } /* * Return quiet NaN or positive infinity. - * Fall thru to negative test if negative infinity. + * Fall through to negative test if negative infinity. */ if (Dbl_iszero_sign(srcp1) || Dbl_isnotzero_mantissa(srcp1,srcp2)) { diff --git a/arch/parisc/math-emu/sfsqrt.c b/arch/parisc/math-emu/sfsqrt.c index cd3f6db1f6f..4657a12c910 100644 --- a/arch/parisc/math-emu/sfsqrt.c +++ b/arch/parisc/math-emu/sfsqrt.c @@ -76,7 +76,7 @@ sgl_fsqrt( } /* * Return quiet NaN or positive infinity. - * Fall thru to negative test if negative infinity. + * Fall through to negative test if negative infinity. */ if (Sgl_iszero_sign(src) || Sgl_isnotzero_mantissa(src)) { *dstptr = src; diff --git a/arch/parisc/math-emu/sgl_float.h b/arch/parisc/math-emu/sgl_float.h index 82519a5c2ba..4ee4cc95e4b 100644 --- a/arch/parisc/math-emu/sgl_float.h +++ b/arch/parisc/math-emu/sgl_float.h @@ -23,7 +23,7 @@ PA header file -- do not include this header file for non-PA builds. #endif -/* 32-bit word grabing functions */ +/* 32-bit word grabbing functions */ #define Sgl_firstword(value) Sall(value) #define Sgl_secondword(value) dummy_location #define Sgl_thirdword(value) dummy_location @@ -36,7 +36,7 @@ #define Sgl_exponentmantissa(object) Sexponentmantissa(object) #define Sgl_all(object) Sall(object) -/* sgl_and_signs ands the sign bits of each argument and puts the result +/* sgl_and_signs ANDs the sign bits of each argument and puts the result * into the first argument. sgl_or_signs ors those same sign bits */ #define Sgl_and_signs( src1dst, src2) \ Sall(src1dst) = (Sall(src2)|~((unsigned int)1<<31)) & Sall(src1dst) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 75ea9f2a8a4..e724b362c49 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -890,7 +890,7 @@ void __init paging_init(void) #ifdef CONFIG_PA20 /* - * Currently, all PA20 chips have 18 bit protection id's, which is the + * Currently, all PA20 chips have 18 bit protection IDs, which is the * limiting factor (space ids are 32 bits). */ @@ -899,10 +899,10 @@ void __init paging_init(void) #else /* - * Currently we have a one-to-one relationship between space id's and - * protection id's. Older parisc chips (PCXS, PCXT, PCXL, PCXL2) only - * support 15 bit protection id's, so that is the limiting factor. - * PCXT' has 18 bit protection id's, but only 16 bit spaceids, so it's + * Currently we have a one-to-one relationship between space IDs and + * protection IDs. Older parisc chips (PCXS, PCXT, PCXL, PCXL2) only + * support 15 bit protection IDs, so that is the limiting factor. + * PCXT' has 18 bit protection IDs, but only 16 bit spaceids, so it's * probably not worth the effort for a special case here. */ diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 87703df8750..cbca1df8bc6 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -151,12 +151,18 @@ static struct console udbg_console = { static int early_console_initialized; -/* called by setup_system */ +/* + * Called by setup_system after ppc_md->probe and ppc_md->early_init. + * Call it again after setting udbg_putc in ppc_md->setup_arch. + */ void register_early_udbg_console(void) { if (early_console_initialized) return; + if (!udbg_putc) + return; + if (strstr(boot_command_line, "udbg-immortal")) { printk(KERN_INFO "early console immortal !\n"); udbg_console.flags &= ~CON_BOOT; diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 07b1c4ec428..956571526a5 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -363,8 +363,19 @@ static void __init pmac_setup_arch(void) smp_ops = &core99_smp_ops; } #ifdef CONFIG_PPC32 - else + else { + /* + * We have to set bits in cpu_possible_map here since the + * secondary CPU(s) aren't in the device tree, and + * setup_per_cpu_areas only allocates per-cpu data for + * CPUs in the cpu_possible_map. + */ + int cpu; + + for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) + cpu_set(cpu, cpu_possible_map); smp_ops = &psurge_smp_ops; + } #endif #endif /* CONFIG_SMP */ diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 686ed82bde7..cb2d894541c 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -317,7 +317,6 @@ static int __init smp_psurge_probe(void) ncpus = NR_CPUS; for (i = 1; i < ncpus ; ++i) { cpu_set(i, cpu_present_map); - cpu_set(i, cpu_possible_map); set_hard_smp_processor_id(i, i); } diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 7d1a11822a1..8059531bf0a 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -2357,8 +2357,9 @@ sun4v_ldc_unmap: nop .size sun4v_ldc_unmap, .-sun4v_ldc_unmap - /* %o0: cookie - * %o1: mte_cookie + /* %o0: channel + * %o1: cookie + * %o2: mte_cookie * * returns %o0: status */ diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index a36f8dd0c02..e60d283f60b 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -1,7 +1,6 @@ -/* $Id: irq.c,v 1.114 2002/01/11 08:45:38 davem Exp $ - * irq.c: UltraSparc IRQ handling/init/registry. +/* irq.c: UltraSparc IRQ handling/init/registry. * - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) */ @@ -43,6 +42,7 @@ #include <asm/cpudata.h> #include <asm/auxio.h> #include <asm/head.h> +#include <asm/hypervisor.h> /* UPA nodes send interrupt packet to UltraSparc with first data reg * value low 5 (7 on Starfire) bits holding the IRQ identifier being @@ -380,6 +380,76 @@ static void sun4v_irq_end(unsigned int virt_irq) } } +static void sun4v_virq_enable(unsigned int virt_irq) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; + + if (likely(bucket)) { + unsigned long cpuid, dev_handle, dev_ino; + int err; + + cpuid = irq_choose_cpu(virt_irq); + + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; + + err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); + if (err != HV_EOK) + printk("sun4v_vintr_set_target(%lx,%lx,%lu): " + "err(%d)\n", + dev_handle, dev_ino, cpuid, err); + err = sun4v_vintr_set_state(dev_handle, dev_ino, + HV_INTR_ENABLED); + if (err != HV_EOK) + printk("sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_ENABLED): err(%d)\n", + dev_handle, dev_ino, err); + } +} + +static void sun4v_virq_disable(unsigned int virt_irq) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; + + if (likely(bucket)) { + unsigned long dev_handle, dev_ino; + int err; + + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; + + err = sun4v_vintr_set_state(dev_handle, dev_ino, + HV_INTR_DISABLED); + if (err != HV_EOK) + printk("sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_DISABLED): err(%d)\n", + dev_handle, dev_ino, err); + } +} + +static void sun4v_virq_end(unsigned int virt_irq) +{ + struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); + unsigned int ino = bucket - &ivector_table[0]; + + if (likely(bucket)) { + unsigned long dev_handle, dev_ino; + int err; + + dev_handle = ino & IMAP_IGN; + dev_ino = ino & IMAP_INO; + + err = sun4v_vintr_set_state(dev_handle, dev_ino, + HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk("sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_STATE_IDLE): err(%d)\n", + dev_handle, dev_ino, err); + } +} + static void run_pre_handler(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); @@ -434,6 +504,21 @@ static struct irq_chip sun4v_msi = { }; #endif +static struct irq_chip sun4v_virq = { + .typename = "vsun4v", + .enable = sun4v_virq_enable, + .disable = sun4v_virq_disable, + .end = sun4v_virq_end, +}; + +static struct irq_chip sun4v_virq_ack = { + .typename = "vsun4v+ack", + .enable = sun4v_virq_enable, + .disable = sun4v_virq_disable, + .ack = run_pre_handler, + .end = sun4v_virq_end, +}; + void irq_install_pre_handler(int virt_irq, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2) @@ -447,7 +532,8 @@ void irq_install_pre_handler(int virt_irq, chip = get_irq_chip(virt_irq); if (chip == &sun4u_irq_ack || - chip == &sun4v_irq_ack + chip == &sun4v_irq_ack || + chip == &sun4v_virq_ack #ifdef CONFIG_PCI_MSI || chip == &sun4v_msi #endif @@ -455,7 +541,9 @@ void irq_install_pre_handler(int virt_irq, return; chip = (chip == &sun4u_irq ? - &sun4u_irq_ack : &sun4v_irq_ack); + &sun4u_irq_ack : + (chip == &sun4v_irq ? + &sun4v_irq_ack : &sun4v_virq_ack)); set_irq_chip(virt_irq, chip); } @@ -492,19 +580,18 @@ out: return bucket->virt_irq; } -unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) +static unsigned int sun4v_build_common(unsigned long sysino, + struct irq_chip *chip) { struct ino_bucket *bucket; struct irq_handler_data *data; - unsigned long sysino; BUG_ON(tlb_type != hypervisor); - sysino = sun4v_devino_to_sysino(devhandle, devino); bucket = &ivector_table[sysino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - set_irq_chip(bucket->virt_irq, &sun4v_irq); + set_irq_chip(bucket->virt_irq, chip); } data = get_irq_chip_data(bucket->virt_irq); @@ -529,6 +616,32 @@ out: return bucket->virt_irq; } +unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) +{ + unsigned long sysino = sun4v_devino_to_sysino(devhandle, devino); + + return sun4v_build_common(sysino, &sun4v_irq); +} + +unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) +{ + unsigned long sysino, hv_err; + + BUG_ON(devhandle & ~IMAP_IGN); + BUG_ON(devino & ~IMAP_INO); + + sysino = devhandle | devino; + + hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); + if (hv_err) { + prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] " + "err=%lu\n", devhandle, devino, hv_err); + prom_halt(); + } + + return sun4v_build_common(sysino, &sun4v_virq); +} + #ifdef CONFIG_PCI_MSI unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, unsigned int msi_start, unsigned int msi_end) diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index f974fefc3eb..4249214608a 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -291,8 +291,9 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) for (i = 0; i < num_pbm_ranges; i++) { const struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; - unsigned long a; + unsigned long a, size; u32 parent_phys_hi, parent_phys_lo; + u32 size_hi, size_lo; int type; parent_phys_hi = pr->parent_phys_hi; @@ -300,9 +301,14 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) if (tlb_type == hypervisor) parent_phys_hi &= 0x0fffffff; + size_hi = pr->size_hi; + size_lo = pr->size_lo; + type = (pr->child_phys_hi >> 24) & 0x3; a = (((unsigned long)parent_phys_hi << 32UL) | ((unsigned long)parent_phys_lo << 0UL)); + size = (((unsigned long)size_hi << 32UL) | + ((unsigned long)size_lo << 0UL)); switch (type) { case 0: @@ -313,7 +319,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) case 1: /* 16-bit IO space, 16MB */ pbm->io_space.start = a; - pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); + pbm->io_space.end = a + size - 1UL; pbm->io_space.flags = IORESOURCE_IO; saw_io = 1; break; @@ -321,7 +327,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) case 2: /* 32-bit MEM space, 2GB */ pbm->mem_space.start = a; - pbm->mem_space.end = a + (0x80000000UL - 1UL); + pbm->mem_space.end = a + size - 1UL; pbm->mem_space.flags = IORESOURCE_MEM; saw_mem = 1; break; |