diff options
Diffstat (limited to 'arch/arm/mach-ep93xx')
| -rw-r--r-- | arch/arm/mach-ep93xx/Kconfig | 15 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/clock.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/core.c | 157 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/crunch-bits.S | 14 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/include/mach/debug-macro.S | 21 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/include/mach/platform.h | 7 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/include/mach/timex.h | 5 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/include/mach/uncompress.h | 14 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/vision_ep9307.c | 59 |
9 files changed, 173 insertions, 121 deletions
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index fe3c1fa5462..bec570ae649 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -5,6 +5,7 @@ menu "Cirrus EP93xx Implementation Options" config EP93XX_SOC_COMMON bool default y + select SOC_BUS select LEDS_GPIO_REGISTER config CRUNCH @@ -194,20 +195,6 @@ config MACH_VISION_EP9307 Say 'Y' here if you want your kernel to support the Vision Engraving Systems EP9307 SoM. -choice - prompt "Select a UART for early kernel messages" - -config EP93XX_EARLY_UART1 - bool "UART1" - -config EP93XX_EARLY_UART2 - bool "UART2" - -config EP93XX_EARLY_UART3 - bool "UART3" - -endchoice - endmenu endif diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index c95dbce2468..39ef3b61391 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -212,7 +212,7 @@ static struct clk_lookup clocks[] = { INIT_CK(NULL, "hclk", &clk_h), INIT_CK(NULL, "apb_pclk", &clk_p), INIT_CK(NULL, "pll2", &clk_pll2), - INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), + INIT_CK("ohci-platform", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), INIT_CK("ep93xx-fb", NULL, &clk_video), INIT_CK("ep93xx-spi.0", NULL, &clk_spi), diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index c49ed3dc1ae..0e571f1749d 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -21,6 +21,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> +#include <linux/sys_soc.h> #include <linux/timex.h> #include <linux/irq.h> #include <linux/io.h> @@ -35,6 +36,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> #include <linux/irqchip/arm-vic.h> +#include <linux/reboot.h> +#include <linux/usb/ohci_pdriver.h> #include <mach/hardware.h> #include <linux/platform_data/video-ep93xx.h> @@ -42,6 +45,7 @@ #include <linux/platform_data/spi-ep93xx.h> #include <mach/gpio-ep93xx.h> +#include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> @@ -113,7 +117,7 @@ void __init ep93xx_map_io(void) #define EP93XX_TIMER4_CLOCK 983040 #define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1) -#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ) +#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(EP93XX_TIMER4_CLOCK, HZ) static unsigned int last_jiffy_time; @@ -135,7 +139,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) static struct irqaction ep93xx_timer_irq = { .name = "ep93xx timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = ep93xx_timer_interrupt, }; @@ -238,6 +242,7 @@ unsigned int ep93xx_chip_revision(void) v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT; return v; } +EXPORT_SYMBOL_GPL(ep93xx_chip_revision); /************************************************************************* * EP93xx GPIO @@ -280,7 +285,7 @@ static AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE, { IRQ_EP93XX_UART1 }, &ep93xx_uart_data); static AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE, - { IRQ_EP93XX_UART2 }, &ep93xx_uart_data); + { IRQ_EP93XX_UART2 }, NULL); static AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE, { IRQ_EP93XX_UART3 }, &ep93xx_uart_data); @@ -296,25 +301,53 @@ static struct platform_device ep93xx_rtc_device = { .resource = ep93xx_rtc_resource, }; +/************************************************************************* + * EP93xx OHCI USB Host + *************************************************************************/ + +static struct clk *ep93xx_ohci_host_clock; + +static int ep93xx_ohci_power_on(struct platform_device *pdev) +{ + if (!ep93xx_ohci_host_clock) { + ep93xx_ohci_host_clock = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(ep93xx_ohci_host_clock)) + return PTR_ERR(ep93xx_ohci_host_clock); + } + + return clk_enable(ep93xx_ohci_host_clock); +} + +static void ep93xx_ohci_power_off(struct platform_device *pdev) +{ + clk_disable(ep93xx_ohci_host_clock); +} + +static struct usb_ohci_pdata ep93xx_ohci_pdata = { + .power_on = ep93xx_ohci_power_on, + .power_off = ep93xx_ohci_power_off, + .power_suspend = ep93xx_ohci_power_off, +}; static struct resource ep93xx_ohci_resources[] = { DEFINE_RES_MEM(EP93XX_USB_PHYS_BASE, 0x1000), DEFINE_RES_IRQ(IRQ_EP93XX_USB), }; +static u64 ep93xx_ohci_dma_mask = DMA_BIT_MASK(32); static struct platform_device ep93xx_ohci_device = { - .name = "ep93xx-ohci", + .name = "ohci-platform", .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_ohci_resources), + .resource = ep93xx_ohci_resources, .dev = { - .dma_mask = &ep93xx_ohci_device.dev.coherent_dma_mask, + .dma_mask = &ep93xx_ohci_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ep93xx_ohci_pdata, }, - .num_resources = ARRAY_SIZE(ep93xx_ohci_resources), - .resource = ep93xx_ohci_resources, }; - /************************************************************************* * EP93xx physmap'ed flash *************************************************************************/ @@ -895,8 +928,108 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev) } EXPORT_SYMBOL(ep93xx_ide_release_gpio); -void __init ep93xx_init_devices(void) +/************************************************************************* + * EP93xx Security peripheral + *************************************************************************/ + +/* + * The Maverick Key is 256 bits of micro fuses blown at the factory during + * manufacturing to uniquely identify a part. + * + * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key + */ +#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x)) +#define EP93XX_SECURITY_SECFLG EP93XX_SECURITY_REG(0x2400) +#define EP93XX_SECURITY_FUSEFLG EP93XX_SECURITY_REG(0x2410) +#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440) +#define EP93XX_SECURITY_UNIQCHK EP93XX_SECURITY_REG(0x2450) +#define EP93XX_SECURITY_UNIQVAL EP93XX_SECURITY_REG(0x2460) +#define EP93XX_SECURITY_SECID1 EP93XX_SECURITY_REG(0x2500) +#define EP93XX_SECURITY_SECID2 EP93XX_SECURITY_REG(0x2504) +#define EP93XX_SECURITY_SECCHK1 EP93XX_SECURITY_REG(0x2520) +#define EP93XX_SECURITY_SECCHK2 EP93XX_SECURITY_REG(0x2524) +#define EP93XX_SECURITY_UNIQID2 EP93XX_SECURITY_REG(0x2700) +#define EP93XX_SECURITY_UNIQID3 EP93XX_SECURITY_REG(0x2704) +#define EP93XX_SECURITY_UNIQID4 EP93XX_SECURITY_REG(0x2708) +#define EP93XX_SECURITY_UNIQID5 EP93XX_SECURITY_REG(0x270c) + +static char ep93xx_soc_id[33]; + +static const char __init *ep93xx_get_soc_id(void) { + unsigned int id, id2, id3, id4, id5; + + if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1) + return "bad Hamming code"; + + id = __raw_readl(EP93XX_SECURITY_UNIQID); + id2 = __raw_readl(EP93XX_SECURITY_UNIQID2); + id3 = __raw_readl(EP93XX_SECURITY_UNIQID3); + id4 = __raw_readl(EP93XX_SECURITY_UNIQID4); + id5 = __raw_readl(EP93XX_SECURITY_UNIQID5); + + if (id != id2) + return "invalid"; + + snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id), + "%08x%08x%08x%08x", id2, id3, id4, id5); + + return ep93xx_soc_id; +} + +static const char __init *ep93xx_get_soc_rev(void) +{ + int rev = ep93xx_chip_revision(); + + switch (rev) { + case EP93XX_CHIP_REV_D0: + return "D0"; + case EP93XX_CHIP_REV_D1: + return "D1"; + case EP93XX_CHIP_REV_E0: + return "E0"; + case EP93XX_CHIP_REV_E1: + return "E1"; + case EP93XX_CHIP_REV_E2: + return "E2"; + default: + return "unknown"; + } +} + +static const char __init *ep93xx_get_machine_name(void) +{ + return kasprintf(GFP_KERNEL,"%s", machine_desc->name); +} + +static struct device __init *ep93xx_init_soc(void) +{ + struct soc_device_attribute *soc_dev_attr; + struct soc_device *soc_dev; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return NULL; + + soc_dev_attr->machine = ep93xx_get_machine_name(); + soc_dev_attr->family = "Cirrus Logic EP93xx"; + soc_dev_attr->revision = ep93xx_get_soc_rev(); + soc_dev_attr->soc_id = ep93xx_get_soc_id(); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->machine); + kfree(soc_dev_attr); + return NULL; + } + + return soc_device_to_device(soc_dev); +} + +struct device __init *ep93xx_init_devices(void) +{ + struct device *parent; + /* Disallow access to MaverickCrunch initially */ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); @@ -907,6 +1040,8 @@ void __init ep93xx_init_devices(void) EP93XX_SYSCON_DEVCFG_GONIDE | EP93XX_SYSCON_DEVCFG_HONIDE); + parent = ep93xx_init_soc(); + /* Get the GPIO working early, other devices need it */ platform_device_register(&ep93xx_gpio_device); @@ -919,9 +1054,11 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_wdt_device); gpio_led_register_device(-1, &ep93xx_led_data); + + return parent; } -void ep93xx_restart(char mode, const char *cmd) +void ep93xx_restart(enum reboot_mode mode, const char *cmd) { /* * Set then clear the SWRST bit to initiate a software reset diff --git a/arch/arm/mach-ep93xx/crunch-bits.S b/arch/arm/mach-ep93xx/crunch-bits.S index 0ec9bb48fab..e96923a3017 100644 --- a/arch/arm/mach-ep93xx/crunch-bits.S +++ b/arch/arm/mach-ep93xx/crunch-bits.S @@ -16,6 +16,7 @@ #include <asm/ptrace.h> #include <asm/thread_info.h> #include <asm/asm-offsets.h> +#include <asm/assembler.h> #include <mach/ep93xx-regs.h> /* @@ -62,14 +63,16 @@ * r9 = ret_from_exception * lr = undefined instr exit * - * called from prefetch exception handler with interrupts disabled + * called from prefetch exception handler with interrupts enabled */ ENTRY(crunch_task_enable) + inc_preempt_count r10, r3 + ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr ldr r1, [r8, #0x80] tst r1, #0x00800000 @ access to crunch enabled? - movne pc, lr @ if so no business here + bne 2f @ if so no business here mov r3, #0xaa @ unlock syscon swlock str r3, [r8, #0xc0] orr r1, r1, #0x00800000 @ enable access to crunch @@ -142,7 +145,7 @@ crunch_save: teq r0, #0 @ anything to load? cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered - moveq pc, lr + beq 1f crunch_load: cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word @@ -190,6 +193,11 @@ crunch_load: cfldr64 mvdx14, [r0, #CRUNCH_MVDX14] cfldr64 mvdx15, [r0, #CRUNCH_MVDX15] +1: +#ifdef CONFIG_PREEMPT_COUNT + get_thread_info r10 +#endif +2: dec_preempt_count r10, r3 mov pc, lr /* diff --git a/arch/arm/mach-ep93xx/include/mach/debug-macro.S b/arch/arm/mach-ep93xx/include/mach/debug-macro.S deleted file mode 100644 index af54e43132c..00000000000 --- a/arch/arm/mach-ep93xx/include/mach/debug-macro.S +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/debug-macro.S - * Debugging macro include header - * - * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ -#include <mach/ep93xx-regs.h> - - .macro addruart, rp, rv, tmp - ldr \rp, =EP93XX_APB_PHYS_BASE @ Physical base - ldr \rv, =EP93XX_APB_VIRT_BASE @ virtual base - orr \rp, \rp, #0x000c0000 - orr \rv, \rv, #0x000c0000 - .endm - -#include <asm/hardware/debug-pl01x.S> diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index a14e1b37bef..4c0bbd97f74 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -4,6 +4,9 @@ #ifndef __ASSEMBLY__ +#include <linux/reboot.h> + +struct device; struct i2c_gpio_platform_data; struct i2c_board_info; struct spi_board_info; @@ -52,10 +55,10 @@ void ep93xx_register_ide(void); int ep93xx_ide_acquire_gpio(struct platform_device *pdev); void ep93xx_ide_release_gpio(struct platform_device *pdev); -void ep93xx_init_devices(void); +struct device *ep93xx_init_devices(void); extern void ep93xx_timer_init(void); -void ep93xx_restart(char, const char *); +void ep93xx_restart(enum reboot_mode, const char *); void ep93xx_init_late(void); #ifdef CONFIG_CRUNCH diff --git a/arch/arm/mach-ep93xx/include/mach/timex.h b/arch/arm/mach-ep93xx/include/mach/timex.h deleted file mode 100644 index 6b3503b01fa..00000000000 --- a/arch/arm/mach-ep93xx/include/mach/timex.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/timex.h - */ - -#define CLOCK_TICK_RATE 983040 diff --git a/arch/arm/mach-ep93xx/include/mach/uncompress.h b/arch/arm/mach-ep93xx/include/mach/uncompress.h index b5cc77d2380..03c42e5400d 100644 --- a/arch/arm/mach-ep93xx/include/mach/uncompress.h +++ b/arch/arm/mach-ep93xx/include/mach/uncompress.h @@ -31,18 +31,8 @@ static void __raw_writel(unsigned int value, unsigned int ptr) *((volatile unsigned int *)ptr) = value; } -#if defined(CONFIG_EP93XX_EARLY_UART1) -#define UART_BASE EP93XX_UART1_PHYS_BASE -#elif defined(CONFIG_EP93XX_EARLY_UART2) -#define UART_BASE EP93XX_UART2_PHYS_BASE -#elif defined(CONFIG_EP93XX_EARLY_UART3) -#define UART_BASE EP93XX_UART3_PHYS_BASE -#else -#define UART_BASE EP93XX_UART1_PHYS_BASE -#endif - -#define PHYS_UART_DATA (UART_BASE + 0x00) -#define PHYS_UART_FLAG (UART_BASE + 0x18) +#define PHYS_UART_DATA (CONFIG_DEBUG_UART_PHYS + 0x00) +#define PHYS_UART_FLAG (CONFIG_DEBUG_UART_PHYS + 0x18) #define UART_FLAG_TXFF 0x20 static inline void putc(int c) diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 605956fd07a..6bc1c181581 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -23,7 +23,7 @@ #include <linux/mtd/partitions.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> -#include <linux/i2c/pca953x.h> +#include <linux/platform_data/pca953x.h> #include <linux/spi/spi.h> #include <linux/spi/flash.h> #include <linux/spi/mmc_spi.h> @@ -224,62 +224,15 @@ static struct ep93xx_spi_chip_ops vision_spi_flash_hw = { #define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0) #define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15 -static struct gpio vision_spi_mmc_gpios[] = { - { VISION_SPI_MMC_WP, GPIOF_DIR_IN, "mmc_spi:wp" }, - { VISION_SPI_MMC_CD, GPIOF_DIR_IN, "mmc_spi:cd" }, -}; - -static int vision_spi_mmc_init(struct device *pdev, - irqreturn_t (*func)(int, void *), void *pdata) -{ - int err; - - err = gpio_request_array(vision_spi_mmc_gpios, - ARRAY_SIZE(vision_spi_mmc_gpios)); - if (err) - return err; - - err = gpio_set_debounce(VISION_SPI_MMC_CD, 1); - if (err) - goto exit_err; - - err = request_irq(gpio_to_irq(VISION_SPI_MMC_CD), func, - IRQ_TYPE_EDGE_BOTH, "mmc_spi:cd", pdata); - if (err) - goto exit_err; - - return 0; - -exit_err: - gpio_free_array(vision_spi_mmc_gpios, ARRAY_SIZE(vision_spi_mmc_gpios)); - return err; - -} - -static void vision_spi_mmc_exit(struct device *pdev, void *pdata) -{ - free_irq(gpio_to_irq(VISION_SPI_MMC_CD), pdata); - gpio_free_array(vision_spi_mmc_gpios, ARRAY_SIZE(vision_spi_mmc_gpios)); -} - -static int vision_spi_mmc_get_ro(struct device *pdev) -{ - return !!gpio_get_value(VISION_SPI_MMC_WP); -} - -static int vision_spi_mmc_get_cd(struct device *pdev) -{ - return !gpio_get_value(VISION_SPI_MMC_CD); -} - static struct mmc_spi_platform_data vision_spi_mmc_data = { - .init = vision_spi_mmc_init, - .exit = vision_spi_mmc_exit, - .get_ro = vision_spi_mmc_get_ro, - .get_cd = vision_spi_mmc_get_cd, .detect_delay = 100, .powerup_msecs = 100, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, + .cd_gpio = VISION_SPI_MMC_CD, + .cd_debounce = 1, + .ro_gpio = VISION_SPI_MMC_WP, + .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, }; static int vision_spi_mmc_hw_setup(struct spi_device *spi) |
