diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index c45fc4d..2d4721a 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -15,20 +15,17 @@ config AT91SAM9_SMC bool -config AT91SAM9_TIMER - bool - config SOC_AT91SAM9 bool select CPU_ARM926T select AT91SAM9_SMC - select AT91SAM9_TIMER + select CLOCKSOURCE_ATMEL_PIT config SOC_SAMA5 bool select CPU_V7 select AT91SAM9_SMC - select AT91SAM9_TIMER + select CLOCKSOURCE_ATMEL_PIT config ARCH_TEXT_BASE hex diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index c2991b0..1f63b09 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_AT91SAM9G45_RESET) += at91sam9g45_reset.o obj-$(CONFIG_AT91SAM9_SMC) += sam9_smc.o -obj-$(CONFIG_AT91SAM9_TIMER) += at91sam926x_time.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 7b68cda..a110ee3 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -250,16 +250,16 @@ resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PA30, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA31, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PA17, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA18, 1); /* RXD0 */ if (pins & ATMEL_UART_CTS) at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ @@ -277,8 +277,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB20, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB21, 1); /* RXD1 */ if (pins & ATMEL_UART_RI) at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ @@ -298,8 +298,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ - at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PA22, 1); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* TXD2 */ if (pins & ATMEL_UART_CTS) at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */ @@ -311,8 +311,8 @@ resource_size_t __init at91_configure_usart3(unsigned pins) { - at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ - at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ + at91_set_B_periph(AT91_PIN_PA5, 0); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PA6, 1); /* RXD3 */ if (pins & ATMEL_UART_CTS) at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */ diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 67c4ea8..99919b3 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -261,16 +261,16 @@ resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PB14, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PB5, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ @@ -290,8 +290,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB6, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB7, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ @@ -303,8 +303,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PB9, 1); /* RXD2 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */ @@ -316,8 +316,8 @@ resource_size_t __init at91_configure_usart3(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ - at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB11, 1); /* RXD3 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */ @@ -329,16 +329,16 @@ resource_size_t __init at91_configure_usart4(unsigned pins) { - at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ - at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ + at91_set_B_periph(AT91_PIN_PA31, 0); /* TXD4 */ + at91_set_B_periph(AT91_PIN_PA30, 1); /* RXD4 */ return AT91SAM9260_BASE_US4; } resource_size_t __init at91_configure_usart5(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ - at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* TXD5 */ + at91_set_A_periph(AT91_PIN_PB13, 1); /* RXD5 */ return AT91SAM9260_BASE_US5; } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 620ed65..e63e0e7 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -265,16 +265,16 @@ resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PA9, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PC8, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PC9, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ @@ -286,8 +286,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PC13, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */ @@ -299,8 +299,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ - at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PC15, 1); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PC14, 0); /* TXD2 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/ diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index a3683e5..559b77e 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -296,16 +296,16 @@ resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PC30, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PC31, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PA26, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA27, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ @@ -317,8 +317,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PD0, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PD1, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ @@ -330,8 +330,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PD2, 0); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PD3, 1); /* RXD2 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c deleted file mode 100644 index cc7ad2f..0000000 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) -#define pit_write(reg, val) __raw_writel(val, pit_base + reg) -#define pit_read(reg) __raw_readl(pit_base + reg) - -static __iomem void *pit_base; - -uint64_t at91sam9_clocksource_read(void) -{ - return pit_read(AT91_PIT_PIIR); -} - -static struct clocksource cs = { - .read = at91sam9_clocksource_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 10, -}; - -static void at91_pit_stop(void) -{ - /* Disable timer and irqs */ - pit_write(AT91_PIT_MR, 0); - - /* Clear any pending interrupts, wait for PIT to stop counting */ - while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0); -} - -static void at91sam926x_pit_reset(void) -{ - at91_pit_stop(); - - /* Start PIT but don't enable IRQ */ - pit_write(AT91_PIT_MR, 0xfffff | AT91_PIT_PITEN); -} - -static int at91_pit_probe(struct device_d *dev) -{ - struct clk *clk; - u32 pit_rate; - int ret; - - clk = clk_get(dev, NULL); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - dev_err(dev, "clock not found: %d\n", ret); - return ret; - } - - ret = clk_enable(clk); - if (ret < 0) { - dev_err(dev, "clock failed to enable: %d\n", ret); - clk_put(clk); - return ret; - } - - pit_base = dev_request_mem_region_err_null(dev, 0); - if (!pit_base) - return -ENOENT; - - pit_rate = clk_get_rate(clk) / 16; - - at91sam926x_pit_reset(); - - cs.mult = clocksource_hz2mult(pit_rate, cs.shift); - - return init_clock(&cs); -} - -static struct driver_d at91_pit_driver = { - .name = "at91-pit", - .probe = at91_pit_probe, -}; - -static int at91_pit_init(void) -{ - return platform_driver_register(&at91_pit_driver); -} -postcore_initcall(at91_pit_init); diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index bad7f9c..bc41320 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -213,16 +213,16 @@ resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PB12, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PB18, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */ @@ -234,8 +234,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB5, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */ @@ -247,8 +247,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PB6, 0); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PB7, 1); /* RXD2 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */ @@ -260,8 +260,8 @@ resource_size_t __init at91_configure_usart3(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */ - at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB9, 1); /* RXD3 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */ diff --git a/arch/arm/mach-at91/at91sam9n12_devices.c b/arch/arm/mach-at91/at91sam9n12_devices.c index bac023f..84c871c 100644 --- a/arch/arm/mach-at91/at91sam9n12_devices.c +++ b/arch/arm/mach-at91/at91sam9n12_devices.c @@ -370,16 +370,16 @@ #if defined(CONFIG_DRIVER_SERIAL_ATMEL) resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PA9, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA0, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PA0, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA1, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PA2, 0); /* RTS0 */ @@ -391,8 +391,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA5, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PA6, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PA5, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PA6, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_C_periph(AT91_PIN_PC27, 0); /* RTS1 */ @@ -404,8 +404,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA7, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PA8, 1); /* RXD2 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS2 */ @@ -417,8 +417,8 @@ resource_size_t __init at91_configure_usart3(unsigned pins) { - at91_set_B_periph(AT91_PIN_PC22, 1); /* TXD3 */ - at91_set_B_periph(AT91_PIN_PC23, 0); /* RXD3 */ + at91_set_B_periph(AT91_PIN_PC22, 0); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PC23, 1); /* RXD3 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PC24, 0); /* RTS3 */ diff --git a/arch/arm/mach-at91/at91sam9x5_devices.c b/arch/arm/mach-at91/at91sam9x5_devices.c index 34537d8..d7ddda4 100644 --- a/arch/arm/mach-at91/at91sam9x5_devices.c +++ b/arch/arm/mach-at91/at91sam9x5_devices.c @@ -453,16 +453,16 @@ #if defined(CONFIG_DRIVER_SERIAL_ATMEL) resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PA9, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* DTXD */ return AT91_BASE_SYS + AT91_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA0, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PA0, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA1, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PA2, 0); /* RTS0 */ @@ -474,8 +474,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA5, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PA6, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PA5, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PA6, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_C_periph(AT91_PIN_PC27, 0); /* RTS1 */ @@ -487,8 +487,8 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_A_periph(AT91_PIN_PA7, 1); /* TXD2 */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PA8, 1); /* RXD2 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS2 */ @@ -500,8 +500,8 @@ resource_size_t __init at91_configure_usart3(unsigned pins) { - at91_set_B_periph(AT91_PIN_PC22, 1); /* TXD3 */ - at91_set_B_periph(AT91_PIN_PC23, 0); /* RXD3 */ + at91_set_B_periph(AT91_PIN_PC22, 0); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PC23, 1); /* RXD3 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PC24, 0); /* RTS3 */ diff --git a/arch/arm/mach-at91/include/mach/debug_ll.h b/arch/arm/mach-at91/include/mach/debug_ll.h index 1a85ae4..42728a4 100644 --- a/arch/arm/mach-at91/include/mach/debug_ll.h +++ b/arch/arm/mach-at91/include/mach/debug_ll.h @@ -11,7 +11,7 @@ #include #include -#ifdef COFNIG_HAVE_AT91_DBGU0 +#ifdef CONFIG_HAVE_AT91_DBGU0 #define UART_BASE AT91_BASE_DBGU0 #else #define UART_BASE AT91_BASE_DBGU1 diff --git a/arch/arm/mach-at91/sama5d3_devices.c b/arch/arm/mach-at91/sama5d3_devices.c index 3fdfca8..c6f5e3a 100644 --- a/arch/arm/mach-at91/sama5d3_devices.c +++ b/arch/arm/mach-at91/sama5d3_devices.c @@ -464,16 +464,16 @@ #if defined(CONFIG_DRIVER_SERIAL_ATMEL) resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PB30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PB31, 1); /* DTXD */ + at91_set_A_periph(AT91_PIN_PB30, 1); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB31, 0); /* DTXD */ return AT91_BASE_DBGU1; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PD18, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PD17, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PD18, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PD17, 1); /* RXD0 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS0 */ @@ -485,8 +485,8 @@ resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PB29, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB28, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB28, 1); /* RXD1 */ if (pins & ATMEL_UART_RTS) at91_set_A_periph(AT91_PIN_PB27, 0); /* RTS1 */ diff --git a/arch/arm/mach-at91/sama5d4_devices.c b/arch/arm/mach-at91/sama5d4_devices.c index e1b0a64..c2f171a 100644 --- a/arch/arm/mach-at91/sama5d4_devices.c +++ b/arch/arm/mach-at91/sama5d4_devices.c @@ -430,24 +430,24 @@ #if defined(CONFIG_DRIVER_SERIAL_ATMEL) resource_size_t __init at91_configure_dbgu(void) { - at91_set_A_periph(AT91_PIN_PB25, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB24, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* DTXD */ + at91_set_A_periph(AT91_PIN_PB24, 1); /* DRXD */ return SAMA5D4_BASE_DBGU; } resource_size_t __init at91_configure_usart0(unsigned pins) { - at91_set_A_periph(AT91_PIN_PD13, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PD12, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PD13, 0); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PD12, 1); /* RXD0 */ return SAMA5D4_BASE_USART0; } resource_size_t __init at91_configure_usart1(unsigned pins) { - at91_set_A_periph(AT91_PIN_PD17, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PD16, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PD17, 0); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PD16, 1); /* RXD1 */ return SAMA5D4_BASE_USART1; } @@ -455,40 +455,40 @@ resource_size_t __init at91_configure_usart2(unsigned pins) { - at91_set_B_periph(AT91_PIN_PB5, 1); /* TXD1 */ - at91_set_B_periph(AT91_PIN_PB4, 0); /* RXD1 */ + at91_set_B_periph(AT91_PIN_PB5, 0); /* TXD2 */ + at91_set_B_periph(AT91_PIN_PB4, 1); /* RXD2 */ return SAMA5D4_BASE_USART2; } resource_size_t __init at91_configure_usart3(unsigned pins) { - at91_set_B_periph(AT91_PIN_PE17, 1); /* TXD1 */ - at91_set_B_periph(AT91_PIN_PE16, 0); /* RXD1 */ + at91_set_B_periph(AT91_PIN_PE17, 0); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PE16, 1); /* RXD3 */ return SAMA5D4_BASE_USART3; } resource_size_t __init at91_configure_usart4(unsigned pins) { - at91_set_B_periph(AT91_PIN_PE27, 1); /* TXD1 */ - at91_set_B_periph(AT91_PIN_PE26, 0); /* RXD1 */ + at91_set_B_periph(AT91_PIN_PE27, 0); /* TXD4 */ + at91_set_B_periph(AT91_PIN_PE26, 1); /* RXD4 */ return SAMA5D4_BASE_USART4; } resource_size_t __init at91_configure_usart5(unsigned pins) { - at91_set_B_periph(AT91_PIN_PE30, 1); /* TXD1 */ - at91_set_B_periph(AT91_PIN_PE29, 0); /* RXD1 */ + at91_set_B_periph(AT91_PIN_PE30, 0); /* UTXD0 */ + at91_set_B_periph(AT91_PIN_PE29, 1); /* URXD0 */ return SAMA5D4_BASE_UART0; } resource_size_t __init at91_configure_usart6(unsigned pins) { - at91_set_C_periph(AT91_PIN_PC26, 1); /* TXD1 */ - at91_set_C_periph(AT91_PIN_PC25, 0); /* RXD1 */ + at91_set_C_periph(AT91_PIN_PC26, 0); /* UTXD1 */ + at91_set_C_periph(AT91_PIN_PC25, 1); /* URXD1 */ return SAMA5D4_BASE_UART1; } diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1cf0ccb..dedbf6c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -10,6 +10,7 @@ config COMMON_CLK_OF_PROVIDER bool + depends on OFTREE help Clock driver provides OF-Tree based clock lookup. diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 40b63d6..a3dbf33 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -93,7 +93,7 @@ return &f->clk; } -#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER) +#if defined(CONFIG_COMMON_CLK_OF_PROVIDER) /** * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock */ diff --git a/drivers/clk/clk-fixed.c b/drivers/clk/clk-fixed.c index 8164005..f0f7fba 100644 --- a/drivers/clk/clk-fixed.c +++ b/drivers/clk/clk-fixed.c @@ -55,7 +55,7 @@ return &fix->clk; } -#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER) +#if defined(CONFIG_COMMON_CLK_OF_PROVIDER) /** * of_fixed_clk_setup() - Setup function for simple fixed rate clock */ diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 93e000c..5bb147e 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -346,7 +346,7 @@ return clk_set_rate(clk_get_parent(clk), rate); } -#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER) +#if defined(CONFIG_COMMON_CLK_OF_PROVIDER) /** * struct of_clk_provider - Clock provider registration structure * @link: Entry in global list of clock providers @@ -452,6 +452,24 @@ return clk; } +/** + * of_clk_get_parent_count() - Count the number of clocks a device node has + * @np: device node to count + * + * Returns: The number of clocks that are possible parents of this node + */ +unsigned int of_clk_get_parent_count(struct device_node *np) +{ + int count; + + count = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (count < 0) + return 0; + + return count; +} +EXPORT_SYMBOL_GPL(of_clk_get_parent_count); + char *of_clk_get_parent_name(struct device_node *np, unsigned int index) { struct of_phandle_args clkspec; @@ -472,6 +490,27 @@ } EXPORT_SYMBOL_GPL(of_clk_get_parent_name); +/** + * of_clk_parent_fill() - Fill @parents with names of @np's parents and return + * number of parents + * @np: Device node pointer associated with clock provider + * @parents: pointer to char array that hold the parents' names + * @size: size of the @parents array + * + * Return: number of parents for the clock node. + */ +int of_clk_parent_fill(struct device_node *np, const char **parents, + unsigned int size) +{ + unsigned int i = 0; + + while (i < size && (parents[i] = of_clk_get_parent_name(np, i)) != NULL) + i++; + + return i; +} +EXPORT_SYMBOL_GPL(of_clk_parent_fill); + struct clock_provider { of_clk_init_cb_t clk_init_cb; struct device_node *np; diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 1bc5c6d..7f9f8f2 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -24,7 +24,7 @@ static LIST_HEAD(clocks); -#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER) +#if defined(CONFIG_COMMON_CLK_OF_PROVIDER) struct clk *of_clk_get(struct device_node *np, int index) { struct of_phandle_args clkspec; diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f1ab554..f3c3255 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -53,3 +53,7 @@ config CLOCKSOURCE_ROCKCHIP bool depends on ARCH_ROCKCHIP + +config CLOCKSOURCE_ATMEL_PIT + bool + depends on SOC_AT91SAM9 || SOC_SAMA5 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 39982ff..0564d8f 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o obj-$(CONFIG_CLOCKSOURCE_UEMD) += uemd.o obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o +obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c new file mode 100644 index 0000000..cc7ad2f --- /dev/null +++ b/drivers/clocksource/timer-atmel-pit.c @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) +#define pit_write(reg, val) __raw_writel(val, pit_base + reg) +#define pit_read(reg) __raw_readl(pit_base + reg) + +static __iomem void *pit_base; + +uint64_t at91sam9_clocksource_read(void) +{ + return pit_read(AT91_PIT_PIIR); +} + +static struct clocksource cs = { + .read = at91sam9_clocksource_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 10, +}; + +static void at91_pit_stop(void) +{ + /* Disable timer and irqs */ + pit_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts, wait for PIT to stop counting */ + while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0); +} + +static void at91sam926x_pit_reset(void) +{ + at91_pit_stop(); + + /* Start PIT but don't enable IRQ */ + pit_write(AT91_PIT_MR, 0xfffff | AT91_PIT_PITEN); +} + +static int at91_pit_probe(struct device_d *dev) +{ + struct clk *clk; + u32 pit_rate; + int ret; + + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(clk); + if (ret < 0) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(clk); + return ret; + } + + pit_base = dev_request_mem_region_err_null(dev, 0); + if (!pit_base) + return -ENOENT; + + pit_rate = clk_get_rate(clk) / 16; + + at91sam926x_pit_reset(); + + cs.mult = clocksource_hz2mult(pit_rate, cs.shift); + + return init_clock(&cs); +} + +static struct driver_d at91_pit_driver = { + .name = "at91-pit", + .probe = at91_pit_probe, +}; + +static int at91_pit_init(void) +{ + return platform_driver_register(&at91_pit_driver); +} +postcore_initcall(at91_pit_init); diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 6ef30ce..957d9a7 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -28,6 +28,34 @@ struct device_node *np; void __iomem *base; struct list_head list; + struct regmap *regmap; +}; + +static int syscon_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + struct syscon *syscon = context; + writel(val, syscon->base + reg); + return 0; +} + +static int syscon_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct syscon *syscon = context; + *val = readl(syscon->base + reg); + return 0; +} + +static const struct regmap_bus syscon_regmap_bus = { + .reg_write = syscon_reg_write, + .reg_read = syscon_reg_read, +}; + +static const struct regmap_config syscon_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, }; static struct syscon *of_syscon_register(struct device_node *np) @@ -51,6 +79,10 @@ list_add_tail(&syscon->list, &syscon_list); + syscon->regmap = regmap_init(NULL, + &syscon_regmap_bus, + syscon, + &syscon_regmap_config); return syscon; err_map: @@ -58,7 +90,7 @@ return ERR_PTR(ret); } -static void __iomem *syscon_node_to_base(struct device_node *np) +static struct syscon *node_to_syscon(struct device_node *np) { struct syscon *entry, *syscon = NULL; @@ -74,6 +106,16 @@ if (IS_ERR(syscon)) return ERR_CAST(syscon); + return syscon; +} + +static void __iomem *syscon_node_to_base(struct device_node *np) +{ + struct syscon *syscon = node_to_syscon(np); + + if (IS_ERR(syscon)) + return ERR_CAST(syscon); + return syscon->base; } @@ -108,6 +150,16 @@ return syscon_node_to_base(syscon_np); } +struct regmap *syscon_node_to_regmap(struct device_node *np) +{ + struct syscon *syscon = node_to_syscon(np); + + if (IS_ERR(syscon)) + return ERR_CAST(syscon); + + return syscon->regmap; +} + static int syscon_probe(struct device_d *dev) { struct syscon *syscon; diff --git a/drivers/of/base.c b/drivers/of/base.c index 0c20fcd..bef8f1d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -472,21 +472,20 @@ int of_device_is_compatible(const struct device_node *device, const char *compat) { + struct property *prop; const char *cp; - int cplen, l; + int index = 0, score = 0; - cp = of_get_property(device, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (of_compat_cmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; + prop = of_find_property(device, "compatible", NULL); + for (cp = of_prop_next_string(prop, NULL); cp; + cp = of_prop_next_string(prop, cp), index++) { + if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { + score = INT_MAX/2 - (index << 2); + break; + } } - return 0; + return score; } EXPORT_SYMBOL(of_device_is_compatible); @@ -602,16 +601,22 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node) { + const struct of_device_id *best_match = NULL; + int score, best_score = 0; + if (!matches || !node) return NULL; - while (matches->compatible) { - if (of_device_is_compatible(node, matches->compatible) == 1) - return matches; - matches++; + for (; matches->compatible; matches++) { + score = of_device_is_compatible(node, matches->compatible); + + if (score > best_score) { + best_match = matches; + best_score = score; + } } - return NULL; + return best_match; } /** diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index ebbc6f6..021c1e5 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -414,8 +414,10 @@ { unsigned int mask; void __iomem *pio; + struct at91_gpio_chip *at91_gpio; - pio = pin_to_controller(pin_num); + at91_gpio = pin_to_controller(pin_num); + pio = at91_gpio->regbase; mask = pin_to_mask(pin_num); if (conf & PULL_UP && conf & PULL_DOWN) @@ -460,6 +462,8 @@ mux = be32_to_cpu(*list++); conf = be32_to_cpu(*list++); + pin_num += bank_num * MAX_NB_GPIO_PER_BANK; + ret = at91_mux_pin(pin_num, mux, conf & PULL_UP); if (ret) { dev_err(pdev->dev, "failed to mux pin %d\n", pin_num); @@ -564,6 +568,21 @@ return 0; } +static int at91_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + u32 osr; + + if (mask & __raw_readl(pio + PIO_PSR)) { + osr = __raw_readl(pio + PIO_OSR); + return !(osr & mask); + } else { + return -EBUSY; + } +} + static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); @@ -599,6 +618,7 @@ .free = at91_gpio_free, .direction_input = at91_gpio_direction_input, .direction_output = at91_gpio_direction_output, + .get_direction = at91_gpio_get_direction, .get = at91_gpio_get, .set = at91_gpio_set, }; diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c index 4e4624e..ab94fd2 100644 --- a/drivers/serial/atmel.c +++ b/drivers/serial/atmel.c @@ -403,6 +403,11 @@ return -ENOENT; uart->clk = clk_get(dev, "usart"); + if (IS_ERR(uart->clk)) { + dev_err(dev, "Failed to get 'usart' clock\n"); + return PTR_ERR(uart->clk); + } + clk_enable(uart->clk); uart->uartclk = clk_get_rate(uart->clk); diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 3f2c527..ef57867 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -40,11 +40,16 @@ #include "atmel_spi.h" +struct atmel_spi_caps { + bool is_spi2; +}; + struct atmel_spi { struct spi_master master; void __iomem *regs; struct clk *clk; int *cs_pins; + struct atmel_spi_caps caps; }; #define to_atmel_spi(p) container_of(p, struct atmel_spi, master) @@ -62,9 +67,9 @@ * register, but I haven't checked that it exists on all chips, and * this is cheaper anyway. */ -static inline bool atmel_spi_is_v2(void) +static inline bool atmel_spi_is_v2(struct atmel_spi *as) { - return !cpu_is_at91rm9200(); + return as->caps.is_spi2; } /* @@ -104,7 +109,7 @@ csr = (u32)spi->controller_data; - if (atmel_spi_is_v2()) { + if (atmel_spi_is_v2(as)) { /* * Always use CSR0. This ensures that the clock * switches to the correct idle polarity before we @@ -163,8 +168,9 @@ npcs_pin, active ? " (low)" : "", mr); - if (atmel_spi_is_v2() || npcs_pin != AT91_PIN_PA3) + if (atmel_spi_is_v2(as) || npcs_pin != AT91_PIN_PA3) { gpio_set_value(npcs_pin, !active); + } } static int atmel_spi_setup(struct spi_device *spi) @@ -172,6 +178,8 @@ struct spi_master *master = spi->master; struct atmel_spi *as = to_atmel_spi(master); + int npcs_pin; + unsigned active = spi->mode & SPI_CS_HIGH; u32 scbr, csr; unsigned int bits = spi->bits_per_word; unsigned long bus_hz; @@ -183,6 +191,8 @@ return -EINVAL; } + npcs_pin = as->cs_pins[spi->chip_select]; + if (bits < 8 || bits > 16) { dev_dbg(&spi->dev, "setup: invalid bits_per_word %u (8 to 16)\n", @@ -195,7 +205,7 @@ spi->max_speed_hz); bus_hz = clk_get_rate(as->clk); - if (!atmel_spi_is_v2()) + if (!atmel_spi_is_v2(as)) bus_hz /= 2; if (spi->max_speed_hz) { @@ -235,7 +245,7 @@ csr |= SPI_BF(DLYBS, 0); csr |= SPI_BF(DLYBCT, 0); - /* gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); */ + gpio_direction_output(npcs_pin, !active); dev_dbg(master->dev, "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); @@ -244,7 +254,7 @@ cs_deactivate(as, spi); - if (!atmel_spi_is_v2()) + if (!atmel_spi_is_v2(as)) spi_writel(as, CSR0 + 4 * spi->chip_select, csr); return 0; @@ -369,6 +379,21 @@ return ret; } +static inline unsigned int atmel_get_version(struct atmel_spi *as) +{ + return spi_readl(as, VERSION) & 0x00000fff; +} + +static void atmel_get_caps(struct atmel_spi *as) +{ + unsigned int version; + + version = atmel_get_version(as); + dev_info(as->master.dev, "version: 0x%x\n", version); + + as->caps.is_spi2 = version > 0x121; +} + static int atmel_spi_probe(struct device_d *dev) { struct resource *iores; @@ -405,6 +430,8 @@ return PTR_ERR(iores); as->regs = IOMEM(iores->start); + atmel_get_caps(as); + for (i = 0; i < master->num_chipselect; i++) { ret = gpio_request(as->cs_pins[i], dev_name(dev)); if (ret) diff --git a/drivers/spi/atmel_spi.h b/drivers/spi/atmel_spi.h index 38ce119..3f4d7ba 100644 --- a/drivers/spi/atmel_spi.h +++ b/drivers/spi/atmel_spi.h @@ -23,6 +23,7 @@ #define SPI_CSR1 0x0034 #define SPI_CSR2 0x0038 #define SPI_CSR3 0x003c +#define SPI_VERSION 0x00fc #define SPI_RPR 0x0100 #define SPI_RCR 0x0104 #define SPI_TPR 0x0108 diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index cc9636c..f075b50 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -29,34 +29,55 @@ #include "ehci.h" -/* interface and function clocks; sometimes also an AHB clock */ -static struct clk *iclk, *fclk; +struct atmel_ehci_priv { + struct device_d *dev; + struct clk *iclk; + struct clk *uclk; +}; -static void atmel_start_clock(void) +static int atmel_start_clock(struct atmel_ehci_priv *atehci) { - clk_enable(iclk); - clk_enable(fclk); + int ret; + ret = clk_enable(atehci->iclk); + if (ret < 0) { + dev_err(atehci->dev, + "Error enabling interface clock\n"); + return ret; + } + + ret = clk_enable(atehci->uclk); + if (ret < 0) + dev_err(atehci->dev, + "Error enabling function clock\n"); + + return ret; } -static void atmel_stop_clock(void) +static void atmel_stop_clock(struct atmel_ehci_priv *atehci) { - clk_disable(fclk); - clk_disable(iclk); + clk_disable(atehci->iclk); + clk_disable(atehci->uclk); } static int atmel_ehci_probe(struct device_d *dev) { + int ret; struct resource *iores; struct ehci_data data; + struct atmel_ehci_priv *atehci; - iclk = clk_get(dev, "ehci_clk"); - if (IS_ERR(iclk)) { + atehci = xzalloc(sizeof(*atehci)); + atehci->dev = dev; + dev->priv = atehci; + + atehci->iclk = clk_get(dev, "ehci_clk"); + if (IS_ERR(atehci->iclk)) { dev_err(dev, "Error getting interface clock\n"); return -ENOENT; } - fclk = clk_get(dev, "uhpck"); - if (IS_ERR(fclk)) { + atehci->uclk = clk_get(dev, "uhpck"); + if (IS_ERR(atehci->iclk)) { dev_err(dev, "Error getting function clock\n"); return -ENOENT; } @@ -64,18 +85,18 @@ /* * Start the USB clocks. */ - atmel_start_clock(); + ret = atmel_start_clock(atehci); + if (ret < 0) + return ret; - data.flags = 0; + memset(&data, 0, sizeof(data)); iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) return PTR_ERR(iores); data.hccr = IOMEM(iores->start); - ehci_register(dev, &data); - - return 0; + return ehci_register(dev, &data); } static void atmel_ehci_remove(struct device_d *dev) @@ -83,7 +104,7 @@ /* * Stop the USB clocks. */ - atmel_stop_clock(); + atmel_stop_clock(dev->priv); } static struct driver_d atmel_ehci_driver = { diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 0f5c8f1..5f74526 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -27,57 +27,97 @@ #include "ohci.h" -/* interface and function clocks; sometimes also an AHB clock */ -static struct clk *iclk, *fclk; +struct ohci_at91_priv { + struct device_d *dev; + struct clk *iclk; + struct clk *fclk; + struct ohci_regs __iomem *regs; +}; -static void at91_start_clock(void) +static int at91_start_clock(struct ohci_at91_priv *ohci_at91) { - clk_enable(iclk); - clk_enable(fclk); + int ret; + + ret = clk_enable(ohci_at91->iclk); + if (ret < 0) { + dev_err(ohci_at91->dev, "Failed to enable 'iclk'\n"); + return ret; + } + + ret = clk_enable(ohci_at91->fclk); + if (ret < 0) { + dev_err(ohci_at91->dev, "Failed to enable 'fclk'\n"); + return ret; + } + + return 0; } -static void at91_stop_clock(void) +static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) { - clk_disable(fclk); - clk_disable(iclk); + clk_disable(ohci_at91->fclk); + clk_disable(ohci_at91->iclk); } static int at91_ohci_probe(struct device_d *dev) { - struct ohci_regs __iomem *regs = (struct ohci_regs __iomem *)dev->resource[0].start; + int ret; + struct resource *io; + struct ohci_at91_priv *ohci_at91 = xzalloc(sizeof(*ohci_at91)); - iclk = clk_get(NULL, "ohci_clk"); - fclk = clk_get(NULL, "uhpck"); + dev->priv = ohci_at91; + ohci_at91->dev = dev; + + io = dev_get_resource(dev, IORESOURCE_MEM, 0); + if (IS_ERR(io)) { + dev_err(dev, "Failed to get IORESOURCE_MEM\n"); + return PTR_ERR(io); + } + ohci_at91->regs = IOMEM(io->start); + + ohci_at91->iclk = clk_get(NULL, "ohci_clk"); + if (IS_ERR(ohci_at91->iclk)) { + dev_err(dev, "Failed to get 'ohci_clk'\n"); + return PTR_ERR(ohci_at91->iclk); + } + + ohci_at91->fclk = clk_get(NULL, "uhpck"); + if (IS_ERR(ohci_at91->fclk)) { + dev_err(dev, "Failed to get 'uhpck'\n"); + return PTR_ERR(ohci_at91->fclk); + } /* * Start the USB clocks. */ - at91_start_clock(); + ret = at91_start_clock(ohci_at91); + if (ret < 0) + return ret; /* * The USB host controller must remain in reset. */ - writel(0, ®s->control); + writel(0, &ohci_at91->regs->control); - add_generic_device("ohci", DEVICE_ID_DYNAMIC, NULL, dev->resource[0].start, - resource_size(&dev->resource[0]), IORESOURCE_MEM, NULL); + add_generic_device("ohci", DEVICE_ID_DYNAMIC, NULL, io->start, + resource_size(io), IORESOURCE_MEM, NULL); return 0; } static void at91_ohci_remove(struct device_d *dev) { - struct ohci_regs __iomem *regs = (struct ohci_regs __iomem *)dev->resource[0].start; + struct ohci_at91_priv *ohci_at91 = dev->priv; /* * Put the USB host controller into reset. */ - writel(0, ®s->control); + writel(0, &ohci_at91->regs->control); /* * Stop the USB clocks. */ - at91_stop_clock(); + at91_stop_clock(ohci_at91); } static struct driver_d at91_ohci_driver = { diff --git a/include/linux/clk.h b/include/linux/clk.h index 7dd5238..a061398 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -329,7 +329,7 @@ __attribute__ ((unused,section (".__clk_of_table"))) \ = { .compatible = compat, .data = fn } -#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER) +#if defined(CONFIG_COMMON_CLK_OF_PROVIDER) int of_clk_add_provider(struct device_node *np, struct clk *(*clk_src_get)(struct of_phandle_args *args, void *data), @@ -348,7 +348,10 @@ struct clk *of_clk_get(struct device_node *np, int index); struct clk *of_clk_get_by_name(struct device_node *np, const char *name); struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec); +unsigned int of_clk_get_parent_count(struct device_node *np); char *of_clk_get_parent_name(struct device_node *np, unsigned int index); +int of_clk_parent_fill(struct device_node *np, const char **parents, + unsigned int size); int of_clk_init(struct device_node *root, const struct of_device_id *matches); #else static inline struct clk *of_clk_get(struct device_node *np, int index) diff --git a/include/mfd/syscon.h b/include/mfd/syscon.h index 651d4c2..63b893e 100644 --- a/include/mfd/syscon.h +++ b/include/mfd/syscon.h @@ -14,10 +14,13 @@ #ifndef __MFD_SYSCON_H__ #define __MFD_SYSCON_H__ +#include + #ifdef CONFIG_MFD_SYSCON void __iomem *syscon_base_lookup_by_pdevname(const char *s); void __iomem *syscon_base_lookup_by_phandle (struct device_node *np, const char *property); +struct regmap *syscon_node_to_regmap(struct device_node *np); #else static inline void __iomem *syscon_base_lookup_by_pdevname(const char *s) { @@ -29,6 +32,11 @@ { return ERR_PTR(-ENOSYS); } + +static inline struct regmap *syscon_node_to_regmap(struct device_node *np) +{ + return ERR_PTR(-ENOSYS); +} #endif #endif