From 400943cf88102423ac10a19c56d053d9c1580a77 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 8 Mar 2012 08:37:25 +0100
Subject: [PATCH 18/70] MIPS: lantiq: use devres managed gpios

3.2 introduced devm_request_gpio() to allow managed gpios.

The devres api requires a struct device pointer to work. Add a parameter to ltq_gpio_request()
so that managed gpios can work.

Signed-off-by: John Crispin <blogic@openwrt.org>
---
 .../include/asm/mach-lantiq/falcon/lantiq_soc.h    |    4 +---
 arch/mips/include/asm/mach-lantiq/lantiq.h         |    4 ++++
 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h |    3 ---
 arch/mips/lantiq/falcon/gpio.c                     |    4 ++--
 arch/mips/lantiq/falcon/prom.c                     |    7 -------
 arch/mips/lantiq/xway/gpio.c                       |    4 ++--
 arch/mips/lantiq/xway/gpio_stp.c                   |   13 ++++++++-----
 arch/mips/pci/pci-lantiq.c                         |   18 ++++++++++--------
 drivers/net/ethernet/lantiq_etop.c                 |    9 ++++++---
 drivers/tty/serial/lantiq.c                        |   12 ++++++++++++
 10 files changed, 45 insertions(+), 33 deletions(-)

--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -126,9 +126,7 @@ extern __iomem void *ltq_sys1_membase;
 #define ltq_sys1_w32_mask(clear, set, reg)   \
 	ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
 
-/* gpio_request wrapper to help configure the pin */
-extern int  ltq_gpio_request(unsigned int pin, unsigned int mux,
-				unsigned int dir, const char *name);
+/* gpio wrapper to help configure the pin muxing */
 extern int ltq_gpio_mux_set(unsigned int pin, unsigned int mux);
 
 /* to keep the irq code generic we need to define these to 0 as falcon
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -37,6 +37,10 @@ extern unsigned int ltq_get_soc_type(voi
 /* spinlock all ebu i/o */
 extern spinlock_t ebu_lock;
 
+/* request a non-gpio and set the PIO config */
+extern int ltq_gpio_request(struct device *dev, unsigned int pin,
+		unsigned int mux, unsigned int dir, const char *name);
+
 /* some irq helpers */
 extern void ltq_disable_irq(struct irq_data *data);
 extern void ltq_mask_and_ack_irq(struct irq_data *data);
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -145,9 +145,6 @@
 extern __iomem void *ltq_ebu_membase;
 extern __iomem void *ltq_cgu_membase;
 
-/* request a non-gpio and set the PIO config */
-extern int  ltq_gpio_request(unsigned int pin, unsigned int mux,
-				unsigned int dir, const char *name);
 extern void ltq_pmu_enable(unsigned int module);
 extern void ltq_pmu_disable(unsigned int module);
 extern void ltq_cgu_enable(unsigned int clk);
--- a/arch/mips/lantiq/falcon/gpio.c
+++ b/arch/mips/lantiq/falcon/gpio.c
@@ -97,7 +97,7 @@ int ltq_gpio_mux_set(unsigned int pin, u
 }
 EXPORT_SYMBOL(ltq_gpio_mux_set);
 
