diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/common/sa1111.c | 59 | ||||
-rw-r--r-- | arch/arm/include/asm/cputype.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/sa1111.h | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/proc-fns.h | 61 | ||||
-rw-r--r-- | arch/arm/kernel/bugs.c | 4 | ||||
-rw-r--r-- | arch/arm/kernel/head-common.S | 6 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 40 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/mainstone.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-pxa/lubbock.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mainstone.c | 53 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/assabet.c | 143 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/cerf.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/generic.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/h3100.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/jornada720.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/neponset.c | 19 | ||||
-rw-r--r-- | arch/arm/mm/proc-macros.S | 10 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7-bugs.c | 17 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7.S | 2 | ||||
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 2 |
23 files changed, 291 insertions, 218 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index a2c878769eaf..45412d21aa6b 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1282,65 +1282,6 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev) } EXPORT_SYMBOL(sa1111_get_audio_rate); -void sa1111_set_io_dir(struct sa1111_dev *sadev, - unsigned int bits, unsigned int dir, - unsigned int sleep_dir) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long flags; - unsigned int val; - void __iomem *gpio = sachip->base + SA1111_GPIO; - -#define MODIFY_BITS(port, mask, dir) \ - if (mask) { \ - val = readl_relaxed(port); \ - val &= ~(mask); \ - val |= (dir) & (mask); \ - writel_relaxed(val, port); \ - } - - spin_lock_irqsave(&sachip->lock, flags); - MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir); - MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8); - MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16); - - MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir); - MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8); - MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16); - spin_unlock_irqrestore(&sachip->lock, flags); -} -EXPORT_SYMBOL(sa1111_set_io_dir); - -void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long flags; - unsigned int val; - void __iomem *gpio = sachip->base + SA1111_GPIO; - - spin_lock_irqsave(&sachip->lock, flags); - MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v); - MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8); - MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16); - spin_unlock_irqrestore(&sachip->lock, flags); -} -EXPORT_SYMBOL(sa1111_set_io); - -void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long flags; - unsigned int val; - void __iomem *gpio = sachip->base + SA1111_GPIO; - - spin_lock_irqsave(&sachip->lock, flags); - MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v); - MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8); - MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16); - spin_unlock_irqrestore(&sachip->lock, flags); -} -EXPORT_SYMBOL(sa1111_set_sleep_io); - /* * Individual device operations. */ diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 0d289240b6ca..775cac3c02bb 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -111,6 +111,7 @@ #include <linux/kernel.h> extern unsigned int processor_id; +struct proc_info_list *lookup_processor(u32 midr); #ifdef CONFIG_CPU_CP15 #define read_cpuid(reg) \ diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 798e520e8a49..d134b9a5ff94 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -433,10 +433,6 @@ int sa1111_check_dma_bug(dma_addr_t addr); int sa1111_driver_register(struct sa1111_driver *); void sa1111_driver_unregister(struct sa1111_driver *); -void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir); -void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v); -void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v); - struct sa1111_platform_data { int irq_base; /* base for cascaded on-chip IRQs */ unsigned disable_devs; diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index e25f4392e1b2..e1b6f280ab08 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h @@ -23,7 +23,7 @@ struct mm_struct; /* * Don't change this structure - ASM code relies on it. */ -extern struct processor { +struct processor { /* MISC * get data abort address/flags */ @@ -79,9 +79,13 @@ extern struct processor { unsigned int suspend_size; void (*do_suspend)(void *); void (*do_resume)(void *); -} processor; +}; #ifndef MULTI_CPU +static inline void init_proc_vtable(const struct processor *p) +{ +} + extern void cpu_proc_init(void); extern void cpu_proc_fin(void); extern int cpu_do_idle(void); @@ -98,17 +102,50 @@ extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn)); extern void cpu_do_suspend(void *); extern void cpu_do_resume(void *); #else -#define cpu_proc_init processor._proc_init -#define cpu_proc_fin processor._proc_fin -#define cpu_reset processor.reset -#define cpu_do_idle processor._do_idle -#define cpu_dcache_clean_area processor.dcache_clean_area -#define cpu_set_pte_ext processor.set_pte_ext -#define cpu_do_switch_mm processor.switch_mm -/* These three are private to arch/arm/kernel/suspend.c */ -#define cpu_do_suspend processor.do_suspend -#define cpu_do_resume processor.do_resume +extern struct processor processor; +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) +#include <linux/smp.h> +/* + * This can't be a per-cpu variable because we need to access it before + * per-cpu has been initialised. We have a couple of functions that are + * called in a pre-emptible context, and so can't use smp_processor_id() + * there, hence PROC_TABLE(). We insist in init_proc_vtable() that the + * function pointers for these are identical across all CPUs. + */ +extern struct processor *cpu_vtable[]; +#define PROC_VTABLE(f) cpu_vtable[smp_processor_id()]->f +#define PROC_TABLE(f) cpu_vtable[0]->f +static inline void init_proc_vtable(const struct processor *p) +{ + unsigned int cpu = smp_processor_id(); + *cpu_vtable[cpu] = *p; + WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area != + cpu_vtable[0]->dcache_clean_area); + WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext != + cpu_vtable[0]->set_pte_ext); +} +#else +#define PROC_VTABLE(f) processor.f +#define PROC_TABLE(f) processor.f +static inline void init_proc_vtable(const struct processor *p) +{ + processor = *p; +} +#endif + +#define cpu_proc_init PROC_VTABLE(_proc_init) +#define cpu_check_bugs PROC_VTABLE(check_bugs) +#define cpu_proc_fin PROC_VTABLE(_proc_fin) +#define cpu_reset PROC_VTABLE(reset) +#define cpu_do_idle PROC_VTABLE(_do_idle) +#define cpu_dcache_clean_area PROC_TABLE(dcache_clean_area) +#define cpu_set_pte_ext PROC_TABLE(set_pte_ext) +#define cpu_do_switch_mm PROC_VTABLE(switch_mm) + +/* These two are private to arch/arm/kernel/suspend.c */ +#define cpu_do_suspend PROC_VTABLE(do_suspend) +#define cpu_do_resume PROC_VTABLE(do_resume) #endif extern void cpu_resume(void); diff --git a/arch/arm/kernel/bugs.c b/arch/arm/kernel/bugs.c index 7be511310191..d41d3598e5e5 100644 --- a/arch/arm/kernel/bugs.c +++ b/arch/arm/kernel/bugs.c @@ -6,8 +6,8 @@ void check_other_bugs(void) { #ifdef MULTI_CPU - if (processor.check_bugs) - processor.check_bugs(); + if (cpu_check_bugs) + cpu_check_bugs(); #endif } diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 6e0375e7db05..997b02302c31 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -145,6 +145,9 @@ __mmap_switched_data: #endif .size __mmap_switched_data, . - __mmap_switched_data + __FINIT + .text + /* * This provides a C-API version of __lookup_processor_type */ @@ -156,9 +159,6 @@ ENTRY(lookup_processor_type) ldmfd sp!, {r4 - r6, r9, pc} ENDPROC(lookup_processor_type) - __FINIT - .text - /* * Read processor ID register (CP#15, CR0), and look up in the linker-built * supported processor list. Note that we can't use the absolute addresses diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index ac7e08886863..375b13f7e780 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -114,6 +114,11 @@ EXPORT_SYMBOL(elf_hwcap2); #ifdef MULTI_CPU struct processor processor __ro_after_init; +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) +struct processor *cpu_vtable[NR_CPUS] = { + [0] = &processor, +}; +#endif #endif #ifdef MULTI_TLB struct cpu_tlb_fns cpu_tlb __ro_after_init; @@ -666,28 +671,33 @@ static void __init smp_build_mpidr_hash(void) } #endif -static void __init setup_processor(void) +/* + * locate processor in the list of supported processor types. The linker + * builds this table for us from the entries in arch/arm/mm/proc-*.S + */ +struct proc_info_list *lookup_processor(u32 midr) { - struct proc_info_list *list; + struct proc_info_list *list = lookup_processor_type(midr); - /* - * locate processor in the list of supported processor - * types. The linker builds this table for us from the - * entries in arch/arm/mm/proc-*.S - */ - list = lookup_processor_type(read_cpuid_id()); if (!list) { - pr_err("CPU configuration botched (ID %08x), unable to continue.\n", - read_cpuid_id()); - while (1); + pr_err("CPU%u: configuration botched (ID %08x), CPU halted\n", + smp_processor_id(), midr); + while (1) + /* can't use cpu_relax() here as it may require MMU setup */; } + return list; +} + +static void __init setup_processor(void) +{ + unsigned int midr = read_cpuid_id(); + struct proc_info_list *list = lookup_processor(midr); + cpu_name = list->cpu_name; __cpu_architecture = __get_cpu_architecture(); -#ifdef MULTI_CPU - processor = *list->proc; -#endif + init_proc_vtable(list->proc); #ifdef MULTI_TLB cpu_tlb = *list->tlb; #endif @@ -699,7 +709,7 @@ static void __init setup_processor(void) #endif pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", - cpu_name, read_cpuid_id(), read_cpuid_id() & 15, + list->cpu_name, midr, midr & 15, proc_arch[cpu_architecture()], get_cr()); snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index f574a5e0d589..3bf82232b1be 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -42,6 +42,7 @@ #include <asm/mmu_context.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> +#include <asm/procinfo.h> #include <asm/processor.h> #include <asm/sections.h> #include <asm/tlbflush.h> @@ -102,6 +103,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd) #endif } +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) +static int secondary_biglittle_prepare(unsigned int cpu) +{ + if (!cpu_vtable[cpu]) + cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL); + + return cpu_vtable[cpu] ? 0 : -ENOMEM; +} + +static void secondary_biglittle_init(void) +{ + init_proc_vtable(lookup_processor(read_cpuid_id())->proc); +} +#else +static int secondary_biglittle_prepare(unsigned int cpu) +{ + return 0; +} + +static void secondary_biglittle_init(void) +{ +} +#endif + int __cpu_up(unsigned int cpu, struct task_struct *idle) { int ret; @@ -109,6 +134,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) if (!smp_ops.smp_boot_secondary) return -ENOSYS; + ret = secondary_biglittle_prepare(cpu); + if (ret) + return ret; + /* * We need to tell the secondary core where to find * its stack and the page tables. @@ -359,6 +388,8 @@ asmlinkage void secondary_start_kernel(void) struct mm_struct *mm = &init_mm; unsigned int cpu; + secondary_biglittle_init(); + /* * The identity mapping is uncached (strongly ordered), so * switch away from it before attempting any exclusive accesses. diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 0853eb2818b7..7298d07a9f71 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -46,6 +46,7 @@ config ARCH_LUBBOCK config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)" + select GPIO_REG select PXA27x config MACH_ZYLONITE diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index e82a7d31104e..474041a83d80 100644 --- a/arch/arm/mach-pxa/include/mach/mainstone.h +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -119,6 +119,10 @@ #define MST_PCMCIA_PWR_VCC_33 0x8 /* voltage VCC = 3.3V */ #define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */ +#define MST_PCMCIA_INPUTS \ + (MST_PCMCIA_nIRQ | MST_PCMCIA_nSPKR_BVD2 | MST_PCMCIA_nSTSCHG_BVD1 | \ + MST_PCMCIA_nVS2 | MST_PCMCIA_nVS1 | MST_PCMCIA_nCD) + /* board specific IRQs */ #define MAINSTONE_NR_IRQS IRQ_BOARD_START diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index fe2ef9b78602..8e24455facd8 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -136,10 +136,26 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { // no D+ pullup; lubbock can't connect/disconnect in software }; +/* GPIOs for SA1111 PCMCIA */ +static struct gpiod_lookup_table sa1111_pcmcia_gpio_table = { + .dev_id = "1800", + .table = { + { "sa1111", 0, "a0vpp", GPIO_ACTIVE_HIGH }, + { "sa1111", 1, "a1vpp", GPIO_ACTIVE_HIGH }, + { "sa1111", 2, "a0vcc", GPIO_ACTIVE_HIGH }, + { "sa1111", 3, "a1vcc", GPIO_ACTIVE_HIGH }, + { "lubbock", 14, "b0vcc", GPIO_ACTIVE_HIGH }, + { "lubbock", 15, "b1vcc", GPIO_ACTIVE_HIGH }, + { }, + }, +}; + static void lubbock_init_pcmcia(void) { struct clk *clk; + gpiod_add_lookup_table(&sa1111_pcmcia_gpio_table); + /* Add an alias for the SA1111 PCMCIA clock */ clk = clk_get_sys("pxa2xx-pcmcia", NULL); if (!IS_ERR(clk)) { diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index afd62a94fdbf..d40de190d630 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -13,6 +13,7 @@ * published by the Free Software Foundation. */ #include <linux/gpio.h> +#include <linux/gpio/gpio-reg.h> #include <linux/gpio/machine.h> #include <linux/init.h> #include <linux/platform_device.h> @@ -507,12 +508,64 @@ static void __init mainstone_init_keypad(void) static inline void mainstone_init_keypad(void) {} #endif +static int mst_pcmcia0_irqs[11] = { + [0 ... 10] = -1, + [5] = MAINSTONE_S0_CD_IRQ, + [8] = MAINSTONE_S0_STSCHG_IRQ, + [10] = MAINSTONE_S0_IRQ, +}; + +static int mst_pcmcia1_irqs[11] = { + [0 ... 10] = -1, + [5] = MAINSTONE_S1_CD_IRQ, + [8] = MAINSTONE_S1_STSCHG_IRQ, + [10] = MAINSTONE_S1_IRQ, +}; + +static struct gpiod_lookup_table mainstone_pcmcia_gpio_table = { + .dev_id = "pxa2xx-pcmcia", + .table = { + GPIO_LOOKUP("mst-pcmcia0", 0, "a0vpp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 1, "a1vpp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 2, "a0vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 3, "a1vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 4, "areset", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 5, "adetect", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("mst-pcmcia0", 6, "avs1", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("mst-pcmcia0", 7, "avs2", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("mst-pcmcia0", 8, "abvd1", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 9, "abvd2", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia0", 10, "aready", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 0, "b0vpp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 1, "b1vpp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 2, "b0vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 3, "b1vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 4, "breset", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 5, "bdetect", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("mst-pcmcia1", 6, "bvs1", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("mst-pcmcia1", 7, "bvs2", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("mst-pcmcia1", 8, "bbvd1", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 9, "bbvd2", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("mst-pcmcia1", 10, "bready", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static void __init mainstone_init(void) { int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config)); + /* Register board control register(s) as GPIOs */ + gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0, -1, 11, + "mst-pcmcia0", MST_PCMCIA_INPUTS, 0, NULL, + NULL, mst_pcmcia0_irqs); + gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA1, -1, 11, + "mst-pcmcia1", MST_PCMCIA_INPUTS, 0, NULL, + NULL, mst_pcmcia1_irqs); + gpiod_add_lookup_table(&mainstone_pcmcia_gpio_table); + pxa_set_ffuart_info(NULL); pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index fde7ef1ab192..af15ae50b5a2 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -6,6 +6,7 @@ config SA1100_ASSABET bool "Assabet" select ARM_SA1110_CPUFREQ select GPIO_REG + select LEDS_GPIO_REGISTER select REGULATOR select REGULATOR_FIXED_VOLTAGE help @@ -24,6 +25,7 @@ config ASSABET_NEPONSET config SA1100_CERF bool "CerfBoard" select ARM_SA1110_CPUFREQ + select LEDS_GPIO_REGISTER help The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued). More information is available at: diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 3e8c0948abcc..dfa42496ec27 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -15,6 +15,7 @@ #include <linux/errno.h> #include <linux/gpio/gpio-reg.h> #include <linux/gpio/machine.h> +#include <linux/gpio_keys.h> #include <linux/ioport.h> #include <linux/platform_data/sa11x0-serial.h> #include <linux/regulator/fixed.h> @@ -101,7 +102,7 @@ static int __init assabet_init_gpio(void __iomem *reg, u32 def_val) assabet_bcr_gc = gc; - return 0; + return gc->base; } /* @@ -479,6 +480,49 @@ static struct gpiod_lookup_table assabet_cf_vcc_gpio_table = { }, }; +static struct gpio_led assabet_leds[] __initdata = { + { + .name = "assabet:red", + .default_trigger = "cpu0", + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_KEEP, + }, { + .name = "assabet:green", + .default_trigger = "heartbeat", + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_KEEP, + }, +}; + +static const struct gpio_led_platform_data assabet_leds_pdata __initconst = { + .num_leds = ARRAY_SIZE(assabet_leds), + .leds = assabet_leds, +}; + +static struct gpio_keys_button assabet_keys_buttons[] = { + { + .gpio = 0, + .irq = IRQ_GPIO0, + .desc = "gpio0", + .wakeup = 1, + .can_disable = 1, + .debounce_interval = 5, + }, { + .gpio = 1, + .irq = IRQ_GPIO1, + .desc = "gpio1", + .wakeup = 1, + .can_disable = 1, + .debounce_interval = 5, + }, +}; + +static const struct gpio_keys_platform_data assabet_keys_pdata = { + .buttons = assabet_keys_buttons, + .nbuttons = ARRAY_SIZE(assabet_keys_buttons), + .rep = 0, +}; + static void __init assabet_init(void) { /* @@ -533,6 +577,13 @@ static void __init assabet_init(void) } + platform_device_register_resndata(NULL, "gpio-keys", 0, + NULL, 0, + &assabet_keys_pdata, + sizeof(assabet_keys_pdata)); + + gpio_led_register_device(-1, &assabet_leds_pdata); + #ifndef ASSABET_PAL_VIDEO sa11x0_register_lcd(&lq039q2ds54_info); #else @@ -726,92 +777,9 @@ static void __init assabet_map_io(void) sa1100_register_uart(2, 3); } -/* LEDs */ -#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) -struct assabet_led { - struct led_classdev cdev; - u32 mask; -}; - -/* - * The triggers lines up below will only be used if the - * LED triggers are compiled in. - */ -static const struct { - const char *name; - const char *trigger; -} assabet_leds[] = { - { "assabet:red", "cpu0",}, - { "assabet:green", "heartbeat", }, -}; - -/* - * The LED control in Assabet is reversed: - * - setting bit means turn off LED - * - clearing bit means turn on LED - */ -static void assabet_led_set(struct led_classdev *cdev, - enum led_brightness b) -{ - struct assabet_led *led = container_of(cdev, - struct assabet_led, cdev); - - if (b != LED_OFF) - ASSABET_BCR_clear(led->mask); - else - ASSABET_BCR_set(led->mask); -} - -static enum led_brightness assabet_led_get(struct led_classdev *cdev) -{ - struct assabet_led *led = container_of(cdev, - struct assabet_led, cdev); - - return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL; -} - -static int __init assabet_leds_init(void) -{ - int i; - - if (!machine_is_assabet()) - return -ENODEV; - - for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) { - struct assabet_led *led; - - led = kzalloc(sizeof(*led), GFP_KERNEL); - if (!led) - break; - - led->cdev.name = assabet_leds[i].name; - led->cdev.brightness_set = assabet_led_set; - led->cdev.brightness_get = assabet_led_get; - led->cdev.default_trigger = assabet_leds[i].trigger; - - if (!i) - led->mask = ASSABET_BCR_LED_RED; - else - led->mask = ASSABET_BCR_LED_GREEN; - - if (led_classdev_register(NULL, &led->cdev) < 0) { - kfree(led); - break; - } - } - - return 0; -} - -/* - * Since we may have triggers on any subsystem, defer registration - * until after subsystem_init. - */ -fs_initcall(assabet_leds_init); -#endif - void __init assabet_init_irq(void) { + unsigned int assabet_gpio_base; u32 def_val; sa1100_init_irq(); @@ -826,7 +794,10 @@ void __init assabet_init_irq(void) * * This must precede any driver calls to BCR_set() or BCR_clear(). */ - assabet_init_gpio((void *)&ASSABET_BCR, def_val); + assabet_gpio_base = assabet_init_gpio((void *)&ASSABET_BCR, def_val); + + assabet_leds[0].gpio = assabet_gpio_base + 13; + assabet_leds[1].gpio = assabet_gpio_base + 14; } MACHINE_START(ASSABET, "Intel-Assabet") diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index b2a4b41626ef..88e526561a24 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -89,18 +89,8 @@ static struct gpio_led_platform_data cerf_gpio_led_info = { .num_leds = ARRAY_SIZE(cerf_gpio_leds), }; -static struct platform_device cerf_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &cerf_gpio_led_info, - } -}; - - static struct platform_device *cerf_devices[] __initdata = { &cerfuart2_device, - &cerf_leds, }; #ifdef CONFIG_SA1100_CERF_FLASH_32MB @@ -176,6 +166,7 @@ static void __init cerf_init(void) { sa11x0_ppc_configure_mcp(); platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); + gpio_led_register_device(-1, &cerf_gpio_led_info); sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); sa11x0_register_mcp(&cerf_mcp_data); sa11x0_register_pcmcia(1, &cerf_cf_gpio_table); diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 800321c6cbd8..755290bf658b 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -235,18 +235,11 @@ void sa11x0_register_lcd(struct sa1100fb_mach_info *inf) sa11x0_register_device(&sa11x0fb_device, inf); } -static bool sa11x0pcmcia_legacy = true; -static struct platform_device sa11x0pcmcia_device = { - .name = "sa11x0-pcmcia", - .id = -1, -}; - void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table) { if (table) gpiod_add_lookup_table(table); platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0); - sa11x0pcmcia_legacy = false; } static struct platform_device sa11x0mtd_device = { @@ -331,9 +324,6 @@ static int __init sa1100_init(void) { pm_power_off = sa1100_power_off; - if (sa11x0pcmcia_legacy) - platform_device_register(&sa11x0pcmcia_device); - regulator_has_full_constraints(); return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices)); diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c index c6b412054a3c..9dc5bcb7326b 100644 --- a/arch/arm/mach-sa1100/h3100.c +++ b/arch/arm/mach-sa1100/h3100.c @@ -126,6 +126,7 @@ static void __init h3100_mach_init(void) { h3xxx_mach_init(); + sa11x0_register_pcmcia(-1, NULL); sa11x0_register_lcd(&h3100_lcd_info); sa11x0_register_irda(&h3100_irda_data); } diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 0a2ca9be00e6..6298bad09ef3 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -190,6 +190,17 @@ static struct platform_device s1d13xxxfb_device = { .resource = s1d13xxxfb_resources, }; +static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = { + .dev_id = "1800", + .table = { + GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static struct resource sa1111_resources[] = { [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN), [1] = DEFINE_RES_IRQ(IRQ_GPIO1), @@ -265,6 +276,7 @@ static int __init jornada720_init(void) udelay(20); /* give it some time to restart */ gpiod_add_lookup_table(&jornada_ts_gpiod_table); + gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index b1823f445358..eb60a71cf125 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -5,6 +5,7 @@ #include <linux/err.h> #include <linux/gpio/driver.h> #include <linux/gpio/gpio-reg.h> +#include <linux/gpio/machine.h> #include <linux/init.h> #include <linux/ioport.h> #include <linux/irq.h> @@ -96,6 +97,19 @@ struct neponset_drvdata { struct gpio_chip *gpio[4]; }; +static struct gpiod_lookup_table neponset_pcmcia_table = { + .dev_id = "1800", + .table = { + GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static struct neponset_drvdata *nep; void neponset_ncr_frob(unsigned int mask, unsigned int val) @@ -374,6 +388,8 @@ static int neponset_probe(struct platform_device *dev) d->base + AUD_CTL, AUD_NGPIO, false, neponset_aud_names); + gpiod_add_lookup_table(&neponset_pcmcia_table); + /* * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately * something on the Neponset activates this IRQ on sleep (eth?) @@ -424,6 +440,9 @@ static int neponset_remove(struct platform_device *dev) platform_device_unregister(d->sa1111); if (!IS_ERR(d->smc91x)) platform_device_unregister(d->smc91x); + + gpiod_remove_lookup_table(&neponset_pcmcia_table); + irq_set_chained_handler(irq, NULL); irq_free_descs(d->irq_base, NEP_IRQ_NR); nep = NULL; diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 81d0efb055c6..5461d589a1e2 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -274,6 +274,13 @@ .endm .macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0, bugs=0 +/* + * If we are building for big.Little with branch predictor hardening, + * we need the processor function tables to remain available after boot. + */ +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) + .section ".rodata" +#endif .type \name\()_processor_functions, #object .align 2 ENTRY(\name\()_processor_functions) @@ -309,6 +316,9 @@ ENTRY(\name\()_processor_functions) .endif .size \name\()_processor_functions, . - \name\()_processor_functions +#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) + .previous +#endif .endm .macro define_cache_functions name:req diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c index 5544b82a2e7a..9a07916af8dd 100644 --- a/arch/arm/mm/proc-v7-bugs.c +++ b/arch/arm/mm/proc-v7-bugs.c @@ -52,8 +52,6 @@ static void cpu_v7_spectre_init(void) case ARM_CPU_PART_CORTEX_A17: case ARM_CPU_PART_CORTEX_A73: case ARM_CPU_PART_CORTEX_A75: - if (processor.switch_mm != cpu_v7_bpiall_switch_mm) - goto bl_error; per_cpu(harden_branch_predictor_fn, cpu) = harden_branch_predictor_bpiall; spectre_v2_method = "BPIALL"; @@ -61,8 +59,6 @@ static void cpu_v7_spectre_init(void) case ARM_CPU_PART_CORTEX_A15: case ARM_CPU_PART_BRAHMA_B15: - if (processor.switch_mm != cpu_v7_iciallu_switch_mm) - goto bl_error; per_cpu(harden_branch_predictor_fn, cpu) = harden_branch_predictor_iciallu; spectre_v2_method = "ICIALLU"; @@ -88,11 +84,9 @@ static void cpu_v7_spectre_init(void) ARM_SMCCC_ARCH_WORKAROUND_1, &res); if ((int)res.a0 != 0) break; - if (processor.switch_mm != cpu_v7_hvc_switch_mm && cpu) - goto bl_error; per_cpu(harden_branch_predictor_fn, cpu) = call_hvc_arch_workaround_1; - processor.switch_mm = cpu_v7_hvc_switch_mm; + cpu_do_switch_mm = cpu_v7_hvc_switch_mm; spectre_v2_method = "hypervisor"; break; @@ -101,11 +95,9 @@ static void cpu_v7_spectre_init(void) ARM_SMCCC_ARCH_WORKAROUND_1, &res); if ((int)res.a0 != 0) break; - if (processor.switch_mm != cpu_v7_smc_switch_mm && cpu) - goto bl_error; per_cpu(harden_branch_predictor_fn, cpu) = call_smc_arch_workaround_1; - processor.switch_mm = cpu_v7_smc_switch_mm; + cpu_do_switch_mm = cpu_v7_smc_switch_mm; spectre_v2_method = "firmware"; break; @@ -119,11 +111,6 @@ static void cpu_v7_spectre_init(void) if (spectre_v2_method) pr_info("CPU%u: Spectre v2: using %s workaround\n", smp_processor_id(), spectre_v2_method); - return; - -bl_error: - pr_err("CPU%u: Spectre v2: incorrect context switching function, system vulnerable\n", - cpu); } #else static void cpu_v7_spectre_init(void) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 6fe52819e014..339eb17c9808 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -112,7 +112,7 @@ ENTRY(cpu_v7_hvc_switch_mm) hvc #0 ldmfd sp!, {r0 - r3} b cpu_v7_switch_mm -ENDPROC(cpu_v7_smc_switch_mm) +ENDPROC(cpu_v7_hvc_switch_mm) #endif ENTRY(cpu_v7_iciallu_switch_mm) mov r3, #0 diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index aff6e6eadc70..ee7b07938dd5 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -573,7 +573,7 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp, */ ufp_exc->fpexc = hwstate->fpexc; ufp_exc->fpinst = hwstate->fpinst; - ufp_exc->fpinst2 = ufp_exc->fpinst2; + ufp_exc->fpinst2 = hwstate->fpinst2; /* Ensure that VFP is disabled. */ vfp_flush_hwstate(thread); |