diff options
141 files changed, 1653 insertions, 1022 deletions
diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt new file mode 100644 index 000000000000..52478c83d0cc --- /dev/null +++ b/Documentation/devicetree/bindings/arm/arch_timer.txt @@ -0,0 +1,27 @@ +* ARM architected timer + +ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which +provides per-cpu timers. + +The timer is attached to a GIC to deliver its per-processor interrupts. + +** Timer node properties: + +- compatible : Should at least contain "arm,armv7-timer". + +- interrupts : Interrupt list for secure, non-secure, virtual and + hypervisor timers, in that order. + +- clock-frequency : The frequency of the main counter, in Hz. Optional. + +Example: + + timer { + compatible = "arm,cortex-a15-timer", + "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + clock-frequency = <100000000>; + }; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2f67f6c62f56..ed244933b256 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1187,6 +1187,15 @@ if !MMU source "arch/arm/Kconfig-nommu" endif +config ARM_ERRATA_326103 + bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" + depends on CPU_V6 + help + Executing a SWP instruction to read-only memory does not set bit 11 + of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to + treat the access as a read, preventing a COW from occurring and + causing the faulting task to livelock. + config ARM_ERRATA_411920 bool "ARM errata: Invalidation of the Instruction Cache operation can fail" depends on CPU_V6 || CPU_V6K @@ -1544,6 +1553,12 @@ config HAVE_ARM_SCU help This option enables support for the ARM system coherency unit +config ARM_ARCH_TIMER + bool "Architected timer support" + depends on CPU_V7 + help + This option enables support for the ARM architected timer + config HAVE_ARM_TWD bool depends on SMP diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts index 0b32925f2147..e2fe3195c0d1 100644 --- a/arch/arm/boot/dts/versatile-ab.dts +++ b/arch/arm/boot/dts/versatile-ab.dts @@ -173,7 +173,7 @@ mmc@5000 { compatible = "arm,primecell"; reg = < 0x5000 0x1000>; - interrupts = <22>; + interrupts = <22 34>; }; kmi@6000 { compatible = "arm,pl050", "arm,primecell"; diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index 166461073b78..7e8175269064 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -41,7 +41,7 @@ mmc@b000 { compatible = "arm,primecell"; reg = <0xb000 0x1000>; - interrupts = <23>; + interrupts = <23 34>; }; }; }; diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index dcb13494ca0d..c4110d1b1f2d 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -222,7 +222,7 @@ static int it8152_pci_write_config(struct pci_bus *bus, return PCIBIOS_SUCCESSFUL; } -static struct pci_ops it8152_ops = { +struct pci_ops it8152_ops = { .read = it8152_pci_read_config, .write = it8152_pci_write_config, }; @@ -346,9 +346,4 @@ void pcibios_set_master(struct pci_dev *dev) } -struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, nr, &it8152_ops, sys, &sys->resources); -} - EXPORT_SYMBOL(dma_set_coherent_mask); diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c index 1171a5010aea..6cb362e56d29 100644 --- a/arch/arm/common/via82c505.c +++ b/arch/arm/common/via82c505.c @@ -51,7 +51,7 @@ via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -static struct pci_ops via82c505_ops = { +struct pci_ops via82c505_ops = { .read = via82c505_read_config, .write = via82c505_write_config, }; @@ -81,12 +81,3 @@ int __init via82c505_setup(int nr, struct pci_sys_data *sys) { return (nr == 0); } - -struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata) -{ - if (nr == 0) - return pci_scan_root_bus(NULL, 0, &via82c505_ops, sysdata, - &sysdata->resources); - - return NULL; -} diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h new file mode 100644 index 000000000000..ed2e95d46e29 --- /dev/null +++ b/arch/arm/include/asm/arch_timer.h @@ -0,0 +1,19 @@ +#ifndef __ASMARM_ARCH_TIMER_H +#define __ASMARM_ARCH_TIMER_H + +#ifdef CONFIG_ARM_ARCH_TIMER +int arch_timer_of_register(void); +int arch_timer_sched_clock_init(void); +#else +static inline int arch_timer_of_register(void) +{ + return -ENXIO; +} + +static inline int arch_timer_sched_clock_init(void) +{ + return -ENXIO; +} +#endif + +#endif diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 73f84fa4f366..d36a73d7c0e8 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -110,6 +110,6 @@ extern void it8152_irq_demux(unsigned int irq, struct irq_desc *desc); extern void it8152_init_irq(void); extern int it8152_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); extern int it8152_pci_setup(int nr, struct pci_sys_data *sys); -extern struct pci_bus *it8152_pci_scan_bus(int nr, struct pci_sys_data *sys); +extern struct pci_ops it8152_ops; #endif /* __ASM_HARDWARE_IT8152_H */ diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index d943b7d20f11..26c511fddf8f 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -12,13 +12,14 @@ #define __ASM_MACH_PCI_H struct pci_sys_data; +struct pci_ops; struct pci_bus; struct hw_pci { #ifdef CONFIG_PCI_DOMAINS int domain; #endif - struct list_head buses; + struct pci_ops *ops; int nr_controllers; int (*setup)(int nr, struct pci_sys_data *); struct pci_bus *(*scan)(int nr, struct pci_sys_data *); @@ -45,16 +46,10 @@ struct pci_sys_data { u8 (*swizzle)(struct pci_dev *, u8 *); /* IRQ mapping */ int (*map_irq)(const struct pci_dev *, u8, u8); - struct hw_pci *hw; void *private_data; /* platform controller private data */ }; /* - * This is the standard PCI-PCI bridge swizzling algorithm. - */ -#define pci_std_swizzle pci_common_swizzle - -/* * Call this with your hw_pci struct to initialise the PCI system. */ void pci_common_init(struct hw_pci *); @@ -62,22 +57,22 @@ void pci_common_init(struct hw_pci *); /* * PCI controllers */ +extern struct pci_ops iop3xx_ops; extern int iop3xx_pci_setup(int nr, struct pci_sys_data *); -extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *); extern void iop3xx_pci_preinit(void); extern void iop3xx_pci_preinit_cond(void); +extern struct pci_ops dc21285_ops; extern int dc21285_setup(int nr, struct pci_sys_data *); -extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); extern void dc21285_preinit(void); extern void dc21285_postinit(void); +extern struct pci_ops via82c505_ops; extern int via82c505_setup(int nr, struct pci_sys_data *); -extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *); extern void via82c505_init(void *sysdata); +extern struct pci_ops pci_v3_ops; extern int pci_v3_setup(int nr, struct pci_sys_data *); -extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); extern void pci_v3_preinit(void); extern void pci_v3_postinit(void); diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index b8e580a297e4..14965658a923 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -34,11 +34,4 @@ typedef struct { #endif -/* - * switch_mm() may do a full cache flush over the context switch, - * so enable interrupts over the context switch to avoid high - * latency. - */ -#define __ARCH_WANT_INTERRUPTS_ON_CTXSW - #endif diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index a0b3cac0547c..0306bc642c0d 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -43,45 +43,104 @@ void __check_kvm_seq(struct mm_struct *mm); #define ASID_FIRST_VERSION (1 << ASID_BITS) extern unsigned int cpu_last_asid; -#ifdef CONFIG_SMP -DECLARE_PER_CPU(struct mm_struct *, current_mm); -#endif void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); void __new_context(struct mm_struct *mm); +void cpu_set_reserved_ttbr0(void); -static inline void check_context(struct mm_struct *mm) +static inline void switch_new_context(struct mm_struct *mm) { - /* - * This code is executed with interrupts enabled. Therefore, - * mm->context.id cannot be updated to the latest ASID version - * on a different CPU (and condition below not triggered) - * without first getting an IPI to reset the context. The - * alternative is to take a read_lock on mm->context.id_lock - * (after changing its type to rwlock_t). - */ - if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) - __new_context(mm); + unsigned long flags; + + __new_context(mm); + + local_irq_save(flags); + cpu_switch_mm(mm->pgd, mm); + local_irq_restore(flags); +} +static inline void check_and_switch_context(struct mm_struct *mm, + struct task_struct *tsk) +{ if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) __check_kvm_seq(mm); + + /* + * Required during context switch to avoid speculative page table + * walking with the wrong TTBR. + */ + cpu_set_reserved_ttbr0(); + + if (!((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) + /* + * The ASID is from the current generation, just switch to the + * new pgd. This condition is only true for calls from + * context_switch() and interrupts are already disabled. + */ + cpu_switch_mm(mm->pgd, mm); + else if (irqs_disabled()) + /* + * Defer the new ASID allocation until after the context + * switch critical region since __new_context() cannot be + * called with interrupts disabled (it sends IPIs). + */ + set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM); + else + /* + * That is a direct call to switch_mm() or activate_mm() with + * interrupts enabled and a new context. + */ + switch_new_context(mm); } #define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0) -#else - -static inline void check_context(struct mm_struct *mm) +#define finish_arch_post_lock_switch \ + finish_arch_post_lock_switch +static inline void finish_arch_post_lock_switch(void) { + if (test_and_clear_thread_flag(TIF_SWITCH_MM)) + switch_new_context(current->mm); +} + +#else /* !CONFIG_CPU_HAS_ASID */ + #ifdef CONFIG_MMU + +static inline void check_and_switch_context(struct mm_struct *mm, + struct task_struct *tsk) +{ if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) __check_kvm_seq(mm); -#endif + + if (irqs_disabled()) + /* + * cpu_switch_mm() needs to flush the VIVT caches. To avoid + * high interrupt latencies, defer the call and continue + * running with the old mm. Since we only support UP systems + * on non-ASID CPUs, the old mm will remain valid until the + * finish_arch_post_lock_switch() call. + */ + set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM); + else + cpu_switch_mm(mm->pgd, mm); } +#define finish_arch_post_lock_switch \ + finish_arch_post_lock_switch +static inline void finish_arch_post_lock_switch(void) +{ + if (test_and_clear_thread_flag(TIF_SWITCH_MM)) { + struct mm_struct *mm = current->mm; + cpu_switch_mm(mm->pgd, mm); + } +} + +#endif /* CONFIG_MMU */ + #define init_new_context(tsk,mm) 0 -#endif +#endif /* CONFIG_CPU_HAS_ASID */ #define destroy_context(mm) do { } while(0) @@ -119,12 +178,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, __flush_icache_all(); #endif if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { -#ifdef CONFIG_SMP - struct mm_struct **crt_mm = &per_cpu(current_mm, cpu); - *crt_mm = next; -#endif - check_context(next); - cpu_switch_mm(next->pgd, next); + check_and_switch_context(next, tsk); if (cache_is_vivt()) cpumask_clear_cpu(cpu, mm_cpumask(prev)); } diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index d4c24d412a8d..68388eb4946b 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -118,6 +118,13 @@ extern void iwmmxt_task_switch(struct thread_info *); extern void vfp_sync_hwstate(struct thread_info *); extern void vfp_flush_hwstate(struct thread_info *); +struct user_vfp; +struct user_vfp_exc; + +extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, + struct user_vfp_exc __user *); +extern int vfp_restore_user_hwstate(struct user_vfp __user *, + struct user_vfp_exc __user *); #endif /* @@ -146,6 +153,7 @@ extern void vfp_flush_hwstate(struct thread_info *); #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 20 #define TIF_SECCOMP 21 +#define TIF_SWITCH_MM 22 /* deferred switch_mm */ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h index 60843eb0f61c..73409e6c0251 100644 --- a/arch/arm/include/asm/tls.h +++ b/arch/arm/include/asm/tls.h @@ -7,6 +7,8 @@ .macro set_tls_v6k, tp, tmp1, tmp2 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register + mov \tmp1, #0 + mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register .endm .macro set_tls_v6, tp, tmp1, tmp2 @@ -15,6 +17,8 @@ mov \tmp2, #0xffff0fff tst \tmp1, #HWCAP_TLS @ hardware TLS available? mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register + movne \tmp1, #0 + mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 .endm diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 7b787d642af4..22b0f1e255f0 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o +obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c new file mode 100644 index 000000000000..dd58035621f7 --- /dev/null +++ b/arch/arm/kernel/arch_timer.c @@ -0,0 +1,350 @@ +/* + * linux/arch/arm/kernel/arch_timer.c + * + * Copyright (C) 2011 ARM Ltd. + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/smp.h> +#include <linux/cpu.h> +#include <linux/jiffies.h> +#include <linux/clockchips.h> +#include <linux/interrupt.h> +#include <linux/of_irq.h> +#include <linux/io.h> + +#include <asm/cputype.h> +#include <asm/localtimer.h> +#include <asm/arch_timer.h> +#include <asm/system_info.h> +#include <asm/sched_clock.h> + +static unsigned long arch_timer_rate; +static int arch_timer_ppi; +static int arch_timer_ppi2; + +static struct clock_event_device __percpu **arch_timer_evt; + +/* + * Architected system timer support. + */ + +#define ARCH_TIMER_CTRL_ENABLE (1 << 0) +#define ARCH_TIMER_CTRL_IT_MASK (1 << 1) +#define ARCH_TIMER_CTRL_IT_STAT (1 << 2) + +#define ARCH_TIMER_REG_CTRL 0 +#define ARCH_TIMER_REG_FREQ 1 +#define ARCH_TIMER_REG_TVAL 2 + +static void arch_timer_reg_write(int reg, u32 val) +{ + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); + break; + } + + isb(); +} + +static u32 arch_timer_reg_read(int reg) +{ + u32 val; + + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); + break; + case ARCH_TIMER_REG_FREQ: + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); + break; + default: + BUG(); + } + + return val; +} + +static irqreturn_t arch_timer_handler(int irq, void *dev_id) +{ + struct clock_event_device *evt = *(struct clock_event_device **)dev_id; + unsigned long ctrl; + + ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); + if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { + ctrl |= ARCH_TIMER_CTRL_IT_MASK; + arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); + evt->event_handler(evt); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static void arch_timer_disable(void) +{ + unsigned long ctrl; + + ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); + ctrl &= ~ARCH_TIMER_CTRL_ENABLE; + arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); +} + +static void arch_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *clk) +{ + switch (mode) { + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + arch_timer_disable(); + break; + default: + break; + } +} + +static int arch_timer_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long ctrl; + + ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL); + ctrl |= ARCH_TIMER_CTRL_ENABLE; + ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; + + arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt); + arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl); + + return 0; +} + +static int __cpuinit arch_timer_setup(struct clock_event_device *clk) +{ + /* Be safe... */ + arch_timer_disable(); + + clk->features = CLOCK_EVT_FEAT_ONESHOT; + clk->name = "arch_sys_timer"; + clk->rating = 450; + clk->set_mode = arch_timer_set_mode; + clk->set_next_event = arch_timer_set_next_event; + clk->irq = arch_timer_ppi; + + clockevents_config_and_register(clk, arch_timer_rate, + 0xf, 0x7fffffff); + + *__this_cpu_ptr(arch_timer_evt) = clk; + + enable_percpu_irq(clk->irq, 0); + if (arch_timer_ppi2) + enable_percpu_irq(arch_timer_ppi2, 0); + + return 0; +} + +/* Is the optional system timer available? */ +static int local_timer_is_architected(void) +{ + return (cpu_architecture() >= CPU_ARCH_ARMv7) && + ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1; +} + +static int arch_timer_available(void) +{ + unsigned long freq; + + if (!local_timer_is_architected()) + return -ENXIO; + + if (arch_timer_rate == 0) { + arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0); + freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ); + + /* Check the timer frequency. */ + if (freq == 0) { + pr_warn("Architected timer frequency not available\n"); + return -EINVAL; + } + + arch_timer_rate = freq; + } + + pr_info_once("Architected local timer running at %lu.%02luMHz.\n", + arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100); + return 0; +} + +static inline cycle_t arch_counter_get_cntpct(void) +{ + u32 cvall, cvalh; + + asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh)); + + return ((cycle_t) cvalh << 32) | cvall; +} + +static inline cycle_t arch_counter_get_cntvct(void) +{ + u32 cvall, cvalh; + + asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh)); + + return ((cycle_t) cvalh << 32) | cvall; +} + +static u32 notrace arch_counter_get_cntvct32(void) +{ + cycle_t cntvct = arch_counter_get_cntvct(); + + /* + * The sched_clock infrastructure only knows about counters + * with at most 32bits. Forget about the upper 24 bits for the + * time being... + */ + return (u32)(cntvct & (u32)~0); +} + +static cycle_t arch_counter_read(struct clocksource *cs) +{ + return arch_counter_get_cntpct(); +} + +static struct clocksource clocksource_counter = { + .name = "arch_sys_counter", + .rating = 400, + .read = arch_counter_read, + .mask = CLOCKSOURCE_MASK(56), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static void __cpuinit arch_timer_stop(struct clock_event_device *clk) +{ + pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", + clk->irq, smp_processor_id()); + disable_percpu_irq(clk->irq); + if (arch_timer_ppi2) + disable_percpu_irq(arch_timer_ppi2); + arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk); +} + +static struct local_timer_ops arch_timer_ops __cpuinitdata = { + .setup = arch_timer_setup, + .stop = arch_timer_stop, +}; + +static struct clock_event_device arch_timer_global_evt; + +static int __init arch_timer_register(void) +{ + int err; + + err = arch_timer_available(); + if (err) + return err; + + arch_timer_evt = alloc_percpu(struct clock_event_device *); + if (!arch_timer_evt) + return -ENOMEM; + + clocksource_register_hz(&clocksource_counter, arch_timer_rate); + + err = request_percpu_irq(arch_timer_ppi, arch_timer_handler, + "arch_timer", arch_timer_evt); + if (err) { + pr_err("arch_timer: can't register interrupt %d (%d)\n", + arch_timer_ppi, err); + goto out_free; + } + + if (arch_timer_ppi2) { + err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler, + "arch_timer", arch_timer_evt); + if (err) { + pr_err("arch_timer: can't register interrupt %d (%d)\n", + arch_timer_ppi2, err); + arch_timer_ppi2 = 0; + goto out_free_irq; + } + } + + err = local_timer_register(&arch_timer_ops); + if (err) { + /* + * We couldn't register as a local timer (could be + * because we're on a UP platform, or because some + * other local timer is already present...). Try as a + * global timer instead. + */ + arch_timer_global_evt.cpumask = cpumask_of(0); + err = arch_timer_setup(&arch_timer_global_evt); + } + + if (err) + goto out_free_irq; + + return 0; + +out_free_irq: + free_percpu_irq(arch_timer_ppi, arch_timer_evt); + if (arch_timer_ppi2) + free_percpu_irq(arch_timer_ppi2, arch_timer_evt); + +out_free: + free_percpu(arch_timer_evt); + + return err; +} + +static const struct of_device_id arch_timer_of_match[] __initconst = { + { .compatible = "arm,armv7-timer", }, + {}, +}; + +int __init arch_timer_of_register(void) +{ + struct device_node *np; + u32 freq; + + np = of_find_matching_node(NULL, arch_timer_of_match); + if (!np) { + pr_err("arch_timer: can't find DT node\n"); + return -ENODEV; + } + + /* Try to determine the frequency from the device tree or CNTFRQ */ + if (!of_property_read_u32(np, "clock-frequency", &freq)) + arch_timer_rate = freq; + + arch_timer_ppi = irq_of_parse_and_map(np, 0); + arch_timer_ppi2 = irq_of_parse_and_map(np, 1); + pr_info("arch_timer: found %s irqs %d %d\n", + np->name, arch_timer_ppi, arch_timer_ppi2); + + return arch_timer_register(); +} + +int __init arch_timer_sched_clock_init(void) +{ + int err; + + err = arch_timer_available(); + if (err) + return err; + + setup_sched_clock(arch_counter_get_cntvct32, 32, arch_timer_rate); + return 0; +} diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index ede5f7741c42..25552508c3fd 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -374,16 +374,29 @@ EXPORT_SYMBOL(pcibios_fixup_bus); #endif /* - * Swizzle the device pin each time we cross a bridge. - * This might update pin and returns the slot number. + * Swizzle the device pin each time we cross a bridge. If a platform does + * not provide a swizzle function, we perform the standard PCI swizzling. + * + * The default swizzling walks up the bus tree one level at a time, applying + * the standard swizzle function at each step, stopping when it finds the PCI + * root bus. This will return the slot number of the bridge device on the + * root bus and the interrupt pin on that device which should correspond + * with the downstream device interrupt. + * + * Platforms may override this, in which case the slot and pin returned + * depend entirely on the platform code. However, please note that the + * PCI standard swizzle is implemented on plug-in cards and Cardbus based + * PCI extenders, so it can not be ignored. */ static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin) { struct pci_sys_data *sys = dev->sysdata; - int slot = 0, oldpin = *pin; + int slot, oldpin = *pin; if (sys->swizzle) slot = sys->swizzle(dev, pin); + else + slot = pci_common_swizzle(dev, pin); if (debug_pci) printk("PCI: %s swizzling pin %d => pin %d slot %d\n", @@ -410,7 +423,7 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq; } -static void __init pcibios_init_hw(struct hw_pci *hw) +static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head) { struct pci_sys_data *sys = NULL; int ret; @@ -424,7 +437,6 @@ static void __init pcibios_init_hw(struct hw_pci *hw) #ifdef CONFIG_PCI_DOMAINS sys->domain = hw->domain; #endif - sys->hw = hw; sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; @@ -440,14 +452,18 @@ static void __init pcibios_init_hw(struct hw_pci *hw) &iomem_resource, sys->mem_offset); } - sys->bus = hw->scan(nr, sys); + if (hw->scan) + sys->bus = hw->scan(nr, sys); + else + sys->bus = pci_scan_root_bus(NULL, sys->busnr, + hw->ops, sys, &sys->resources); if (!sys->bus) panic("PCI: unable to scan bus!"); busnr = sys->bus->subordinate + 1; - list_add(&sys->node, &hw->buses); + list_add(&sys->node, head); } else { kfree(sys); if (ret < 0) @@ -459,19 +475,18 @@ static void __init pcibios_init_hw(struct hw_pci *hw) void __init pci_common_init(struct hw_pci *hw) { struct pci_sys_data *sys; - - INIT_LIST_HEAD(&hw->buses); + LIST_HEAD(head); pci_add_flags(PCI_REASSIGN_ALL_RSRC); if (hw->preinit) hw->preinit(); - pcibios_init_hw(hw); + pcibios_init_hw(hw, &head); if (hw->postinit) hw->postinit(); pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); - list_for_each_entry(sys, &hw->buses, node) { + list_for_each_entry(sys, &head, node) { struct pci_bus *bus = sys->bus; if (!pci_has_flag(PCI_PROBE_ONLY)) { diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 71ccdbfed662..8349d4e97e2b 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -155,10 +155,10 @@ static bool migrate_one_irq(struct irq_desc *desc) } c = irq_data_get_irq_chip(d); - if (c->irq_set_affinity) - c->irq_set_affinity(d, affinity, true); - else + if (!c->irq_set_affinity) pr_debug("IRQ%u: unable to set affinity\n", d->irq); + else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret) + cpumask_copy(d->affinity, affinity); return ret; } diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 80abafb9bf33..9650c143afc1 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -906,27 +906,14 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -#ifdef __ARMEB__ -#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB -#else -#define AUDIT_ARCH_NR AUDIT_ARCH_ARM -#endif - asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) { unsigned long ip; - /* - * Save IP. IP is used to denote syscall entry/exit: - * IP = 0 -> entry, = 1 -> exit - */ - ip = regs->ARM_ip; - regs->ARM_ip = why; - - if (!ip) + if (why) audit_syscall_exit(regs); else - audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0, + audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); if (!test_thread_flag(TIF_SYSCALL_TRACE)) @@ -936,6 +923,13 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) current_thread_info()->syscall = scno; + /* + * IP is used to denote syscall entry/exit: + * IP = 0 -> entry, =1 -> exit + */ + ip = regs->ARM_ip; + regs->ARM_ip = why; + /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 7cb532fc8aa4..d68d1b694680 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -180,44 +180,23 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) static int preserve_vfp_context(struct vfp_sigframe __user *frame) { - struct thread_info *thread = current_thread_info(); - struct vfp_hard_struct *h = &thread->vfpstate.hard; const unsigned long magic = VFP_MAGIC; const unsigned long size = VFP_STORAGE_SIZE; int err = 0; - vfp_sync_hwstate(thread); __put_user_error(magic, &frame->magic, err); __put_user_error(size, &frame->size, err); - /* - * Copy the floating point registers. There can be unused - * registers see asm/hwcap.h for details. - */ - err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, - sizeof(h->fpregs)); - /* - * Copy the status and control register. - */ - __put_user_error(h->fpscr, &frame->ufp.fpscr, err); - - /* - * Copy the exception registers. - */ - __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); - __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); - __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + if (err) + return -EFAULT; - return err ? -EFAULT : 0; + return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); } static int restore_vfp_context(struct vfp_sigframe __user *frame) { - struct thread_info *thread = current_thread_info(); - struct vfp_hard_struct *h = &thread->vfpstate.hard; unsigned long magic; unsigned long size; - unsigned long fpexc; int err = 0; __get_user_error(magic, &frame->magic, err); @@ -228,33 +207,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) return -EINVAL; - vfp_flush_hwstate(thread); - - /* - * Copy the floating point registers. There can be unused - * registers see asm/hwcap.h for details. - */ - err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, - sizeof(h->fpregs)); - /* - * Copy the status and control register. - */ - __get_user_error(h->fpscr, &frame->ufp.fpscr, err); - - /* - * Sanitise and restore the exception registers. - */ - __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); - /* Ensure the VFP is enabled. */ - fpexc |= FPEXC_EN; - /* Ensure FPINST2 is invalid and the exception flag is cleared. */ - fpexc &= ~(FPEXC_EX | FPEXC_FP2V); - h->fpexc = fpexc; - - __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); - __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); - - return err ? -EFAULT : 0; + return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc); } #endif diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index addbbe8028c2..cf58558ef4b9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -251,8 +251,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) struct mm_struct *mm = &init_mm; unsigned int cpu = smp_processor_id(); - printk("CPU%u: Booted secondary processor\n", cpu); - /* * All kernel threads share the same mm context; grab a * reference and switch to it. @@ -264,6 +262,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void) enter_lazy_tlb(mm, current); local_flush_tlb_all(); + printk("CPU%u: Booted secondary processor\n", cpu); + cpu_init(); preempt_disable(); trace_hardirqs_off(); @@ -454,6 +454,9 @@ static struct local_timer_ops *lt_ops; #ifdef CONFIG_LOCAL_TIMERS int local_timer_register(struct local_timer_ops *ops) { + if (!is_smp() || !setup_max_cpus) + return -ENXIO; + if (lt_ops) return -EBUSY; @@ -510,10 +513,6 @@ static void ipi_cpu_stop(unsigned int cpu) local_fiq_disable(); local_irq_disable(); -#ifdef CONFIG_HOTPLUG_CPU - platform_cpu_kill(cpu); -#endif - while (1) cpu_relax(); } @@ -576,17 +575,25 @@ void smp_send_reschedule(int cpu) smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); } +#ifdef CONFIG_HOTPLUG_CPU +static void smp_kill_cpus(cpumask_t *mask) +{ + unsigned int cpu; + for_each_cpu(cpu, mask) + platform_cpu_kill(cpu); +} +#else +static void smp_kill_cpus(cpumask_t *mask) { } +#endif + void smp_send_stop(void) { unsigned long timeout; + struct cpumask mask; - if (num_online_cpus() > 1) { - struct cpumask mask; - cpumask_copy(&mask, cpu_online_mask); - cpumask_clear_cpu(smp_processor_id(), &mask); - - smp_cross_call(&mask, IPI_CPU_STOP); - } + cpumask_copy(&mask, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &mask); + smp_cross_call(&mask, IPI_CPU_STOP); /* Wait up to one second for other CPUs to stop */ timeout = USEC_PER_SEC; @@ -595,6 +602,8 @@ void smp_send_stop(void) if (num_online_cpus() > 1) pr_warning("SMP: failed to stop secondary CPUs\n"); + + smp_kill_cpus(&mask); } /* diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index d2b177905cdb..76cbb055dd05 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -115,7 +115,7 @@ int kernel_execve(const char *filename, "Ir" (THREAD_START_SP - sizeof(regs)), "r" (®s), "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); + : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory"); out: return ret; diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index 79d001f831e0..311328314163 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -166,12 +166,6 @@ static struct pci_ops cns3xxx_pcie_ops = { .write = cns3xxx_pci_write_config, }; -static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &cns3xxx_pcie_ops, sys, - &sys->resources); -} - static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev); @@ -221,10 +215,9 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, }, .hw_pci = { .domain = 0, - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &cns3xxx_pcie_ops, .setup = cns3xxx_pci_setup, - .scan = cns3xxx_pci_scan_bus, .map_irq = cns3xxx_pcie_map_irq, }, }, @@ -264,10 +257,9 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = { .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, }, .hw_pci = { .domain = 1, - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &cns3xxx_pcie_ops, .setup = cns3xxx_pci_setup, - .scan = cns3xxx_pci_scan_bus, .map_irq = cns3xxx_pcie_map_irq, }, }, diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 48a032005ea3..47921b0cdc65 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c @@ -43,6 +43,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) return 0; pp = &pcie_port[nr]; + sys->private_data = pp; pp->root_bus_nr = sys->busnr; /* @@ -93,19 +94,6 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -static struct pcie_port *bus_to_port(int bus) -{ - int i; - - for (i = num_pcie_ports - 1; i >= 0; i--) { - int rbus = pcie_port[i].root_bus_nr; - if (rbus != -1 && rbus <= bus) - break; - } - - return i >= 0 ? pcie_port + i : NULL; -} - static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* @@ -121,7 +109,8 @@ static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pcie_port *pp = bus_to_port(bus->number); + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; @@ -140,7 +129,8 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pcie_port *pp = bus_to_port(bus->number); + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; @@ -194,14 +184,14 @@ dove_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct pcie_port *pp = bus_to_port(dev->bus->number); + struct pci_sys_data *sys = dev->sysdata; + struct pcie_port *pp = sys->private_data; return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0; } static struct hw_pci dove_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = dove_pcie_setup, .scan = dove_pcie_scan_bus, .map_irq = dove_pcie_map_irq, diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c index 32321f66dec4..5cec2567c9c5 100644 --- a/arch/arm/mach-footbridge/cats-pci.c +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -16,6 +16,11 @@ /* cats host-specific stuff */ static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; +static u8 cats_no_swizzle(struct pci_dev *dev, u8 *pin) +{ + return 0; +} + static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->irq >= 255) @@ -39,11 +44,11 @@ static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) * cards being used (ie, pci-pci bridge based cards)? */ static struct hw_pci cats_pci __initdata = { - .swizzle = NULL, + .swizzle = cats_no_swizzle, .map_irq = cats_map_irq, .nr_controllers = 1, + .ops = &dc21285_ops, .setup = dc21285_setup, - .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index e17e11de4f5e..9d62e3381024 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -129,7 +129,7 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -static struct pci_ops dc21285_ops = { +struct pci_ops dc21285_ops = { .read = dc21285_read_config, .write = dc21285_write_config, }; @@ -284,11 +284,6 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) return 1; } -struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, 0, &dc21285_ops, sys, &sys->resources); -} - #define dc21285_request_irq(_a, _b, _c, _d, _e) \ WARN_ON(request_irq(_a, _b, _c, _d, _e) < 0) diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c index 511c673ffa9d..fd12d8a36dc5 100644 --- a/arch/arm/mach-footbridge/ebsa285-pci.c +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -29,11 +29,10 @@ static int __init ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci ebsa285_pci __initdata = { - .swizzle = pci_std_swizzle, .map_irq = ebsa285_map_irq, .nr_controllers = 1, + .ops = &dc21285_ops, .setup = dc21285_setup, - .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c index 62187610e17e..0fba5134e4fe 100644 --- a/arch/arm/mach-footbridge/netwinder-pci.c +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -43,11 +43,10 @@ static int __init netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci netwinder_pci __initdata = { - .swizzle = pci_std_swizzle, .map_irq = netwinder_map_irq, .nr_controllers = 1, + .ops = &dc21285_ops, .setup = dc21285_setup, - .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c index aeb651d914a6..5c9ee54613b2 100644 --- a/arch/arm/mach-footbridge/personal-pci.c +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -41,8 +41,8 @@ static int __init personal_server_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci personal_server_pci __initdata = { .map_irq = personal_server_map_irq, .nr_controllers = 1, + .ops = &dc21285_ops, .setup = dc21285_setup, - .scan = dc21285_scan_bus, .preinit = dc21285_preinit, .postinit = dc21285_postinit, }; diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 3e538da6cb1f..e428f3ab15c7 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -398,24 +398,16 @@ static int impd1_probe(struct lm_device *dev) struct impd1_device *idev = impd1_devs + i; struct amba_device *d; unsigned long pc_base; + char devname[32]; pc_base = dev->resource.start + idev->offset; - - d = amba_device_alloc(NULL, pc_base, SZ_4K); - if (!d) + snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); + d = amba_ahb_device_add(&dev->dev, devname, pc_base, SZ_4K, + dev->irq, dev->irq, + idev->platform_data, idev->id); + if (IS_ERR(d)) { + dev_err(&dev->dev, "unable to register device: %ld\n", PTR_ERR(d)); continue; - - dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12); - d->dev.parent = &dev->dev; - d->irq[0] = dev->irq; - d->irq[1] = dev->irq; - d->periphid = idev->id; - d->dev.platform_data = idev->platform_data; - - ret = amba_device_add(d, &dev->resource); - if (ret) { - dev_err(&d->dev, "unable to register device: %d\n", ret); - amba_device_put(d); } } diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c index f1ca9c122861..6c1667e728f5 100644 --- a/arch/arm/mach-integrator/pci.c +++ b/arch/arm/mach-integrator/pci.c @@ -70,21 +70,10 @@ */ static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp) { - int pin = *pinp; + if (*pinp == 0) + *pinp = 1; - if (pin == 0) - pin = 1; - - while (dev->bus->self) { - pin = pci_swizzle_interrupt_pin(dev, pin); - /* - * move up the chain of bridges, swizzling as we go. - */ - dev = dev->bus->self; - } - *pinp = pin; - - return PCI_SLOT(dev->devfn); + return pci_common_swizzle(dev, pinp); } static int irq_tab[4] __initdata = { @@ -109,7 +98,7 @@ static struct hw_pci integrator_pci __initdata = { .map_irq = integrator_map_irq, .setup = pci_v3_setup, .nr_controllers = 1, - .scan = pci_v3_scan_bus, + .ops = &pci_v3_ops, .preinit = pci_v3_preinit, .postinit = pci_v3_postinit, }; diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 67e6f9a9d1a0..b866880e82ac 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -340,7 +340,7 @@ static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -static struct pci_ops pci_v3_ops = { +struct pci_ops pci_v3_ops = { .read = v3_read_config, .write = v3_write_config, }; @@ -488,12 +488,6 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys) return ret; } -struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &pci_v3_ops, sys, - &sys->resources); -} - /* * V3_LB_BASE? - local bus address * V3_LB_MAP? - pci bus address diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 5c96b73e6964..e3f3e7daa79e 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -54,7 +54,6 @@ iq81340mc_pcix_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin) } static struct hw_pci iq81340mc_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 0, .setup = iop13xx_pci_setup, .map_irq = iq81340mc_pcix_map_irq, diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index aa4dd750135a..060cddde2fd4 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -56,7 +56,6 @@ iq81340sc_atux_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) } static struct hw_pci iq81340sc_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 0, .setup = iop13xx_pci_setup, .scan = iop13xx_scan_bus, diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c index 24069e03fdc1..9f369f09c29d 100644 --- a/arch/arm/mach-iop32x/em7210.c +++ b/arch/arm/mach-iop32x/em7210.c @@ -103,11 +103,10 @@ em7210_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci em7210_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, .map_irq = em7210_pci_map_irq, }; diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index 204e1d1cd766..c15a100ba779 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -96,11 +96,10 @@ glantank_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci glantank_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, .map_irq = glantank_pci_map_irq, }; diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index 3eb642af1cdc..ddd1c7ecfe57 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -130,11 +130,10 @@ ep80219_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci ep80219_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, .map_irq = ep80219_pci_map_irq, }; @@ -166,11 +165,10 @@ iq31244_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq31244_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, .map_irq = iq31244_pci_map_irq, }; diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 2ec724b58a2c..bf155e6a3b45 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -101,11 +101,10 @@ iq80321_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq80321_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit_cond, - .scan = iop3xx_pci_scan_bus, .map_irq = iq80321_pci_map_irq, }; diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 6b6d55912444..5a7ae91e8849 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -114,11 +114,10 @@ n2100_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci n2100_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, .map_irq = n2100_pci_map_irq, }; diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index abce934f3816..e74a7debe793 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -84,11 +84,10 @@ iq80331_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq80331_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit_cond, - .scan = iop3xx_pci_scan_bus, .map_irq = iq80331_pci_map_irq, }; diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 7513559e25bb..e2f5beece6e8 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -84,11 +84,10 @@ iq80332_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) } static struct hw_pci iq80332_pci __initdata = { - .swizzle = pci_std_swizzle, .nr_controllers = 1, + .ops = &iop3xx_ops, .setup = iop3xx_pci_setup, .preinit = iop3xx_pci_preinit_cond, - .scan = iop3xx_pci_scan_bus, .map_irq = iq80332_pci_map_irq, }; diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 4867f408617c..73df2f688813 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -141,13 +141,6 @@ static struct pci_ops enp2611_pci_ops = { .write = enp2611_pci_write_config }; -static struct pci_bus * __init enp2611_pci_scan_bus(int nr, - struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &enp2611_pci_ops, sys, - &sys->resources); -} - static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { @@ -180,9 +173,9 @@ static int __init enp2611_pci_map_irq(const struct pci_dev *dev, u8 slot, struct hw_pci enp2611_pci __initdata = { .nr_controllers = 1, + .ops = &enp2611_pci_ops, .setup = enp2611_pci_setup, .preinit = enp2611_pci_preinit, - .scan = enp2611_pci_scan_bus, .map_irq = enp2611_pci_map_irq, }; diff --git a/arch/arm/mach-ixp2000/include/mach/platform.h b/arch/arm/mach-ixp2000/include/mach/platform.h index bb0f8dcf9ee1..6b500c0858be 100644 --- a/arch/arm/mach-ixp2000/include/mach/platform.h +++ b/arch/arm/mach-ixp2000/include/mach/platform.h @@ -127,10 +127,10 @@ unsigned long ixp2000_gettimeoffset(void); struct pci_sys_data; +extern struct pci_ops ixp2000_pci_ops; u32 *ixp2000_pci_config_addr(unsigned int bus, unsigned int devfn, int where); void ixp2000_pci_preinit(void); int ixp2000_pci_setup(int, struct pci_sys_data*); -struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*); int ixp2000_pci_read_config(struct pci_bus*, unsigned int, int, int, u32 *); int ixp2000_pci_write_config(struct pci_bus*, unsigned int, int, int, u32); diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 915ad49e3b8f..4ec44801d303 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -146,10 +146,10 @@ static void ixdp2400_pci_postinit(void) static struct hw_pci ixdp2400_pci __initdata = { .nr_controllers = 1, + .ops = &ixp2000_pci_ops, .setup = ixdp2400_pci_setup, .preinit = ixdp2400_pci_preinit, .postinit = ixdp2400_pci_postinit, - .scan = ixp2000_pci_scan_bus, .map_irq = ixdp2400_pci_map_irq, }; diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index a9f1819ea049..44378c31d177 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -246,10 +246,10 @@ static void __init ixdp2800_pci_postinit(void) struct __initdata hw_pci ixdp2800_pci __initdata = { .nr_controllers = 1, + .ops = &ixp2000_pci_ops, .setup = ixdp2800_pci_setup, .preinit = ixdp2800_pci_preinit, .postinit = ixdp2800_pci_postinit, - .scan = ixp2000_pci_scan_bus, .map_irq = ixdp2800_pci_map_irq, }; diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 5196c39cdba4..af8b801d7d59 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -327,9 +327,9 @@ static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys) struct hw_pci ixdp2x01_pci __initdata = { .nr_controllers = 1, + .ops = &ixp2000_pci_ops, .setup = ixdp2x01_pci_setup, .preinit = ixdp2x01_pci_preinit, - .scan = ixp2000_pci_scan_bus, .map_irq = ixdp2x01_pci_map_irq, }; diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 9c02de932fac..d706838db023 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -124,17 +124,11 @@ int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, } -static struct pci_ops ixp2000_pci_ops = { +struct pci_ops ixp2000_pci_ops = { .read = ixp2000_pci_read_config, .write = ixp2000_pci_write_config }; -struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata) -{ - return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops, - sysdata, &sysdata->resources); -} - int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { diff --git a/arch/arm/mach-ixp23xx/include/mach/platform.h b/arch/arm/mach-ixp23xx/include/mach/platform.h index 50de558e722e..798d8b42ab4a 100644 --- a/arch/arm/mach-ixp23xx/include/mach/platform.h +++ b/arch/arm/mach-ixp23xx/include/mach/platform.h @@ -37,7 +37,7 @@ void ixp23xx_sys_init(void); void ixp23xx_restart(char, const char *); int ixp23xx_pci_setup(int, struct pci_sys_data *); void ixp23xx_pci_preinit(void); -struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*); +extern struct pci_ops ixp23xx_pci_ops; void ixp23xx_pci_slave_init(void); extern struct sys_timer ixp23xx_timer; diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index b0e07db5ceaf..8b48e32a8a62 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c @@ -251,9 +251,9 @@ static int __init ixdp2351_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci ixdp2351_pci __initdata = { .nr_controllers = 1, + .ops = &ixp23xx_pci_ops, .preinit = ixp23xx_pci_preinit, .setup = ixp23xx_pci_setup, - .scan = ixp23xx_pci_scan_bus, .map_irq = ixdp2351_map_irq, }; diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 911f5a58e006..9211506ef556 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -140,12 +140,6 @@ struct pci_ops ixp23xx_pci_ops = { .write = ixp23xx_pci_write_config, }; -struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata) -{ - return pci_scan_root_bus(NULL, sysdata->busnr, &ixp23xx_pci_ops, - sysdata, &sysdata->resources); -} - int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { volatile unsigned long temp; diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index eaaa3fa9fd05..8c0e5de3c609 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c @@ -118,9 +118,9 @@ static void __init roadrunner_pci_preinit(void) static struct hw_pci roadrunner_pci __initdata = { .nr_controllers = 1, + .ops = &ixp23xx_pci_ops, .preinit = roadrunner_pci_preinit, .setup = ixp23xx_pci_setup, - .scan = ixp23xx_pci_scan_bus, .map_irq = roadrunner_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c index 8fea0a3c5246..548c7d43ade6 100644 --- a/arch/arm/mach-ixp4xx/avila-pci.c +++ b/arch/arm/mach-ixp4xx/avila-pci.c @@ -65,10 +65,9 @@ static int __init avila_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci avila_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = avila_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = avila_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index d5719eb42591..1694f01ce2b6 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -480,12 +480,6 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) return 1; } -struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &ixp4xx_ops, sys, - &sys->resources); -} - int dma_set_coherent_mask(struct device *dev, u64 mask) { if (mask >= SZ_64M - 1) diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c index 71f5c9c60fc3..5d14ce2aee6d 100644 --- a/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/arch/arm/mach-ixp4xx/coyote-pci.c @@ -48,10 +48,9 @@ static int __init coyote_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci coyote_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = coyote_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = coyote_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c index 0532510b5e8c..8dca76937723 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-pci.c +++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c @@ -62,10 +62,9 @@ static int __init dsmg600_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci __initdata dsmg600_pci = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = dsmg600_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = dsmg600_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c index d2ac803328f7..fd4a8625b4ae 100644 --- a/arch/arm/mach-ixp4xx/fsg-pci.c +++ b/arch/arm/mach-ixp4xx/fsg-pci.c @@ -59,10 +59,9 @@ static int __init fsg_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci fsg_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = fsg_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = fsg_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c index 76581fb467c4..d9d6cc089707 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-pci.c +++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c @@ -47,10 +47,9 @@ static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot, struct hw_pci gateway7001_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = gateway7001_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = gateway7001_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index 46bb924962ee..b800a031207c 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -473,11 +473,10 @@ static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci gmlr_hw_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = gmlr_pci_preinit, .postinit = gmlr_pci_postinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = gmlr_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c index d68fc068c38d..551d114c9e14 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -67,10 +67,9 @@ static int __init gtwx5715_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci gtwx5715_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = gtwx5715_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = gtwx5715_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h index b66bedc64de1..5bce94aacca9 100644 --- a/arch/arm/mach-ixp4xx/include/mach/platform.h +++ b/arch/arm/mach-ixp4xx/include/mach/platform.h @@ -130,7 +130,7 @@ extern void ixp4xx_restart(char, const char *); extern void ixp4xx_pci_preinit(void); struct pci_sys_data; extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); -extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); +extern struct pci_ops ixp4xx_ops; /* * GPIO-functions diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c index fffd8c5e40bf..318424dd3c50 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -60,10 +60,9 @@ static int __init ixdp425_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci ixdp425_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = ixdp425_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = ixdp425_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c index 34efe75015ec..1f8717ba13dc 100644 --- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -42,10 +42,9 @@ static int __init ixdpg425_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci ixdpg425_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = ixdpg425_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = ixdpg425_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/miccpt-pci.c b/arch/arm/mach-ixp4xx/miccpt-pci.c index ca0bae7fca90..d114ccd2017c 100644 --- a/arch/arm/mach-ixp4xx/miccpt-pci.c +++ b/arch/arm/mach-ixp4xx/miccpt-pci.c @@ -61,10 +61,9 @@ static int __init miccpt_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci miccpt_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = miccpt_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = miccpt_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c index 5434ccf553eb..8f0eba0a6800 100644 --- a/arch/arm/mach-ixp4xx/nas100d-pci.c +++ b/arch/arm/mach-ixp4xx/nas100d-pci.c @@ -58,10 +58,9 @@ static int __init nas100d_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci __initdata nas100d_pci = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = nas100d_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = nas100d_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c index b57160535e47..032defe111aa 100644 --- a/arch/arm/mach-ixp4xx/nslu2-pci.c +++ b/arch/arm/mach-ixp4xx/nslu2-pci.c @@ -54,10 +54,9 @@ static int __init nslu2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci __initdata nslu2_pci = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = nslu2_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = nslu2_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c index 0bc3f34c282f..a4220fa5e0c3 100644 --- a/arch/arm/mach-ixp4xx/vulcan-pci.c +++ b/arch/arm/mach-ixp4xx/vulcan-pci.c @@ -56,10 +56,9 @@ static int __init vulcan_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci vulcan_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = vulcan_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = vulcan_map_irq, }; diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c index f27dfcfe811b..c92e5b82af36 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-pci.c +++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c @@ -46,10 +46,9 @@ static int __init wg302v2_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) struct hw_pci wg302v2_pci __initdata = { .nr_controllers = 1, + .ops = &ixp4xx_ops, .preinit = wg302v2_pci_preinit, - .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, .map_irq = wg302v2_map_irq, }; diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index f56a0118c1bb..de373176ee67 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -44,12 +44,6 @@ struct pcie_port { static int pcie_port_map[2]; static int num_pcie_ports; -static inline struct pcie_port *bus_to_port(struct pci_bus *bus) -{ - struct pci_sys_data *sys = bus->sysdata; - return sys->private_data; -} - static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* @@ -79,7 +73,8 @@ static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pcie_port *pp = bus_to_port(bus); + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; @@ -98,7 +93,8 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pcie_port *pp = bus_to_port(bus); + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; @@ -248,13 +244,13 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int __init kirkwood_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct pcie_port *pp = bus_to_port(dev->bus); + struct pci_sys_data *sys = dev->sysdata; + struct pcie_port *pp = sys->private_data; return pp->irq; } static struct hw_pci kirkwood_pci __initdata = { - .swizzle = pci_std_swizzle, .setup = kirkwood_pcie_setup, .scan = kirkwood_pcie_scan_bus, .map_irq = kirkwood_pcie_map_irq, diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index acc701435817..bb18193b4bac 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c @@ -141,12 +141,6 @@ static struct pci_ops ks8695_pci_ops = { .write = ks8695_pci_writeconfig, }; -static struct pci_bus* __init ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &ks8695_pci_ops, sys, - &sys->resources); -} - static struct resource pci_mem = { .name = "PCI Memory space", .start = KS8695_PCIMEM_PA, @@ -302,11 +296,10 @@ static void ks8695_show_pciregs(void) static struct hw_pci ks8695_pci __initdata = { .nr_controllers = 1, + .ops = &ks8695_pci_ops, .preinit = ks8695_pci_preinit, .setup = ks8695_pci_setup, - .scan = ks8695_pci_scan_bus, .postinit = NULL, - .swizzle = pci_std_swizzle, .map_irq = NULL, }; diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index df3e38055a24..2e56e86b6d68 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -147,6 +147,7 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) return 0; pp = &pcie_port[nr]; + sys->private_data = pp; pp->root_bus_nr = sys->busnr; /* @@ -161,19 +162,6 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -static struct pcie_port *bus_to_port(int bus) -{ - int i; - - for (i = num_pcie_ports - 1; i >= 0; i--) { - int rbus = pcie_port[i].root_bus_nr; - if (rbus != -1 && rbus <= bus) - break; - } - - return i >= 0 ? pcie_port + i : NULL; -} - static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) { /* @@ -189,7 +177,8 @@ static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pcie_port *pp = bus_to_port(bus->number); + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; @@ -208,7 +197,8 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pcie_port *pp = bus_to_port(bus->number); + struct pci_sys_data *sys = bus->sysdata; + struct pcie_port *pp = sys->private_data; unsigned long flags; int ret; @@ -263,7 +253,8 @@ mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - struct pcie_port *pp = bus_to_port(dev->bus->number); + struct pci_sys_data *sys = dev->bus->sysdata; + struct pcie_port *pp = sys->private_data; return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min; } @@ -271,7 +262,6 @@ static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci mv78xx0_pci __initdata = { .nr_controllers = 8, .preinit = mv78xx0_pcie_preinit, - .swizzle = pci_std_swizzle, .setup = mv78xx0_pcie_setup, .scan = mv78xx0_pcie_scan_bus, .map_irq = mv78xx0_pcie_map_irq, diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h index 4d1329d59287..9acdd6387047 100644 --- a/arch/arm/mach-mxs/devices-mx23.h +++ b/arch/arm/mach-mxs/devices-mx23.h @@ -11,10 +11,16 @@ #include <mach/mx23.h> #include <mach/devices-common.h> #include <mach/mxsfb.h> +#include <linux/amba/bus.h> -extern const struct amba_device mx23_duart_device __initconst; -#define mx23_add_duart() \ - mxs_add_duart(&mx23_duart_device) +static inline int mx23_add_duart(void) +{ + struct amba_device *d; + + d = amba_ahb_device_add(NULL, "duart", MX23_DUART_BASE_ADDR, SZ_8K, + MX23_INT_DUART, 0, 0, 0); + return IS_ERR(d) ? PTR_ERR(d) : 0; +} extern const struct mxs_auart_data mx23_auart_data[] __initconst; #define mx23_add_auart(id) mxs_add_auart(&mx23_auart_data[id]) diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h index 9dbeae130842..84b2960df117 100644 --- a/arch/arm/mach-mxs/devices-mx28.h +++ b/arch/arm/mach-mxs/devices-mx28.h @@ -11,10 +11,16 @@ #include <mach/mx28.h> #include <mach/devices-common.h> #include <mach/mxsfb.h> +#include <linux/amba/bus.h> -extern const struct amba_device mx28_duart_device __initconst; -#define mx28_add_duart() \ - mxs_add_duart(&mx28_duart_device) +static inline int mx28_add_duart(void) +{ + struct amba_device *d; + + d = amba_ahb_device_add(NULL, "duart", MX28_DUART_BASE_ADDR, SZ_8K, + MX28_INT_DUART, 0, 0, 0); + return IS_ERR(d) ? PTR_ERR(d) : 0; +} extern const struct mxs_auart_data mx28_auart_data[] __initconst; #define mx28_add_auart(id) mxs_add_auart(&mx28_auart_data[id]) diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c index 01faffec3064..cf50b5a66dda 100644 --- a/arch/arm/mach-mxs/devices.c +++ b/arch/arm/mach-mxs/devices.c @@ -75,22 +75,6 @@ err: return pdev; } -int __init mxs_add_amba_device(const struct amba_device *dev) -{ - struct amba_device *adev = amba_device_alloc(dev->dev.init_name, - dev->res.start, resource_size(&dev->res)); - - if (!adev) { - pr_err("%s: failed to allocate memory", __func__); - return -ENOMEM; - } - - adev->irq[0] = dev->irq[0]; - adev->irq[1] = dev->irq[1]; - - return amba_device_add(adev, &iomem_resource); -} - struct device mxs_apbh_bus = { .init_name = "mxs_apbh", .parent = &platform_bus, diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile index c8f5c9541a30..5f72d9787444 100644 --- a/arch/arm/mach-mxs/devices/Makefile +++ b/arch/arm/mach-mxs/devices/Makefile @@ -1,4 +1,3 @@ -obj-$(CONFIG_MXS_HAVE_AMBA_DUART) += amba-duart.o obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o obj-y += platform-dma.o obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c deleted file mode 100644 index a5479f766046..000000000000 --- a/arch/arm/mach-mxs/devices/amba-duart.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2009-2010 Pengutronix - * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> - * - * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License version 2 as published by the - * Free Software Foundation. - */ -#include <asm/irq.h> -#include <mach/mx23.h> -#include <mach/mx28.h> -#include <mach/devices-common.h> - -#define MXS_AMBA_DUART_DEVICE(name, soc) \ -const struct amba_device name##_device __initconst = { \ - .dev = { \ - .init_name = "duart", \ - }, \ - .res = { \ - .start = soc ## _DUART_BASE_ADDR, \ - .end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - .irq = {soc ## _INT_DUART}, \ -} - -#ifdef CONFIG_SOC_IMX23 -MXS_AMBA_DUART_DEVICE(mx23_duart, MX23); -#endif - -#ifdef CONFIG_SOC_IMX28 -MXS_AMBA_DUART_DEVICE(mx28_duart, MX28); -#endif - -int __init mxs_add_duart(const struct amba_device *dev) -{ - return mxs_add_amba_device(dev); -} diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index f2e383955d88..21e45a70d344 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h @@ -27,11 +27,6 @@ static inline struct platform_device *mxs_add_platform_device( name, id, res, num_resources, data, size_data, 0); } -int __init mxs_add_amba_device(const struct amba_device *dev); - -/* duart */ -int __init mxs_add_duart(const struct amba_device *dev); - /* auart */ struct mxs_auart_data { int id; diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index e52108c9aaea..49a3fd630313 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -265,7 +265,6 @@ static int __init db88f5281_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci db88f5281_pci __initdata = { .nr_controllers = 2, .preinit = db88f5281_pci_preinit, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = db88f5281_pci_map_irq, diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index c3ed15b8ea25..8c06ccac44c2 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -86,7 +86,6 @@ static int __init dns323_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci dns323_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = dns323_pci_map_irq, diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index 47587b832842..1e458efafb9a 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -138,7 +138,6 @@ static int __init kurobox_pro_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci kurobox_pro_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = kurobox_pro_pci_map_irq, diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c index 65faaa34de61..1c16d045333e 100644 --- a/arch/arm/mach-orion5x/mss2-setup.c +++ b/arch/arm/mach-orion5x/mss2-setup.c @@ -89,7 +89,6 @@ static int __init mss2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci mss2_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = mss2_pci_map_irq, diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c index 292038fc59fd..78a6a11d8216 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c @@ -149,7 +149,6 @@ rd88f5181l_fxo_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci rd88f5181l_fxo_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = rd88f5181l_fxo_pci_map_irq, diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c index c44eabaabc16..2f5dc54cd4cd 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c @@ -161,7 +161,6 @@ rd88f5181l_ge_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci rd88f5181l_ge_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = rd88f5181l_ge_pci_map_irq, diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c index e3ce61711478..399130fac0b6 100644 --- a/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/arch/arm/mach-orion5x/rd88f5182-setup.c @@ -200,7 +200,6 @@ static int __init rd88f5182_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci rd88f5182_pci __initdata = { .nr_controllers = 2, .preinit = rd88f5182_pci_preinit, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = rd88f5182_pci_map_irq, diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c index 2c5fab00d205..e91bf0ba4e8e 100644 --- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c @@ -102,7 +102,6 @@ static void __init rd88f6183ap_ge_init(void) static struct hw_pci rd88f6183ap_ge_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = orion5x_pci_map_irq, diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c index 632a861ef82b..90e571dc4deb 100644 --- a/arch/arm/mach-orion5x/terastation_pro2-setup.c +++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c @@ -122,7 +122,6 @@ static int __init tsp2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static struct hw_pci tsp2_pci __initdata = { .nr_controllers = 2, .preinit = tsp2_pci_preinit, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = tsp2_pci_map_irq, diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 5d6408745582..b184f680e0db 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -170,7 +170,6 @@ static int __init qnap_ts209_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci qnap_ts209_pci __initdata = { .nr_controllers = 2, .preinit = qnap_ts209_pci_preinit, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = qnap_ts209_pci_map_irq, diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c index 4e6ff759cd32..a5c2e64c4ece 100644 --- a/arch/arm/mach-orion5x/ts409-setup.c +++ b/arch/arm/mach-orion5x/ts409-setup.c @@ -140,7 +140,6 @@ static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci qnap_ts409_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = qnap_ts409_pci_map_irq, diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c index 078c03f7cd52..754c12b6abf0 100644 --- a/arch/arm/mach-orion5x/wnr854t-setup.c +++ b/arch/arm/mach-orion5x/wnr854t-setup.c @@ -155,7 +155,6 @@ static int __init wnr854t_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci wnr854t_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = wnr854t_pci_map_irq, diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c index 46a9778171ce..45c21251eb1e 100644 --- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -243,7 +243,6 @@ static int __init wrt350n_v2_pci_map_irq(const struct pci_dev *dev, u8 slot, static struct hw_pci wrt350n_v2_pci __initdata = { .nr_controllers = 2, - .swizzle = pci_std_swizzle, .setup = orion5x_pci_sys_setup, .scan = orion5x_pci_sys_scan_bus, .map_irq = wrt350n_v2_pci_map_irq, diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c index ebd9259f5ac9..d8f816c24a2f 100644 --- a/arch/arm/mach-pxa/cm-x2xx-pci.c +++ b/arch/arm/mach-pxa/cm-x2xx-pci.c @@ -181,11 +181,10 @@ static void cmx2xx_pci_preinit(void) } static struct hw_pci cmx2xx_pci __initdata = { - .swizzle = pci_std_swizzle, .map_irq = cmx2xx_pci_map_irq, .nr_controllers = 1, + .ops = &it8152_ops, .setup = it8152_pci_setup, - .scan = it8152_pci_scan_bus, .preinit = cmx2xx_pci_preinit, }; diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index b49108b890a8..ff02e2da99f2 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c @@ -129,12 +129,6 @@ static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot, return NANOENGINE_IRQ_GPIO_PCI; } -struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &pci_nano_ops, sys, - &sys->resources); -} - static struct resource pci_io_ports = DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO"); @@ -274,7 +268,7 @@ int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys) static struct hw_pci nanoengine_pci __initdata = { .map_irq = pci_nanoengine_map_irq, .nr_controllers = 1, - .scan = pci_nanoengine_scan_bus, + .ops = &pci_nano_ops, .setup = pci_nanoengine_setup, }; diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c index 7cb79a092f31..9089407d5326 100644 --- a/arch/arm/mach-shark/pci.c +++ b/arch/arm/mach-shark/pci.c @@ -29,10 +29,9 @@ extern void __init via82c505_preinit(void); static struct hw_pci shark_pci __initdata = { .setup = via82c505_setup, - .swizzle = pci_std_swizzle, .map_irq = shark_map_irq, .nr_controllers = 1, - .scan = via82c505_scan_bus, + .ops = &via82c505_ops, .preinit = via82c505_preinit, }; diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index 54a816ff3847..0e09137506ec 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -475,7 +475,6 @@ static struct hw_pci tegra_pcie_hw __initdata = { .nr_controllers = 2, .setup = tegra_pcie_setup, .scan = tegra_pcie_scan_bus, - .swizzle = pci_std_swizzle, .map_irq = tegra_pcie_map_irq, }; diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index c5312a4b49f5..dfdd4a54668d 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -11,7 +11,6 @@ #include <linux/irq.h> #include <linux/slab.h> #include <linux/platform_device.h> -#include <linux/amba/bus.h> #include <plat/gpio-nomadik.h> @@ -19,38 +18,6 @@ #include "devices-common.h" -struct amba_device * -dbx500_add_amba_device(struct device *parent, const char *name, - resource_size_t base, int irq, void *pdata, - unsigned int periphid) -{ - struct amba_device *dev; - int ret; - - dev = amba_device_alloc(name, base, SZ_4K); - if (!dev) - return ERR_PTR(-ENOMEM); - - dev->dma_mask = DMA_BIT_MASK(32); - dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - - dev->irq[0] = irq; - - dev->periphid = periphid; - - dev->dev.platform_data = pdata; - - dev->dev.parent = parent; - - ret = amba_device_add(dev, &iomem_resource); - if (ret) { - amba_device_put(dev); - return ERR_PTR(ret); - } - - return dev; -} - static struct platform_device * dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index 39c74ec82add..f75bcb2ab13b 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h @@ -11,13 +11,9 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/sys_soc.h> +#include <linux/amba/bus.h> #include <plat/i2c.h> -extern struct amba_device * -dbx500_add_amba_device(struct device *parent, const char *name, - resource_size_t base, int irq, void *pdata, - unsigned int periphid); - struct spi_master_cntlr; static inline struct amba_device * @@ -25,8 +21,8 @@ dbx500_add_msp_spi(struct device *parent, const char *name, resource_size_t base, int irq, struct spi_master_cntlr *pdata) { - return dbx500_add_amba_device(parent, name, base, irq, - pdata, 0); + return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, + pdata, 0); } static inline struct amba_device * @@ -34,8 +30,8 @@ dbx500_add_spi(struct device *parent, const char *name, resource_size_t base, int irq, struct spi_master_cntlr *pdata, u32 periphid) { - return dbx500_add_amba_device(parent, name, base, irq, - pdata, periphid); + return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, + pdata, periphid); } struct mmci_platform_data; @@ -44,8 +40,8 @@ static inline struct amba_device * dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base, int irq, struct mmci_platform_data *pdata, u32 periphid) { - return dbx500_add_amba_device(parent, name, base, irq, - pdata, periphid); + return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, + pdata, periphid); } struct amba_pl011_data; @@ -54,7 +50,7 @@ static inline struct amba_device * dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, int irq, struct amba_pl011_data *pdata) { - return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); + return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0); } struct nmk_i2c_controller; @@ -85,7 +81,8 @@ dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, static inline struct amba_device * dbx500_add_rtc(struct device *parent, resource_size_t base, int irq) { - return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0); + return amba_apb_device_add(parent, "rtc-pl031", base, SZ_4K, irq, + 0, NULL, 0); } struct nmk_gpio_platform_data; diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index 9fd93e9da529..6fc7eb24d9a0 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -31,7 +31,7 @@ static inline struct amba_device * db8500_add_ssp(struct device *parent, const char *name, resource_size_t base, int irq, struct pl022_ssp_controller *pdata) { - return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); + return amba_ahb_device_add(parent, name, base, SZ_4K, irq, 0, pdata, 0); } diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index d2268be8c34c..15c6a00000ec 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -303,12 +303,6 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) } -struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &pci_versatile_ops, sys, - &sys->resources); -} - void __init pci_versatile_preinit(void) { pcibios_min_io = 0x44000000; @@ -339,19 +333,16 @@ static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) * 26 1 29 * 27 1 30 */ - irq = 27 + ((slot + pin - 1) & 3); - - printk("PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq); + irq = 27 + ((slot - 24 + pin - 1) & 3); return irq; } static struct hw_pci versatile_pci __initdata = { - .swizzle = NULL, .map_irq = versatile_map_irq, .nr_controllers = 1, + .ops = &pci_versatile_ops, .setup = pci_versatile_setup, - .scan = pci_versatile_scan_bus, .preinit = pci_versatile_preinit, }; diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 47cdcca5a7e7..04dd092211b8 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -19,8 +19,10 @@ #include <linux/clkdev.h> #include <linux/mtd/physmap.h> +#include <asm/arch_timer.h> #include <asm/mach-types.h> #include <asm/sizes.h> +#include <asm/smp_twd.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> @@ -616,7 +618,6 @@ void __init v2m_dt_init_early(void) } clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups)); - versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); } static struct of_device_id vexpress_irq_match[] __initdata = { @@ -643,6 +644,11 @@ static void __init v2m_dt_timer_init(void) return; node = of_find_node_by_path(path); v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0)); + if (arch_timer_of_register() != 0) + twd_local_timer_of_register(); + + if (arch_timer_sched_clock_init() != 0) + versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); } static struct sys_timer v2m_dt_timer = { diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index ff1f7cc11f87..80741992a9fc 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -26,18 +26,23 @@ ENTRY(v6_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR /* - * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103). - * The test below covers all the write situations, including Java bytecodes + * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR. */ - bic r1, r1, #1 << 11 @ clear bit 11 of FSR +#ifdef CONFIG_ARM_ERRATA_326103 + ldr ip, =0x4107b36 + mrc p15, 0, r3, c0, c0, 0 @ get processor id + teq ip, r3, lsr #4 @ r0 ARM1136? + bne do_DataAbort tst r5, #PSR_J_BIT @ Java? + tsteq r5, #PSR_T_BIT @ Thumb? bne do_DataAbort - do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 - ldreq r3, [r4] @ read aborted ARM instruction + bic r1, r1, #1 << 11 @ clear bit 11 of FSR + ldr r3, [r4] @ read aborted ARM instruction #ifdef CONFIG_CPU_ENDIAN_BE8 - reveq r3, r3 + rev r3, r3 #endif do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes. +#endif b do_DataAbort diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index a53fd2aaa2f4..2a8e380501e8 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -32,6 +32,7 @@ static void __iomem *l2x0_base; static DEFINE_RAW_SPINLOCK(l2x0_lock); static u32 l2x0_way_mask; /* Bitmask of active ways */ static u32 l2x0_size; +static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; struct l2x0_regs l2x0_saved_regs; @@ -61,12 +62,7 @@ static inline void cache_sync(void) { void __iomem *base = l2x0_base; -#ifdef CONFIG_PL310_ERRATA_753970 - /* write to an unmmapped register */ - writel_relaxed(0, base + L2X0_DUMMY_REG); -#else - writel_relaxed(0, base + L2X0_CACHE_SYNC); -#endif + writel_relaxed(0, base + sync_reg_offset); cache_wait(base + L2X0_CACHE_SYNC, 1); } @@ -85,10 +81,13 @@ static inline void l2x0_inv_line(unsigned long addr) } #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) +static inline void debug_writel(unsigned long val) +{ + if (outer_cache.set_debug) + outer_cache.set_debug(val); +} -#define debug_writel(val) outer_cache.set_debug(val) - -static void l2x0_set_debug(unsigned long val) +static void pl310_set_debug(unsigned long val) { writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); } @@ -98,7 +97,7 @@ static inline void debug_writel(unsigned long val) { } -#define l2x0_set_debug NULL +#define pl310_set_debug NULL #endif #ifdef CONFIG_PL310_ERRATA_588369 @@ -331,6 +330,11 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) else ways = 8; type = "L310"; +#ifdef CONFIG_PL310_ERRATA_753970 + /* Unmapped register. */ + sync_reg_offset = L2X0_DUMMY_REG; +#endif + outer_cache.set_debug = pl310_set_debug; break; case L2X0_CACHE_ID_PART_L210: ways = (aux >> 13) & 0xf; @@ -379,7 +383,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) outer_cache.flush_all = l2x0_flush_all; outer_cache.inv_all = l2x0_inv_all; outer_cache.disable = l2x0_disable; - outer_cache.set_debug = l2x0_set_debug; printk(KERN_INFO "%s cache controller enabled\n", type); printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index ee9bb363d606..806cc4f63516 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -18,30 +18,39 @@ static DEFINE_RAW_SPINLOCK(cpu_asid_lock); unsigned int cpu_last_asid = ASID_FIRST_VERSION; -#ifdef CONFIG_SMP -DEFINE_PER_CPU(struct mm_struct *, current_mm); -#endif #ifdef CONFIG_ARM_LPAE -#define cpu_set_asid(asid) { \ - unsigned long ttbl, ttbh; \ - asm volatile( \ - " mrrc p15, 0, %0, %1, c2 @ read TTBR0\n" \ - " mov %1, %2, lsl #(48 - 32) @ set ASID\n" \ - " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n" \ - : "=&r" (ttbl), "=&r" (ttbh) \ - : "r" (asid & ~ASID_MASK)); \ +void cpu_set_reserved_ttbr0(void) +{ + unsigned long ttbl = __pa(swapper_pg_dir); + unsigned long ttbh = 0; + + /* + * Set TTBR0 to swapper_pg_dir which contains only global entries. The + * ASID is set to 0. + */ + asm volatile( + " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n" + : + : "r" (ttbl), "r" (ttbh)); + isb(); } #else -#define cpu_set_asid(asid) \ - asm(" mcr p15, 0, %0, c13, c0, 1\n" : : "r" (asid)) +void cpu_set_reserved_ttbr0(void) +{ + u32 ttb; + /* Copy TTBR1 into TTBR0 */ + asm volatile( + " mrc p15, 0, %0, c2, c0, 1 @ read TTBR1\n" + " mcr p15, 0, %0, c2, c0, 0 @ set TTBR0\n" + : "=r" (ttb)); + isb(); +} #endif /* * We fork()ed a process, and we need a new context for the child - * to run in. We reserve version 0 for initial tasks so we will - * always allocate an ASID. The ASID 0 is reserved for the TTBR - * register changing sequence. + * to run in. */ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) { @@ -51,9 +60,7 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) static void flush_context(void) { - /* set the reserved ASID before flushing the TLB */ - cpu_set_asid(0); - isb(); + cpu_set_reserved_ttbr0(); local_flush_tlb_all(); if (icache_is_vivt_asid_tagged()) { __flush_icache_all(); @@ -98,14 +105,7 @@ static void reset_context(void *info) { unsigned int asid; unsigned int cpu = smp_processor_id(); - struct mm_struct *mm = per_cpu(current_mm, cpu); - - /* - * Check if a current_mm was set on this CPU as it might still - * be in the early booting stages and using the reserved ASID. - */ - if (!mm) - return; + struct mm_struct *mm = current->active_mm; smp_rmb(); asid = cpu_last_asid + cpu + 1; @@ -114,8 +114,7 @@ static void reset_context(void *info) set_mm_context(mm, asid); /* set the new ASID */ - cpu_set_asid(mm->context.id); - isb(); + cpu_switch_mm(mm->pgd, mm); } #else diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index f07467533365..5bb48356d217 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -247,7 +247,9 @@ good_area: return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); check_stack: - if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) + /* Don't allow expansion below FIRST_USER_ADDRESS */ + if (vma->vm_flags & VM_GROWSDOWN && + addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr)) goto good_area; out: return fault; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 595079fa9d1d..8f5813bbffb5 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -293,11 +293,11 @@ EXPORT_SYMBOL(pfn_valid); #endif #ifndef CONFIG_SPARSEMEM -static void arm_memory_present(void) +static void __init arm_memory_present(void) { } #else -static void arm_memory_present(void) +static void __init arm_memory_present(void) { struct memblock_region *reg; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index b86f8933ff91..aa78de8bfdd3 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -489,7 +489,8 @@ static void __init build_mem_type_table(void) */ for (i = 0; i < ARRAY_SIZE(mem_types); i++) { mem_types[i].prot_pte |= PTE_EXT_AF; - mem_types[i].prot_sect |= PMD_SECT_AF; + if (mem_types[i].prot_sect) + mem_types[i].prot_sect |= PMD_SECT_AF; } kern_pgprot |= PTE_EXT_AF; vecs_pgprot |= PTE_EXT_AF; @@ -618,8 +619,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr, } } -static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, - unsigned long phys, const struct mem_type *type) +static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, + unsigned long end, unsigned long phys, const struct mem_type *type) { pud_t *pud = pud_offset(pgd, addr); unsigned long next; diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S index 3a4b3e7b888c..42ac069c8012 100644 --- a/arch/arm/mm/proc-v7-2level.S +++ b/arch/arm/mm/proc-v7-2level.S @@ -49,15 +49,10 @@ ENTRY(cpu_v7_switch_mm) #ifdef CONFIG_ARM_ERRATA_754322 dsb #endif - mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID - isb -1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 - isb -#ifdef CONFIG_ARM_ERRATA_754322 - dsb -#endif mcr p15, 0, r1, c13, c0, 1 @ set context ID isb + mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 + isb #endif mov pc, lr ENDPROC(cpu_v7_switch_mm) diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index 0da42058a20f..8daae9b230ea 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -160,7 +160,7 @@ iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where, return PCIBIOS_SUCCESSFUL; } -static struct pci_ops iop3xx_ops = { +struct pci_ops iop3xx_ops = { .read = iop3xx_read_config, .write = iop3xx_write_config, }; @@ -220,12 +220,6 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) return 1; } -struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_root_bus(NULL, sys->busnr, &iop3xx_ops, sys, - &sys->resources); -} - void __init iop3xx_atu_setup(void) { /* BAR 0 ( Disabled ) */ diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index ecdb3da0dea9..c58d896cd5c3 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -916,6 +916,13 @@ void omap_start_dma(int lch) l |= OMAP_DMA_CCR_BUFFERING_DISABLE; l |= OMAP_DMA_CCR_EN; + /* + * As dma_write() uses IO accessors which are weakly ordered, there + * is no guarantee that data in coherent DMA memory will be visible + * to the DMA device. Add a memory barrier here to ensure that any + * such data is visible prior to enabling DMA. + */ + mb(); p->dma_write(l, CCR, lch); dma_chan[lch].flags |= OMAP_DMA_ACTIVE; @@ -965,6 +972,13 @@ void omap_stop_dma(int lch) p->dma_write(l, CCR, lch); } + /* + * Ensure that data transferred by DMA is visible to any access + * after DMA has been disabled. This is important for coherent + * DMA regions. + */ + mb(); + if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; char dma_chan_link_map[dma_lch_count]; diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index f9c9f33f8cbe..2997e56ce0dd 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -16,7 +16,7 @@ # are merged into mainline or have been edited in the machine database # within the last 12 months. References to machine_is_NAME() do not count! # -# Last update: Tue Dec 6 11:07:38 2011 +# Last update: Thu Apr 26 08:44:23 2012 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -205,6 +205,7 @@ omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970 snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986 omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993 smdk2412 MACH_SMDK2412 SMDK2412 1009 +bkde303 MACH_BKDE303 BKDE303 1021 smdk2413 MACH_SMDK2413 SMDK2413 1022 aml_m5900 MACH_AML_M5900 AML_M5900 1024 balloon3 MACH_BALLOON3 BALLOON3 1029 @@ -381,8 +382,6 @@ davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157 at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159 omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160 magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162 -btmavb101 MACH_BTMAVB101 BTMAVB101 2172 -btmawb101 MACH_BTMAWB101 BTMAWB101 2173 tx25 MACH_TX25 TX25 2177 omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178 anw6410 MACH_ANW6410 ANW6410 2183 @@ -397,7 +396,6 @@ net2big_v2 MACH_NET2BIG_V2 NET2BIG_V2 2204 net5big_v2 MACH_NET5BIG_V2 NET5BIG_V2 2206 inetspace_v2 MACH_INETSPACE_V2 INETSPACE_V2 2208 at91sam9g45ekes MACH_AT91SAM9G45EKES AT91SAM9G45EKES 2212 -pc7302 MACH_PC7302 PC7302 2220 spear600 MACH_SPEAR600 SPEAR600 2236 spear300 MACH_SPEAR300 SPEAR300 2237 lilly1131 MACH_LILLY1131 LILLY1131 2239 @@ -407,7 +405,6 @@ d2net MACH_D2NET D2NET 2282 bigdisk MACH_BIGDISK BIGDISK 2283 at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288 bcmring MACH_BCMRING BCMRING 2289 -dp6xx MACH_DP6XX DP6XX 2302 mahimahi MACH_MAHIMAHI MAHIMAHI 2304 smdk6442 MACH_SMDK6442 SMDK6442 2324 openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325 @@ -444,8 +441,6 @@ mx28evk MACH_MX28EVK MX28EVK 2531 smartq5 MACH_SMARTQ5 SMARTQ5 2534 davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548 mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 -riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576 -riot_x37 MACH_RIOT_X37 RIOT_X37 2578 pca101 MACH_PCA101 PCA101 2595 capc7117 MACH_CAPC7117 CAPC7117 2612 icontrol MACH_ICONTROL ICONTROL 2624 @@ -460,7 +455,6 @@ spear320 MACH_SPEAR320 SPEAR320 2661 aquila MACH_AQUILA AQUILA 2676 esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678 msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679 -ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683 terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697 msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703 msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704 @@ -479,8 +473,6 @@ wbd222 MACH_WBD222 WBD222 2753 msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755 msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756 tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758 -nanos MACH_NANOS NANOS 2759 -stamp9g45 MACH_STAMP9G45 STAMP9G45 2761 cns3420vb MACH_CNS3420VB CNS3420VB 2776 omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791 ti8168evm MACH_TI8168EVM TI8168EVM 2800 @@ -490,12 +482,9 @@ eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821 eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822 eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823 smdkc210 MACH_SMDKC210 SMDKC210 2838 -pca102 MACH_PCA102 PCA102 2843 +pcaal1 MACH_PCAAL1 PCAAL1 2843 t5325 MACH_T5325 T5325 2846 income MACH_INCOME INCOME 2849 -vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2 2857 -vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2 2858 -vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859 mx257sx MACH_MX257SX MX257SX 2861 goni MACH_GONI GONI 2862 bv07 MACH_BV07 BV07 2882 @@ -504,6 +493,7 @@ devixp MACH_DEVIXP DEVIXP 2885 miccpt MACH_MICCPT MICCPT 2886 mic256 MACH_MIC256 MIC256 2887 u5500 MACH_U5500 U5500 2890 +pov15hd MACH_POV15HD POV15HD 2910 linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913 smdkv310 MACH_SMDKV310 SMDKV310 2925 wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928 @@ -537,243 +527,24 @@ trimslice MACH_TRIMSLICE TRIMSLICE 3209 mackerel MACH_MACKEREL MACKEREL 3211 kaen MACH_KAEN KAEN 3217 nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 -dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 -quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 -abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 -svcid MACH_SVCID SVCID 3229 msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230 msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231 -icon_g MACH_ICON_G ICON_G 3232 -mb3 MACH_MB3 MB3 3233 gsia18s MACH_GSIA18S GSIA18S 3234 -pivicc MACH_PIVICC PIVICC 3235 -pcm048 MACH_PCM048 PCM048 3236 -dds MACH_DDS DDS 3237 -chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 -ts48xx MACH_TS48XX TS48XX 3239 -tonga2_tfttimer MACH_TONGA2_TFTTIMER TONGA2_TFTTIMER 3240 -whistler MACH_WHISTLER WHISTLER 3241 -asl_phoenix MACH_ASL_PHOENIX ASL_PHOENIX 3242 -at91sam9263otlite MACH_AT91SAM9263OTLITE AT91SAM9263OTLITE 3243 -ddplug MACH_DDPLUG DDPLUG 3244 -d2plug MACH_D2PLUG D2PLUG 3245 -kzm9d MACH_KZM9D KZM9D 3246 -verdi_lte MACH_VERDI_LTE VERDI_LTE 3247 -nanozoom MACH_NANOZOOM NANOZOOM 3248 -dm3730_som_lv MACH_DM3730_SOM_LV DM3730_SOM_LV 3249 -dm3730_torpedo MACH_DM3730_TORPEDO DM3730_TORPEDO 3250 -anchovy MACH_ANCHOVY ANCHOVY 3251 -re2rev20 MACH_RE2REV20 RE2REV20 3253 -re2rev21 MACH_RE2REV21 RE2REV21 3254 -cns21xx MACH_CNS21XX CNS21XX 3255 -rider MACH_RIDER RIDER 3257 -nsk330 MACH_NSK330 NSK330 3258 -cns2133evb MACH_CNS2133EVB CNS2133EVB 3259 -z3_816x_mod MACH_Z3_816X_MOD Z3_816X_MOD 3260 -z3_814x_mod MACH_Z3_814X_MOD Z3_814X_MOD 3261 -beect MACH_BEECT BEECT 3262 -dma_thunderbug MACH_DMA_THUNDERBUG DMA_THUNDERBUG 3263 -omn_at91sam9g20 MACH_OMN_AT91SAM9G20 OMN_AT91SAM9G20 3264 -mx25_e2s_uc MACH_MX25_E2S_UC MX25_E2S_UC 3265 -mione MACH_MIONE MIONE 3266 -top9000_tcu MACH_TOP9000_TCU TOP9000_TCU 3267 -top9000_bsl MACH_TOP9000_BSL TOP9000_BSL 3268 -kingdom MACH_KINGDOM KINGDOM 3269 -armadillo460 MACH_ARMADILLO460 ARMADILLO460 3270 -lq2 MACH_LQ2 LQ2 3271 -sweda_tms2 MACH_SWEDA_TMS2 SWEDA_TMS2 3272 mx53_loco MACH_MX53_LOCO MX53_LOCO 3273 -acer_a8 MACH_ACER_A8 ACER_A8 3275 -acer_gauguin MACH_ACER_GAUGUIN ACER_GAUGUIN 3276 -guppy MACH_GUPPY GUPPY 3277 -mx61_ard MACH_MX61_ARD MX61_ARD 3278 tx53 MACH_TX53 TX53 3279 -omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280 -uemd MACH_UEMD UEMD 3281 -ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282 -rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283 encore MACH_ENCORE ENCORE 3284 -hkdkc100 MACH_HKDKC100 HKDKC100 3285 -ts42xx MACH_TS42XX TS42XX 3286 -aebl MACH_AEBL AEBL 3287 wario MACH_WARIO WARIO 3288 -gfs_spm MACH_GFS_SPM GFS_SPM 3289 cm_t3730 MACH_CM_T3730 CM_T3730 3290 -isc3 MACH_ISC3 ISC3 3291 -rascal MACH_RASCAL RASCAL 3292 hrefv60 MACH_HREFV60 HREFV60 3293 -tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294 -splendor MACH_SPLENDOR SPLENDOR 3296 -msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298 -htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299 -athene MACH_ATHENE ATHENE 3300 -deep_r_ek_1 MACH_DEEP_R_EK_1 DEEP_R_EK_1 3301 -vivow_ct MACH_VIVOW_CT VIVOW_CT 3302 -nery_1000 MACH_NERY_1000 NERY_1000 3303 -rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304 -nmh MACH_NMH NMH 3305 -wn802t MACH_WN802T WN802T 3306 -dragonet MACH_DRAGONET DRAGONET 3307 -at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309 -bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310 -bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311 -koi MACH_KOI KOI 3312 -ts4800 MACH_TS4800 TS4800 3313 -tqma9263 MACH_TQMA9263 TQMA9263 3314 -holiday MACH_HOLIDAY HOLIDAY 3315 -pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317 -hwgw6410 MACH_HWGW6410 HWGW6410 3318 -shenzhou MACH_SHENZHOU SHENZHOU 3319 -cwme9210 MACH_CWME9210 CWME9210 3320 -cwme9210js MACH_CWME9210JS CWME9210JS 3321 -colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323 -w21 MACH_W21 W21 3324 -polysat1 MACH_POLYSAT1 POLYSAT1 3325 -dataway MACH_DATAWAY DATAWAY 3326 -cobral138 MACH_COBRAL138 COBRAL138 3327 -roverpcs8 MACH_ROVERPCS8 ROVERPCS8 3328 -marvelc MACH_MARVELC MARVELC 3329 -navefihid MACH_NAVEFIHID NAVEFIHID 3330 -dm365_cv100 MACH_DM365_CV100 DM365_CV100 3331 -able MACH_ABLE ABLE 3332 -legacy MACH_LEGACY LEGACY 3333 -icong MACH_ICONG ICONG 3334 -rover_g8 MACH_ROVER_G8 ROVER_G8 3335 -t5388p MACH_T5388P T5388P 3336 -dingo MACH_DINGO DINGO 3337 -goflexhome MACH_GOFLEXHOME GOFLEXHOME 3338 -lanreadyfn511 MACH_LANREADYFN511 LANREADYFN511 3340 -omap3_baia MACH_OMAP3_BAIA OMAP3_BAIA 3341 -omap3smartdisplay MACH_OMAP3SMARTDISPLAY OMAP3SMARTDISPLAY 3342 -xilinx MACH_XILINX XILINX 3343 -a2f MACH_A2F A2F 3344 -sky25 MACH_SKY25 SKY25 3345 -ccmx53 MACH_CCMX53 CCMX53 3346 -ccmx53js MACH_CCMX53JS CCMX53JS 3347 -ccwmx53 MACH_CCWMX53 CCWMX53 3348 -ccwmx53js MACH_CCWMX53JS CCWMX53JS 3349 -frisms MACH_FRISMS FRISMS 3350 -msm7x27a_ffa MACH_MSM7X27A_FFA MSM7X27A_FFA 3351 -msm7x27a_surf MACH_MSM7X27A_SURF MSM7X27A_SURF 3352 -msm7x27a_rumi3 MACH_MSM7X27A_RUMI3 MSM7X27A_RUMI3 3353 -dimmsam9g20 MACH_DIMMSAM9G20 DIMMSAM9G20 3354 -dimm_imx28 MACH_DIMM_IMX28 DIMM_IMX28 3355 -amk_a4 MACH_AMK_A4 AMK_A4 3356 -gnet_sgme MACH_GNET_SGME GNET_SGME 3357 -shooter_u MACH_SHOOTER_U SHOOTER_U 3358 -vmx53 MACH_VMX53 VMX53 3359 -rhino MACH_RHINO RHINO 3360 armlex4210 MACH_ARMLEX4210 ARMLEX4210 3361 -swarcoextmodem MACH_SWARCOEXTMODEM SWARCOEXTMODEM 3362 snowball MACH_SNOWBALL SNOWBALL 3363 -pcm049 MACH_PCM049 PCM049 3364 -vigor MACH_VIGOR VIGOR 3365 -oslo_amundsen MACH_OSLO_AMUNDSEN OSLO_AMUNDSEN 3366 -gsl_diamond MACH_GSL_DIAMOND GSL_DIAMOND 3367 -cv2201 MACH_CV2201 CV2201 3368 -cv2202 MACH_CV2202 CV2202 3369 -cv2203 MACH_CV2203 CV2203 3370 -vit_ibox MACH_VIT_IBOX VIT_IBOX 3371 -dm6441_esp MACH_DM6441_ESP DM6441_ESP 3372 -at91sam9x5ek MACH_AT91SAM9X5EK AT91SAM9X5EK 3373 -libra MACH_LIBRA LIBRA 3374 -easycrrh MACH_EASYCRRH EASYCRRH 3375 -tripel MACH_TRIPEL TRIPEL 3376 -endian_mini MACH_ENDIAN_MINI ENDIAN_MINI 3377 xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378 nuri MACH_NURI NURI 3379 -janus MACH_JANUS JANUS 3380 -ddnas MACH_DDNAS DDNAS 3381 -tag MACH_TAG TAG 3382 -tagw MACH_TAGW TAGW 3383 -nitrogen_vm_imx51 MACH_NITROGEN_VM_IMX51 NITROGEN_VM_IMX51 3384 -viprinet MACH_VIPRINET VIPRINET 3385 -bockw MACH_BOCKW BOCKW 3386 -eva2000 MACH_EVA2000 EVA2000 3387 -steelyard MACH_STEELYARD STEELYARD 3388 -nsslsboard MACH_NSSLSBOARD NSSLSBOARD 3392 -geneva_b5 MACH_GENEVA_B5 GENEVA_B5 3393 -spear1340 MACH_SPEAR1340 SPEAR1340 3394 -rexmas MACH_REXMAS REXMAS 3395 -msm8960_cdp MACH_MSM8960_CDP MSM8960_CDP 3396 -msm8960_fluid MACH_MSM8960_FLUID MSM8960_FLUID 3398 -msm8960_apq MACH_MSM8960_APQ MSM8960_APQ 3399 -helios_v2 MACH_HELIOS_V2 HELIOS_V2 3400 -mif10p MACH_MIF10P MIF10P 3401 -iam28 MACH_IAM28 IAM28 3402 -picasso MACH_PICASSO PICASSO 3403 -mr301a MACH_MR301A MR301A 3404 -notle MACH_NOTLE NOTLE 3405 -eelx2 MACH_EELX2 EELX2 3406 -moon MACH_MOON MOON 3407 -ruby MACH_RUBY RUBY 3408 -goldengate MACH_GOLDENGATE GOLDENGATE 3409 -ctbu_gen2 MACH_CTBU_GEN2 CTBU_GEN2 3410 -kmp_am17_01 MACH_KMP_AM17_01 KMP_AM17_01 3411 wtplug MACH_WTPLUG WTPLUG 3412 -mx27su2 MACH_MX27SU2 MX27SU2 3413 -nb31 MACH_NB31 NB31 3414 -hjsdu MACH_HJSDU HJSDU 3415 -td3_rev1 MACH_TD3_REV1 TD3_REV1 3416 -eag_ci4000 MACH_EAG_CI4000 EAG_CI4000 3417 -net5big_nand_v2 MACH_NET5BIG_NAND_V2 NET5BIG_NAND_V2 3418 -cpx2 MACH_CPX2 CPX2 3419 -net2big_nand_v2 MACH_NET2BIG_NAND_V2 NET2BIG_NAND_V2 3420 -ecuv5 MACH_ECUV5 ECUV5 3421 -hsgx6d MACH_HSGX6D HSGX6D 3422 -dawad7 MACH_DAWAD7 DAWAD7 3423 -sam9repeater MACH_SAM9REPEATER SAM9REPEATER 3424 -gt_i5700 MACH_GT_I5700 GT_I5700 3425 -ctera_plug_c2 MACH_CTERA_PLUG_C2 CTERA_PLUG_C2 3426 -marvelct MACH_MARVELCT MARVELCT 3427 -ag11005 MACH_AG11005 AG11005 3428 -vangogh MACH_VANGOGH VANGOGH 3430 -matrix505 MACH_MATRIX505 MATRIX505 3431 -oce_nigma MACH_OCE_NIGMA OCE_NIGMA 3432 -t55 MACH_T55 T55 3433 -bio3k MACH_BIO3K BIO3K 3434 -expressct MACH_EXPRESSCT EXPRESSCT 3435 -cardhu MACH_CARDHU CARDHU 3436 -aruba MACH_ARUBA ARUBA 3437 -bonaire MACH_BONAIRE BONAIRE 3438 -nuc700evb MACH_NUC700EVB NUC700EVB 3439 -nuc710evb MACH_NUC710EVB NUC710EVB 3440 -nuc740evb MACH_NUC740EVB NUC740EVB 3441 -nuc745evb MACH_NUC745EVB NUC745EVB 3442 -transcede MACH_TRANSCEDE TRANSCEDE 3443 -mora MACH_MORA MORA 3444 -nda_evm MACH_NDA_EVM NDA_EVM 3445 -timu MACH_TIMU TIMU 3446 -expressh MACH_EXPRESSH EXPRESSH 3447 veridis_a300 MACH_VERIDIS_A300 VERIDIS_A300 3448 -dm368_leopard MACH_DM368_LEOPARD DM368_LEOPARD 3449 -omap_mcop MACH_OMAP_MCOP OMAP_MCOP 3450 -tritip MACH_TRITIP TRITIP 3451 -sm1k MACH_SM1K SM1K 3452 -monch MACH_MONCH MONCH 3453 -curacao MACH_CURACAO CURACAO 3454 origen MACH_ORIGEN ORIGEN 3455 -epc10 MACH_EPC10 EPC10 3456 -sgh_i740 MACH_SGH_I740 SGH_I740 3457 -tuna MACH_TUNA TUNA 3458 -mx51_tulip MACH_MX51_TULIP MX51_TULIP 3459 -mx51_aster7 MACH_MX51_ASTER7 MX51_ASTER7 3460 -acro37xbrd MACH_ACRO37XBRD ACRO37XBRD 3461 -elke MACH_ELKE ELKE 3462 -sbc6000x MACH_SBC6000X SBC6000X 3463 -r1801e MACH_R1801E R1801E 3464 -h1600 MACH_H1600 H1600 3465 -mini210 MACH_MINI210 MINI210 3466 -mini8168 MACH_MINI8168 MINI8168 3467 -pc7308 MACH_PC7308 PC7308 3468 -kmm2m01 MACH_KMM2M01 KMM2M01 3470 -mx51erebus MACH_MX51EREBUS MX51EREBUS 3471 wm8650refboard MACH_WM8650REFBOARD WM8650REFBOARD 3472 -tuxrail MACH_TUXRAIL TUXRAIL 3473 -arthur MACH_ARTHUR ARTHUR 3474 -doorboy MACH_DOORBOY DOORBOY 3475 xarina MACH_XARINA XARINA 3476 -roverx7 MACH_ROVERX7 ROVERX7 3477 sdvr MACH_SDVR SDVR 3478 acer_maya MACH_ACER_MAYA ACER_MAYA 3479 pico MACH_PICO PICO 3480 @@ -999,6 +770,7 @@ promwad_jade MACH_PROMWAD_JADE PROMWAD_JADE 3708 amp MACH_AMP AMP 3709 gnet_amp MACH_GNET_AMP GNET_AMP 3710 toques MACH_TOQUES TOQUES 3711 +apx4devkit MACH_APX4DEVKIT APX4DEVKIT 3712 dct_storm MACH_DCT_STORM DCT_STORM 3713 owl MACH_OWL OWL 3715 cogent_csb1741 MACH_COGENT_CSB1741 COGENT_CSB1741 3716 @@ -1063,7 +835,6 @@ shelter MACH_SHELTER SHELTER 3778 omap3_devkit8500 MACH_OMAP3_DEVKIT8500 OMAP3_DEVKIT8500 3779 edgetd MACH_EDGETD EDGETD 3780 copperyard MACH_COPPERYARD COPPERYARD 3781 -edge MACH_EDGE EDGE 3782 edge_u MACH_EDGE_U EDGE_U 3783 edge_td MACH_EDGE_TD EDGE_TD 3784 wdss MACH_WDSS WDSS 3785 @@ -1169,3 +940,269 @@ elite_ulk MACH_ELITE_ULK ELITE_ULK 3888 pov2 MACH_POV2 POV2 3889 ipod_touch_2g MACH_IPOD_TOUCH_2G IPOD_TOUCH_2G 3890 da850_pqab MACH_DA850_PQAB DA850_PQAB 3891 +fermi MACH_FERMI FERMI 3892 +ccardwmx28 MACH_CCARDWMX28 CCARDWMX28 3893 +ccardmx28 MACH_CCARDMX28 CCARDMX28 3894 +fs20_fcm2050 MACH_FS20_FCM2050 FS20_FCM2050 3895 +kinetis MACH_KINETIS KINETIS 3896 +kai MACH_KAI KAI 3897 +bcthb2 MACH_BCTHB2 BCTHB2 3898 +inels3_cu MACH_INELS3_CU INELS3_CU 3899 +da850_apollo MACH_DA850_APOLLO DA850_APOLLO 3901 +tracnas MACH_TRACNAS TRACNAS 3902 +mityarm335x MACH_MITYARM335X MITYARM335X 3903 +xcgz7x MACH_XCGZ7X XCGZ7X 3904 +cubox MACH_CUBOX CUBOX 3905 +terminator MACH_TERMINATOR TERMINATOR 3906 +eye03 MACH_EYE03 EYE03 3907 +kota3 MACH_KOTA3 KOTA3 3908 +pscpe MACH_PSCPE PSCPE 3910 +akt1100 MACH_AKT1100 AKT1100 3911 +pcaaxl2 MACH_PCAAXL2 PCAAXL2 3912 +primodd_ct MACH_PRIMODD_CT PRIMODD_CT 3913 +nsbc MACH_NSBC NSBC 3914 +meson2_skt MACH_MESON2_SKT MESON2_SKT 3915 +meson2_ref MACH_MESON2_REF MESON2_REF 3916 +ccardwmx28js MACH_CCARDWMX28JS CCARDWMX28JS 3917 +ccardmx28js MACH_CCARDMX28JS CCARDMX28JS 3918 +indico MACH_INDICO INDICO 3919 +msm8960dt MACH_MSM8960DT MSM8960DT 3920 +primods MACH_PRIMODS PRIMODS 3921 +beluga_m1388 MACH_BELUGA_M1388 BELUGA_M1388 3922 +primotd MACH_PRIMOTD PRIMOTD 3923 +varan_master MACH_VARAN_MASTER VARAN_MASTER 3924 +primodd MACH_PRIMODD PRIMODD 3925 +jetduo MACH_JETDUO JETDUO 3926 +mx53_umobo MACH_MX53_UMOBO MX53_UMOBO 3927 +trats MACH_TRATS TRATS 3928 +starcraft MACH_STARCRAFT STARCRAFT 3929 +qseven_tegra2 MACH_QSEVEN_TEGRA2 QSEVEN_TEGRA2 3930 +lichee_sun4i_devbd MACH_LICHEE_SUN4I_DEVBD LICHEE_SUN4I_DEVBD 3931 +movenow MACH_MOVENOW MOVENOW 3932 +golf_u MACH_GOLF_U GOLF_U 3933 +msm7627a_evb MACH_MSM7627A_EVB MSM7627A_EVB 3934 +rambo MACH_RAMBO RAMBO 3935 +golfu MACH_GOLFU GOLFU 3936 +mango310 MACH_MANGO310 MANGO310 3937 +dns343 MACH_DNS343 DNS343 3938 +var_som_om44 MACH_VAR_SOM_OM44 VAR_SOM_OM44 3939 +naon MACH_NAON NAON 3940 +vp4000 MACH_VP4000 VP4000 3941 +impcard MACH_IMPCARD IMPCARD 3942 +smoovcam MACH_SMOOVCAM SMOOVCAM 3943 +cobham3725 MACH_COBHAM3725 COBHAM3725 3944 +cobham3730 MACH_COBHAM3730 COBHAM3730 3945 +cobham3703 MACH_COBHAM3703 COBHAM3703 3946 +quetzal MACH_QUETZAL QUETZAL 3947 +apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948 +apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949 +apq8064_fluid MACH_APQ8064_FLUID APQ8064_FLUID 3950 +apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951 +mango210 MACH_MANGO210 MANGO210 3952 +mango100 MACH_MANGO100 MANGO100 3953 +mango24 MACH_MANGO24 MANGO24 3954 +mango64 MACH_MANGO64 MANGO64 3955 +nsa320 MACH_NSA320 NSA320 3956 +elv_ccu2 MACH_ELV_CCU2 ELV_CCU2 3957 +triton_x00 MACH_TRITON_X00 TRITON_X00 3958 +triton_1500_2000 MACH_TRITON_1500_2000 TRITON_1500_2000 3959 +pogoplugv4 MACH_POGOPLUGV4 POGOPLUGV4 3960 +venus_cl MACH_VENUS_CL VENUS_CL 3961 +vulcano_g20 MACH_VULCANO_G20 VULCANO_G20 3962 +sgs_i9100 MACH_SGS_I9100 SGS_I9100 3963 +stsv2 MACH_STSV2 STSV2 3964 +csb1724 MACH_CSB1724 CSB1724 3965 +omapl138_lcdk MACH_OMAPL138_LCDK OMAPL138_LCDK 3966 +pvd_mx25 MACH_PVD_MX25 PVD_MX25 3968 +meson6_skt MACH_MESON6_SKT MESON6_SKT 3969 +meson6_ref MACH_MESON6_REF MESON6_REF 3970 +pxm MACH_PXM PXM 3971 +pogoplugv3 MACH_POGOPLUGV3 POGOPLUGV3 3973 +mlp89626 MACH_MLP89626 MLP89626 3974 +iomegahmndce MACH_IOMEGAHMNDCE IOMEGAHMNDCE 3975 +pogoplugv3pci MACH_POGOPLUGV3PCI POGOPLUGV3PCI 3976 +bntv250 MACH_BNTV250 BNTV250 3977 +mx53_qseven MACH_MX53_QSEVEN MX53_QSEVEN 3978 +gtl_it1100 MACH_GTL_IT1100 GTL_IT1100 3979 +mx6q_sabresd MACH_MX6Q_SABRESD MX6Q_SABRESD 3980 +mt4 MACH_MT4 MT4 3981 +jumbo_d MACH_JUMBO_D JUMBO_D 3982 +jumbo_i MACH_JUMBO_I JUMBO_I 3983 +fs20_dmp MACH_FS20_DMP FS20_DMP 3984 +dns320 MACH_DNS320 DNS320 3985 +mx28bacos MACH_MX28BACOS MX28BACOS 3986 +tl80 MACH_TL80 TL80 3987 +polatis_nic_1001 MACH_POLATIS_NIC_1001 POLATIS_NIC_1001 3988 +tely MACH_TELY TELY 3989 +u8520 MACH_U8520 U8520 3990 +manta MACH_MANTA MANTA 3991 +mpq8064_cdp MACH_MPQ8064_CDP MPQ8064_CDP 3993 +mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995 +dm368som MACH_DM368SOM DM368SOM 3996 +gprisb2 MACH_GPRISB2 GPRISB2 3997 +chammid MACH_CHAMMID CHAMMID 3998 +seoul2 MACH_SEOUL2 SEOUL2 3999 +omap4_nooktablet MACH_OMAP4_NOOKTABLET OMAP4_NOOKTABLET 4000 +aalto MACH_AALTO AALTO 4001 +metro MACH_METRO METRO 4002 +cydm3730 MACH_CYDM3730 CYDM3730 4003 +tqma53 MACH_TQMA53 TQMA53 4004 +msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005 +mx28_canby MACH_MX28_CANBY MX28_CANBY 4006 +tiger MACH_TIGER TIGER 4007 +pcats_9307_type_a MACH_PCATS_9307_TYPE_A PCATS_9307_TYPE_A 4008 +pcats_9307_type_o MACH_PCATS_9307_TYPE_O PCATS_9307_TYPE_O 4009 +pcats_9307_type_r MACH_PCATS_9307_TYPE_R PCATS_9307_TYPE_R 4010 +streamplug MACH_STREAMPLUG STREAMPLUG 4011 +icechicken_dev MACH_ICECHICKEN_DEV ICECHICKEN_DEV 4012 +hedgehog MACH_HEDGEHOG HEDGEHOG 4013 +yusend_obc MACH_YUSEND_OBC YUSEND_OBC 4014 +imxninja MACH_IMXNINJA IMXNINJA 4015 +omap4_jarod MACH_OMAP4_JAROD OMAP4_JAROD 4016 +eco5_pk MACH_ECO5_PK ECO5_PK 4017 +qj2440 MACH_QJ2440 QJ2440 4018 +mx6q_mercury MACH_MX6Q_MERCURY MX6Q_MERCURY 4019 +cm6810 MACH_CM6810 CM6810 4020 +omap4_torpedo MACH_OMAP4_TORPEDO OMAP4_TORPEDO 4021 +nsa310 MACH_NSA310 NSA310 4022 +tmx536 MACH_TMX536 TMX536 4023 +ktt20 MACH_KTT20 KTT20 4024 +dragonix MACH_DRAGONIX DRAGONIX 4025 +lungching MACH_LUNGCHING LUNGCHING 4026 +bulogics MACH_BULOGICS BULOGICS 4027 +mx535_sx MACH_MX535_SX MX535_SX 4028 +ngui3250 MACH_NGUI3250 NGUI3250 4029 +salutec_dac MACH_SALUTEC_DAC SALUTEC_DAC 4030 +loco MACH_LOCO LOCO 4031 +ctera_plug_usi MACH_CTERA_PLUG_USI CTERA_PLUG_USI 4032 +scepter MACH_SCEPTER SCEPTER 4033 +sga MACH_SGA SGA 4034 +p_81_j5 MACH_P_81_J5 P_81_J5 4035 +p_81_o4 MACH_P_81_O4 P_81_O4 4036 +msm8625_surf MACH_MSM8625_SURF MSM8625_SURF 4037 +carallon_shark MACH_CARALLON_SHARK CARALLON_SHARK 4038 +ordog MACH_ORDOG ORDOG 4040 +puente_io MACH_PUENTE_IO PUENTE_IO 4041 +msm8625_evb MACH_MSM8625_EVB MSM8625_EVB 4042 +ev_am1707 MACH_EV_AM1707 EV_AM1707 4043 +ev_am1707e2 MACH_EV_AM1707E2 EV_AM1707E2 4044 +ev_am3517e2 MACH_EV_AM3517E2 EV_AM3517E2 4045 +calabria MACH_CALABRIA CALABRIA 4046 +ev_imx287 MACH_EV_IMX287 EV_IMX287 4047 +erau MACH_ERAU ERAU 4048 +sichuan MACH_SICHUAN SICHUAN 4049 +davinci_da850 MACH_DAVINCI_DA850 DAVINCI_DA850 4051 +omap138_trunarc MACH_OMAP138_TRUNARC OMAP138_TRUNARC 4052 +bcm4761 MACH_BCM4761 BCM4761 4053 +picasso_e2 MACH_PICASSO_E2 PICASSO_E2 4054 +picasso_mf MACH_PICASSO_MF PICASSO_MF 4055 +miro MACH_MIRO MIRO 4056 +at91sam9g20ewon3 MACH_AT91SAM9G20EWON3 AT91SAM9G20EWON3 4057 +yoyo MACH_YOYO YOYO 4058 +windjkl MACH_WINDJKL WINDJKL 4059 +monarudo MACH_MONARUDO MONARUDO 4060 +batan MACH_BATAN BATAN 4061 +tadao MACH_TADAO TADAO 4062 +baso MACH_BASO BASO 4063 +mahon MACH_MAHON MAHON 4064 +villec2 MACH_VILLEC2 VILLEC2 4065 +asi1230 MACH_ASI1230 ASI1230 4066 +alaska MACH_ALASKA ALASKA 4067 +swarco_shdsl2 MACH_SWARCO_SHDSL2 SWARCO_SHDSL2 4068 +oxrtu MACH_OXRTU OXRTU 4069 +omap5_panda MACH_OMAP5_PANDA OMAP5_PANDA 4070 +c8000 MACH_C8000 C8000 4072 +bje_display3_5 MACH_BJE_DISPLAY3_5 BJE_DISPLAY3_5 4073 +picomod7 MACH_PICOMOD7 PICOMOD7 4074 +picocom5 MACH_PICOCOM5 PICOCOM5 4075 +qblissa8 MACH_QBLISSA8 QBLISSA8 4076 +armstonea8 MACH_ARMSTONEA8 ARMSTONEA8 4077 +netdcu14 MACH_NETDCU14 NETDCU14 4078 +at91sam9x5_epiphan MACH_AT91SAM9X5_EPIPHAN AT91SAM9X5_EPIPHAN 4079 +p2u MACH_P2U P2U 4080 +doris MACH_DORIS DORIS 4081 +j49 MACH_J49 J49 4082 +vdss2e MACH_VDSS2E VDSS2E 4083 +vc300 MACH_VC300 VC300 4084 +ns115_pad_test MACH_NS115_PAD_TEST NS115_PAD_TEST 4085 +ns115_pad_ref MACH_NS115_PAD_REF NS115_PAD_REF 4086 +ns115_phone_test MACH_NS115_PHONE_TEST NS115_PHONE_TEST 4087 +ns115_phone_ref MACH_NS115_PHONE_REF NS115_PHONE_REF 4088 +golfc MACH_GOLFC GOLFC 4089 +xerox_olympus MACH_XEROX_OLYMPUS XEROX_OLYMPUS 4090 +mx6sl_arm2 MACH_MX6SL_ARM2 MX6SL_ARM2 4091 +csb1701_csb1726 MACH_CSB1701_CSB1726 CSB1701_CSB1726 4092 +at91sam9xeek MACH_AT91SAM9XEEK AT91SAM9XEEK 4093 +ebv210 MACH_EBV210 EBV210 4094 +msm7627a_qrd7 MACH_MSM7627A_QRD7 MSM7627A_QRD7 4095 +svthin MACH_SVTHIN SVTHIN 4096 +duovero MACH_DUOVERO DUOVERO 4097 +chupacabra MACH_CHUPACABRA CHUPACABRA 4098 +scorpion MACH_SCORPION SCORPION 4099 +davinci_he_hmi10 MACH_DAVINCI_HE_HMI10 DAVINCI_HE_HMI10 4100 +topkick MACH_TOPKICK TOPKICK 4101 +m3_auguestrush MACH_M3_AUGUESTRUSH M3_AUGUESTRUSH 4102 +ipc335x MACH_IPC335X IPC335X 4103 +sun4i MACH_SUN4I SUN4I 4104 +imx233_olinuxino MACH_IMX233_OLINUXINO IMX233_OLINUXINO 4105 +k2_wl MACH_K2_WL K2_WL 4106 +k2_ul MACH_K2_UL K2_UL 4107 +k2_cl MACH_K2_CL K2_CL 4108 +minbari_w MACH_MINBARI_W MINBARI_W 4109 +minbari_m MACH_MINBARI_M MINBARI_M 4110 +k035 MACH_K035 K035 4111 +ariel MACH_ARIEL ARIEL 4112 +arielsaarc MACH_ARIELSAARC ARIELSAARC 4113 +arieldkb MACH_ARIELDKB ARIELDKB 4114 +armadillo810 MACH_ARMADILLO810 ARMADILLO810 4115 +tam335x MACH_TAM335X TAM335X 4116 +grouper MACH_GROUPER GROUPER 4117 +mpcsa21_9g20 MACH_MPCSA21_9G20 MPCSA21_9G20 4118 +m6u_cpu MACH_M6U_CPU M6U_CPU 4119 +davinci_dp10 MACH_DAVINCI_DP10 DAVINCI_DP10 4120 +ginkgo MACH_GINKGO GINKGO 4121 +cgt_qmx6 MACH_CGT_QMX6 CGT_QMX6 4122 +profpga MACH_PROFPGA PROFPGA 4123 +acfx100oc MACH_ACFX100OC ACFX100OC 4124 +acfx100nb MACH_ACFX100NB ACFX100NB 4125 +capricorn MACH_CAPRICORN CAPRICORN 4126 +pisces MACH_PISCES PISCES 4127 +aries MACH_ARIES ARIES 4128 +cancer MACH_CANCER CANCER 4129 +leo MACH_LEO LEO 4130 +virgo MACH_VIRGO VIRGO 4131 +sagittarius MACH_SAGITTARIUS SAGITTARIUS 4132 +devil MACH_DEVIL DEVIL 4133 +ballantines MACH_BALLANTINES BALLANTINES 4134 +omap3_procerusvpu MACH_OMAP3_PROCERUSVPU OMAP3_PROCERUSVPU 4135 +my27 MACH_MY27 MY27 4136 +sun6i MACH_SUN6I SUN6I 4137 +sun5i MACH_SUN5I SUN5I 4138 +mx512_mx MACH_MX512_MX MX512_MX 4139 +kzm9g MACH_KZM9G KZM9G 4140 +vdstbn MACH_VDSTBN VDSTBN 4141 +cfa10036 MACH_CFA10036 CFA10036 4142 +cfa10049 MACH_CFA10049 CFA10049 4143 +pcm051 MACH_PCM051 PCM051 4144 +vybrid_vf7xx MACH_VYBRID_VF7XX VYBRID_VF7XX 4145 +vybrid_vf6xx MACH_VYBRID_VF6XX VYBRID_VF6XX 4146 +vybrid_vf5xx MACH_VYBRID_VF5XX VYBRID_VF5XX 4147 +vybrid_vf4xx MACH_VYBRID_VF4XX VYBRID_VF4XX 4148 +aria_g25 MACH_ARIA_G25 ARIA_G25 4149 +bcm21553 MACH_BCM21553 BCM21553 4150 +smdk5410 MACH_SMDK5410 SMDK5410 4151 +lpc18xx MACH_LPC18XX LPC18XX 4152 +oratisparty MACH_ORATISPARTY ORATISPARTY 4153 +qseven MACH_QSEVEN QSEVEN 4154 +gmv_generic MACH_GMV_GENERIC GMV_GENERIC 4155 +th_link_eth MACH_TH_LINK_ETH TH_LINK_ETH 4156 +tn_muninn MACH_TN_MUNINN TN_MUNINN 4157 +rampage MACH_RAMPAGE RAMPAGE 4158 +visstrim_mv10 MACH_VISSTRIM_MV10 VISSTRIM_MV10 4159 +mx28_wilma MACH_MX28_WILMA MX28_WILMA 4164 +msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166 +vpu101 MACH_VPU101 VPU101 4167 +baileys MACH_BAILEYS BAILEYS 4169 +familybox MACH_FAMILYBOX FAMILYBOX 4170 +ensemble_mx35 MACH_ENSEMBLE_MX35 ENSEMBLE_MX35 4171 +sc_sps_1 MACH_SC_SPS_1 SC_SPS_1 4172 diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 858748eaa144..b0197b2c857d 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -11,12 +11,15 @@ #include <linux/types.h> #include <linux/cpu.h> #include <linux/cpu_pm.h> +#include <linux/hardirq.h> #include <linux/kernel.h> #include <linux/notifier.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/init.h> +#include <linux/uaccess.h> +#include <linux/user.h> #include <asm/cp15.h> #include <asm/cputype.h> @@ -430,7 +433,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) static void vfp_enable(void *unused) { - u32 access = get_copro_access(); + u32 access; + + BUG_ON(preemptible()); + access = get_copro_access(); /* * Enable full access to VFP (cp10 and cp11) @@ -529,6 +535,93 @@ void vfp_flush_hwstate(struct thread_info *thread) } /* + * Save the current VFP state into the provided structures and prepare + * for entry into a new function (signal handler). + */ +int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, + struct user_vfp_exc __user *ufp_exc) +{ + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; + int err = 0; + + /* Ensure that the saved hwstate is up-to-date. */ + vfp_sync_hwstate(thread); + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs, + sizeof(hwstate->fpregs)); + /* + * Copy the status and control register. + */ + __put_user_error(hwstate->fpscr, &ufp->fpscr, err); + + /* + * Copy the exception registers. + */ + __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err); + __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); + __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); + + if (err) + return -EFAULT; + + /* Ensure that VFP is disabled. */ + vfp_flush_hwstate(thread); + + /* + * As per the PCS, clear the length and stride bits for function + * entry. + */ + hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); + return 0; +} + +/* Sanitise and restore the current VFP state from the provided structures. */ +int vfp_restore_user_hwstate(struct user_vfp __user *ufp, + struct user_vfp_exc __user *ufp_exc) +{ + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; + unsigned long fpexc; + int err = 0; + + /* Disable VFP to avoid corrupting the new thread state. */ + vfp_flush_hwstate(thread); + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs, + sizeof(hwstate->fpregs)); + /* + * Copy the status and control register. + */ + __get_user_error(hwstate->fpscr, &ufp->fpscr, err); + + /* + * Sanitise and restore the exception registers. + */ + __get_user_error(fpexc, &ufp_exc->fpexc, err); + + /* Ensure the VFP is enabled. */ + fpexc |= FPEXC_EN; + + /* Ensure FPINST2 is invalid and the exception flag is cleared. */ + fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + hwstate->fpexc = fpexc; + + __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); + __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); + + return err ? -EFAULT : 0; +} + +/* * VFP hardware can lose all context when a CPU goes offline. * As we will be running in SMP mode with CPU hotplug, we will save the * hardware state at every thread switch. We clear our held state when @@ -558,7 +651,7 @@ static int __init vfp_init(void) unsigned int cpu_arch = cpu_architecture(); if (cpu_arch >= CPU_ARCH_ARMv6) - vfp_enable(NULL); + on_each_cpu(vfp_enable, NULL, 1); /* * First check that there is a VFP that we can use. @@ -579,8 +672,6 @@ static int __init vfp_init(void) } else { hotcpu_notifier(vfp_hotplug, 0); - smp_call_function(vfp_enable, NULL, 1); - VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ printk("implementor %02x architecture %d part %02x variant %x rev %x\n", (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e648af92ced1..0e40843a1c6e 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -18,10 +18,6 @@ #include <linux/atomic.h> -/* Define a way to iterate across irqs. */ -#define for_each_irq(i) \ - for ((i) = 0; (i) < NR_IRQS; ++(i)) - extern atomic_t ppc_n_lost_interrupts; /* This number is used when no interrupt has been assigned */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5ec1b2354ca6..43eb74fcedde 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -330,14 +330,10 @@ void migrate_irqs(void) alloc_cpumask_var(&mask, GFP_KERNEL); - for_each_irq(irq) { + for_each_irq_desc(irq, desc) { struct irq_data *data; struct irq_chip *chip; - desc = irq_to_desc(irq); - if (!desc) - continue; - data = irq_desc_get_irq_data(desc); if (irqd_is_per_cpu(data)) continue; diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index c957b1202bdc..5df777794403 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -23,14 +23,11 @@ void machine_kexec_mask_interrupts(void) { unsigned int i; + struct irq_desc *desc; - for_each_irq(i) { - struct irq_desc *desc = irq_to_desc(i); + for_each_irq_desc(i, desc) { struct irq_chip *chip; - if (!desc) - continue; - chip = irq_desc_get_chip(desc); if (!chip) continue; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index d09f3e8e6867..85825b5401e5 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) pr_devel("axon_msi: woff %x roff %x msi %x\n", write_offset, msic->read_offset, msi); - if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { + if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { generic_handle_irq(msi); msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); } else { @@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (rc) return rc; - /* We rely on being able to stash a virq in a u16 */ - BUILD_BUG_ON(NR_IRQS > 65536); - list_for_each_entry(entry, &dev->msi_list, list) { virq = irq_create_direct_mapping(msic->irq_domain); if (virq == NO_IRQ) { @@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device) } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); - msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); + /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ + msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); if (!msic->irq_domain) { printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", dn->full_name); diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index f9a48af335cb..8c6dc42ecf65 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c @@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void) { int i; - for (i = 1; i < NR_IRQS; i++) + for (i = 1; i < nr_irqs; i++) beat_destruct_irq_plug(i); } diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 66ad93de1d55..c4e630576ff2 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -57,9 +57,9 @@ static int max_real_irqs; static DEFINE_RAW_SPINLOCK(pmac_pic_lock); -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +/* The max irq number this driver deals with is 128; see max_irqs */ +static DECLARE_BITMAP(ppc_lost_interrupts, 128); +static DECLARE_BITMAP(ppc_cached_irq_mask, 128); static int pmac_irq_cascade = -1; static struct irq_domain *pmac_pic_host; diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index aadbe4f6d537..178a5f300bc9 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -30,9 +30,9 @@ config PPC_SPLPAR two or more partitions. config EEH - bool "PCI Extended Error Handling (EEH)" if EXPERT + bool depends on PPC_PSERIES && PCI - default y if !EXPERT + default y config PSERIES_MSI bool diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index d3be961e2ae7..10386b676d87 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -51,8 +51,7 @@ static intctl_cpm2_t __iomem *cpm2_intctl; static struct irq_domain *cpm2_pic_host; -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */ static const u_char irq_to_siureg[] = { 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c index d5f5416be310..b724622c3a0b 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/sysdev/mpc8xx_pic.c @@ -18,69 +18,45 @@ extern int cpm_get_irq(struct pt_regs *regs); static struct irq_domain *mpc8xx_pic_host; -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long mpc8xx_cached_irq_mask; static sysconf8xx_t __iomem *siu_reg; -int cpm_get_irq(struct pt_regs *regs); +static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) +{ + return 0x80000000 >> irqd_to_hwirq(d); +} static void mpc8xx_unmask_irq(struct irq_data *d) { - int bit, word; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] |= (1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); + mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); } static void mpc8xx_mask_irq(struct irq_data *d) { - int bit, word; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); + mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); } static void mpc8xx_ack(struct irq_data *d) { - int bit; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); + out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d)); } static void mpc8xx_end_irq(struct irq_data *d) { - int bit, word; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] |= (1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); + mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); } static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) { - if (flow_type & IRQ_TYPE_EDGE_FALLING) { - irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); + /* only external IRQ senses are programmable */ + if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) { unsigned int siel = in_be32(&siu_reg->sc_siel); - - /* only external IRQ senses are programmable */ - if ((hw & 1) == 0) { - siel |= (0x80000000 >> hw); - out_be32(&siu_reg->sc_siel, siel); - __irq_set_handler_locked(d->irq, handle_edge_irq); - } + siel |= mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_siel, siel); + __irq_set_handler_locked(d->irq, handle_edge_irq); } return 0; } @@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct, IRQ_TYPE_EDGE_FALLING, }; + if (intspec[0] > 0x1f) + return 0; + *out_hwirq = intspec[0]; if (intsize > 1 && intspec[1] < 4) *out_flags = map_pic_senses[intspec[1]]; diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index ea5e204e3450..cd1d18db92c6 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void) { int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); unsigned int irq, virq; + struct irq_desc *desc; /* If we used to be the default server, move to the new "boot_cpuid" */ if (hw_cpu == xics_default_server) @@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void) /* Allow IPIs again... */ icp_ops->set_priority(DEFAULT_PRIORITY); - for_each_irq(virq) { - struct irq_desc *desc; + for_each_irq_desc(virq, desc) { struct irq_chip *chip; long server; unsigned long flags; @@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void) /* We can't set affinity on ISA interrupts */ if (virq < NUM_ISA_INTERRUPTS) continue; - desc = irq_to_desc(virq); /* We only need to migrate enabled IRQS */ - if (!desc || !desc->action) + if (!desc->action) continue; if (desc->irq_data.domain != xics_host) continue; diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index cc273226dbd0..b7e728517284 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -527,9 +527,9 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) if (ret) goto err_release; - if (dev->irq[0] && dev->irq[0] != NO_IRQ) + if (dev->irq[0]) ret = device_create_file(&dev->dev, &dev_attr_irq0); - if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ) + if (ret == 0 && dev->irq[1]) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; @@ -543,6 +543,55 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) } EXPORT_SYMBOL_GPL(amba_device_add); +static struct amba_device * +amba_aphb_device_add(struct device *parent, const char *name, + resource_size_t base, size_t size, int irq1, int irq2, + void *pdata, unsigned int periphid, u64 dma_mask) +{ + struct amba_device *dev; + int ret; + + dev = amba_device_alloc(name, base, size); + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->dma_mask = dma_mask; + dev->dev.coherent_dma_mask = dma_mask; + dev->irq[0] = irq1; + dev->irq[1] = irq2; + dev->periphid = periphid; + dev->dev.platform_data = pdata; + dev->dev.parent = parent; + + ret = amba_device_add(dev, &iomem_resource); + if (ret) { + amba_device_put(dev); + return ERR_PTR(ret); + } + + return dev; +} + +struct amba_device * +amba_apb_device_add(struct device *parent, const char *name, + resource_size_t base, size_t size, int irq1, int irq2, + void *pdata, unsigned int periphid) +{ + return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata, + periphid, 0); +} +EXPORT_SYMBOL_GPL(amba_apb_device_add); + +struct amba_device * +amba_ahb_device_add(struct device *parent, const char *name, + resource_size_t base, size_t size, int irq1, int irq2, + void *pdata, unsigned int periphid) +{ + return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata, + periphid, ~0ULL); +} +EXPORT_SYMBOL_GPL(amba_ahb_device_add); + static void amba_device_initialize(struct amba_device *dev, const char *name) { device_initialize(&dev->dev); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 93dabdcd2cbe..22226350cd0c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3399,7 +3399,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) */ shost->max_host_blocked = 1; - rc = scsi_add_host(ap->scsi_host, &ap->tdev); + rc = scsi_add_host_with_dma(ap->scsi_host, + &ap->tdev, ap->host->dev); if (rc) goto err_add; } @@ -3838,18 +3839,25 @@ void ata_sas_port_stop(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ata_sas_port_stop); -int ata_sas_async_port_init(struct ata_port *ap) +/** + * ata_sas_async_probe - simply schedule probing and return + * @ap: Port to probe + * + * For batch scheduling of probe for sas attached ata devices, assumes + * the port has already been through ata_sas_port_init() + */ +void ata_sas_async_probe(struct ata_port *ap) { - int rc = ap->ops->port_start(ap); - - if (!rc) { - ap->print_id = atomic_inc_return(&ata_print_id); - __ata_port_probe(ap); - } + __ata_port_probe(ap); +} +EXPORT_SYMBOL_GPL(ata_sas_async_probe); - return rc; +int ata_sas_sync_probe(struct ata_port *ap) +{ + return ata_port_probe(ap); } -EXPORT_SYMBOL_GPL(ata_sas_async_port_init); +EXPORT_SYMBOL_GPL(ata_sas_sync_probe); + /** * ata_sas_port_init - Initialize a SATA device @@ -3866,12 +3874,10 @@ int ata_sas_port_init(struct ata_port *ap) { int rc = ap->ops->port_start(ap); - if (!rc) { - ap->print_id = atomic_inc_return(&ata_print_id); - rc = ata_port_probe(ap); - } - - return rc; + if (rc) + return rc; + ap->print_id = atomic_inc_return(&ata_print_id); + return 0; } EXPORT_SYMBOL_GPL(ata_sas_port_init); diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index d25599f2a3f8..891e4674d29b 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -191,6 +191,176 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) } } +static bool +validate_device_path(struct efi_variable *var, int match, u8 *buffer, int len) +{ + struct efi_generic_dev_path *node; + int offset = 0; + + node = (struct efi_generic_dev_path *)buffer; + + while (offset < len) { + offset += node->length; + + if (offset > len) + return false; + + if ((node->type == EFI_DEV_END_PATH || + node->type == EFI_DEV_END_PATH2) && + node->sub_type == EFI_DEV_END_ENTIRE) + return true; + + node = (struct efi_generic_dev_path *)(buffer + offset); + } + + /* + * If we're here then either node->length pointed past the end + * of the buffer or we reached the end of the buffer without + * finding a device path end node. + */ + return false; +} + +static bool +validate_boot_order(struct efi_variable *var, int match, u8 *buffer, int len) +{ + /* An array of 16-bit integers */ + if ((len % 2) != 0) + return false; + + return true; +} + +static bool +validate_load_option(struct efi_variable *var, int match, u8 *buffer, int len) +{ + u16 filepathlength; + int i, desclength = 0; + + /* Either "Boot" or "Driver" followed by four digits of hex */ + for (i = match; i < match+4; i++) { + if (hex_to_bin(var->VariableName[i] & 0xff) < 0) + return true; + } + + /* A valid entry must be at least 6 bytes */ + if (len < 6) + return false; + + filepathlength = buffer[4] | buffer[5] << 8; + + /* + * There's no stored length for the description, so it has to be + * found by hand + */ + desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len) + 2; + + /* Each boot entry must have a descriptor */ + if (!desclength) + return false; + + /* + * If the sum of the length of the description, the claimed filepath + * length and the original header are greater than the length of the + * variable, it's malformed + */ + if ((desclength + filepathlength + 6) > len) + return false; + + /* + * And, finally, check the filepath + */ + return validate_device_path(var, match, buffer + desclength + 6, + filepathlength); +} + +static bool +validate_uint16(struct efi_variable *var, int match, u8 *buffer, int len) +{ + /* A single 16-bit integer */ + if (len != 2) + return false; + + return true; +} + +static bool +validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, int len) +{ + int i; + + for (i = 0; i < len; i++) { + if (buffer[i] > 127) + return false; + + if (buffer[i] == 0) + return true; + } + + return false; +} + +struct variable_validate { + char *name; + bool (*validate)(struct efi_variable *var, int match, u8 *data, + int len); +}; + +static const struct variable_validate variable_validate[] = { + { "BootNext", validate_uint16 }, + { "BootOrder", validate_boot_order }, + { "DriverOrder", validate_boot_order }, + { "Boot*", validate_load_option }, + { "Driver*", validate_load_option }, + { "ConIn", validate_device_path }, + { "ConInDev", validate_device_path }, + { "ConOut", validate_device_path }, + { "ConOutDev", validate_device_path }, + { "ErrOut", validate_device_path }, + { "ErrOutDev", validate_device_path }, + { "Timeout", validate_uint16 }, + { "Lang", validate_ascii_string }, + { "PlatformLang", validate_ascii_string }, + { "", NULL }, +}; + +static bool +validate_var(struct efi_variable *var, u8 *data, int len) +{ + int i; + u16 *unicode_name = var->VariableName; + + for (i = 0; variable_validate[i].validate != NULL; i++) { + const char *name = variable_validate[i].name; + int match; + + for (match = 0; ; match++) { + char c = name[match]; + u16 u = unicode_name[match]; + + /* All special variables are plain ascii */ + if (u > 127) + return true; + + /* Wildcard in the matching name means we've matched */ + if (c == '*') + return variable_validate[i].validate(var, + match, data, len); + + /* Case sensitive match */ + if (c != u) + break; + + /* Reached the end of the string while matching */ + if (!c) + return variable_validate[i].validate(var, + match, data, len); + } + } + + return true; +} + static efi_status_t get_var_data_locked(struct efivars *efivars, struct efi_variable *var) { @@ -324,6 +494,12 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) return -EINVAL; } + if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || + validate_var(new_var, new_var->Data, new_var->DataSize) == false) { + printk(KERN_ERR "efivars: Malformed variable content\n"); + return -EINVAL; + } + spin_lock(&efivars->lock); status = efivars->ops->set_variable(new_var->VariableName, &new_var->VendorGuid, @@ -626,6 +802,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || + validate_var(new_var, new_var->Data, new_var->DataSize) == false) { + printk(KERN_ERR "efivars: Malformed variable content\n"); + return -EINVAL; + } + spin_lock(&efivars->lock); /* diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 8081a0a5d602..a4b14a41cbf4 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -274,7 +274,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) static unsigned char param = 0xc8; struct synaptics_data *priv = psmouse->private; - if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) + if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || + SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))) return 0; if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 032b84791a16..b6f38421d541 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -94,6 +94,17 @@ static struct variant_data variant_u300 = { .signal_direction = true, }; +static struct variant_data variant_nomadik = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits = 24, + .sdio = true, + .st_clkdiv = true, + .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, +}; + static struct variant_data variant_ux500 = { .fifosize = 30 * 4, .fifohalfsize = 8 * 4, @@ -1397,7 +1408,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret) goto unmap; - if (dev->irq[1] == NO_IRQ || !dev->irq[1]) + if (!dev->irq[1]) host->singleirq = true; else { ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, @@ -1569,6 +1580,11 @@ static struct amba_id mmci_ids[] = { .data = &variant_u300, }, { + .id = 0x10180180, + .mask = 0xf0ffffff, + .data = &variant_nomadik, + }, + { .id = 0x00280180, .mask = 0x00ffffff, .data = &variant_u300, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e002cd466e9a..467dc38246f9 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4549,8 +4549,12 @@ static int ipr_ata_slave_alloc(struct scsi_device *sdev) ENTER; if (sdev->sdev_target) sata_port = sdev->sdev_target->hostdata; - if (sata_port) + if (sata_port) { rc = ata_sas_port_init(sata_port->ap); + if (rc == 0) + rc = ata_sas_sync_probe(sata_port->ap); + } + if (rc) ipr_slave_destroy(sdev); diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index ef9560dff295..cc83b66d45b7 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -1742,17 +1742,19 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK; - if (mfs >= FC_SP_MIN_MAX_PAYLOAD && - mfs <= lport->mfs) { - lport->mfs = mfs; - fc_host_maxframe_size(lport->host) = mfs; - } else { + + if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " "lport->mfs:%hu\n", mfs, lport->mfs); fc_lport_error(lport, fp); goto err; } + if (mfs <= lport->mfs) { + lport->mfs = mfs; + fc_host_maxframe_size(lport->host) = mfs; + } + csp_flags = ntohs(flp->fl_csp.sp_features); r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index bc0cecc6ad62..441d88ad99a7 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -546,11 +546,12 @@ static struct ata_port_info sata_port_info = { .port_ops = &sas_sata_ops }; -int sas_ata_init_host_and_port(struct domain_device *found_dev) +int sas_ata_init(struct domain_device *found_dev) { struct sas_ha_struct *ha = found_dev->port->ha; struct Scsi_Host *shost = ha->core.shost; struct ata_port *ap; + int rc; ata_host_init(&found_dev->sata_dev.ata_host, ha->dev, @@ -567,8 +568,11 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev) ap->private_data = found_dev; ap->cbl = ATA_CBL_SATA; ap->scsi_host = shost; - /* publish initialized ata port */ - smp_wmb(); + rc = ata_sas_port_init(ap); + if (rc) { + ata_sas_port_destroy(ap); + return rc; + } found_dev->sata_dev.ap = ap; return 0; @@ -648,18 +652,13 @@ static void sas_get_ata_command_set(struct domain_device *dev) void sas_probe_sata(struct asd_sas_port *port) { struct domain_device *dev, *n; - int err; mutex_lock(&port->ha->disco_mutex); - list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { + list_for_each_entry(dev, &port->disco_list, disco_list_node) { if (!dev_is_sata(dev)) continue; - err = sas_ata_init_host_and_port(dev); - if (err) - sas_fail_probe(dev, __func__, err); - else - ata_sas_async_port_init(dev->sata_dev.ap); + ata_sas_async_probe(dev->sata_dev.ap); } mutex_unlock(&port->ha->disco_mutex); @@ -718,18 +717,6 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie) sas_put_device(dev); } -static bool sas_ata_dev_eh_valid(struct domain_device *dev) -{ - struct ata_port *ap; - - if (!dev_is_sata(dev)) - return false; - ap = dev->sata_dev.ap; - /* consume fully initialized ata ports */ - smp_rmb(); - return !!ap; -} - void sas_ata_strategy_handler(struct Scsi_Host *shost) { struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); @@ -753,7 +740,7 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost) spin_lock(&port->dev_list_lock); list_for_each_entry(dev, &port->dev_list, dev_list_node) { - if (!sas_ata_dev_eh_valid(dev)) + if (!dev_is_sata(dev)) continue; async_schedule_domain(async_sas_ata_eh, dev, &async); } diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 364679675602..629a0865b130 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -72,6 +72,7 @@ static int sas_get_port_device(struct asd_sas_port *port) struct asd_sas_phy *phy; struct sas_rphy *rphy; struct domain_device *dev; + int rc = -ENODEV; dev = sas_alloc_device(); if (!dev) @@ -110,9 +111,16 @@ static int sas_get_port_device(struct asd_sas_port *port) sas_init_dev(dev); + dev->port = port; switch (dev->dev_type) { - case SAS_END_DEV: case SATA_DEV: + rc = sas_ata_init(dev); + if (rc) { + rphy = NULL; + break; + } + /* fall through */ + case SAS_END_DEV: rphy = sas_end_device_alloc(port->port); break; case EDGE_DEV: @@ -131,19 +139,14 @@ static int sas_get_port_device(struct asd_sas_port *port) if (!rphy) { sas_put_device(dev); - return -ENODEV; + return rc; } - spin_lock_irq(&port->phy_list_lock); - list_for_each_entry(phy, &port->phy_list, port_phy_el) - sas_phy_set_target(phy, dev); - spin_unlock_irq(&port->phy_list_lock); rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); sas_fill_in_rphy(dev, rphy); sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); port->port_dev = dev; - dev->port = port; dev->linkrate = port->linkrate; dev->min_linkrate = port->linkrate; dev->max_linkrate = port->linkrate; @@ -155,6 +158,7 @@ static int sas_get_port_device(struct asd_sas_port *port) sas_device_set_phy(dev, port->port); dev->rphy = rphy; + get_device(&dev->rphy->dev); if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV) list_add_tail(&dev->disco_list_node, &port->disco_list); @@ -164,6 +168,11 @@ static int sas_get_port_device(struct asd_sas_port *port) spin_unlock_irq(&port->dev_list_lock); } + spin_lock_irq(&port->phy_list_lock); + list_for_each_entry(phy, &port->phy_list, port_phy_el) + sas_phy_set_target(phy, dev); + spin_unlock_irq(&port->phy_list_lock); + return 0; } @@ -205,8 +214,7 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) static void sas_probe_devices(struct work_struct *work) { struct domain_device *dev, *n; - struct sas_discovery_event *ev = - container_of(work, struct sas_discovery_event, work); + struct sas_discovery_event *ev = to_sas_discovery_event(work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_PROBE, &port->disc.pending); @@ -255,6 +263,9 @@ void sas_free_device(struct kref *kref) { struct domain_device *dev = container_of(kref, typeof(*dev), kref); + put_device(&dev->rphy->dev); + dev->rphy = NULL; + if (dev->parent) sas_put_device(dev->parent); @@ -291,8 +302,7 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d static void sas_destruct_devices(struct work_struct *work) { struct domain_device *dev, *n; - struct sas_discovery_event *ev = - container_of(work, struct sas_discovery_event, work); + struct sas_discovery_event *ev = to_sas_discovery_event(work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_DESTRUCT, &port->disc.pending); @@ -302,7 +312,6 @@ static void sas_destruct_devices(struct work_struct *work) sas_remove_children(&dev->rphy->dev); sas_rphy_delete(dev->rphy); - dev->rphy = NULL; sas_unregister_common_dev(port, dev); } } @@ -314,11 +323,11 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) /* this rphy never saw sas_rphy_add */ list_del_init(&dev->disco_list_node); sas_rphy_free(dev->rphy); - dev->rphy = NULL; sas_unregister_common_dev(port, dev); + return; } - if (dev->rphy && !test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { + if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { sas_rphy_unlink(dev->rphy); list_move_tail(&dev->disco_list_node, &port->destroy_list); sas_discover_event(dev->port, DISCE_DESTRUCT); @@ -377,8 +386,7 @@ static void sas_discover_domain(struct work_struct *work) { struct domain_device *dev; int error = 0; - struct sas_discovery_event *ev = - container_of(work, struct sas_discovery_event, work); + struct sas_discovery_event *ev = to_sas_discovery_event(work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending); @@ -419,8 +427,6 @@ static void sas_discover_domain(struct work_struct *work) if (error) { sas_rphy_free(dev->rphy); - dev->rphy = NULL; - list_del_init(&dev->disco_list_node); spin_lock_irq(&port->dev_list_lock); list_del_init(&dev->dev_list_node); @@ -437,8 +443,7 @@ static void sas_discover_domain(struct work_struct *work) static void sas_revalidate_domain(struct work_struct *work) { int res = 0; - struct sas_discovery_event *ev = - container_of(work, struct sas_discovery_event, work); + struct sas_discovery_event *ev = to_sas_discovery_event(work); struct asd_sas_port *port = ev->port; struct sas_ha_struct *ha = port->ha; @@ -466,21 +471,25 @@ static void sas_revalidate_domain(struct work_struct *work) /* ---------- Events ---------- */ -static void sas_chain_work(struct sas_ha_struct *ha, struct work_struct *work) +static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) { - /* chained work is not subject to SA_HA_DRAINING or SAS_HA_REGISTERED */ - scsi_queue_work(ha->core.shost, work); + /* chained work is not subject to SA_HA_DRAINING or + * SAS_HA_REGISTERED, because it is either submitted in the + * workqueue, or known to be submitted from a context that is + * not racing against draining + */ + scsi_queue_work(ha->core.shost, &sw->work); } static void sas_chain_event(int event, unsigned long *pending, - struct work_struct *work, + struct sas_work *sw, struct sas_ha_struct *ha) { if (!test_and_set_bit(event, pending)) { unsigned long flags; spin_lock_irqsave(&ha->state_lock, flags); - sas_chain_work(ha, work); + sas_chain_work(ha, sw); spin_unlock_irqrestore(&ha->state_lock, flags); } } @@ -519,7 +528,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) disc->pending = 0; for (i = 0; i < DISC_NUM_EVENTS; i++) { - INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]); + INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]); disc->disc_work[i].port = port; } } diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 16639bbae629..4e4292d210c1 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c @@ -27,19 +27,21 @@ #include "sas_internal.h" #include "sas_dump.h" -void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work) +void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw) { if (!test_bit(SAS_HA_REGISTERED, &ha->state)) return; - if (test_bit(SAS_HA_DRAINING, &ha->state)) - list_add(&work->entry, &ha->defer_q); - else - scsi_queue_work(ha->core.shost, work); + if (test_bit(SAS_HA_DRAINING, &ha->state)) { + /* add it to the defer list, if not already pending */ + if (list_empty(&sw->drain_node)) + list_add(&sw->drain_node, &ha->defer_q); + } else + scsi_queue_work(ha->core.shost, &sw->work); } static void sas_queue_event(int event, unsigned long *pending, - struct work_struct *work, + struct sas_work *work, struct sas_ha_struct *ha) { if (!test_and_set_bit(event, pending)) { @@ -55,7 +57,7 @@ static void sas_queue_event(int event, unsigned long *pending, void __sas_drain_work(struct sas_ha_struct *ha) { struct workqueue_struct *wq = ha->core.shost->work_q; - struct work_struct *w, *_w; + struct sas_work *sw, *_sw; set_bit(SAS_HA_DRAINING, &ha->state); /* flush submitters */ @@ -66,9 +68,9 @@ void __sas_drain_work(struct sas_ha_struct *ha) spin_lock_irq(&ha->state_lock); clear_bit(SAS_HA_DRAINING, &ha->state); - list_for_each_entry_safe(w, _w, &ha->defer_q, entry) { - list_del_init(&w->entry); - sas_queue_work(ha, w); + list_for_each_entry_safe(sw, _sw, &ha->defer_q, drain_node) { + list_del_init(&sw->drain_node); + sas_queue_work(ha, sw); } spin_unlock_irq(&ha->state_lock); } @@ -151,7 +153,7 @@ int sas_init_events(struct sas_ha_struct *sas_ha) int i; for (i = 0; i < HA_NUM_EVENTS; i++) { - INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); + INIT_SAS_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); sas_ha->ha_events[i].ha = sas_ha; } diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 05acd9e35fc4..caa0525d2523 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -202,6 +202,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) u8 sas_addr[SAS_ADDR_SIZE]; struct smp_resp *resp = rsp; struct discover_resp *dr = &resp->disc; + struct sas_ha_struct *ha = dev->port->ha; struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; struct sas_rphy *rphy = dev->rphy; @@ -209,6 +210,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) char *type; if (new_phy) { + if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))) + return; phy->phy = sas_phy_alloc(&rphy->dev, phy_id); /* FIXME: error_handling */ @@ -233,6 +236,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_dev_type = to_dev_type(dr); + if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) + goto out; phy->phy_id = phy_id; phy->linkrate = dr->linkrate; phy->attached_sata_host = dr->attached_sata_host; @@ -240,7 +245,14 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) phy->attached_sata_ps = dr->attached_sata_ps; phy->attached_iproto = dr->iproto << 1; phy->attached_tproto = dr->tproto << 1; - memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); + /* help some expanders that fail to zero sas_address in the 'no + * device' case + */ + if (phy->attached_dev_type == NO_DEVICE || + phy->linkrate < SAS_LINK_RATE_1_5_GBPS) + memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); + else + memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_phy_id = dr->attached_phy_id; phy->phy_change_count = dr->change_count; phy->routing_attr = dr->routing_attr; @@ -266,6 +278,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) return; } + out: switch (phy->attached_dev_type) { case SATA_PENDING: type = "stp pending"; @@ -304,7 +317,15 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) else return; - SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", + /* if the attached device type changed and ata_eh is active, + * make sure we run revalidation when eh completes (see: + * sas_enable_revalidation) + */ + if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) + set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending); + + SAS_DPRINTK("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", + test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "", SAS_ADDR(dev->sas_addr), phy->phy_id, sas_route_char(dev, phy), phy->linkrate, SAS_ADDR(phy->attached_sas_addr), type); @@ -776,13 +797,16 @@ static struct domain_device *sas_ex_discover_end_dev( if (res) goto out_free; + sas_init_dev(child); + res = sas_ata_init(child); + if (res) + goto out_free; rphy = sas_end_device_alloc(phy->port); - if (unlikely(!rphy)) + if (!rphy) goto out_free; - sas_init_dev(child); - child->rphy = rphy; + get_device(&rphy->dev); list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -806,6 +830,7 @@ static struct domain_device *sas_ex_discover_end_dev( sas_init_dev(child); child->rphy = rphy; + get_device(&rphy->dev); sas_fill_in_rphy(child, rphy); list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -830,8 +855,6 @@ static struct domain_device *sas_ex_discover_end_dev( out_list_del: sas_rphy_free(child->rphy); - child->rphy = NULL; - list_del(&child->disco_list_node); spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); @@ -911,6 +934,7 @@ static struct domain_device *sas_ex_discover_expander( } port = parent->port; child->rphy = rphy; + get_device(&rphy->dev); edev = rphy_to_expander_device(rphy); child->dev_type = phy->attached_dev_type; kref_get(&parent->kref); @@ -934,6 +958,7 @@ static struct domain_device *sas_ex_discover_expander( res = sas_discover_expander(child); if (res) { + sas_rphy_delete(rphy); spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); spin_unlock_irq(&parent->port->dev_list_lock); @@ -1718,9 +1743,17 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, int phy_change_count = 0; res = sas_get_phy_change_count(dev, i, &phy_change_count); - if (res) - goto out; - else if (phy_change_count != ex->ex_phy[i].phy_change_count) { + switch (res) { + case SMP_RESP_PHY_VACANT: + case SMP_RESP_NO_PHY: + continue; + case SMP_RESP_FUNC_ACC: + break; + default: + return res; + } + + if (phy_change_count != ex->ex_phy[i].phy_change_count) { if (update) ex->ex_phy[i].phy_change_count = phy_change_count; @@ -1728,8 +1761,7 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, return 0; } } -out: - return res; + return 0; } static int sas_get_ex_change_count(struct domain_device *dev, int *ecc) diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 120bff64be30..10cb5ae30977 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -94,8 +94,7 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) void sas_hae_reset(struct work_struct *work) { - struct sas_ha_event *ev = - container_of(work, struct sas_ha_event, work); + struct sas_ha_event *ev = to_sas_ha_event(work); struct sas_ha_struct *ha = ev->ha; clear_bit(HAE_RESET, &ha->pending); @@ -369,14 +368,14 @@ static void sas_phy_release(struct sas_phy *phy) static void phy_reset_work(struct work_struct *work) { - struct sas_phy_data *d = container_of(work, typeof(*d), reset_work); + struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work); d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset); } static void phy_enable_work(struct work_struct *work) { - struct sas_phy_data *d = container_of(work, typeof(*d), enable_work); + struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work); d->enable_result = sas_phy_enable(d->phy, d->enable); } @@ -389,8 +388,8 @@ static int sas_phy_setup(struct sas_phy *phy) return -ENOMEM; mutex_init(&d->event_lock); - INIT_WORK(&d->reset_work, phy_reset_work); - INIT_WORK(&d->enable_work, phy_enable_work); + INIT_SAS_WORK(&d->reset_work, phy_reset_work); + INIT_SAS_WORK(&d->enable_work, phy_enable_work); d->phy = phy; phy->hostdata = d; diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index f05c63879949..507e4cf12e56 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -45,10 +45,10 @@ struct sas_phy_data { struct mutex event_lock; int hard_reset; int reset_result; - struct work_struct reset_work; + struct sas_work reset_work; int enable; int enable_result; - struct work_struct enable_work; + struct sas_work enable_work; }; void sas_scsi_recover_host(struct Scsi_Host *shost); @@ -80,7 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work); void sas_porte_link_reset_err(struct work_struct *work); void sas_porte_timer_event(struct work_struct *work); void sas_porte_hard_reset(struct work_struct *work); -void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work); +void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw); int sas_notify_lldd_dev_found(struct domain_device *); void sas_notify_lldd_dev_gone(struct domain_device *); diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index dcfd4a9105c5..521422e857ab 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c @@ -32,8 +32,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending); @@ -43,8 +42,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work) static void sas_phye_oob_done(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending); @@ -53,8 +51,7 @@ static void sas_phye_oob_done(struct work_struct *work) static void sas_phye_oob_error(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; struct sas_ha_struct *sas_ha = phy->ha; struct asd_sas_port *port = phy->port; @@ -85,8 +82,7 @@ static void sas_phye_oob_error(struct work_struct *work) static void sas_phye_spinup_hold(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *i = @@ -127,14 +123,12 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) phy->error = 0; INIT_LIST_HEAD(&phy->port_phy_el); for (k = 0; k < PORT_NUM_EVENTS; k++) { - INIT_WORK(&phy->port_events[k].work, - sas_port_event_fns[k]); + INIT_SAS_WORK(&phy->port_events[k].work, sas_port_event_fns[k]); phy->port_events[k].phy = phy; } for (k = 0; k < PHY_NUM_EVENTS; k++) { - INIT_WORK(&phy->phy_events[k].work, - sas_phy_event_fns[k]); + INIT_SAS_WORK(&phy->phy_events[k].work, sas_phy_event_fns[k]); phy->phy_events[k].phy = phy; } @@ -144,8 +138,7 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) spin_lock_init(&phy->sas_prim_lock); phy->frame_rcvd_size = 0; - phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, - i); + phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, i); if (!phy->phy) return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index eb19c016d500..e884a8c58a0c 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c @@ -123,7 +123,7 @@ static void sas_form_port(struct asd_sas_phy *phy) spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); if (!port->port) { - port->port = sas_port_alloc(phy->phy->dev.parent, phy->id); + port->port = sas_port_alloc(phy->phy->dev.parent, port->id); BUG_ON(!port->port); sas_port_add(port->port); } @@ -208,8 +208,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) void sas_porte_bytes_dmaed(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending); @@ -219,8 +218,7 @@ void sas_porte_bytes_dmaed(struct work_struct *work) void sas_porte_broadcast_rcvd(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; unsigned long flags; u32 prim; @@ -237,8 +235,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work) void sas_porte_link_reset_err(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending); @@ -248,8 +245,7 @@ void sas_porte_link_reset_err(struct work_struct *work) void sas_porte_timer_event(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending); @@ -259,8 +255,7 @@ void sas_porte_timer_event(struct work_struct *work) void sas_porte_hard_reset(struct work_struct *work) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); + struct asd_sas_event *ev = to_asd_sas_event(work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_HARD_RESET, &phy->port_events_pending); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ead6405f3e51..5dfd7495d1a1 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1638,7 +1638,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, request_fn_proc *request_fn) { struct request_queue *q; - struct device *dev = shost->shost_gendev.parent; + struct device *dev = shost->dma_dev; q = blk_init_queue(request_fn, NULL); if (!q) diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 08ebe901bb59..654755a990df 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) tty = NULL; if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { if (!ZS_IS_OPEN(uap_a)) { - pmz_debug("ChanA interrupt while open !\n"); + pmz_debug("ChanA interrupt while not open !\n"); goto skip_a; } write_zsreg(uap_a, R0, RES_H_IUS); @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) spin_lock(&uap_b->port.lock); tty = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { - if (!ZS_IS_OPEN(uap_a)) { - pmz_debug("ChanB interrupt while open !\n"); + if (!ZS_IS_OPEN(uap_b)) { + pmz_debug("ChanB interrupt while not open !\n"); goto skip_b; } write_zsreg(uap_b, R0, RES_H_IUS); diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 4767429264a2..ed3f9206a0ee 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -577,7 +577,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) struct cld_net *cn = nn->cld_net; if (mlen != sizeof(*cmsg)) { - dprintk("%s: got %lu bytes, expected %lu\n", __func__, mlen, + dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen, sizeof(*cmsg)); return -EINVAL; } diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 8d54f79457ba..d36417158d8f 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -63,6 +63,14 @@ struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); void amba_device_put(struct amba_device *); int amba_device_add(struct amba_device *, struct resource *); int amba_device_register(struct amba_device *, struct resource *); +struct amba_device *amba_apb_device_add(struct device *parent, const char *name, + resource_size_t base, size_t size, + int irq1, int irq2, void *pdata, + unsigned int periphid); +struct amba_device *amba_ahb_device_add(struct device *parent, const char *name, + resource_size_t base, size_t size, + int irq1, int irq2, void *pdata, + unsigned int periphid); void amba_device_unregister(struct amba_device *); struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int); int amba_request_regions(struct amba_device *, const char *); diff --git a/include/linux/efi.h b/include/linux/efi.h index 88ec80670d5f..ec45ccd8708a 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -554,7 +554,18 @@ extern int __init efi_setup_pcdp_console(char *); #define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 #define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 - +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 +#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040 + +#define EFI_VARIABLE_MASK (EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ + EFI_VARIABLE_RUNTIME_ACCESS | \ + EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ + EFI_VARIABLE_APPEND_WRITE) /* * The type of search to perform when calling boottime->locate_handle */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 42378d637ffb..e926df7b54c9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -996,7 +996,8 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, extern void ata_sas_port_destroy(struct ata_port *); extern struct ata_port *ata_sas_port_alloc(struct ata_host *, struct ata_port_info *, struct Scsi_Host *); -extern int ata_sas_async_port_init(struct ata_port *); +extern void ata_sas_async_probe(struct ata_port *ap); +extern int ata_sas_sync_probe(struct ata_port *ap); extern int ata_sas_port_init(struct ata_port *); extern int ata_sas_port_start(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap); diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 5f5ed1b8b41b..f4f1c96dca72 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -217,11 +217,29 @@ struct domain_device { struct kref kref; }; -struct sas_discovery_event { +struct sas_work { + struct list_head drain_node; struct work_struct work; +}; + +static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *)) +{ + INIT_WORK(&sw->work, fn); + INIT_LIST_HEAD(&sw->drain_node); +} + +struct sas_discovery_event { + struct sas_work work; struct asd_sas_port *port; }; +static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work) +{ + struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work); + + return ev; +} + struct sas_discovery { struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; unsigned long pending; @@ -244,7 +262,7 @@ struct asd_sas_port { struct list_head destroy_list; enum sas_linkrate linkrate; - struct work_struct work; + struct sas_work work; /* public: */ int id; @@ -270,10 +288,17 @@ struct asd_sas_port { }; struct asd_sas_event { - struct work_struct work; + struct sas_work work; struct asd_sas_phy *phy; }; +static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work) +{ + struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work); + + return ev; +} + /* The phy pretty much is controlled by the LLDD. * The class only reads those fields. */ @@ -333,10 +358,17 @@ struct scsi_core { }; struct sas_ha_event { - struct work_struct work; + struct sas_work work; struct sas_ha_struct *ha; }; +static inline struct sas_ha_event *to_sas_ha_event(struct work_struct *work) +{ + struct sas_ha_event *ev = container_of(work, typeof(*ev), work.work); + + return ev; +} + enum sas_ha_state { SAS_HA_REGISTERED, SAS_HA_DRAINING, diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index cdccd2eb7b6c..77670e823ed8 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h @@ -37,7 +37,7 @@ static inline int dev_is_sata(struct domain_device *dev) } int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy); -int sas_ata_init_host_and_port(struct domain_device *found_dev); +int sas_ata_init(struct domain_device *dev); void sas_ata_task_abort(struct sas_task *task); void sas_ata_strategy_handler(struct Scsi_Host *shost); void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, @@ -52,7 +52,7 @@ static inline int dev_is_sata(struct domain_device *dev) { return 0; } -static inline int sas_ata_init_host_and_port(struct domain_device *found_dev) +static inline int sas_ata_init(struct domain_device *dev) { return 0; } |