-int ltq_gpio_request(unsigned int pin, unsigned int mux,
+int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
 			unsigned int dir, const char *name)
 {
 	int port = pin / 100;
@@ -106,7 +106,7 @@ int ltq_gpio_request(unsigned int pin, u
 	if (offset >= PINS_PER_PORT || port >= MAX_PORTS)
 		return -EINVAL;
 
-	if (gpio_request(pin, name)) {
+	if (devm_gpio_request(dev, pin, name)) {
 		pr_err("failed to setup lantiq gpio: %s\n", name);
 		return -EBUSY;
 	}
--- a/arch/mips/lantiq/falcon/prom.c
+++ b/arch/mips/lantiq/falcon/prom.c
@@ -27,9 +27,6 @@
 #define TYPE_SHIFT	26
 #define TYPE_MASK	0x3C000000
 
-#define MUXC_SIF_RX_PIN		112
-#define MUXC_SIF_TX_PIN		113
-
 /* this parameter allows us enable/disable asc1 via commandline */
 static int register_asc1;
 static int __init
@@ -48,10 +45,6 @@ ltq_soc_setup(void)
 	falcon_register_gpio();
 	if (register_asc1) {
 		ltq_register_asc(1);
-		if (ltq_gpio_request(MUXC_SIF_RX_PIN, 3, 0, "asc1-rx"))
-			pr_err("failed to request asc1-rx");
-		if (ltq_gpio_request(MUXC_SIF_TX_PIN, 3, 1, "asc1-tx"))
-			pr_err("failed to request asc1-tx");
 		ltq_sysctl_activate(SYSCTL_SYS1, ACTS_ASC1_ACT);
 	}
 }
--- a/arch/mips/lantiq/xway/gpio.c
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -50,14 +50,14 @@ int irq_to_gpio(unsigned int gpio)
 }
 EXPORT_SYMBOL(irq_to_gpio);
 
-int ltq_gpio_request(unsigned int pin, unsigned int mux,
+int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux,
 			unsigned int dir, const char *name)
 {
 	int id = 0;
 
 	if (pin >= (MAX_PORTS * PINS_PER_PORT))
 		return -EINVAL;
-	if (gpio_request(pin, name)) {
+	if (devm_gpio_request(dev, pin, name)) {
 		pr_err("failed to setup lantiq gpio: %s\n", name);
 		return -EBUSY;
 	}
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -80,11 +80,6 @@ static struct gpio_chip ltq_stp_chip = {
 
 static int ltq_stp_hw_init(void)
 {
-	/* the 3 pins used to control the external stp */
-	ltq_gpio_request(4, 2, 1, "stp-st");
-	ltq_gpio_request(5, 2, 1, "stp-d");
-	ltq_gpio_request(6, 2, 1, "stp-sh");
-
 	/* sane defaults */
 	ltq_stp_w32(0, LTQ_STP_AR);
 	ltq_stp_w32(0, LTQ_STP_CPU0);
@@ -133,6 +128,14 @@ static int __devinit ltq_stp_probe(struc
 		dev_err(&pdev->dev, "failed to remap STP memory\n");
 		return -ENOMEM;
 	}
+
+	/* the 3 pins used to control the external stp */
+	if (ltq_gpio_request(&pdev->dev, 4, 2, 1, "stp-st") ||
+			ltq_gpio_request(&pdev->dev, 5, 2, 1, "stp-d") ||
+			ltq_gpio_request(&pdev->dev, 6, 2, 1, "stp-sh")) {
+		dev_err(&pdev->dev, "failed to request needed gpios\n");
+		return -EBUSY;
+	}
 	ret = gpiochip_add(&ltq_stp_chip);
 	if (!ret)
 		ret = ltq_stp_hw_init();
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -150,24 +150,26 @@ static u32 ltq_calc_bar11mask(void)
 	return bar11mask;
 }
 
-static void ltq_pci_setup_gpio(int gpio)
+static void ltq_pci_setup_gpio(struct device *dev)
 {
+	struct ltq_pci_data *conf = (struct ltq_pci_data *) dev->platform_data;
 	int i;
 	for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
-		if (gpio & (1 << i)) {
-			ltq_gpio_request(ltq_pci_gpio_map[i].pin,
+		if (conf->gpio & (1 << i)) {
+			ltq_gpio_request(dev, ltq_pci_gpio_map[i].pin,
 				ltq_pci_gpio_map[i].mux,
 				ltq_pci_gpio_map[i].dir,
 				ltq_pci_gpio_map[i].name);
 		}
 	}
-	ltq_gpio_request(21, 0, 1, "pci-reset");
-	ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
+	ltq_gpio_request(dev, 21, 0, 1, "pci-reset");
+	ltq_pci_req_mask = (conf->gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
 }
 
-static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
+static int __devinit ltq_pci_startup(struct device *dev)
 {
 	u32 temp_buffer;
+	struct ltq_pci_data *conf = (struct ltq_pci_data *) dev->platform_data;
 
 	/* set clock to 33Mhz */
 	if (ltq_is_ar9()) {
@@ -190,7 +192,7 @@ static int __devinit ltq_pci_startup(str
 	}
 
 	/* setup pci clock and gpis used by pci */
-	ltq_pci_setup_gpio(conf->gpio);
+	ltq_pci_setup_gpio(dev);
 
 	/* enable auto-switching between PCI and EBU */
 	ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
@@ -275,7 +277,7 @@ static int __devinit ltq_pci_probe(struc
 		ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
 	ltq_pci_controller.io_map_base =
 		(unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
-	ltq_pci_startup(ltq_pci_data);
+	ltq_pci_startup(&pdev->dev);
 	register_pci_controller(&ltq_pci_controller);
 
 	return 0;
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -292,9 +292,6 @@ ltq_etop_gbit_init(void)
 {
 	ltq_pmu_enable(PMU_SWITCH);
 
-	ltq_gpio_request(42, 2, 1, "MDIO");
-	ltq_gpio_request(43, 2, 1, "MDC");
-
 	ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
 	/** Disable MDIO auto polling mode */
 	ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
@@ -870,6 +867,12 @@ ltq_etop_probe(struct platform_device *p
 			err = -ENOMEM;
 			goto err_out;
 		}
+		if (ltq_gpio_request(&pdev->dev, 42, 2, 1, "MDIO") ||
+				ltq_gpio_request(&pdev->dev, 43, 2, 1, "MDC")) {
+			dev_err(&pdev->dev, "failed to request MDIO gpios\n");
+			err = -EBUSY;
+			goto err_out;
+		}
 	}
 
 	dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -107,6 +107,9 @@
 #define ASCFSTAT_TXFREEMASK	0x3F000000
 #define ASCFSTAT_TXFREEOFF	24
 
+#define MUXC_SIF_RX_PIN		112
+#define MUXC_SIF_TX_PIN		113
+
 static void lqasc_tx_chars(struct uart_port *port);
 static struct ltq_uart_port *lqasc_port[MAXPORTS];
 static struct uart_driver lqasc_reg;
@@ -529,6 +532,15 @@ lqasc_request_port(struct uart_port *por
 		if (port->membase == NULL)
 			return -ENOMEM;
 	}
+	if (ltq_is_falcon() && (port->line == 1)) {
+		struct ltq_uart_port *ltq_port = lqasc_port[pdev->id];
+		if (ltq_gpio_request(&pdev->dev, MUXC_SIF_RX_PIN,
+				3, 0, "asc1-rx"))
+			return -EBUSY;
+		if (ltq_gpio_request(&pdev->dev, MUXC_SIF_TX_PIN,
+				3, 1, "asc1-tx"))
+			return -EBUSY;
+	}
 	return 0;
 }
 
