From: Rosen Penev Date: Sun, 5 Jul 2026 23:28:56 +0000 (-0700) Subject: ramips: move GPIO driver to files X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1006c536b506a2e3d5fbe852eb938d16416d18cb;p=thirdparty%2Fopenwrt.git ramips: move GPIO driver to files This was last attempted to be upstreamed in 2014. Move it to files as with other local drivers. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/24095 Signed-off-by: Jonas Jelonek --- diff --git a/target/linux/ramips/files/drivers/gpio/gpio-ralink.c b/target/linux/ramips/files/drivers/gpio/gpio-ralink.c new file mode 100644 index 00000000000..91094a932c6 --- /dev/null +++ b/target/linux/ramips/files/drivers/gpio/gpio-ralink.c @@ -0,0 +1,316 @@ +/* + * 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. + * + * Copyright (C) 2009-2011 Gabor Juhos + * Copyright (C) 2013 John Crispin + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_NGPIOS 95 + +enum ralink_gpio_reg { + GPIO_REG_INT = 0, + GPIO_REG_EDGE, + GPIO_REG_RENA, + GPIO_REG_FENA, + GPIO_REG_DATA, + GPIO_REG_DIR, + GPIO_REG_POL, + GPIO_REG_SET, + GPIO_REG_RESET, + GPIO_REG_TOGGLE, + GPIO_REG_MAX +}; + +struct ralink_gpio_chip { + struct gpio_chip chip; + u8 regs[GPIO_REG_MAX]; + + spinlock_t lock; + void __iomem *membase; + int gpio_irq; + + u32 rising; + u32 falling; +}; + +static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val) +{ + iowrite32(val, rg->membase + rg->regs[reg]); +} + +static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg) +{ + return ioread32(rg->membase + rg->regs[reg]); +} + +static irqreturn_t ralink_gpio_irq_handler(int irq, void *data) +{ + struct gpio_chip *gc = data; + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + irqreturn_t ret = IRQ_NONE; + unsigned long pending; + int bit; + + pending = rt_gpio_r32(rg, GPIO_REG_INT); + for_each_set_bit(bit, &pending, rg->chip.ngpio) { + generic_handle_domain_irq(gc->irq.domain, bit); + rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit)); + ret |= IRQ_HANDLED; + } + + return ret; +} + +static void ralink_gpio_irq_unmask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + unsigned long flags; + u32 rise, fall; + + rise = rt_gpio_r32(rg, GPIO_REG_RENA); + fall = rt_gpio_r32(rg, GPIO_REG_FENA); + + spin_lock_irqsave(&rg->lock, flags); + rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising)); + rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling)); + spin_unlock_irqrestore(&rg->lock, flags); +} + +static void ralink_gpio_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + unsigned long flags; + u32 rise, fall; + + rise = rt_gpio_r32(rg, GPIO_REG_RENA); + fall = rt_gpio_r32(rg, GPIO_REG_FENA); + + spin_lock_irqsave(&rg->lock, flags); + rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq)); + rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq)); + spin_unlock_irqrestore(&rg->lock, flags); +} + +static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + u32 mask = BIT(d->hwirq); + + if (type == IRQ_TYPE_PROBE) { + if ((rg->rising | rg->falling) & mask) + return 0; + + type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; + } + + if (type & IRQ_TYPE_EDGE_RISING) + rg->rising |= mask; + else + rg->rising &= ~mask; + + if (type & IRQ_TYPE_EDGE_FALLING) + rg->falling |= mask; + else + rg->falling &= ~mask; + + return 0; +} + +static struct irq_chip ralink_gpio_irq_chip = { + .name = "gpio-ralink", + .irq_unmask = ralink_gpio_irq_unmask, + .irq_mask = ralink_gpio_irq_mask, + .irq_mask_ack = ralink_gpio_irq_mask, + .irq_set_type = ralink_gpio_irq_type, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int ralink_get_direction(struct gpio_chip *gc, unsigned offset) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + + return !(rt_gpio_r32(rg, GPIO_REG_DIR) & BIT(offset)); +} + +static int ralink_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + u32 val = rt_gpio_r32(rg, GPIO_REG_DIR); + rt_gpio_w32(rg, GPIO_REG_DIR, val & ~BIT(offset)); + + return 0; +} + +static int ralink_direction_output(struct gpio_chip *gc, unsigned offset, int val) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + rt_gpio_w32(rg, val ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); + rt_gpio_w32(rg, GPIO_REG_DIR, rt_gpio_r32(rg, GPIO_REG_DIR) | BIT(offset)); + + return 0; +} + +static int ralink_get(struct gpio_chip *gc, unsigned offset) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + + return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset)); +} + +static int ralink_set(struct gpio_chip *gc, unsigned offset, int val) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + rt_gpio_w32(rg, val ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); + + return 0; +} + +static int ralink_set_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + unsigned long set = *mask & *bits; + unsigned long reset = *mask & ~*bits; + + if (set) + rt_gpio_w32(rg, GPIO_REG_SET, set); + if (reset) + rt_gpio_w32(rg, GPIO_REG_RESET, reset); + + return 0; +} + +static int ralink_get_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + struct ralink_gpio_chip *rg = gpiochip_get_data(gc); + *bits = rt_gpio_r32(rg, GPIO_REG_DATA) & *mask; + + return 0; +} + +static int ralink_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct ralink_gpio_chip *rg; + struct of_phandle_args args; + u32 ngpios = 0; + int ret; + + rg = devm_kzalloc(dev, sizeof(struct ralink_gpio_chip), GFP_KERNEL); + if (!rg) + return -ENOMEM; + + rg->membase = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rg->membase)) + return PTR_ERR(rg->membase); + + if (of_property_read_u8_array(np, "ralink,register-map", + rg->regs, GPIO_REG_MAX)) { + dev_err(dev, "failed to read register definition\n"); + return -EINVAL; + } + + if (of_property_read_u32(np, "ngpios", &ngpios) < 0) + ngpios = 0; + + if (ngpios == 0) { + if (of_parse_phandle_with_args(np, "gpio-ranges", "#gpio-cells", 0, &args) == 0) { + if (args.args_count > 0) + ngpios = args.args[args.args_count - 1]; + of_node_put(args.np); + } + } + + if (ngpios == 0 || ngpios > MAX_NGPIOS) + ngpios = MAX_NGPIOS; + + spin_lock_init(&rg->lock); + + rg->chip.label = dev_name(dev); + rg->chip.parent = dev; + rg->chip.owner = THIS_MODULE; + rg->chip.base = -1; + rg->chip.ngpio = ngpios; + rg->chip.get_direction = ralink_get_direction; + rg->chip.direction_input = ralink_direction_input; + rg->chip.direction_output= ralink_direction_output; + rg->chip.get = ralink_get; + rg->chip.set = ralink_set; + rg->chip.get_multiple = ralink_get_multiple; + rg->chip.set_multiple = ralink_set_multiple; + + /* set polarity to low for all lines */ + rt_gpio_w32(rg, GPIO_REG_POL, 0); + + rg->gpio_irq = platform_get_irq(pdev, 0); + if (rg->gpio_irq < 0) + return rg->gpio_irq; + + if (rg->gpio_irq) { + struct gpio_irq_chip *girq; + + /* + * Directly request the irq here instead of passing + * a flow-handler because the irq is shared. + */ + ret = devm_request_irq(dev, rg->gpio_irq, + ralink_gpio_irq_handler, IRQF_SHARED, + NULL, &rg->chip); + if (ret) { + dev_err(dev, "Error requesting IRQ %d: %d\n", + rg->gpio_irq, ret); + return ret; + } + + girq = &rg->chip.irq; + gpio_irq_chip_set_chip(girq, &ralink_gpio_irq_chip); + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + + rt_gpio_w32(rg, GPIO_REG_RENA, 0); + rt_gpio_w32(rg, GPIO_REG_FENA, 0); + } + + return devm_gpiochip_add_data(dev, &rg->chip, rg); +} + +static const struct of_device_id ralink_gpio_match[] = { + { .compatible = "ralink,rt2880-gpio" }, + {}, +}; +MODULE_DEVICE_TABLE(of, ralink_gpio_match); + +static struct platform_driver ralink_gpio_driver = { + .probe = ralink_gpio_probe, + .driver = { + .name = "ralink_gpio", + .of_match_table = ralink_gpio_match, + }, +}; + +static int __init ralink_gpio_init(void) +{ + return platform_driver_register(&ralink_gpio_driver); +} + +subsys_initcall(ralink_gpio_init); diff --git a/target/linux/ramips/patches-6.18/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-6.18/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch index 75892d4c8cd..3a7e8d3bbfb 100644 --- a/target/linux/ramips/patches-6.18/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch +++ b/target/linux/ramips/patches-6.18/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch @@ -9,9 +9,7 @@ Signed-off-by: John Crispin --- drivers/gpio/Kconfig | 8 ++ drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-ralink.c | 230 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 239 insertions(+) - create mode 100644 drivers/gpio/gpio-ralink.c + 2 files changed, 9 insertions(+) --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -40,322 +38,3 @@ Signed-off-by: John Crispin obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o ---- /dev/null -+++ b/drivers/gpio/gpio-ralink.c -@@ -0,0 +1,316 @@ -+/* -+ * 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. -+ * -+ * Copyright (C) 2009-2011 Gabor Juhos -+ * Copyright (C) 2013 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_NGPIOS 95 -+ -+enum ralink_gpio_reg { -+ GPIO_REG_INT = 0, -+ GPIO_REG_EDGE, -+ GPIO_REG_RENA, -+ GPIO_REG_FENA, -+ GPIO_REG_DATA, -+ GPIO_REG_DIR, -+ GPIO_REG_POL, -+ GPIO_REG_SET, -+ GPIO_REG_RESET, -+ GPIO_REG_TOGGLE, -+ GPIO_REG_MAX -+}; -+ -+struct ralink_gpio_chip { -+ struct gpio_chip chip; -+ u8 regs[GPIO_REG_MAX]; -+ -+ spinlock_t lock; -+ void __iomem *membase; -+ int gpio_irq; -+ -+ u32 rising; -+ u32 falling; -+}; -+ -+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val) -+{ -+ iowrite32(val, rg->membase + rg->regs[reg]); -+} -+ -+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg) -+{ -+ return ioread32(rg->membase + rg->regs[reg]); -+} -+ -+static irqreturn_t ralink_gpio_irq_handler(int irq, void *data) -+{ -+ struct gpio_chip *gc = data; -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ irqreturn_t ret = IRQ_NONE; -+ unsigned long pending; -+ int bit; -+ -+ pending = rt_gpio_r32(rg, GPIO_REG_INT); -+ for_each_set_bit(bit, &pending, rg->chip.ngpio) { -+ generic_handle_domain_irq(gc->irq.domain, bit); -+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit)); -+ ret |= IRQ_HANDLED; -+ } -+ -+ return ret; -+} -+ -+static void ralink_gpio_irq_unmask(struct irq_data *d) -+{ -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ unsigned long flags; -+ u32 rise, fall; -+ -+ rise = rt_gpio_r32(rg, GPIO_REG_RENA); -+ fall = rt_gpio_r32(rg, GPIO_REG_FENA); -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising)); -+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling)); -+ spin_unlock_irqrestore(&rg->lock, flags); -+} -+ -+static void ralink_gpio_irq_mask(struct irq_data *d) -+{ -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ unsigned long flags; -+ u32 rise, fall; -+ -+ rise = rt_gpio_r32(rg, GPIO_REG_RENA); -+ fall = rt_gpio_r32(rg, GPIO_REG_FENA); -+ -+ spin_lock_irqsave(&rg->lock, flags); -+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq)); -+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq)); -+ spin_unlock_irqrestore(&rg->lock, flags); -+} -+ -+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type) -+{ -+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ u32 mask = BIT(d->hwirq); -+ -+ if (type == IRQ_TYPE_PROBE) { -+ if ((rg->rising | rg->falling) & mask) -+ return 0; -+ -+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; -+ } -+ -+ if (type & IRQ_TYPE_EDGE_RISING) -+ rg->rising |= mask; -+ else -+ rg->rising &= ~mask; -+ -+ if (type & IRQ_TYPE_EDGE_FALLING) -+ rg->falling |= mask; -+ else -+ rg->falling &= ~mask; -+ -+ return 0; -+} -+ -+static struct irq_chip ralink_gpio_irq_chip = { -+ .name = "gpio-ralink", -+ .irq_unmask = ralink_gpio_irq_unmask, -+ .irq_mask = ralink_gpio_irq_mask, -+ .irq_mask_ack = ralink_gpio_irq_mask, -+ .irq_set_type = ralink_gpio_irq_type, -+ .flags = IRQCHIP_IMMUTABLE, -+ GPIOCHIP_IRQ_RESOURCE_HELPERS, -+}; -+ -+static int ralink_get_direction(struct gpio_chip *gc, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ -+ return !(rt_gpio_r32(rg, GPIO_REG_DIR) & BIT(offset)); -+} -+ -+static int ralink_direction_input(struct gpio_chip *gc, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ u32 val = rt_gpio_r32(rg, GPIO_REG_DIR); -+ rt_gpio_w32(rg, GPIO_REG_DIR, val & ~BIT(offset)); -+ -+ return 0; -+} -+ -+static int ralink_direction_output(struct gpio_chip *gc, unsigned offset, int val) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ rt_gpio_w32(rg, val ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); -+ rt_gpio_w32(rg, GPIO_REG_DIR, rt_gpio_r32(rg, GPIO_REG_DIR) | BIT(offset)); -+ -+ return 0; -+} -+ -+static int ralink_get(struct gpio_chip *gc, unsigned offset) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ -+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset)); -+} -+ -+static int ralink_set(struct gpio_chip *gc, unsigned offset, int val) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ rt_gpio_w32(rg, val ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); -+ -+ return 0; -+} -+ -+static int ralink_set_multiple(struct gpio_chip *gc, unsigned long *mask, -+ unsigned long *bits) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ unsigned long set = *mask & *bits; -+ unsigned long reset = *mask & ~*bits; -+ -+ if (set) -+ rt_gpio_w32(rg, GPIO_REG_SET, set); -+ if (reset) -+ rt_gpio_w32(rg, GPIO_REG_RESET, reset); -+ -+ return 0; -+} -+ -+static int ralink_get_multiple(struct gpio_chip *gc, unsigned long *mask, -+ unsigned long *bits) -+{ -+ struct ralink_gpio_chip *rg = gpiochip_get_data(gc); -+ *bits = rt_gpio_r32(rg, GPIO_REG_DATA) & *mask; -+ -+ return 0; -+} -+ -+static int ralink_gpio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct ralink_gpio_chip *rg; -+ struct of_phandle_args args; -+ u32 ngpios = 0; -+ int ret; -+ -+ rg = devm_kzalloc(dev, sizeof(struct ralink_gpio_chip), GFP_KERNEL); -+ if (!rg) -+ return -ENOMEM; -+ -+ rg->membase = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(rg->membase)) -+ return PTR_ERR(rg->membase); -+ -+ if (of_property_read_u8_array(np, "ralink,register-map", -+ rg->regs, GPIO_REG_MAX)) { -+ dev_err(dev, "failed to read register definition\n"); -+ return -EINVAL; -+ } -+ -+ if (of_property_read_u32(np, "ngpios", &ngpios) < 0) -+ ngpios = 0; -+ -+ if (ngpios == 0) { -+ if (of_parse_phandle_with_args(np, "gpio-ranges", "#gpio-cells", 0, &args) == 0) { -+ if (args.args_count > 0) -+ ngpios = args.args[args.args_count - 1]; -+ of_node_put(args.np); -+ } -+ } -+ -+ if (ngpios == 0 || ngpios > MAX_NGPIOS) -+ ngpios = MAX_NGPIOS; -+ -+ spin_lock_init(&rg->lock); -+ -+ rg->chip.label = dev_name(dev); -+ rg->chip.parent = dev; -+ rg->chip.owner = THIS_MODULE; -+ rg->chip.base = -1; -+ rg->chip.ngpio = ngpios; -+ rg->chip.get_direction = ralink_get_direction; -+ rg->chip.direction_input = ralink_direction_input; -+ rg->chip.direction_output= ralink_direction_output; -+ rg->chip.get = ralink_get; -+ rg->chip.set = ralink_set; -+ rg->chip.get_multiple = ralink_get_multiple; -+ rg->chip.set_multiple = ralink_set_multiple; -+ -+ /* set polarity to low for all lines */ -+ rt_gpio_w32(rg, GPIO_REG_POL, 0); -+ -+ rg->gpio_irq = platform_get_irq(pdev, 0); -+ if (rg->gpio_irq < 0) -+ return rg->gpio_irq; -+ -+ if (rg->gpio_irq) { -+ struct gpio_irq_chip *girq; -+ -+ /* -+ * Directly request the irq here instead of passing -+ * a flow-handler because the irq is shared. -+ */ -+ ret = devm_request_irq(dev, rg->gpio_irq, -+ ralink_gpio_irq_handler, IRQF_SHARED, -+ NULL, &rg->chip); -+ if (ret) { -+ dev_err(dev, "Error requesting IRQ %d: %d\n", -+ rg->gpio_irq, ret); -+ return ret; -+ } -+ -+ girq = &rg->chip.irq; -+ gpio_irq_chip_set_chip(girq, &ralink_gpio_irq_chip); -+ /* This will let us handle the parent IRQ in the driver */ -+ girq->parent_handler = NULL; -+ girq->num_parents = 0; -+ girq->parents = NULL; -+ girq->default_type = IRQ_TYPE_NONE; -+ girq->handler = handle_simple_irq; -+ -+ rt_gpio_w32(rg, GPIO_REG_RENA, 0); -+ rt_gpio_w32(rg, GPIO_REG_FENA, 0); -+ } -+ -+ return devm_gpiochip_add_data(dev, &rg->chip, rg); -+} -+ -+static const struct of_device_id ralink_gpio_match[] = { -+ { .compatible = "ralink,rt2880-gpio" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ralink_gpio_match); -+ -+static struct platform_driver ralink_gpio_driver = { -+ .probe = ralink_gpio_probe, -+ .driver = { -+ .name = "ralink_gpio", -+ .of_match_table = ralink_gpio_match, -+ }, -+}; -+ -+static int __init ralink_gpio_init(void) -+{ -+ return platform_driver_register(&ralink_gpio_driver); -+} -+ -+subsys_initcall(ralink_gpio_init);