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

Reply via email to