[LEDE-DEV] [PATCH] ar71xx: GPIO driver backport

John Crispin john at phrozen.org
Thu Feb 9 00:34:15 PST 2017



On 31/01/2017 18:19, Daniel Gonzalez Cabanelas wrote:
> Backport the ath79 GPIO driver to kernel 4.4.
> 
> Benefits this driver has compared with the old one:
> - support for the interrupt controller
> - module removable
> 
> The new code using the generic MMIO GPIO driver starts in 
> kernel 4.6, therefore this patch won't be useful anymore 
> when this version is adopted. The intention is to integrate 
> the patch into the stable release 17.01
> 
> Patch tested in an AR7240 based board.

Hi,

with trunk now moving to v4.9 i would vote to not apply this patch. It
will be part of the v4.9 update anyhow. i would prefer if we simply test
the new driver as me move to the new kernel.

	John


> 
> Signed-off-by: Daniel Gonzalez Cabanelas <dgcbueu at gmail.com>
> diff --git a/target/linux/ar71xx/config-4.4 b/target/linux/ar71xx/config-4.4
> index 4b2f736..d3ecf4d 100644
> --- a/target/linux/ar71xx/config-4.4
> +++ b/target/linux/ar71xx/config-4.4
> @@ -267,6 +267,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
>  CONFIG_GENERIC_TIME_VSYSCALL=y
>  CONFIG_GPIOLIB=y
>  CONFIG_GPIOLIB_IRQCHIP=y
> +CONFIG_GPIO_ATH79=y
>  CONFIG_GPIO_DEVRES=y
>  # CONFIG_GPIO_LATCH is not set
>  CONFIG_GPIO_NXP_74HC153=y
> diff --git a/target/linux/ar71xx/patches-4.4/455-gpio-ath79-driver_backport-irqchip.patch b/target/linux/ar71xx/patches-4.4/455-gpio-ath79-driver_backport-irqchip.patch
> new file mode 100644
> index 0000000..e0f8622
> --- /dev/null
> +++ b/target/linux/ar71xx/patches-4.4/455-gpio-ath79-driver_backport-irqchip.patch
> @@ -0,0 +1,469 @@
> +--- a/drivers/gpio/gpio-ath79.c
> ++++ b/drivers/gpio/gpio-ath79.c
> +@@ -1,145 +1,237 @@
> + /*
> +  *  Atheros AR71XX/AR724X/AR913X GPIO API support
> +  *
> ++ *  Copyright (C) 2015 Alban Bedel <albeu at free.fr>
> +  *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan at atheros.com>
> +  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg at openwrt.org>
> +  *  Copyright (C) 2008 Imre Kaloz <kaloz at openwrt.org>
> +  *
> +- *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
> +- *
> +  *  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.
> +  */
> + 
> + #include <linux/gpio/driver.h>
> ++#include <linux/basic_mmio_gpio.h>
> + #include <linux/platform_data/gpio-ath79.h>
> + #include <linux/of_device.h>
> ++#include <linux/interrupt.h>
> ++#include <linux/module.h>
> ++#include <linux/irq.h>
> + 
> +-#include <asm/mach-ath79/ar71xx_regs.h>
> ++#define AR71XX_GPIO_REG_OE		0x00
> ++#define AR71XX_GPIO_REG_IN		0x04
> ++#define AR71XX_GPIO_REG_SET		0x0c
> ++#define AR71XX_GPIO_REG_CLEAR		0x10
> ++
> ++#define AR71XX_GPIO_REG_INT_ENABLE	0x14
> ++#define AR71XX_GPIO_REG_INT_TYPE	0x18
> ++#define AR71XX_GPIO_REG_INT_POLARITY	0x1c
> ++#define AR71XX_GPIO_REG_INT_PENDING	0x20
> ++#define AR71XX_GPIO_REG_INT_MASK	0x24
> + 
> + struct ath79_gpio_ctrl {
> +-	struct gpio_chip chip;
> ++	struct bgpio_chip bgc;
> + 	void __iomem *base;
> + 	spinlock_t lock;
> ++	unsigned long both_edges;
> + };
> + 
> +-#define to_ath79_gpio_ctrl(c) container_of(c, struct ath79_gpio_ctrl, chip)
> + 
> +-static void ath79_gpio_set_value(struct gpio_chip *chip,
> +-				unsigned gpio, int value)
> ++static inline struct ath79_gpio_ctrl *to_ath79_gpio_ctrl(struct gpio_chip *gc)
> + {
> +-	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
> ++	struct bgpio_chip *bgc = to_bgpio_chip(gc);
> + 
> +-	if (value)
> +-		__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_SET);
> +-	else
> +-		__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_CLEAR);
> ++	return container_of(bgc, struct ath79_gpio_ctrl, bgc);
> + }
> + 
> +-static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
> ++static struct ath79_gpio_ctrl *irq_data_to_ath79_gpio(struct irq_data *data)
> + {
> +-	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
> ++	struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
> ++	return to_ath79_gpio_ctrl(gc);
> ++}
> + 
> +-	return (__raw_readl(ctrl->base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
> ++static u32 ath79_gpio_read(struct ath79_gpio_ctrl *ctrl, unsigned reg)
> ++{
> ++	return readl(ctrl->base + reg);
> + }
> + 
> +-static int ath79_gpio_direction_input(struct gpio_chip *chip,
> +-				       unsigned offset)
> ++static void ath79_gpio_write(struct ath79_gpio_ctrl *ctrl,
> ++			unsigned reg, u32 val)
> + {
> +-	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
> +-	unsigned long flags;
> ++	return writel(val, ctrl->base + reg);
> ++}
> + 
> +-	spin_lock_irqsave(&ctrl->lock, flags);
> ++static bool ath79_gpio_update_bits(
> ++	struct ath79_gpio_ctrl *ctrl, unsigned reg, u32 mask, u32 bits)
> ++{
> ++	u32 old_val, new_val;
> + 
> +-	__raw_writel(
> +-		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
> +-		ctrl->base + AR71XX_GPIO_REG_OE);
> ++	old_val = ath79_gpio_read(ctrl, reg);
> ++	new_val = (old_val & ~mask) | (bits & mask);
> + 
> +-	spin_unlock_irqrestore(&ctrl->lock, flags);
> ++	if (new_val != old_val)
> ++		ath79_gpio_write(ctrl, reg, new_val);
> + 
> +-	return 0;
> ++	return new_val != old_val;
> + }
> + 
> +-static int ath79_gpio_direction_output(struct gpio_chip *chip,
> +-					unsigned offset, int value)
> ++static void ath79_gpio_irq_unmask(struct irq_data *data)
> + {
> +-	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
> ++	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
> ++	u32 mask = BIT(irqd_to_hwirq(data));
> + 	unsigned long flags;
> + 
> + 	spin_lock_irqsave(&ctrl->lock, flags);
> ++	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
> ++	spin_unlock_irqrestore(&ctrl->lock, flags);
> ++}
> + 
> +-	if (value)
> +-		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
> +-	else
> +-		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
> +-
> +-	__raw_writel(
> +-		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
> +-		ctrl->base + AR71XX_GPIO_REG_OE);
> ++static void ath79_gpio_irq_mask(struct irq_data *data)
> ++{
> ++	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
> ++	u32 mask = BIT(irqd_to_hwirq(data));
> ++	unsigned long flags;
> + 
> ++	spin_lock_irqsave(&ctrl->lock, flags);
> ++	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
> + 	spin_unlock_irqrestore(&ctrl->lock, flags);
> +-
> +-	return 0;
> + }
> + 
> +-static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> ++static void ath79_gpio_irq_enable(struct irq_data *data)
> + {
> +-	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
> ++	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
> ++	u32 mask = BIT(irqd_to_hwirq(data));
> + 	unsigned long flags;
> + 
> + 	spin_lock_irqsave(&ctrl->lock, flags);
> ++	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
> ++	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
> ++	spin_unlock_irqrestore(&ctrl->lock, flags);
> ++}
> + 
> +-	__raw_writel(
> +-		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
> +-		ctrl->base + AR71XX_GPIO_REG_OE);
> ++static void ath79_gpio_irq_disable(struct irq_data *data)
> ++{
> ++	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
> ++	u32 mask = BIT(irqd_to_hwirq(data));
> ++	unsigned long flags;
> + 
> ++	spin_lock_irqsave(&ctrl->lock, flags);
> ++	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
> ++	ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
> + 	spin_unlock_irqrestore(&ctrl->lock, flags);
> +-
> +-	return 0;
> + }
> + 
> +-static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
> +-					int value)
> ++static int ath79_gpio_irq_set_type(struct irq_data *data,
> ++				unsigned int flow_type)
> + {
> +-	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
> ++	struct ath79_gpio_ctrl *ctrl = irq_data_to_ath79_gpio(data);
> ++	u32 mask = BIT(irqd_to_hwirq(data));
> ++	u32 type = 0, polarity = 0;
> + 	unsigned long flags;
> ++	bool disabled;
> ++
> ++	switch (flow_type) {
> ++	case IRQ_TYPE_EDGE_RISING:
> ++		polarity |= mask;
> ++	case IRQ_TYPE_EDGE_FALLING:
> ++	case IRQ_TYPE_EDGE_BOTH:
> ++		break;
> ++
> ++	case IRQ_TYPE_LEVEL_HIGH:
> ++		polarity |= mask;
> ++	case IRQ_TYPE_LEVEL_LOW:
> ++		type |= mask;
> ++		break;
> ++
> ++	default:
> ++		return -EINVAL;
> ++	}
> + 
> + 	spin_lock_irqsave(&ctrl->lock, flags);
> + 
> +-	if (value)
> +-		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
> +-	else
> +-		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
> ++	if (flow_type == IRQ_TYPE_EDGE_BOTH) {
> ++		ctrl->both_edges |= mask;
> ++		polarity = ~ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN);
> ++	} else {
> ++		ctrl->both_edges &= ~mask;
> ++	}
> + 
> +-	__raw_writel(
> +-		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
> +-		ctrl->base + AR71XX_GPIO_REG_OE);
> ++	/* As the IRQ configuration can't be loaded atomically we
> ++	 * have to disable the interrupt while the configuration state
> ++	 * is invalid.
> ++	 */
> ++	disabled = ath79_gpio_update_bits(
> ++		ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
> ++
> ++	ath79_gpio_update_bits(
> ++		ctrl, AR71XX_GPIO_REG_INT_TYPE, mask, type);
> ++	ath79_gpio_update_bits(
> ++		ctrl, AR71XX_GPIO_REG_INT_POLARITY, mask, polarity);
> ++
> ++	if (disabled)
> ++		ath79_gpio_update_bits(
> ++			ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
> + 
> + 	spin_unlock_irqrestore(&ctrl->lock, flags);
> + 
> + 	return 0;
> + }
> + 
> +-static const struct gpio_chip ath79_gpio_chip = {
> +-	.label			= "ath79",
> +-	.get			= ath79_gpio_get_value,
> +-	.set			= ath79_gpio_set_value,
> +-	.direction_input	= ath79_gpio_direction_input,
> +-	.direction_output	= ath79_gpio_direction_output,
> +-	.base			= 0,
> ++static struct irq_chip ath79_gpio_irqchip = {
> ++	.name = "gpio-ath79",
> ++	.irq_enable = ath79_gpio_irq_enable,
> ++	.irq_disable = ath79_gpio_irq_disable,
> ++	.irq_mask = ath79_gpio_irq_mask,
> ++	.irq_unmask = ath79_gpio_irq_unmask,
> ++	.irq_set_type = ath79_gpio_irq_set_type,
> + };
> + 
> ++static void ath79_gpio_irq_handler(struct irq_desc *desc)
> ++{
> ++	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
> ++	struct irq_chip *irqchip = irq_desc_get_chip(desc);
> ++	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(gc);
> ++	unsigned long flags, pending;
> ++	u32 both_edges, state;
> ++	int irq;
> ++
> ++	chained_irq_enter(irqchip, desc);
> ++
> ++	spin_lock_irqsave(&ctrl->lock, flags);
> ++
> ++	pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING);
> ++
> ++	/* Update the polarity of the both edges irqs */
> ++	both_edges = ctrl->both_edges & pending;
> ++	if (both_edges) {
> ++		state = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_IN);
> ++		ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_POLARITY,
> ++				both_edges, ~state);
> ++	}
> ++
> ++	spin_unlock_irqrestore(&ctrl->lock, flags);
> ++
> ++	if (pending) {
> ++		for_each_set_bit(irq, &pending, gc->ngpio)
> ++			generic_handle_irq(
> ++				irq_linear_revmap(gc->irqdomain, irq));
> ++	}
> ++
> ++	chained_irq_exit(irqchip, desc);
> ++}
> ++
> + static const struct of_device_id ath79_gpio_of_match[] = {
> + 	{ .compatible = "qca,ar7100-gpio" },
> + 	{ .compatible = "qca,ar9340-gpio" },
> + 	{},
> + };
> ++MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
> + 
> + static int ath79_gpio_probe(struct platform_device *pdev)
> + {
> +-	struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data;
> ++	struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
> + 	struct device_node *np = pdev->dev.of_node;
> + 	struct ath79_gpio_ctrl *ctrl;
> + 	struct resource *res;
> + 	u32 ath79_gpio_count;
> +@@ -148,19 +240,16 @@
> + 
> + 	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
> + 	if (!ctrl)
> + 		return -ENOMEM;
> ++	platform_set_drvdata(pdev, ctrl);
> + 
> + 	if (np) {
> + 		err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
> + 		if (err) {
> + 			dev_err(&pdev->dev, "ngpios property is not valid\n");
> + 			return err;
> + 		}
> +-		if (ath79_gpio_count >= 32) {
> +-			dev_err(&pdev->dev, "ngpios must be less than 32\n");
> +-			return -EINVAL;
> +-		}
> + 		oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
> + 	} else if (pdata) {
> + 		ath79_gpio_count = pdata->ngpios;
> + 		oe_inverted = pdata->oe_inverted;
> +@@ -168,30 +257,68 @@
> + 		dev_err(&pdev->dev, "No DT node or platform data found\n");
> + 		return -EINVAL;
> + 	}
> + 
> ++	if (ath79_gpio_count >= 32) {
> ++		dev_err(&pdev->dev, "ngpios must be less than 32\n");
> ++		return -EINVAL;
> ++	}
> ++
> + 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + 	ctrl->base = devm_ioremap_nocache(
> + 		&pdev->dev, res->start, resource_size(res));
> + 	if (!ctrl->base)
> + 		return -ENOMEM;
> + 
> + 	spin_lock_init(&ctrl->lock);
> +-	memcpy(&ctrl->chip, &ath79_gpio_chip, sizeof(ctrl->chip));
> +-	ctrl->chip.dev = &pdev->dev;
> +-	ctrl->chip.ngpio = ath79_gpio_count;
> +-	if (oe_inverted) {
> +-		ctrl->chip.direction_input = ar934x_gpio_direction_input;
> +-		ctrl->chip.direction_output = ar934x_gpio_direction_output;
> ++	err = bgpio_init(&ctrl->bgc, &pdev->dev, 4,
> ++			ctrl->base + AR71XX_GPIO_REG_IN,
> ++			ctrl->base + AR71XX_GPIO_REG_SET,
> ++			ctrl->base + AR71XX_GPIO_REG_CLEAR,
> ++			oe_inverted ? NULL : ctrl->base + AR71XX_GPIO_REG_OE,
> ++			oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL,
> ++			0);
> ++	if (err) {
> ++		dev_err(&pdev->dev, "bgpio_init failed\n");
> ++		return err;
> + 	}
> ++	/* Use base 0 to stay compatible with legacy platforms */
> ++	ctrl->bgc.gc.base = 0;
> ++	ctrl->bgc.gc.ngpio = ath79_gpio_count;
> + 
> +-	err = gpiochip_add(&ctrl->chip);
> ++	err = gpiochip_add(&ctrl->bgc.gc);
> + 	if (err) {
> + 		dev_err(&pdev->dev,
> + 			"cannot add AR71xx GPIO chip, error=%d", err);
> + 		return err;
> + 	}
> + 
> ++	if (np && !of_property_read_bool(np, "interrupt-controller"))
> ++		return 0;
> ++
> ++	err = gpiochip_irqchip_add(&ctrl->bgc.gc, &ath79_gpio_irqchip, 0,
> ++				handle_simple_irq, IRQ_TYPE_NONE);
> ++	if (err) {
> ++		dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
> ++		goto gpiochip_remove;
> ++	}
> ++
> ++	gpiochip_set_chained_irqchip(&ctrl->bgc.gc, &ath79_gpio_irqchip,
> ++				platform_get_irq(pdev, 0),
> ++				ath79_gpio_irq_handler);
> ++
> ++	return 0;
> ++
> ++gpiochip_remove:
> ++	gpiochip_remove(&ctrl->bgc.gc);
> ++	return err;
> ++}
> ++
> ++static int ath79_gpio_remove(struct platform_device *pdev)
> ++{
> ++	struct ath79_gpio_ctrl *ctrl = platform_get_drvdata(pdev);
> ++
> ++	gpiochip_remove(&ctrl->bgc.gc);
> + 	return 0;
> + }
> + 
> + static struct platform_driver ath79_gpio_driver = {
> +@@ -199,8 +326,9 @@
> + 		.name = "ath79-gpio",
> + 		.of_match_table	= ath79_gpio_of_match,
> + 	},
> + 	.probe = ath79_gpio_probe,
> ++	.remove = ath79_gpio_remove,
> + };
> + 
> + static int __init ath79_gpio_init(void)
> + {
> +--- a/arch/mips/include/asm/mach-ath79/irq.h
> ++++ b/arch/mips/include/asm/mach-ath79/irq.h
> +@@ -7,13 +7,13 @@
> +  *  by the Free Software Foundation.
> +  */
> + #ifndef __ASM_MACH_ATH79_IRQ_H
> + #define __ASM_MACH_ATH79_IRQ_H
> + 
> + #define MIPS_CPU_IRQ_BASE	0
> +-#define NR_IRQS			51
> ++#define NR_IRQS			83
> + 
> + #define ATH79_CPU_IRQ(_x)	(MIPS_CPU_IRQ_BASE + (_x))
> + 
> + #define ATH79_MISC_IRQ_BASE	8
> + #define ATH79_MISC_IRQ_COUNT	32
> + #define ATH79_MISC_IRQ(_x)	(ATH79_MISC_IRQ_BASE + (_x))
> +--- a/drivers/gpio/Kconfig
> ++++ b/drivers/gpio/Kconfig
> +@@ -124,12 +124,22 @@
> + 	tristate "AMD Promontory GPIO support"
> + 	depends on ACPI
> + 	help
> + 	  driver for GPIO functionality on Promontory IOHub
> + 	  Require ACPI ASL code to enumerate as a platform device.
> + 
> ++config GPIO_ATH79
> ++	tristate "Atheros AR71XX/AR724X/AR913X GPIO support"
> ++	default y if ATH79
> ++	depends on ATH79 || COMPILE_TEST
> ++	select GPIO_GENERIC
> ++	select GPIOLIB_IRQCHIP
> ++	help
> ++	  Select this option to enable GPIO driver for
> ++	  Atheros AR71XX/AR724X/AR913X SoC devices.
> ++
> + config GPIO_BCM_KONA
> + 	bool "Broadcom Kona GPIO"
> + 	depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
> + 	help
> + 	  Turn on GPIO support for Broadcom "Kona" chips.
> + 
> +--- a/drivers/gpio/Makefile
> ++++ b/drivers/gpio/Makefile
> +@@ -19,13 +19,13 @@
> + obj-$(CONFIG_GPIO_ADP5520)	+= gpio-adp5520.o
> + obj-$(CONFIG_GPIO_ADP5588)	+= gpio-adp5588.o
> + obj-$(CONFIG_GPIO_ALTERA)  	+= gpio-altera.o
> + obj-$(CONFIG_GPIO_AMD8111)	+= gpio-amd8111.o
> + obj-$(CONFIG_GPIO_AMDPT)	+= gpio-amdpt.o
> + obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
> +-obj-$(CONFIG_ATH79)		+= gpio-ath79.o
> ++obj-$(CONFIG_GPIO_ATH79)	+= gpio-ath79.o
> + obj-$(CONFIG_GPIO_BCM_KONA)	+= gpio-bcm-kona.o
> + obj-$(CONFIG_GPIO_BRCMSTB)	+= gpio-brcmstb.o
> + obj-$(CONFIG_GPIO_BT8XX)	+= gpio-bt8xx.o
> + obj-$(CONFIG_GPIO_CLPS711X)	+= gpio-clps711x.o
> + obj-$(CONFIG_GPIO_CS5535)	+= gpio-cs5535.o
> + obj-$(CONFIG_GPIO_CRYSTAL_COVE)	+= gpio-crystalcove.o
> 
> 
> _______________________________________________
> Lede-dev mailing list
> Lede-dev at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/lede-dev
> 



More information about the Lede-dev mailing list