diff options
Diffstat (limited to 'arch/arm/mach-s3c24xx')
-rw-r--r-- | arch/arm/mach-s3c24xx/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/clock-s3c2416.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/clock-s3c2443.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/common-s3c2443.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/dma-s3c2443.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/include/mach/dma.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/include/mach/irqs.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/include/mach/map.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/irq-s3c2416.c | 98 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/s3c2416.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c24xx/setup-spi.c | 39 |
12 files changed, 196 insertions, 10 deletions
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index b34287ab5af..e24961109b7 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -518,6 +518,11 @@ config S3C2443_DMA help Internal config node for S3C2443 DMA support +config S3C2443_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations + endif # CPU_S3C2443 || CPU_S3C2416 if CPU_S3C2443 diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile index 3518fe812d5..d0f3a92f9e4 100644 --- a/arch/arm/mach-s3c24xx/Makefile +++ b/arch/arm/mach-s3c24xx/Makefile @@ -91,5 +91,6 @@ obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o # device setup obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi.o obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c index dbc9ab4aaca..8702ecfaab3 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2416.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c @@ -144,6 +144,7 @@ static struct clk_lookup s3c2416_clk_lookup[] = { CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk), CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk), CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &hsspi_mux.clk), }; void __init s3c2416_init_clocks(int xtal) diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c index efb3ac35956..a4c5a520d99 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2443.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c @@ -179,6 +179,11 @@ static struct clk *clks[] __initdata = { &clk_hsmmc, }; +static struct clk_lookup s3c2443_clk_lookup[] = { + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_hsmmc), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_hsspi.clk), +}; + void __init s3c2443_init_clocks(int xtal) { unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); @@ -210,6 +215,7 @@ void __init s3c2443_init_clocks(int xtal) s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup)); s3c_pwmclk_init(); } diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c index 460431589f3..aeeb2be283f 100644 --- a/arch/arm/mach-s3c24xx/common-s3c2443.c +++ b/arch/arm/mach-s3c24xx/common-s3c2443.c @@ -424,11 +424,6 @@ static struct clk init_clocks_off[] = { .enable = s3c2443_clkcon_enable_p, .ctrlbit = S3C2443_PCLKCON_IIS, }, { - .name = "hsspi", - .parent = &clk_p, - .enable = s3c2443_clkcon_enable_p, - .ctrlbit = S3C2443_PCLKCON_HSSPI, - }, { .name = "adc", .parent = &clk_p, .enable = s3c2443_clkcon_enable_p, @@ -562,6 +557,14 @@ static struct clk hsmmc1_clk = { .ctrlbit = S3C2443_HCLKCON_HSMMC, }; +static struct clk hsspi_clk = { + .name = "spi", + .devname = "s3c64xx-spi.0", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_HSSPI, +}; + /* EPLLCON compatible enough to get on/off information */ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) @@ -612,6 +615,7 @@ static struct clk *clks[] __initdata = { &clk_usb_bus, &clk_armdiv, &hsmmc1_clk, + &hsspi_clk, }; static struct clksrc_clk *clksrcs[] __initdata = { @@ -629,6 +633,7 @@ static struct clk_lookup s3c2443_clk_lookup[] = { CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk), CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &hsspi_clk), }; void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c index e227c472a40..2d94228d286 100644 --- a/arch/arm/mach-s3c24xx/dma-s3c2443.c +++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c @@ -55,12 +55,20 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { .name = "sdi", .channels = MAP(S3C2443_DMAREQSEL_SDI), }, - [DMACH_SPI0] = { - .name = "spi0", + [DMACH_SPI0_RX] = { + .name = "spi0-rx", + .channels = MAP(S3C2443_DMAREQSEL_SPI0RX), + }, + [DMACH_SPI0_TX] = { + .name = "spi0-tx", .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), }, - [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */ - .name = "spi1", + [DMACH_SPI1_RX] = { /* only on S3C2443/S3C2450 */ + .name = "spi1-rx", + .channels = MAP(S3C2443_DMAREQSEL_SPI1RX), + }, + [DMACH_SPI1_TX] = { /* only on S3C2443/S3C2450 */ + .name = "spi1-tx", .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), }, [DMACH_UART0] = { diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h index acbdfecd418..454831b6603 100644 --- a/arch/arm/mach-s3c24xx/include/mach/dma.h +++ b/arch/arm/mach-s3c24xx/include/mach/dma.h @@ -47,6 +47,10 @@ enum dma_ch { DMACH_UART2_SRC2, DMACH_UART3, /* s3c2443 has extra uart */ DMACH_UART3_SRC2, + DMACH_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */ + DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */ + DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */ + DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */ DMACH_MAX, /* the end entry */ }; diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index e53b2177319..b7a9f4d469e 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -134,6 +134,17 @@ #define IRQ_S32416_WDT S3C2410_IRQSUB(27) #define IRQ_S32416_AC97 S3C2410_IRQSUB(28) +/* second interrupt-register of s3c2416/s3c2450 */ + +#define S3C2416_IRQ(x) S3C2410_IRQ((x) + 54 + 29) +#define IRQ_S3C2416_2D S3C2416_IRQ(0) +#define IRQ_S3C2416_IIC1 S3C2416_IRQ(1) +#define IRQ_S3C2416_RESERVED2 S3C2416_IRQ(2) +#define IRQ_S3C2416_RESERVED3 S3C2416_IRQ(3) +#define IRQ_S3C2416_PCM0 S3C2416_IRQ(4) +#define IRQ_S3C2416_PCM1 S3C2416_IRQ(5) +#define IRQ_S3C2416_I2S0 S3C2416_IRQ(6) +#define IRQ_S3C2416_I2S1 S3C2416_IRQ(7) /* extra irqs for s3c2440 */ @@ -175,7 +186,9 @@ #define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) #define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) -#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) +#if defined(CONFIG_CPU_S3C2416) +#define NR_IRQS (IRQ_S3C2416_I2S1 + 1) +#elif defined(CONFIG_CPU_S3C2443) #define NR_IRQS (IRQ_S3C2443_AC97+1) #else #define NR_IRQS (IRQ_S3C2440_AC97+1) diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h index 78ae807f128..8ba381f2dbe 100644 --- a/arch/arm/mach-s3c24xx/include/mach/map.h +++ b/arch/arm/mach-s3c24xx/include/mach/map.h @@ -98,6 +98,8 @@ /* SPI */ #define S3C2410_PA_SPI (0x59000000) +#define S3C2443_PA_SPI0 (0x52000000) +#define S3C2443_PA_SPI1 S3C2410_PA_SPI /* SDI */ #define S3C2410_PA_SDI (0x5A000000) @@ -162,4 +164,7 @@ #define S3C_PA_WDT S3C2410_PA_WATCHDOG #define S3C_PA_NAND S3C24XX_PA_NAND +#define S3C_PA_SPI0 S3C2443_PA_SPI0 +#define S3C_PA_SPI1 S3C2443_PA_SPI1 + #endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c index fd49f35e448..23ec97370f3 100644 --- a/arch/arm/mach-s3c24xx/irq-s3c2416.c +++ b/arch/arm/mach-s3c24xx/irq-s3c2416.c @@ -27,6 +27,7 @@ #include <linux/ioport.h> #include <linux/device.h> #include <linux/io.h> +#include <linux/syscore_ops.h> #include <mach/hardware.h> #include <asm/irq.h> @@ -192,6 +193,43 @@ static struct irq_chip s3c2416_irq_uart3 = { .irq_ack = s3c2416_irq_uart3_ack, }; +/* second interrupt register */ + +static inline void s3c2416_irq_ack_second(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); + + __raw_writel(bitval, S3C2416_SRCPND2); + __raw_writel(bitval, S3C2416_INTPND2); +} + +static void s3c2416_irq_mask_second(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); + unsigned long mask; + + mask = __raw_readl(S3C2416_INTMSK2); + mask |= bitval; + __raw_writel(mask, S3C2416_INTMSK2); +} + +static void s3c2416_irq_unmask_second(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); + unsigned long mask; + + mask = __raw_readl(S3C2416_INTMSK2); + mask &= ~bitval; + __raw_writel(mask, S3C2416_INTMSK2); +} + +struct irq_chip s3c2416_irq_second = { + .irq_ack = s3c2416_irq_ack_second, + .irq_mask = s3c2416_irq_mask_second, + .irq_unmask = s3c2416_irq_unmask_second, +}; + + /* IRQ initialisation code */ static int __init s3c2416_add_sub(unsigned int base, @@ -213,6 +251,42 @@ static int __init s3c2416_add_sub(unsigned int base, return 0; } +static void __init s3c2416_irq_add_second(void) +{ + unsigned long pend; + unsigned long last; + int irqno; + int i; + + /* first, clear all interrupts pending... */ + last = 0; + for (i = 0; i < 4; i++) { + pend = __raw_readl(S3C2416_INTPND2); + + if (pend == 0 || pend == last) + break; + + __raw_writel(pend, S3C2416_SRCPND2); + __raw_writel(pend, S3C2416_INTPND2); + printk(KERN_INFO "irq: clearing pending status %08x\n", + (int)pend); + last = pend; + } + + for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) { + switch (irqno) { + case IRQ_S3C2416_RESERVED2: + case IRQ_S3C2416_RESERVED3: + /* no IRQ here */ + break; + default: + irq_set_chip_and_handler(irqno, &s3c2416_irq_second, + handle_edge_irq); + set_irq_flags(irqno, IRQF_VALID); + } + } +} + static int __init s3c2416_irq_add(struct device *dev, struct subsys_interface *sif) { @@ -232,6 +306,8 @@ static int __init s3c2416_irq_add(struct device *dev, &s3c2416_irq_wdtac97, IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); + s3c2416_irq_add_second(); + return 0; } @@ -248,3 +324,25 @@ static int __init s3c2416_irq_init(void) arch_initcall(s3c2416_irq_init); +#ifdef CONFIG_PM +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C2416_INTMSK2), +}; + +int s3c2416_irq_suspend(void) +{ + s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); + + return 0; +} + +void s3c2416_irq_resume(void) +{ + s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); +} + +struct syscore_ops s3c2416_irq_syscore_ops = { + .suspend = s3c2416_irq_suspend, + .resume = s3c2416_irq_resume, +}; +#endif diff --git a/arch/arm/mach-s3c24xx/s3c2416.c b/arch/arm/mach-s3c24xx/s3c2416.c index 7743fade50d..ed5a95ece9e 100644 --- a/arch/arm/mach-s3c24xx/s3c2416.c +++ b/arch/arm/mach-s3c24xx/s3c2416.c @@ -106,6 +106,7 @@ int __init s3c2416_init(void) register_syscore_ops(&s3c2416_pm_syscore_ops); #endif register_syscore_ops(&s3c24xx_irq_syscore_ops); + register_syscore_ops(&s3c2416_irq_syscore_ops); return device_register(&s3c2416_dev); } diff --git a/arch/arm/mach-s3c24xx/setup-spi.c b/arch/arm/mach-s3c24xx/setup-spi.c new file mode 100644 index 00000000000..5712c85f39b --- /dev/null +++ b/arch/arm/mach-s3c24xx/setup-spi.c @@ -0,0 +1,39 @@ +/* + * HS-SPI device setup for S3C2443/S3C2416 + * + * Copyright (C) 2011 Samsung Electronics Ltd. + * http://www.samsung.com/ + * + * 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/gpio.h> +#include <linux/platform_device.h> + +#include <plat/gpio-cfg.h> +#include <plat/s3c64xx-spi.h> + +#include <mach/hardware.h> +#include <mach/regs-gpio.h> + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, + .tx_st_done = 21, + .high_speed = 1, +}; + +int s3c64xx_spi0_cfg_gpio(struct platform_device *pdev) +{ + /* enable hsspi bit in misccr */ + s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1); + + s3c_gpio_cfgall_range(S3C2410_GPE(11), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + + return 0; +} +#endif |