From 31e16d17690e39e9ca8170a0066404e1069aa072 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Mon, 13 Feb 2017 18:06:56 +0100 Subject: [PATCH 01/20] at91: serial: pullup RX pins, do not pullup TX pins We have a number of sama5d3 devices that sometimes hangs at the barebox prompt during boot due to floating RX pins. This patch fixes the problem for us (and probably others). It is similar in nature to linux kernel commit 138c2b2f175b ("ARM: dts: at91: fixes dbgu pinctrl, set pullup on rx, clear pullup on tx") While at it, remove pointless waste of power that the pullup of the TX pins causes and fix the signal comments for SAMA5D4. Signed-off-by: Peter Rosin Signed-off-by: Sascha Hauer --- arch/arm/mach-at91/at91rm9200_devices.c | 20 +++++++-------- arch/arm/mach-at91/at91sam9260_devices.c | 28 ++++++++++----------- arch/arm/mach-at91/at91sam9261_devices.c | 16 ++++++------ arch/arm/mach-at91/at91sam9263_devices.c | 16 ++++++------ arch/arm/mach-at91/at91sam9g45_devices.c | 20 +++++++-------- arch/arm/mach-at91/at91sam9n12_devices.c | 20 +++++++-------- arch/arm/mach-at91/at91sam9x5_devices.c | 20 +++++++-------- arch/arm/mach-at91/sama5d3_devices.c | 12 ++++----- arch/arm/mach-at91/sama5d4_devices.c | 32 ++++++++++++------------ 9 files changed, 92 insertions(+), 92 deletions(-) diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 7b68cdac2..a110ee3e3 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -250,16 +250,16 @@ void __init at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata 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_usart0(unsigned pins) 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_usart1(unsigned pins) 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_usart2(unsigned pins) 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 67c4ea860..99919b3f8 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -261,16 +261,16 @@ void __init at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata 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_usart0(unsigned pins) 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_usart1(unsigned pins) 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_usart2(unsigned pins) 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_usart3(unsigned pins) 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 620ed652d..e63e0e751 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -265,16 +265,16 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} 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_usart0(unsigned pins) 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_usart1(unsigned pins) 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 a3683e53b..559b77e9d 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -296,16 +296,16 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} 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_usart0(unsigned pins) 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_usart1(unsigned pins) 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/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index bad7f9c5b..bc4132040 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -213,16 +213,16 @@ void at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_de 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_usart0(unsigned pins) 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_usart1(unsigned pins) 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_usart2(unsigned pins) 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 bac023f55..84c871c6e 100644 --- a/arch/arm/mach-at91/at91sam9n12_devices.c +++ b/arch/arm/mach-at91/at91sam9n12_devices.c @@ -370,16 +370,16 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} #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_usart0(unsigned pins) 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_usart1(unsigned pins) 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_usart2(unsigned pins) 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 34537d8cf..d7ddda47c 100644 --- a/arch/arm/mach-at91/at91sam9x5_devices.c +++ b/arch/arm/mach-at91/at91sam9x5_devices.c @@ -453,16 +453,16 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} #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_usart0(unsigned pins) 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_usart1(unsigned pins) 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_usart2(unsigned pins) 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/sama5d3_devices.c b/arch/arm/mach-at91/sama5d3_devices.c index 3fdfca8c6..c6f5e3a87 100644 --- a/arch/arm/mach-at91/sama5d3_devices.c +++ b/arch/arm/mach-at91/sama5d3_devices.c @@ -464,16 +464,16 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} #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_usart0(unsigned pins) 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 e1b0a64d9..c2f171a96 100644 --- a/arch/arm/mach-at91/sama5d4_devices.c +++ b/arch/arm/mach-at91/sama5d4_devices.c @@ -430,24 +430,24 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_platform_data *data) {} #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_usart1(unsigned pins) 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; } From 2574148ad9a678838dcf361cd920531c5a542ec5 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:50 -0800 Subject: [PATCH 02/20] at91: Fix bug/typo in debug_ll.h Correct "COFNIG" to "CONFIG". Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/mach-at91/include/mach/debug_ll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/include/mach/debug_ll.h b/arch/arm/mach-at91/include/mach/debug_ll.h index 1a85ae483..42728a4b2 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 From 943a9eeac42f073518a94f1decd37529c0da5d42 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:51 -0800 Subject: [PATCH 03/20] regmap: Implement syscon_node_to_regmap() Implement syscon_node_to_regmap() to simplify porting kernel code. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/mfd/syscon.c | 54 +++++++++++++++++++++++++++++++++++++++++++- include/mfd/syscon.h | 8 +++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 6ef30ce19..957d9a726 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -28,6 +28,34 @@ struct syscon { 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 @@ static struct syscon *of_syscon_register(struct device_node *np) 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 @@ err_map: 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; @@ -71,6 +103,16 @@ static void __iomem *syscon_node_to_base(struct device_node *np) if (!syscon) syscon = of_syscon_register(np); + 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); @@ -108,6 +150,16 @@ void __iomem *syscon_base_lookup_by_phandle(struct device_node *np, 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/include/mfd/syscon.h b/include/mfd/syscon.h index 651d4c267..63b893e4a 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 @@ static inline void __iomem *syscon_base_lookup_by_phandle { return ERR_PTR(-ENOSYS); } + +static inline struct regmap *syscon_node_to_regmap(struct device_node *np) +{ + return ERR_PTR(-ENOSYS); +} #endif #endif From 7d9679a33a32f2d4fd08628d52e716bb452e8734 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:52 -0800 Subject: [PATCH 04/20] pinctrl: at91: Fix a bug in at91_pinctrl_set_conf() Pin_to_controller returns struct at91_gpio_chip, whereas at91_mux_* functions expect void __iomem * pointing to controller register window. Fix the code to do appropriate conversion between the two. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/pinctrl/pinctrl-at91.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index ebbc6f6f1..e24c9beae 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -414,8 +414,10 @@ static int at91_pinctrl_set_conf(struct at91_pinctrl *info, unsigned int pin_num { 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) From 15426d5c46c57020cf62e350fa6de07a46889ec3 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:53 -0800 Subject: [PATCH 05/20] pinctrl: at91: Fix a bug in at91_pinctrl_set_state() Pin number, as specified in OF pinumx entries, is relative to each bank start, whereas both at91_mux_pin() and at91_pinctrl_set_conf() asssume absolute pin numbering, so we need to take into account each bank's pin base and convert pin number appropriately. Failing to do so results in any pinmux configuration being applied to pins in bank A. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/pinctrl/pinctrl-at91.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index e24c9beae..34fb0ae62 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -462,6 +462,8 @@ static int at91_pinctrl_set_state(struct pinctrl_device *pdev, struct device_nod 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); From da1752b37003a0c1c9b25948b05e19f4ab8055a1 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:54 -0800 Subject: [PATCH 06/20] pinctrl: at91: Implement .get_direction hook Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/pinctrl/pinctrl-at91.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 34fb0ae62..021c1e5a2 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -568,6 +568,21 @@ static int at91_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 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); @@ -603,6 +618,7 @@ static struct gpio_ops at91_gpio_ops = { .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, }; From b5ea2c6acce4cbe4bdf68c052018859b8c8c50b5 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:55 -0800 Subject: [PATCH 07/20] clk: Port two helper functions from Linux Port of_clk_get_parent_count() and of_clk_parent_fill() from Linux. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/clk/clk.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/clk.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 93e000c6e..91895212e 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -452,6 +452,24 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) 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 @@ char *of_clk_get_parent_name(struct device_node *np, unsigned int index) } 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/include/linux/clk.h b/include/linux/clk.h index 7dd52388c..f73b02986 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -348,7 +348,10 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, void *data); 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) From a8b41f2c7266cb4fd01f68937fdc2391f10a11cf Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:56 -0800 Subject: [PATCH 08/20] clk: Make COMMON_CLK_OF_PROVIDER depend on OFTREE Make COMMON_CLK_OF_PROVIDER depend on OFTREE, this way checking for: defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER) can be simplified to just: defined(CONFIG_COMMON_CLK_OF_PROVIDER) Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/clk/Kconfig | 1 + drivers/clk/clk-fixed-factor.c | 2 +- drivers/clk/clk-fixed.c | 2 +- drivers/clk/clk.c | 2 +- drivers/clk/clkdev.c | 2 +- include/linux/clk.h | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1cf0ccb96..dedbf6c4d 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -10,6 +10,7 @@ config COMMON_CLK 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 40b63d6d5..a3dbf334a 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -93,7 +93,7 @@ struct clk *clk_fixed_factor(const char *name, 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 8164005a0..f0f7fbaed 100644 --- a/drivers/clk/clk-fixed.c +++ b/drivers/clk/clk-fixed.c @@ -55,7 +55,7 @@ struct clk *clk_fixed(const char *name, int rate) 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 91895212e..5bb147eee 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -346,7 +346,7 @@ int clk_parent_set_rate(struct clk *clk, unsigned long rate, 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 diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 1bc5c6daa..7f9f8f2ad 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/include/linux/clk.h b/include/linux/clk.h index f73b02986..a06139855 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -329,7 +329,7 @@ const struct of_device_id __clk_of_table_##name \ __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), From 3494084017c4b7e6b44923219a9fd07689fcc2fc Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:58 -0800 Subject: [PATCH 09/20] of: base: Use scoring in DT device matching Port Linux kernel algorithm for both of_device_is_compatible() and of_match_node(). With this change former now returns a score on the scale of 0 to INT_MAX/2, and the latter goes through all compatiblity entries and selects the entry that has the best matching score. This is needed for SoCs where IP blocks are backwards compatible and corresponding OF nodes can proclaim compatibility with several entries found in driver's compatiblity table. One such example would be PIO pinctrl block on AT91SAM9x5 SoCs which declare compatibility with with both "atmel,at91sam9x5-pinctrl" and "atmel,at91rm9200-pinctrl". Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/of/base.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 0c20fcd5c..bef8f1de1 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -472,21 +472,20 @@ EXPORT_SYMBOL(of_get_cpu_node); 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 @@ EXPORT_SYMBOL(of_find_node_with_property); 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; } /** From 6dc7545135c010b3f14061148ffab0874825f471 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:08:59 -0800 Subject: [PATCH 10/20] serial: atmel: Check result of clk_get() Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/serial/atmel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c index 4e4624e23..ab94fd217 100644 --- a/drivers/serial/atmel.c +++ b/drivers/serial/atmel.c @@ -403,6 +403,11 @@ static int atmel_serial_init_port(struct console_device *cdev) 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); From 56f3bd1cd31fe1caefb13189b351640c40d5d2b0 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:00 -0800 Subject: [PATCH 11/20] usb: ohci-at91: Check result of clk_get() Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ohci-at91.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 0f5c8f130..ca583ff4d 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -47,7 +47,16 @@ static int at91_ohci_probe(struct device_d *dev) struct ohci_regs __iomem *regs = (struct ohci_regs __iomem *)dev->resource[0].start; iclk = clk_get(NULL, "ohci_clk"); + if (IS_ERR(iclk)) { + dev_err(dev, "Failed to get 'ohci_clk'\n"); + return PTR_ERR(iclk); + } + fclk = clk_get(NULL, "uhpck"); + if (IS_ERR(fclk)) { + dev_err(dev, "Failed to get 'uhpck'\n"); + return PTR_ERR(fclk); + } /* * Start the USB clocks. From fb1ff1794a29a282927bd859e3c6ff2a304a8ea6 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:01 -0800 Subject: [PATCH 12/20] usb: ohci-at91: Convert global variables to private data Store driver data in per-device private variable as opposed to storing it in global vairables. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ohci-at91.c | 59 ++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index ca583ff4d..cd7b321fd 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -27,66 +27,81 @@ #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 void at91_start_clock(struct ohci_at91_priv *ohci_at91) { - clk_enable(iclk); - clk_enable(fclk); + clk_enable(ohci_at91->iclk); + clk_enable(ohci_at91->fclk); } -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; + struct resource *io; + struct ohci_at91_priv *ohci_at91 = xzalloc(sizeof(*ohci_at91)); - iclk = clk_get(NULL, "ohci_clk"); - if (IS_ERR(iclk)) { + 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(iclk); + return PTR_ERR(ohci_at91->iclk); } - fclk = clk_get(NULL, "uhpck"); - if (IS_ERR(fclk)) { + ohci_at91->fclk = clk_get(NULL, "uhpck"); + if (IS_ERR(ohci_at91->fclk)) { dev_err(dev, "Failed to get 'uhpck'\n"); - return PTR_ERR(fclk); + return PTR_ERR(ohci_at91->fclk); } /* * Start the USB clocks. */ - at91_start_clock(); + at91_start_clock(ohci_at91); /* * 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 = { From bf09557360b40d19ba8fd6e0a052d3849dda3a66 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:02 -0800 Subject: [PATCH 13/20] usb: ohci-at91: Check result of clk_enable() Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ohci-at91.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index cd7b321fd..5f745264b 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -34,10 +34,23 @@ struct ohci_at91_priv { struct ohci_regs __iomem *regs; }; -static void at91_start_clock(struct ohci_at91_priv *ohci_at91) +static int at91_start_clock(struct ohci_at91_priv *ohci_at91) { - clk_enable(ohci_at91->iclk); - clk_enable(ohci_at91->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(struct ohci_at91_priv *ohci_at91) @@ -48,6 +61,7 @@ static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) static int at91_ohci_probe(struct device_d *dev) { + int ret; struct resource *io; struct ohci_at91_priv *ohci_at91 = xzalloc(sizeof(*ohci_at91)); @@ -76,7 +90,9 @@ static int at91_ohci_probe(struct device_d *dev) /* * Start the USB clocks. */ - at91_start_clock(ohci_at91); + ret = at91_start_clock(ohci_at91); + if (ret < 0) + return ret; /* * The USB host controller must remain in reset. From b52eb5a9a228e5f1c0d2fc485b71b7c4e67b143a Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:03 -0800 Subject: [PATCH 14/20] usb: ehci-atmel: Check result of clk_enable() Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ehci-atmel.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index cc9636c4b..fa9ca7d5b 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -32,10 +32,20 @@ /* interface and function clocks; sometimes also an AHB clock */ static struct clk *iclk, *fclk; -static void atmel_start_clock(void) +static int atmel_start_clock(void) { - clk_enable(iclk); - clk_enable(fclk); + int ret; + ret = clk_enable(iclk); + if (ret < 0) { + pr_err("Error enabling interface clock\n"); + return ret; + } + + ret = clk_enable(fclk); + if (ret < 0) + pr_err("Error enabling function clock\n"); + + return ret; } static void atmel_stop_clock(void) @@ -46,6 +56,7 @@ static void atmel_stop_clock(void) static int atmel_ehci_probe(struct device_d *dev) { + int ret; struct resource *iores; struct ehci_data data; @@ -64,7 +75,9 @@ static int atmel_ehci_probe(struct device_d *dev) /* * Start the USB clocks. */ - atmel_start_clock(); + ret = atmel_start_clock(); + if (ret < 0) + return ret; data.flags = 0; From ef54fb4b1f14ed89f06b9e5158770ac6df9b64f8 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:04 -0800 Subject: [PATCH 15/20] usb: echi-atmel: Convert global variables to private data Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ehci-atmel.c | 42 ++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index fa9ca7d5b..7a9d942a1 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -29,29 +29,34 @@ #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 int atmel_start_clock(void) +static int atmel_start_clock(struct atmel_ehci_priv *atehci) { int ret; - ret = clk_enable(iclk); + ret = clk_enable(atehci->iclk); if (ret < 0) { - pr_err("Error enabling interface clock\n"); + dev_err(atehci->dev, + "Error enabling interface clock\n"); return ret; } - ret = clk_enable(fclk); + ret = clk_enable(atehci->uclk); if (ret < 0) - pr_err("Error enabling function clock\n"); + 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) @@ -59,15 +64,20 @@ 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; } @@ -75,7 +85,7 @@ static int atmel_ehci_probe(struct device_d *dev) /* * Start the USB clocks. */ - ret = atmel_start_clock(); + ret = atmel_start_clock(atehci); if (ret < 0) return ret; @@ -96,7 +106,7 @@ static void atmel_ehci_remove(struct device_d *dev) /* * Stop the USB clocks. */ - atmel_stop_clock(); + atmel_stop_clock(dev->priv); } static struct driver_d atmel_ehci_driver = { From 05c34d220c8e3f3a30d5877ab56681fbae85622e Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:05 -0800 Subject: [PATCH 16/20] usb: ehci-atmel: Zero ehci_data before using it Zero ehci_data before using it as an argument for echi_register, otherwise bogus values (some of which are interpreted as callbacks) will be passed through, resulting in illegal memory accesses. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ehci-atmel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 7a9d942a1..4b9fc0a94 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -89,7 +89,7 @@ static int atmel_ehci_probe(struct device_d *dev) if (ret < 0) return ret; - data.flags = 0; + memset(&data, 0, sizeof(data)); iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) From d5f52220e60dbd2ce0c39ba53b783a0a1c438470 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:06 -0800 Subject: [PATCH 17/20] usb: echi-atmel: Check result of ehci_register() Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/usb/host/ehci-atmel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 4b9fc0a94..f075b5080 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -96,9 +96,7 @@ static int atmel_ehci_probe(struct device_d *dev) 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) From dd0f42879ba7954ade946fe4d64f5ff0aaeb17b3 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:07 -0800 Subject: [PATCH 18/20] spi: atmel_spi: Configure CS GPIO as output On AT91 GPIOs default to being inputs, so we need to explicitly configure CS gpio to being an output. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/spi/atmel_spi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 3f2c527d1..67028e6ad 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -172,6 +172,8 @@ static int atmel_spi_setup(struct spi_device *spi) 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 +185,8 @@ static int atmel_spi_setup(struct spi_device *spi) 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", @@ -235,7 +239,7 @@ static int atmel_spi_setup(struct spi_device *spi) 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); From d6200fe41500c9b06e12d43aaddd060eee8e1b8d Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:08 -0800 Subject: [PATCH 19/20] spi: atmel_spi: Use VERSION register instead of CPU type Use VERSION register instead of CPU type to determine IP block's version and capabilities. This what corresponding Linux kernel driver does. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/spi/atmel_spi.c | 35 +++++++++++++++++++++++++++++------ drivers/spi/atmel_spi.h | 1 + 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 67028e6ad..ef5786775 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 @@ struct atmel_spi { * 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 @@ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) 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 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) 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) @@ -199,7 +205,7 @@ static int atmel_spi_setup(struct spi_device *spi) 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) { @@ -248,7 +254,7 @@ static int atmel_spi_setup(struct spi_device *spi) 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; @@ -373,6 +379,21 @@ err: 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; @@ -409,6 +430,8 @@ static int atmel_spi_probe(struct device_d *dev) 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 38ce11998..3f4d7ba12 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 From a76714f7f9c6f1e3f1ebafc4fc2e197181ac9e8c Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 8 Mar 2017 14:09:09 -0800 Subject: [PATCH 20/20] clocksource: at91: Move to 'drivers/clocksource' Move PIT driver code to 'drivers/clocsource' and accomodate it by adjusting Kconfig variables. Rename the file to 'timer-atmel-pit.c' to re-align the driver with code in Linux kernel. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/mach-at91/Kconfig | 7 ++----- arch/arm/mach-at91/Makefile | 1 - drivers/clocksource/Kconfig | 4 ++++ drivers/clocksource/Makefile | 1 + .../clocksource/timer-atmel-pit.c | 0 5 files changed, 7 insertions(+), 6 deletions(-) rename arch/arm/mach-at91/at91sam926x_time.c => drivers/clocksource/timer-atmel-pit.c (100%) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index c45fc4d6b..2d4721a26 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -15,20 +15,17 @@ config HAVE_AT91_LOWLEVEL_INIT 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 c2991b013..1f63b09aa 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_AT91SAM9_RESET) += at91sam9_reset.o 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/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f1ab554f9..f3c3255ff 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -53,3 +53,7 @@ config CLOCKSOURCE_UEMD 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 39982ffb2..0564d8f5a 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o 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/arch/arm/mach-at91/at91sam926x_time.c b/drivers/clocksource/timer-atmel-pit.c similarity index 100% rename from arch/arm/mach-at91/at91sam926x_time.c rename to drivers/clocksource/timer-atmel-pit.c