Commit 5889fc32 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM: SoC fixes from Olof Johansson:
 "I was hoping to be done with fixes for 3.4 but we got two branches
  from subarch maintainers the last couple of days.  So here is one
  last(?) pull request for arm-soc containing 7 patches:

   - Five of them are for shmobile dealing with SMP setup and compile
     failures
   - The remaining two are for regressions on the Samsung platforms"

* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  ARM: EXYNOS: fix ctrlbit for exynos5_clk_pdma1
  ARM: EXYNOS: use s5p-timer for UniversalC210 board
  ARM / mach-shmobile: Invalidate caches when booting secondary cores
  ARM / mach-shmobile: sh73a0 SMP TWD boot regression fix
  ARM / mach-shmobile: r8a7779 SMP TWD boot regression fix
  ARM: mach-shmobile: convert ag5evm to use the generic MMC GPIO hotplug helper
  ARM: mach-shmobile: convert mackerel to use the generic MMC GPIO hotplug helper
parents 1bc4a5be 85d5c4a3
...@@ -232,6 +232,9 @@ config MACH_ARMLEX4210 ...@@ -232,6 +232,9 @@ config MACH_ARMLEX4210
config MACH_UNIVERSAL_C210 config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board" bool "Mobile UNIVERSAL_C210 Board"
select CPU_EXYNOS4210 select CPU_EXYNOS4210
select S5P_HRT
select CLKSRC_MMIO
select HAVE_SCHED_CLOCK
select S5P_GPIO_INT select S5P_GPIO_INT
select S5P_DEV_FIMC0 select S5P_DEV_FIMC0
select S5P_DEV_FIMC1 select S5P_DEV_FIMC1
......
...@@ -678,7 +678,7 @@ static struct clk exynos5_clk_pdma1 = { ...@@ -678,7 +678,7 @@ static struct clk exynos5_clk_pdma1 = {
.name = "dma", .name = "dma",
.devname = "dma-pl330.1", .devname = "dma-pl330.1",
.enable = exynos5_clk_ip_fsys_ctrl, .enable = exynos5_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 1), .ctrlbit = (1 << 2),
}; };
static struct clk exynos5_clk_mdma1 = { static struct clk exynos5_clk_mdma1 = {
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <plat/pd.h> #include <plat/pd.h>
#include <plat/regs-fb-v4.h> #include <plat/regs-fb-v4.h>
#include <plat/fimc-core.h> #include <plat/fimc-core.h>
#include <plat/s5p-time.h>
#include <plat/camport.h> #include <plat/camport.h>
#include <plat/mipi_csis.h> #include <plat/mipi_csis.h>
...@@ -1063,6 +1064,7 @@ static void __init universal_map_io(void) ...@@ -1063,6 +1064,7 @@ static void __init universal_map_io(void)
exynos_init_io(NULL, 0); exynos_init_io(NULL, 0);
s3c24xx_init_clocks(24000000); s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
} }
static void s5p_tv_setup(void) static void s5p_tv_setup(void)
...@@ -1113,7 +1115,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") ...@@ -1113,7 +1115,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
.map_io = universal_map_io, .map_io = universal_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
.init_machine = universal_machine_init, .init_machine = universal_machine_init,
.timer = &exynos4_timer, .timer = &s5p_timer,
.reserve = &universal_reserve, .reserve = &universal_reserve,
.restart = exynos4_restart, .restart = exynos4_restart,
MACHINE_END MACHINE_END
...@@ -365,23 +365,13 @@ static struct platform_device mipidsi0_device = { ...@@ -365,23 +365,13 @@ static struct platform_device mipidsi0_device = {
}; };
/* SDHI0 */ /* SDHI0 */
static irqreturn_t ag5evm_sdhi0_gpio_cd(int irq, void *arg)
{
struct device *dev = arg;
struct sh_mobile_sdhi_info *info = dev->platform_data;
struct tmio_mmc_data *pdata = info->pdata;
tmio_mmc_cd_wakeup(pdata);
return IRQ_HANDLED;
}
static struct sh_mobile_sdhi_info sdhi0_info = { static struct sh_mobile_sdhi_info sdhi0_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
.tmio_caps = MMC_CAP_SD_HIGHSPEED, .tmio_caps = MMC_CAP_SD_HIGHSPEED,
.tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29, .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
.cd_gpio = GPIO_PORT251,
}; };
static struct resource sdhi0_resources[] = { static struct resource sdhi0_resources[] = {
...@@ -557,7 +547,6 @@ static void __init ag5evm_init(void) ...@@ -557,7 +547,6 @@ static void __init ag5evm_init(void)
lcd_backlight_reset(); lcd_backlight_reset();
/* enable SDHI0 on CN15 [SD I/F] */ /* enable SDHI0 on CN15 [SD I/F] */
gpio_request(GPIO_FN_SDHICD0, NULL);
gpio_request(GPIO_FN_SDHIWP0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL);
gpio_request(GPIO_FN_SDHICMD0, NULL); gpio_request(GPIO_FN_SDHICMD0, NULL);
gpio_request(GPIO_FN_SDHICLK0, NULL); gpio_request(GPIO_FN_SDHICLK0, NULL);
...@@ -566,13 +555,6 @@ static void __init ag5evm_init(void) ...@@ -566,13 +555,6 @@ static void __init ag5evm_init(void)
gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_1, NULL);
gpio_request(GPIO_FN_SDHID0_0, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL);
if (!request_irq(intcs_evt2irq(0x3c0), ag5evm_sdhi0_gpio_cd,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
"sdhi0 cd", &sdhi0_device.dev))
sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD;
else
pr_warn("Unable to setup SDHI0 GPIO IRQ\n");
/* enable SDHI1 on CN4 [WLAN I/F] */ /* enable SDHI1 on CN4 [WLAN I/F] */
gpio_request(GPIO_FN_SDHICLK1, NULL); gpio_request(GPIO_FN_SDHICLK1, NULL);
gpio_request(GPIO_FN_SDHICMD1_PU, NULL); gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
......
...@@ -1011,21 +1011,12 @@ static int slot_cn7_get_cd(struct platform_device *pdev) ...@@ -1011,21 +1011,12 @@ static int slot_cn7_get_cd(struct platform_device *pdev)
} }
/* SDHI0 */ /* SDHI0 */
static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg)
{
struct device *dev = arg;
struct sh_mobile_sdhi_info *info = dev->platform_data;
struct tmio_mmc_data *pdata = info->pdata;
tmio_mmc_cd_wakeup(pdata);
return IRQ_HANDLED;
}
static struct sh_mobile_sdhi_info sdhi0_info = { static struct sh_mobile_sdhi_info sdhi0_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
.tmio_flags = TMIO_MMC_USE_GPIO_CD,
.tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
.cd_gpio = GPIO_PORT172,
}; };
static struct resource sdhi0_resources[] = { static struct resource sdhi0_resources[] = {
...@@ -1384,7 +1375,6 @@ static void __init mackerel_init(void) ...@@ -1384,7 +1375,6 @@ static void __init mackerel_init(void)
{ {
u32 srcr4; u32 srcr4;
struct clk *clk; struct clk *clk;
int ret;
/* External clock source */ /* External clock source */
clk_set_rate(&sh7372_dv_clki_clk, 27000000); clk_set_rate(&sh7372_dv_clki_clk, 27000000);
...@@ -1481,7 +1471,6 @@ static void __init mackerel_init(void) ...@@ -1481,7 +1471,6 @@ static void __init mackerel_init(void)
irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);
/* enable SDHI0 */ /* enable SDHI0 */
gpio_request(GPIO_FN_SDHICD0, NULL);
gpio_request(GPIO_FN_SDHIWP0, NULL); gpio_request(GPIO_FN_SDHIWP0, NULL);
gpio_request(GPIO_FN_SDHICMD0, NULL); gpio_request(GPIO_FN_SDHICMD0, NULL);
gpio_request(GPIO_FN_SDHICLK0, NULL); gpio_request(GPIO_FN_SDHICLK0, NULL);
...@@ -1490,13 +1479,6 @@ static void __init mackerel_init(void) ...@@ -1490,13 +1479,6 @@ static void __init mackerel_init(void)
gpio_request(GPIO_FN_SDHID0_1, NULL); gpio_request(GPIO_FN_SDHID0_1, NULL);
gpio_request(GPIO_FN_SDHID0_0, NULL); gpio_request(GPIO_FN_SDHID0_0, NULL);
ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd,
IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev);
if (!ret)
sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD;
else
pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret);
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
/* enable SDHI1 */ /* enable SDHI1 */
gpio_request(GPIO_FN_SDHICMD1, NULL); gpio_request(GPIO_FN_SDHICMD1, NULL);
......
...@@ -16,6 +16,59 @@ ...@@ -16,6 +16,59 @@
__CPUINIT __CPUINIT
/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks!
*
* The secondary kernel init calls v7_flush_dcache_all before it enables
* the L1; however, the L1 comes out of reset in an undefined state, so
* the clean + invalidate performed by v7_flush_dcache_all causes a bunch
* of cache lines with uninitialized data and uninitialized tags to get
* written out to memory, which does really unpleasant things to the main
* processor. We fix this by performing an invalidate, rather than a
* clean + invalidate, before jumping into the kernel.
*
* This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
* to be called for both secondary cores startup and primary core resume
* procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
*/
ENTRY(v7_invalidate_l1)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 2, r0, c0, c0, 0
mrc p15, 1, r0, c0, c0, 0
ldr r1, =0x7fff
and r2, r1, r0, lsr #13
ldr r1, =0x3ff
and r3, r1, r0, lsr #3 @ NumWays - 1
add r2, r2, #1 @ NumSets
and r0, r0, #0x7
add r0, r0, #4 @ SetShift
clz r1, r3 @ WayShift
add r4, r3, #1 @ NumWays
1: sub r2, r2, #1 @ NumSets--
mov r3, r4 @ Temp = NumWays
2: subs r3, r3, #1 @ Temp--
mov r5, r3, lsl r1
mov r6, r2, lsl r0
orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
mcr p15, 0, r5, c7, c6, 2
bgt 2b
cmp r2, #0
bgt 1b
dsb
isb
mov pc, lr
ENDPROC(v7_invalidate_l1)
ENTRY(shmobile_invalidate_start)
bl v7_invalidate_l1
b secondary_startup
ENDPROC(shmobile_invalidate_start)
/* /*
* Reset vector for secondary CPUs. * Reset vector for secondary CPUs.
* This will be mapped at address 0 by SBAR register. * This will be mapped at address 0 by SBAR register.
...@@ -24,4 +77,5 @@ ...@@ -24,4 +77,5 @@
.align 12 .align 12
ENTRY(shmobile_secondary_vector) ENTRY(shmobile_secondary_vector)
ldr pc, 1f ldr pc, 1f
1: .long secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET 1: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
ENDPROC(shmobile_secondary_vector)
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
extern void shmobile_earlytimer_init(void); extern void shmobile_earlytimer_init(void);
extern struct sys_timer shmobile_timer; extern struct sys_timer shmobile_timer;
struct twd_local_timer; struct twd_local_timer;
void shmobile_twd_init(struct twd_local_timer *twd_local_timer);
extern void shmobile_setup_console(void); extern void shmobile_setup_console(void);
extern void shmobile_secondary_vector(void); extern void shmobile_secondary_vector(void);
extern int shmobile_platform_cpu_kill(unsigned int cpu); extern int shmobile_platform_cpu_kill(unsigned int cpu);
...@@ -82,5 +81,6 @@ extern int r8a7779_platform_cpu_kill(unsigned int cpu); ...@@ -82,5 +81,6 @@ extern int r8a7779_platform_cpu_kill(unsigned int cpu);
extern void r8a7779_secondary_init(unsigned int cpu); extern void r8a7779_secondary_init(unsigned int cpu);
extern int r8a7779_boot_secondary(unsigned int cpu); extern int r8a7779_boot_secondary(unsigned int cpu);
extern void r8a7779_smp_prepare_cpus(void); extern void r8a7779_smp_prepare_cpus(void);
extern void r8a7779_register_twd(void);
#endif /* __ARCH_MACH_COMMON_H */ #endif /* __ARCH_MACH_COMMON_H */
...@@ -262,10 +262,14 @@ void __init r8a7779_add_standard_devices(void) ...@@ -262,10 +262,14 @@ void __init r8a7779_add_standard_devices(void)
ARRAY_SIZE(r8a7779_late_devices)); ARRAY_SIZE(r8a7779_late_devices));
} }
/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
void __init __weak r8a7779_register_twd(void) { }
static void __init r8a7779_earlytimer_init(void) static void __init r8a7779_earlytimer_init(void)
{ {
r8a7779_clock_init(); r8a7779_clock_init();
shmobile_earlytimer_init(); shmobile_earlytimer_init();
r8a7779_register_twd();
} }
void __init r8a7779_add_early_devices(void) void __init r8a7779_add_early_devices(void)
......
...@@ -688,10 +688,14 @@ void __init sh73a0_add_standard_devices(void) ...@@ -688,10 +688,14 @@ void __init sh73a0_add_standard_devices(void)
ARRAY_SIZE(sh73a0_late_devices)); ARRAY_SIZE(sh73a0_late_devices));
} }
/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
void __init __weak sh73a0_register_twd(void) { }
static void __init sh73a0_earlytimer_init(void) static void __init sh73a0_earlytimer_init(void)
{ {
sh73a0_clock_init(); sh73a0_clock_init();
shmobile_earlytimer_init(); shmobile_earlytimer_init();
sh73a0_register_twd();
} }
void __init sh73a0_add_early_devices(void) void __init sh73a0_add_early_devices(void)
......
...@@ -64,8 +64,15 @@ static void __iomem *scu_base_addr(void) ...@@ -64,8 +64,15 @@ static void __iomem *scu_base_addr(void)
static DEFINE_SPINLOCK(scu_lock); static DEFINE_SPINLOCK(scu_lock);
static unsigned long tmp; static unsigned long tmp;
#ifdef CONFIG_HAVE_ARM_TWD
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
void __init r8a7779_register_twd(void)
{
twd_local_timer_register(&twd_local_timer);
}
#endif
static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
{ {
void __iomem *scu_base = scu_base_addr(); void __iomem *scu_base = scu_base_addr();
...@@ -84,7 +91,6 @@ unsigned int __init r8a7779_get_core_count(void) ...@@ -84,7 +91,6 @@ unsigned int __init r8a7779_get_core_count(void)
{ {
void __iomem *scu_base = scu_base_addr(); void __iomem *scu_base = scu_base_addr();
shmobile_twd_init(&twd_local_timer);
return scu_get_core_count(scu_base); return scu_get_core_count(scu_base);
} }
......
...@@ -42,7 +42,13 @@ static void __iomem *scu_base_addr(void) ...@@ -42,7 +42,13 @@ static void __iomem *scu_base_addr(void)
static DEFINE_SPINLOCK(scu_lock); static DEFINE_SPINLOCK(scu_lock);
static unsigned long tmp; static unsigned long tmp;
#ifdef CONFIG_HAVE_ARM_TWD
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
void __init sh73a0_register_twd(void)
{
twd_local_timer_register(&twd_local_timer);
}
#endif
static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
{ {
...@@ -62,7 +68,6 @@ unsigned int __init sh73a0_get_core_count(void) ...@@ -62,7 +68,6 @@ unsigned int __init sh73a0_get_core_count(void)
{ {
void __iomem *scu_base = scu_base_addr(); void __iomem *scu_base = scu_base_addr();
shmobile_twd_init(&twd_local_timer);
return scu_get_core_count(scu_base); return scu_get_core_count(scu_base);
} }
......
...@@ -46,15 +46,6 @@ static void __init shmobile_timer_init(void) ...@@ -46,15 +46,6 @@ static void __init shmobile_timer_init(void)
{ {
} }
void __init shmobile_twd_init(struct twd_local_timer *twd_local_timer)
{
#ifdef CONFIG_HAVE_ARM_TWD
int err = twd_local_timer_register(twd_local_timer);
if (err)
pr_err("twd_local_timer_register failed %d\n", err);
#endif
}
struct sys_timer shmobile_timer = { struct sys_timer shmobile_timer = {
.init = shmobile_timer_init, .init = shmobile_timer_init,
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment