Here are my patches for ar71xx enabling UART to be turned on and off
at runtime to free up the GPIO pins,
And I forgot to attach the patches. Sorry. Here they are.
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -20,9 +20,37 @@
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_uart_platform.h>
#include "common.h"
#include "dev-common.h"
+static void ath79_enable_uart(struct platform_device* pdev) {
+ if (soc_is_ar71xx())
+ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar724x())
+ ath79_gpio_function_enable(AR724X_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar913x())
+ ath79_gpio_function_enable(AR913X_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar933x())
+ ath79_gpio_function_enable(AR933X_GPIO_FUNC_UART_EN);
+}
+
+static void ath79_disable_uart(struct platform_device* pdev) {
+ if (soc_is_ar71xx())
+ ath79_gpio_function_disable(AR71XX_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar724x())
+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar913x())
+ ath79_gpio_function_disable(AR913X_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar933x())
+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_UART_EN);
+}
+
+static struct ath79_platform_uart_hooks platform_hooks = {
+ .probe = ath79_enable_uart,
+ .remove = ath79_disable_uart,
+};
+
static struct resource ath79_uart_resources[] = {
{
.start = AR71XX_UART_BASE,
@@ -72,6 +100,9 @@ static struct platform_device ar933x_uar
.id = -1,
.resource = ar933x_uart_resources,
.num_resources = ARRAY_SIZE(ar933x_uart_resources),
+ .dev = {
+ .platform_data = &platform_hooks
+ },
};
void __init ath79_register_uart(void)
@@ -97,6 +128,7 @@ void __init ath79_register_uart(void)
soc_is_qca955x() ||
soc_is_qca956x()) {
ath79_uart_data[0].uartclk = uart_clk_rate;
+ ath79_enable_uart(&ath79_uart_device);
platform_device_register(&ath79_uart_device);
} else if (soc_is_ar933x()) {
platform_device_register(&ar933x_uart_device);
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_uart_platform.h
@@ -0,0 +1,21 @@
+/*
+ * Platform data definition for Atheros AR71XX/AR724X/AR913X UART controller
+ *
+ * Copyright (C) 2015 Piotr Madalinski <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_UART_PLATFORM_H
+#define _ATH79_UART_PLATFORM_H
+
+struct platform_device;
+
+struct ath79_platform_uart_hooks {
+ void (*probe)(struct platform_device*);
+ void (*remove)(struct platform_device*);
+};
+
+#endif /* _ATH79_UART_PLATFORM_H */
--- a/drivers/tty/serial/ar933x_uart.c
+++ b/drivers/tty/serial/ar933x_uart.c
@@ -31,6 +31,7 @@
#include <asm/div64.h>
#include <asm/mach-ath79/ar933x_uart.h>
+#include <asm/mach-ath79/ath79_uart_platform.h>
#define DRIVER_NAME "ar933x-uart"
@@ -50,6 +51,7 @@ struct ar933x_uart_port {
unsigned int min_baud;
unsigned int max_baud;
struct clk *clk;
+ struct ath79_platform_uart_hooks *platform_hooks;
};
static inline bool ar933x_uart_console_enabled(void)
@@ -669,6 +671,10 @@ static int ar933x_uart_probe(struct plat
return PTR_ERR(up->clk);
}
+ up->platform_hooks = dev_get_platdata(&pdev->dev);
+ if (up->platform_hooks && up->platform_hooks->probe)
+ up->platform_hooks->probe(pdev);
+
port = &up->port;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -710,6 +716,7 @@ static int ar933x_uart_probe(struct plat
goto err_disable_clk;
platform_set_drvdata(pdev, up);
+
return 0;
err_disable_clk:
@@ -726,8 +733,9 @@ static int ar933x_uart_remove(struct pla
if (up) {
uart_remove_one_port(&ar933x_uart_driver, &up->port);
clk_disable_unprepare(up->clk);
+ if (up->platform_hooks && up->platform_hooks->remove)
+ up->platform_hooks->remove(pdev);
}
-
return 0;
}
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -67,6 +67,8 @@ static struct plat_serial8250_port ath79
.flags = AR71XX_UART_FLAGS,
.iotype = UPIO_MEM32,
.regshift = 2,
+ .platform_probe = &ath79_enable_uart,
+ .platform_remove = &ath79_disable_uart,
}, {
/* terminating entry */
}
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -3676,6 +3676,9 @@ static int serial8250_probe(struct platf
struct uart_8250_port uart;
int ret, i, irqflag = 0;
+ if (p && p->platform_probe)
+ p->platform_probe(dev);
+
memset(&uart, 0, sizeof(uart));
if (share_irqs)
@@ -3718,6 +3721,7 @@ static int serial8250_probe(struct platf
*/
static int serial8250_remove(struct platform_device *dev)
{
+ struct plat_serial8250_port *p;
int i;
for (i = 0; i < nr_uarts; i++) {
@@ -3726,6 +3730,12 @@ static int serial8250_remove(struct plat
if (up->port.dev == &dev->dev)
serial8250_unregister_port(i);
}
+
+ p = dev_get_platdata(&dev->dev);
+
+ if (p && p->platform_remove)
+ p->platform_remove(dev);
+
return 0;
}
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -39,6 +39,8 @@ struct plat_serial8250_port {
void (*pm)(struct uart_port *, unsigned int state,
unsigned old);
void (*handle_break)(struct uart_port *);
+ void (*platform_probe)(struct platform_device*);
+ void (*platform_remove)(struct platform_device*);
};
/*
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel