From: Arnd Bergmann Date: Mon, 9 Jan 2012 16:14:07 +0000 (+0000) Subject: Merge branch 'samsung/cleanup' into samsung/driver X-Git-Tag: upstream/snapshot3+hdmi~8406^2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=142f2101a86ade2d6c9dfbedf82e1b5b31c8fce6;p=platform%2Fadaptation%2Frenesas_rcar%2Frenesas_kernel.git Merge branch 'samsung/cleanup' into samsung/driver Conflicts: arch/arm/mach-s5p64x0/cpu.c -> common.c More changes to a file that got moved into common.c, see previous conflict resolutions. Signed-off-by: Arnd Bergmann --- 142f2101a86ade2d6c9dfbedf82e1b5b31c8fce6 diff --cc arch/arm/mach-exynos/include/mach/map.h index e6ba01d,d182986..b1de3e7 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@@ -152,11 -148,7 +152,10 @@@ #define S3C_PA_RTC EXYNOS4_PA_RTC #define S3C_PA_WDT EXYNOS4_PA_WATCHDOG #define S3C_PA_UART EXYNOS4_PA_UART +#define S3C_PA_SPI0 EXYNOS4_PA_SPI0 +#define S3C_PA_SPI1 EXYNOS4_PA_SPI1 +#define S3C_PA_SPI2 EXYNOS4_PA_SPI2 - #define S5P_PA_CHIPID EXYNOS4_PA_CHIPID #define S5P_PA_EHCI EXYNOS4_PA_EHCI #define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0 #define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 diff --cc arch/arm/mach-s5p64x0/common.c index 0000000,fcf0778..146fae1 mode 000000,100644..100644 --- a/arch/arm/mach-s5p64x0/common.c +++ b/arch/arm/mach-s5p64x0/common.c @@@ -1,0 -1,437 +1,446 @@@ + /* + * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Common Codes for S5P64X0 machines + * + * 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 + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + + #include + #include + #include + #include ++#include + #include + #include + #include + #include + #include + #include + + #include "common.h" + + static const char name_s5p6440[] = "S5P6440"; + static const char name_s5p6450[] = "S5P6450"; + + static struct cpu_table cpu_ids[] __initdata = { + { + .idcode = S5P6440_CPU_ID, + .idmask = S5P64XX_CPU_MASK, + .map_io = s5p6440_map_io, + .init_clocks = s5p6440_init_clocks, + .init_uarts = s5p6440_init_uarts, + .init = s5p64x0_init, + .name = name_s5p6440, + }, { + .idcode = S5P6450_CPU_ID, + .idmask = S5P64XX_CPU_MASK, + .map_io = s5p6450_map_io, + .init_clocks = s5p6450_init_clocks, + .init_uarts = s5p6450_init_uarts, + .init = s5p64x0_init, + .name = name_s5p6450, + }, + }; + + /* Initial IO mappings */ + + static struct map_desc s5p64x0_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_CHIPID, + .pfn = __phys_to_pfn(S5P64X0_PA_CHIPID), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_SYS, + .pfn = __phys_to_pfn(S5P64X0_PA_SYSCON), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_TIMER, + .pfn = __phys_to_pfn(S5P64X0_PA_TIMER), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_WATCHDOG, + .pfn = __phys_to_pfn(S5P64X0_PA_WDT), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_SROMC, + .pfn = __phys_to_pfn(S5P64X0_PA_SROMC), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P64X0_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5P64X0_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5P64X0_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, + }; + + static struct map_desc s5p6440_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S5P6440_PA_UART(0)), + .length = SZ_4K, + .type = MT_DEVICE, + }, + }; + + static struct map_desc s5p6450_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S5P6450_PA_UART(0)), + .length = SZ_512K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART + SZ_512K, + .pfn = __phys_to_pfn(S5P6450_PA_UART(5)), + .length = SZ_4K, + .type = MT_DEVICE, + }, + }; + + static void s5p64x0_idle(void) + { + unsigned long val; + + if (!need_resched()) { + val = __raw_readl(S5P64X0_PWR_CFG); + val &= ~(0x3 << 5); + val |= (0x1 << 5); + __raw_writel(val, S5P64X0_PWR_CFG); + + cpu_do_idle(); + } + local_irq_enable(); + } + + /* + * s5p64x0_map_io + * + * register the standard CPU IO areas + */ + + void __init s5p64x0_init_io(struct map_desc *mach_desc, int size) + { + /* initialize the io descriptors we need for initialization */ + iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); + if (mach_desc) + iotable_init(mach_desc, size); + + /* detect cpu id and rev. */ + s5p_init_cpu(S5P64X0_SYS_ID); + + s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); + } + + void __init s5p6440_map_io(void) + { + /* initialize any device information early */ + s3c_adc_setname("s3c64xx-adc"); + s3c_fb_setname("s5p64x0-fb"); + ++ s5p64x0_default_sdhci0(); ++ s5p64x0_default_sdhci1(); ++ s5p6440_default_sdhci2(); ++ + iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); + init_consistent_dma_size(SZ_8M); + } + + void __init s5p6450_map_io(void) + { + /* initialize any device information early */ + s3c_adc_setname("s3c64xx-adc"); + s3c_fb_setname("s5p64x0-fb"); + ++ s5p64x0_default_sdhci0(); ++ s5p64x0_default_sdhci1(); ++ s5p6450_default_sdhci2(); ++ + iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc)); + init_consistent_dma_size(SZ_8M); + } + + /* + * s5p64x0_init_clocks + * + * register and setup the CPU clocks + */ + + void __init s5p6440_init_clocks(int xtal) + { + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6440_register_clocks(); + s5p6440_setup_clocks(); + } + + void __init s5p6450_init_clocks(int xtal) + { + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6450_register_clocks(); + s5p6450_setup_clocks(); + } + + /* + * s5p64x0_init_irq + * + * register the CPU interrupts + */ + + void __init s5p6440_init_irq(void) + { + /* S5P6440 supports 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)] + * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22] + */ + vic[0] = 0xff800ae7; + vic[1] = 0xffbf23e5; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); + } + + void __init s5p6450_init_irq(void) + { + /* S5P6450 supports only 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[(13-15), (21-22)] + * VIC1 is missing IRQ VIC1[12, 14, 23] + */ + vic[0] = 0xff9f1fff; + vic[1] = 0xff7fafff; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); + } + + struct sysdev_class s5p64x0_sysclass = { + .name = "s5p64x0-core", + }; + + static struct sys_device s5p64x0_sysdev = { + .cls = &s5p64x0_sysclass, + }; + + static int __init s5p64x0_core_init(void) + { + return sysdev_class_register(&s5p64x0_sysclass); + } + core_initcall(s5p64x0_core_init); + + int __init s5p64x0_init(void) + { + printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n"); + + /* set idle function */ + pm_idle = s5p64x0_idle; + + return sysdev_register(&s5p64x0_sysdev); + } + + /* uart registration process */ + void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) + { + int uart; + + for (uart = 0; uart < no; uart++) { + s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart); + s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; + } + + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); + } + + void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) + { + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); + } + + #define eint_offset(irq) ((irq) - IRQ_EINT(0)) + + static int s5p64x0_irq_eint_set_type(struct irq_data *data, unsigned int type) + { + int offs = eint_offset(data->irq); + int shift; + u32 ctrl, mask; + u32 newvalue = 0; + + if (offs > 15) + return -EINVAL; + + switch (type) { + case IRQ_TYPE_NONE: + printk(KERN_WARNING "No edge setting!\n"); + break; + case IRQ_TYPE_EDGE_RISING: + newvalue = S3C2410_EXTINT_RISEEDGE; + break; + case IRQ_TYPE_EDGE_FALLING: + newvalue = S3C2410_EXTINT_FALLEDGE; + break; + case IRQ_TYPE_EDGE_BOTH: + newvalue = S3C2410_EXTINT_BOTHEDGE; + break; + case IRQ_TYPE_LEVEL_LOW: + newvalue = S3C2410_EXTINT_LOWLEV; + break; + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S3C2410_EXTINT_HILEV; + break; + default: + printk(KERN_ERR "No such irq type %d", type); + return -EINVAL; + } + + shift = (offs / 2) * 4; + mask = 0x7 << shift; + + ctrl = __raw_readl(S5P64X0_EINT0CON0) & ~mask; + ctrl |= newvalue << shift; + __raw_writel(ctrl, S5P64X0_EINT0CON0); + + /* Configure the GPIO pin for 6450 or 6440 based on CPU ID */ + if (soc_is_s5p6450()) + s3c_gpio_cfgpin(S5P6450_GPN(offs), S3C_GPIO_SFN(2)); + else + s3c_gpio_cfgpin(S5P6440_GPN(offs), S3C_GPIO_SFN(2)); + + return 0; + } + + /* + * s5p64x0_irq_demux_eint + * + * This function demuxes the IRQ from the group0 external interrupts, + * from IRQ_EINT(0) to IRQ_EINT(15). It is designed to be inlined into + * the specific handlers s5p64x0_irq_demux_eintX_Y. + */ + static inline void s5p64x0_irq_demux_eint(unsigned int start, unsigned int end) + { + u32 status = __raw_readl(S5P64X0_EINT0PEND); + u32 mask = __raw_readl(S5P64X0_EINT0MASK); + unsigned int irq; + + status &= ~mask; + status >>= start; + status &= (1 << (end - start + 1)) - 1; + + for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) { + if (status & 1) + generic_handle_irq(irq); + status >>= 1; + } + } + + static void s5p64x0_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc) + { + s5p64x0_irq_demux_eint(0, 3); + } + + static void s5p64x0_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc) + { + s5p64x0_irq_demux_eint(4, 11); + } + + static void s5p64x0_irq_demux_eint12_15(unsigned int irq, + struct irq_desc *desc) + { + s5p64x0_irq_demux_eint(12, 15); + } + + static int s5p64x0_alloc_gc(void) + { + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + + gc = irq_alloc_generic_chip("s5p64x0-eint", 1, S5P_IRQ_EINT_BASE, + S5P_VA_GPIO, handle_level_irq); + if (!gc) { + printk(KERN_ERR "%s: irq_alloc_generic_chip for group 0" + "external interrupts failed\n", __func__); + return -EINVAL; + } + + ct = gc->chip_types; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + ct->chip.irq_set_type = s5p64x0_irq_eint_set_type; + ct->chip.irq_set_wake = s3c_irqext_wake; + ct->regs.ack = EINT0PEND_OFFSET; + ct->regs.mask = EINT0MASK_OFFSET; + irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE, + IRQ_NOREQUEST | IRQ_NOPROBE, 0); + return 0; + } + + static int __init s5p64x0_init_irq_eint(void) + { + int ret = s5p64x0_alloc_gc(); + irq_set_chained_handler(IRQ_EINT0_3, s5p64x0_irq_demux_eint0_3); + irq_set_chained_handler(IRQ_EINT4_11, s5p64x0_irq_demux_eint4_11); + irq_set_chained_handler(IRQ_EINT12_15, s5p64x0_irq_demux_eint12_15); + + return ret; + } + arch_initcall(s5p64x0_init_irq_eint); + + void s5p64x0_restart(char mode, const char *cmd) + { + if (mode != 's') + arch_wdt_reset(); + + soft_restart(0); + } diff --cc arch/arm/mach-s5p64x0/mach-smdk6440.c index fe168a0,34d98a1..a40e325 --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@@ -53,8 -52,9 +53,10 @@@ #include #include #include +#include + #include "common.h" + #define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ S3C2410_UCON_RXILEVEL | \ S3C2410_UCON_TXIRQMODE | \ diff --cc arch/arm/mach-s5p64x0/mach-smdk6450.c index 242a415,135cf5d..efb69e2 --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@@ -53,8 -52,9 +53,10 @@@ #include #include #include +#include + #include "common.h" + #define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ S3C2410_UCON_RXILEVEL | \ S3C2410_UCON_TXIRQMODE | \