[ARM] 4757/1: [AT91] UART initialization
Modify the UART initialization to allow the board-initialization code
to specify which pins are connected, and which pins should therefore
be initialized.
The current at91_init_serial() will continue to work as-is, but is
marked as "deprecated" and will be removed once the board-specific
files has been updated to use the new interface.
As in the AVR32 code, we assume that the TX and RX pins will always be
initialized.
Signed-off-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index ba84ba6..467a643 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -867,12 +867,15 @@
.num_resources = ARRAY_SIZE(uart0_resources),
};
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(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_PC10, 0); /* RTS0 */
- at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */
}
static struct resource uart1_resources[] = {
@@ -907,10 +910,15 @@
.num_resources = ARRAY_SIZE(uart1_resources),
};
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */
at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA13, 0); /* CTS1 */
}
static struct resource uart2_resources[] = {
@@ -945,16 +953,21 @@
.num_resources = ARRAY_SIZE(uart2_resources),
};
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(unsigned pins)
{
at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */
at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */
}
static struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
struct platform_device *atmel_default_console_device; /* the serial console device */
-void __init at91_init_serial(struct at91_uart_config *config)
+void __init __deprecated at91_init_serial(struct at91_uart_config *config)
{
int i;
@@ -962,17 +975,17 @@
for (i = 0; i < config->nr_tty; i++) {
switch (config->tty_map[i]) {
case 0:
- configure_usart0_pins();
+ configure_usart0_pins(ATMEL_UART_CTS | ATMEL_UART_RTS);
at91_uarts[i] = &at91sam9261_uart0_device;
at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart");
break;
case 1:
- configure_usart1_pins();
+ configure_usart1_pins(0);
at91_uarts[i] = &at91sam9261_uart1_device;
at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart");
break;
case 2:
- configure_usart2_pins();
+ configure_usart2_pins(0);
at91_uarts[i] = &at91sam9261_uart2_device;
at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart");
break;
@@ -994,6 +1007,48 @@
printk(KERN_INFO "AT91: No default serial console defined.\n");
}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91sam9261_dbgu_device;
+ configure_dbgu_pins();
+ at91_clock_associate("mck", &pdev->dev, "usart");
+ break;
+ case AT91SAM9261_ID_US0:
+ pdev = &at91sam9261_uart0_device;
+ configure_usart0_pins(pins);
+ at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+ break;
+ case AT91SAM9261_ID_US1:
+ pdev = &at91sam9261_uart1_device;
+ configure_usart1_pins(pins);
+ at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+ break;
+ case AT91SAM9261_ID_US2:
+ pdev = &at91sam9261_uart2_device;
+ configure_usart2_pins(pins);
+ at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+ break;
+ default:
+ return;
+ }
+ pdev->id = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART)
+ atmel_default_console_device = at91_uarts[portnr];
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
void __init at91_add_device_serial(void)
{
int i;
@@ -1004,7 +1059,9 @@
}
}
#else
-void __init at91_init_serial(struct at91_uart_config *config) {}
+void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
void __init at91_add_device_serial(void) {}
#endif