All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] gpio: mediatek: driver for gpio chip in MT7621 SoC
@ 2018-06-29 12:43 ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 12:43 UTC (permalink / raw)
  To: linus.walleij
  Cc: devicetree, gregkh, driverdev-devel, linux-gpio, robh+dt, neil

This patch series add support for gpio driver in mediatek MT7621
SoC. This driver has been in staging for a while and after some
cleanups cycles we consider to give it a new try to get mainlined.

Previous comments from Linus Walleij are here:

http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-June/121742.html

Comments from Rob Herring are here:

http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-June/121974.html

Changes in v2 are the ones pointed out in previous mails:

 - use bgpio_init
 - avoid custom irq_domain using IRQF_SHARED and 
   gpiochip_set_chained_irqchip from GPIOLIB_IRQCHIP
 - use only one node in the device tree making it simple
 - Implement high and low level irqs
 - avoid include gpio.h
 - use builtin_platform_driver
 - add COMPILE_TEST
 - cleanups after this changes

Hope this helps and thanks in advance.

Best regards,
    Sergio Paracuellos


Sergio Paracuellos (2):
  gpio: mediatek: add driver for MT7621
  dt-bindings: document gpio-mt7621 bindings

 .../bindings/gpio/mediatek,mt7621-gpio.txt         |  35 +++
 drivers/gpio/Kconfig                               |   8 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-mt7621.c                         | 320 +++++++++++++++++++++
 4 files changed, 364 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt
 create mode 100644 drivers/gpio/gpio-mt7621.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 0/2] gpio: mediatek: driver for gpio chip in MT7621 SoC
@ 2018-06-29 12:43 ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 12:43 UTC (permalink / raw)
  To: linus.walleij
  Cc: devicetree, gregkh, driverdev-devel, linux-gpio, robh+dt, neil

This patch series add support for gpio driver in mediatek MT7621
SoC. This driver has been in staging for a while and after some
cleanups cycles we consider to give it a new try to get mainlined.

Previous comments from Linus Walleij are here:

http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-June/121742.html

Comments from Rob Herring are here:

http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-June/121974.html

Changes in v2 are the ones pointed out in previous mails:

 - use bgpio_init
 - avoid custom irq_domain using IRQF_SHARED and 
   gpiochip_set_chained_irqchip from GPIOLIB_IRQCHIP
 - use only one node in the device tree making it simple
 - Implement high and low level irqs
 - avoid include gpio.h
 - use builtin_platform_driver
 - add COMPILE_TEST
 - cleanups after this changes

Hope this helps and thanks in advance.

Best regards,
    Sergio Paracuellos


Sergio Paracuellos (2):
  gpio: mediatek: add driver for MT7621
  dt-bindings: document gpio-mt7621 bindings

 .../bindings/gpio/mediatek,mt7621-gpio.txt         |  35 +++
 drivers/gpio/Kconfig                               |   8 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-mt7621.c                         | 320 +++++++++++++++++++++
 4 files changed, 364 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt
 create mode 100644 drivers/gpio/gpio-mt7621.c

-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 12:43 ` Sergio Paracuellos
@ 2018-06-29 12:43   ` Sergio Paracuellos
  -1 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 12:43 UTC (permalink / raw)
  To: linus.walleij
  Cc: devicetree, gregkh, driverdev-devel, linux-gpio, robh+dt, neil

Add driver support for gpio of MT7621 SoC.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/gpio/Kconfig       |   8 ++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-mt7621.c | 320 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 329 insertions(+)
 create mode 100644 drivers/gpio/gpio-mt7621.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 71c0ab4..836aa21 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -359,6 +359,14 @@ config GPIO_MPC8XXX
 	  Say Y here if you're going to use hardware that connects to the
 	  MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs.
 
+config GPIO_MT7621
+	bool "Mediatek MT7621 GPIO Support"
+	depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support the Mediatek MT7621 SoC GPIO device
+
 config GPIO_MVEBU
 	def_bool y
 	depends on PLAT_ORION || ARCH_MVEBU
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1324c8f..b264426 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_MOCKUP)      += gpio-mockup.o
 obj-$(CONFIG_GPIO_MPC5200)	+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)	+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSIC)		+= gpio-msic.o
+obj-$(CONFIG_GPIO_MSIC)		+= gpio-mt7621.o
 obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)		+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
new file mode 100644
index 0000000..281e621
--- /dev/null
+++ b/drivers/gpio/gpio-mt7621.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#define MTK_BANK_CNT	3
+#define MTK_BANK_WIDTH	32
+
+#define GPIO_BANK_WIDE	0x04
+#define GPIO_REG_CTRL	0x00
+#define GPIO_REG_POL	0x10
+#define GPIO_REG_DATA	0x20
+#define GPIO_REG_DSET	0x30
+#define GPIO_REG_DCLR	0x40
+#define GPIO_REG_REDGE	0x50
+#define GPIO_REG_FEDGE	0x60
+#define GPIO_REG_HLVL	0x70
+#define GPIO_REG_LLVL	0x80
+#define GPIO_REG_STAT	0x90
+#define GPIO_REG_EDGE	0xA0
+
+struct mtk_gc {
+	struct gpio_chip chip;
+	spinlock_t lock;
+	int bank;
+	u32 rising;
+	u32 falling;
+	u32 hlevel;
+	u32 llevel;
+};
+
+/**
+ * struct mtk_data - state container for
+ * data of the platform driver. It is 3
+ * separate gpio-chip each one with its
+ * own irq_chip.
+ * @dev: device instance
+ * @gpio_membase: memory base address
+ * @gpio_irq: irq number from the device tree
+ * @gc_map: array of the gpio chips
+ */
+struct mtk_data {
+	struct device *dev;
+	void __iomem *gpio_membase;
+	int gpio_irq;
+	struct mtk_gc gc_map[MTK_BANK_CNT];
+};
+
+static inline struct mtk_gc *
+to_mediatek_gpio(struct gpio_chip *chip)
+{
+	return container_of(chip, struct mtk_gc, chip);
+}
+
+static inline void
+mtk_gpio_w32(struct mtk_gc *rg, u32 offset, u32 val)
+{
+	struct gpio_chip *gc = &rg->chip;
+	struct mtk_data *gpio_data = gpiochip_get_data(gc);
+
+	offset = (rg->bank * GPIO_BANK_WIDE) + offset;
+	gc->write_reg(gpio_data->gpio_membase + offset, val);
+}
+
+static inline u32
+mtk_gpio_r32(struct mtk_gc *rg, u32 offset)
+{
+	struct gpio_chip *gc = &rg->chip;
+	struct mtk_data *gpio_data = gpiochip_get_data(gc);
+
+	offset = (rg->bank * GPIO_BANK_WIDE) + offset;
+	return gc->read_reg(gpio_data->gpio_membase + offset);
+}
+
+static irqreturn_t
+mediatek_gpio_irq_handler(int irq, void *data)
+{
+	struct gpio_chip *gc = data;
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	irqreturn_t ret = IRQ_NONE;
+	unsigned long pending;
+	int bit;
+
+	pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
+
+	for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
+		u32 map = irq_find_mapping(gc->irq.domain, bit);
+
+		generic_handle_irq(map);
+		mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
+		ret |= IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static void
+mediatek_gpio_irq_unmask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	int pin = d->hwirq;
+	unsigned long flags;
+	u32 rise, fall, high, low;
+
+	spin_lock_irqsave(&rg->lock, flags);
+	rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
+	fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
+	high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
+	low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
+	mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(pin) & rg->rising));
+	mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(pin) & rg->falling));
+	mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (BIT(pin) & rg->hlevel));
+	mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (BIT(pin) & rg->llevel));
+	spin_unlock_irqrestore(&rg->lock, flags);
+}
+
+static void
+mediatek_gpio_irq_mask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	int pin = d->hwirq;
+	unsigned long flags;
+	u32 rise, fall, high, low;
+
+	spin_lock_irqsave(&rg->lock, flags);
+	rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
+	fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
+	high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
+	low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
+	mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
+	mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
+	mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
+	mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
+	spin_unlock_irqrestore(&rg->lock, flags);
+}
+
+static int
+mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	int pin = d->hwirq;
+	u32 mask = BIT(pin);
+
+	if (type == IRQ_TYPE_PROBE) {
+		if ((rg->rising | rg->falling |
+		     rg->hlevel | rg->llevel) & mask)
+			return 0;
+
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	rg->rising &= ~mask;
+	rg->falling &= ~mask;
+	rg->hlevel &= ~mask;
+	rg->llevel &= ~mask;
+
+	switch (type & IRQ_TYPE_SENSE_MASK) {
+	case IRQ_TYPE_EDGE_BOTH:
+		rg->rising |= mask;
+		rg->falling |= mask;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		rg->rising |= mask;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		rg->falling |= mask;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		rg->hlevel |= mask;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		rg->llevel |= mask;
+		break;
+	}
+
+	return 0;
+}
+
+static struct irq_chip mediatek_gpio_irq_chip = {
+	.irq_unmask		= mediatek_gpio_irq_unmask,
+	.irq_mask		= mediatek_gpio_irq_mask,
+	.irq_mask_ack		= mediatek_gpio_irq_mask,
+	.irq_set_type		= mediatek_gpio_irq_type,
+};
+
+static inline const char * const mediatek_gpio_bank_name(int bank)
+{
+	static const char * const bank_names[] = {
+		"mt7621-bank0", "mt7621-bank1", "mt7621-bank2",
+	};
+
+	return bank_names[bank];
+}
+
+static int
+mediatek_gpio_bank_probe(struct platform_device *pdev,
+			 struct device_node *node, int bank)
+{
+	struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
+	struct mtk_gc *rg;
+	void __iomem *dat, *set, *ctrl, *diro;
+	int ret;
+
+	rg = &gpio->gc_map[bank];
+	memset(rg, 0, sizeof(*rg));
+
+	spin_lock_init(&rg->lock);
+	rg->chip.of_node = node;
+	rg->bank = bank;
+	rg->chip.label = mediatek_gpio_bank_name(rg->bank);
+
+	dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
+	set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
+	ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
+	diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
+
+	ret = bgpio_init(&rg->chip, &pdev->dev, 4,
+			 dat, set, ctrl, diro, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "bgpio_init() failed\n");
+		return ret;
+	}
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
+			rg->chip.ngpio, ret);
+		return ret;
+	}
+
+	if (gpio->gpio_irq) {
+		/*
+		 * Manually request the irq here instead of passing
+		 * a flow-handler to gpiochip_set_chained_irqchip,
+		 * because the irq is shared.
+		 */
+		ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
+				       mediatek_gpio_irq_handler, IRQF_SHARED,
+				       rg->chip.label, &rg->chip);
+
+		if (ret) {
+			dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
+				gpio->gpio_irq, ret);
+			return ret;
+		}
+
+		mediatek_gpio_irq_chip.name = rg->chip.label;
+		ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
+					   0, handle_simple_irq, IRQ_TYPE_NONE);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
+			return ret;
+		}
+
+		gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
+					     gpio->gpio_irq, NULL);
+	}
+
+	/* set polarity to low for all gpios */
+	mtk_gpio_w32(rg, GPIO_REG_POL, 0);
+
+	dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
+
+	return 0;
+}
+
+static int
+mediatek_gpio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct mtk_data *gpio_data;
+	int i;
+
+	gpio_data = devm_kzalloc(&pdev->dev, sizeof(*gpio_data), GFP_KERNEL);
+	if (!gpio_data)
+		return -ENOMEM;
+
+	gpio_data->gpio_membase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(gpio_data->gpio_membase))
+		return PTR_ERR(gpio_data->gpio_membase);
+
+	gpio_data->gpio_irq = irq_of_parse_and_map(np, 0);
+	gpio_data->dev = &pdev->dev;
+	platform_set_drvdata(pdev, gpio_data);
+
+	for (i = 0; i < MTK_BANK_CNT; i++)
+		mediatek_gpio_bank_probe(pdev, np, i);
+
+	return 0;
+}
+
+static const struct of_device_id mediatek_gpio_match[] = {
+	{ .compatible = "mediatek,mt7621-gpio" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
+
+static struct platform_driver mediatek_gpio_driver = {
+	.probe = mediatek_gpio_probe,
+	.driver = {
+		.name = "mt7621_gpio",
+		.of_match_table = mediatek_gpio_match,
+	},
+};
+
+builtin_platform_driver(mediatek_gpio_driver);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-29 12:43   ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 12:43 UTC (permalink / raw)
  To: linus.walleij
  Cc: devicetree, gregkh, driverdev-devel, linux-gpio, robh+dt, neil

Add driver support for gpio of MT7621 SoC.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 drivers/gpio/Kconfig       |   8 ++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-mt7621.c | 320 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 329 insertions(+)
 create mode 100644 drivers/gpio/gpio-mt7621.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 71c0ab4..836aa21 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -359,6 +359,14 @@ config GPIO_MPC8XXX
 	  Say Y here if you're going to use hardware that connects to the
 	  MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs.
 
+config GPIO_MT7621
+	bool "Mediatek MT7621 GPIO Support"
+	depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	help
+	  Say yes here to support the Mediatek MT7621 SoC GPIO device
+
 config GPIO_MVEBU
 	def_bool y
 	depends on PLAT_ORION || ARCH_MVEBU
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1324c8f..b264426 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_MOCKUP)      += gpio-mockup.o
 obj-$(CONFIG_GPIO_MPC5200)	+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)	+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSIC)		+= gpio-msic.o
+obj-$(CONFIG_GPIO_MSIC)		+= gpio-mt7621.o
 obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)		+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
new file mode 100644
index 0000000..281e621
--- /dev/null
+++ b/drivers/gpio/gpio-mt7621.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#define MTK_BANK_CNT	3
+#define MTK_BANK_WIDTH	32
+
+#define GPIO_BANK_WIDE	0x04
+#define GPIO_REG_CTRL	0x00
+#define GPIO_REG_POL	0x10
+#define GPIO_REG_DATA	0x20
+#define GPIO_REG_DSET	0x30
+#define GPIO_REG_DCLR	0x40
+#define GPIO_REG_REDGE	0x50
+#define GPIO_REG_FEDGE	0x60
+#define GPIO_REG_HLVL	0x70
+#define GPIO_REG_LLVL	0x80
+#define GPIO_REG_STAT	0x90
+#define GPIO_REG_EDGE	0xA0
+
+struct mtk_gc {
+	struct gpio_chip chip;
+	spinlock_t lock;
+	int bank;
+	u32 rising;
+	u32 falling;
+	u32 hlevel;
+	u32 llevel;
+};
+
+/**
+ * struct mtk_data - state container for
+ * data of the platform driver. It is 3
+ * separate gpio-chip each one with its
+ * own irq_chip.
+ * @dev: device instance
+ * @gpio_membase: memory base address
+ * @gpio_irq: irq number from the device tree
+ * @gc_map: array of the gpio chips
+ */
+struct mtk_data {
+	struct device *dev;
+	void __iomem *gpio_membase;
+	int gpio_irq;
+	struct mtk_gc gc_map[MTK_BANK_CNT];
+};
+
+static inline struct mtk_gc *
+to_mediatek_gpio(struct gpio_chip *chip)
+{
+	return container_of(chip, struct mtk_gc, chip);
+}
+
+static inline void
+mtk_gpio_w32(struct mtk_gc *rg, u32 offset, u32 val)
+{
+	struct gpio_chip *gc = &rg->chip;
+	struct mtk_data *gpio_data = gpiochip_get_data(gc);
+
+	offset = (rg->bank * GPIO_BANK_WIDE) + offset;
+	gc->write_reg(gpio_data->gpio_membase + offset, val);
+}
+
+static inline u32
+mtk_gpio_r32(struct mtk_gc *rg, u32 offset)
+{
+	struct gpio_chip *gc = &rg->chip;
+	struct mtk_data *gpio_data = gpiochip_get_data(gc);
+
+	offset = (rg->bank * GPIO_BANK_WIDE) + offset;
+	return gc->read_reg(gpio_data->gpio_membase + offset);
+}
+
+static irqreturn_t
+mediatek_gpio_irq_handler(int irq, void *data)
+{
+	struct gpio_chip *gc = data;
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	irqreturn_t ret = IRQ_NONE;
+	unsigned long pending;
+	int bit;
+
+	pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
+
+	for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
+		u32 map = irq_find_mapping(gc->irq.domain, bit);
+
+		generic_handle_irq(map);
+		mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
+		ret |= IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static void
+mediatek_gpio_irq_unmask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	int pin = d->hwirq;
+	unsigned long flags;
+	u32 rise, fall, high, low;
+
+	spin_lock_irqsave(&rg->lock, flags);
+	rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
+	fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
+	high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
+	low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
+	mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(pin) & rg->rising));
+	mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(pin) & rg->falling));
+	mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (BIT(pin) & rg->hlevel));
+	mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (BIT(pin) & rg->llevel));
+	spin_unlock_irqrestore(&rg->lock, flags);
+}
+
+static void
+mediatek_gpio_irq_mask(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	int pin = d->hwirq;
+	unsigned long flags;
+	u32 rise, fall, high, low;
+
+	spin_lock_irqsave(&rg->lock, flags);
+	rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
+	fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
+	high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
+	low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
+	mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
+	mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
+	mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
+	mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
+	spin_unlock_irqrestore(&rg->lock, flags);
+}
+
+static int
+mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct mtk_gc *rg = to_mediatek_gpio(gc);
+	int pin = d->hwirq;
+	u32 mask = BIT(pin);
+
+	if (type == IRQ_TYPE_PROBE) {
+		if ((rg->rising | rg->falling |
+		     rg->hlevel | rg->llevel) & mask)
+			return 0;
+
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	rg->rising &= ~mask;
+	rg->falling &= ~mask;
+	rg->hlevel &= ~mask;
+	rg->llevel &= ~mask;
+
+	switch (type & IRQ_TYPE_SENSE_MASK) {
+	case IRQ_TYPE_EDGE_BOTH:
+		rg->rising |= mask;
+		rg->falling |= mask;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		rg->rising |= mask;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		rg->falling |= mask;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		rg->hlevel |= mask;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		rg->llevel |= mask;
+		break;
+	}
+
+	return 0;
+}
+
+static struct irq_chip mediatek_gpio_irq_chip = {
+	.irq_unmask		= mediatek_gpio_irq_unmask,
+	.irq_mask		= mediatek_gpio_irq_mask,
+	.irq_mask_ack		= mediatek_gpio_irq_mask,
+	.irq_set_type		= mediatek_gpio_irq_type,
+};
+
+static inline const char * const mediatek_gpio_bank_name(int bank)
+{
+	static const char * const bank_names[] = {
+		"mt7621-bank0", "mt7621-bank1", "mt7621-bank2",
+	};
+
+	return bank_names[bank];
+}
+
+static int
+mediatek_gpio_bank_probe(struct platform_device *pdev,
+			 struct device_node *node, int bank)
+{
+	struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
+	struct mtk_gc *rg;
+	void __iomem *dat, *set, *ctrl, *diro;
+	int ret;
+
+	rg = &gpio->gc_map[bank];
+	memset(rg, 0, sizeof(*rg));
+
+	spin_lock_init(&rg->lock);
+	rg->chip.of_node = node;
+	rg->bank = bank;
+	rg->chip.label = mediatek_gpio_bank_name(rg->bank);
+
+	dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
+	set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
+	ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
+	diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
+
+	ret = bgpio_init(&rg->chip, &pdev->dev, 4,
+			 dat, set, ctrl, diro, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "bgpio_init() failed\n");
+		return ret;
+	}
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
+			rg->chip.ngpio, ret);
+		return ret;
+	}
+
+	if (gpio->gpio_irq) {
+		/*
+		 * Manually request the irq here instead of passing
+		 * a flow-handler to gpiochip_set_chained_irqchip,
+		 * because the irq is shared.
+		 */
+		ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
+				       mediatek_gpio_irq_handler, IRQF_SHARED,
+				       rg->chip.label, &rg->chip);
+
+		if (ret) {
+			dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
+				gpio->gpio_irq, ret);
+			return ret;
+		}
+
+		mediatek_gpio_irq_chip.name = rg->chip.label;
+		ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
+					   0, handle_simple_irq, IRQ_TYPE_NONE);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
+			return ret;
+		}
+
+		gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
+					     gpio->gpio_irq, NULL);
+	}
+
+	/* set polarity to low for all gpios */
+	mtk_gpio_w32(rg, GPIO_REG_POL, 0);
+
+	dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
+
+	return 0;
+}
+
+static int
+mediatek_gpio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct mtk_data *gpio_data;
+	int i;
+
+	gpio_data = devm_kzalloc(&pdev->dev, sizeof(*gpio_data), GFP_KERNEL);
+	if (!gpio_data)
+		return -ENOMEM;
+
+	gpio_data->gpio_membase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(gpio_data->gpio_membase))
+		return PTR_ERR(gpio_data->gpio_membase);
+
+	gpio_data->gpio_irq = irq_of_parse_and_map(np, 0);
+	gpio_data->dev = &pdev->dev;
+	platform_set_drvdata(pdev, gpio_data);
+
+	for (i = 0; i < MTK_BANK_CNT; i++)
+		mediatek_gpio_bank_probe(pdev, np, i);
+
+	return 0;
+}
+
+static const struct of_device_id mediatek_gpio_match[] = {
+	{ .compatible = "mediatek,mt7621-gpio" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
+
+static struct platform_driver mediatek_gpio_driver = {
+	.probe = mediatek_gpio_probe,
+	.driver = {
+		.name = "mt7621_gpio",
+		.of_match_table = mediatek_gpio_match,
+	},
+};
+
+builtin_platform_driver(mediatek_gpio_driver);
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/2] dt-bindings: document gpio-mt7621 bindings
  2018-06-29 12:43 ` Sergio Paracuellos
@ 2018-06-29 12:43   ` Sergio Paracuellos
  -1 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 12:43 UTC (permalink / raw)
  To: linus.walleij
  Cc: devicetree, gregkh, driverdev-devel, linux-gpio, robh+dt, neil

Add a devicetree binding documentation for the mt7621 gpio.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 .../bindings/gpio/mediatek,mt7621-gpio.txt         | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt

diff --git a/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt b/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt
new file mode 100644
index 0000000..ba45558
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt
@@ -0,0 +1,35 @@
+Mediatek MT7621 SoC GPIO controller bindings
+
+The IP core used inside these SoCs has 3 banks of 32 GPIOs each.
+The registers of all the banks are interwoven inside one single IO range.
+We load one GPIO controller instance per bank. Also the GPIO controller can receive
+interrupts on any of the GPIOs, either edge or level. It then interrupts the CPU
+using GIC INT12.
+
+Required properties for the top level node:
+- #gpio-cells : Should be two. The first cell is the GPIO pin number and the
+   second cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>.
+   Only the GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+   interrupt. Should be 2. The first cell defines the interrupt number,
+   the second encodes the triger flags encoded as described in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+- compatible:
+  - "mediatek,mt7621-gpio" for Mediatek controllers
+- reg : Physical base address and length of the controller's registers
+- interrupt-parent : phandle of the parent interrupt controller.
+- interrupts : Interrupt specifier for the controllers interrupt.
+- interrupt-controller : Mark the device node as an interrupt controller.
+- gpio-controller : Marks the device node as a GPIO controller.
+
+Example:
+	gpio@600 {
+		#gpio-cells = <2>;
+		#interrupt-cells = <2>;
+		compatible = "mediatek,mt7621-gpio";
+		gpio-controller;
+		interrupt-controller;
+		reg = <0x600 0x100>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 12 IRQ_TYPE_LEVEL_HIGH>;
+	};
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/2] dt-bindings: document gpio-mt7621 bindings
@ 2018-06-29 12:43   ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 12:43 UTC (permalink / raw)
  To: linus.walleij
  Cc: devicetree, gregkh, driverdev-devel, linux-gpio, robh+dt, neil

Add a devicetree binding documentation for the mt7621 gpio.

Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
 .../bindings/gpio/mediatek,mt7621-gpio.txt         | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt

diff --git a/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt b/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt
new file mode 100644
index 0000000..ba45558
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt
@@ -0,0 +1,35 @@
+Mediatek MT7621 SoC GPIO controller bindings
+
+The IP core used inside these SoCs has 3 banks of 32 GPIOs each.
+The registers of all the banks are interwoven inside one single IO range.
+We load one GPIO controller instance per bank. Also the GPIO controller can receive
+interrupts on any of the GPIOs, either edge or level. It then interrupts the CPU
+using GIC INT12.
+
+Required properties for the top level node:
+- #gpio-cells : Should be two. The first cell is the GPIO pin number and the
+   second cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>.
+   Only the GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+   interrupt. Should be 2. The first cell defines the interrupt number,
+   the second encodes the triger flags encoded as described in
+   Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+- compatible:
+  - "mediatek,mt7621-gpio" for Mediatek controllers
+- reg : Physical base address and length of the controller's registers
+- interrupt-parent : phandle of the parent interrupt controller.
+- interrupts : Interrupt specifier for the controllers interrupt.
+- interrupt-controller : Mark the device node as an interrupt controller.
+- gpio-controller : Marks the device node as a GPIO controller.
+
+Example:
+	gpio@600 {
+		#gpio-cells = <2>;
+		#interrupt-cells = <2>;
+		compatible = "mediatek,mt7621-gpio";
+		gpio-controller;
+		interrupt-controller;
+		reg = <0x600 0x100>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 12 IRQ_TYPE_LEVEL_HIGH>;
+	};
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 12:43   ` Sergio Paracuellos
@ 2018-06-29 13:31     ` Dan Carpenter
  -1 siblings, 0 replies; 19+ messages in thread
From: Dan Carpenter @ 2018-06-29 13:31 UTC (permalink / raw)
  To: Sergio Paracuellos
  Cc: devicetree, gregkh, linus.walleij, driverdev-devel, linux-gpio,
	robh+dt, neil

Looks pretty clean to me.  Sorry for not reviewing v1.  Smatch (private
devel version) points out a little bit of dead code.

drivers/staging/mt7621-gpio/gpio-mt7621.c:200 mediatek_gpio_irq_handler() warn: address of 'gpio_data->gc_map[i]' is non-NULL
drivers/staging/mt7621-gpio/gpio-mt7621.c:225 mediatek_gpio_irq_unmask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
drivers/staging/mt7621-gpio/gpio-mt7621.c:246 mediatek_gpio_irq_mask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
drivers/staging/mt7621-gpio/gpio-mt7621.c:266 mediatek_gpio_irq_type() warn: address of 'gpio_data->gc_map[bank]' is non-NULL

But that's harmless and very minor.

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-29 13:31     ` Dan Carpenter
  0 siblings, 0 replies; 19+ messages in thread
From: Dan Carpenter @ 2018-06-29 13:31 UTC (permalink / raw)
  To: Sergio Paracuellos
  Cc: devicetree, gregkh, linus.walleij, driverdev-devel, linux-gpio,
	robh+dt, neil

Looks pretty clean to me.  Sorry for not reviewing v1.  Smatch (private
devel version) points out a little bit of dead code.

drivers/staging/mt7621-gpio/gpio-mt7621.c:200 mediatek_gpio_irq_handler() warn: address of 'gpio_data->gc_map[i]' is non-NULL
drivers/staging/mt7621-gpio/gpio-mt7621.c:225 mediatek_gpio_irq_unmask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
drivers/staging/mt7621-gpio/gpio-mt7621.c:246 mediatek_gpio_irq_mask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
drivers/staging/mt7621-gpio/gpio-mt7621.c:266 mediatek_gpio_irq_type() warn: address of 'gpio_data->gc_map[bank]' is non-NULL

But that's harmless and very minor.

regards,
dan carpenter

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 13:31     ` Dan Carpenter
@ 2018-06-29 13:34       ` Dan Carpenter
  -1 siblings, 0 replies; 19+ messages in thread
From: Dan Carpenter @ 2018-06-29 13:34 UTC (permalink / raw)
  To: Sergio Paracuellos
  Cc: devicetree, gregkh, linus.walleij, driverdev-devel, linux-gpio,
	robh+dt, neil

On Fri, Jun 29, 2018 at 04:31:35PM +0300, Dan Carpenter wrote:
> Looks pretty clean to me.  Sorry for not reviewing v1.  Smatch (private
> devel version) points out a little bit of dead code.
> 
> drivers/staging/mt7621-gpio/gpio-mt7621.c:200 mediatek_gpio_irq_handler() warn: address of 'gpio_data->gc_map[i]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:225 mediatek_gpio_irq_unmask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:246 mediatek_gpio_irq_mask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:266 mediatek_gpio_irq_type() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> 
> But that's harmless and very minor.

I think you fixed all these in the non-staging version...  That's fine
then.

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-29 13:34       ` Dan Carpenter
  0 siblings, 0 replies; 19+ messages in thread
From: Dan Carpenter @ 2018-06-29 13:34 UTC (permalink / raw)
  To: Sergio Paracuellos
  Cc: devicetree, gregkh, linus.walleij, driverdev-devel, linux-gpio,
	robh+dt, neil

On Fri, Jun 29, 2018 at 04:31:35PM +0300, Dan Carpenter wrote:
> Looks pretty clean to me.  Sorry for not reviewing v1.  Smatch (private
> devel version) points out a little bit of dead code.
> 
> drivers/staging/mt7621-gpio/gpio-mt7621.c:200 mediatek_gpio_irq_handler() warn: address of 'gpio_data->gc_map[i]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:225 mediatek_gpio_irq_unmask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:246 mediatek_gpio_irq_mask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:266 mediatek_gpio_irq_type() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> 
> But that's harmless and very minor.

I think you fixed all these in the non-staging version...  That's fine
then.

regards,
dan carpenter

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 13:31     ` Dan Carpenter
@ 2018-06-29 13:51       ` Sergio Paracuellos
  -1 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 13:51 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, Linus Walleij, driverdev-devel,
	open list:GPIO SUBSYSTEM, Rob Herring, NeilBrown

On Fri, Jun 29, 2018 at 3:31 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> Looks pretty clean to me.  Sorry for not reviewing v1.  Smatch (private
> devel version) points out a little bit of dead code.
>
> drivers/staging/mt7621-gpio/gpio-mt7621.c:200 mediatek_gpio_irq_handler() warn: address of 'gpio_data->gc_map[i]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:225 mediatek_gpio_irq_unmask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:246 mediatek_gpio_irq_mask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:266 mediatek_gpio_irq_type() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
>
> But that's harmless and very minor.

That warnings should not being in the staging version. Last patch
series was applied yesterday... Maybe you have not run against the
updated tree?

This patch fix them:

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git/commit/?h=staging-testing&id=bfb623c5b0935a2e4b5fe86eab79a37a37b67209

>
> regards,
> dan carpenter

Thanks.

Best regards,
    Sergio Paracuellos
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-29 13:51       ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 13:51 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, Linus Walleij, driverdev-devel,
	open list:GPIO SUBSYSTEM, Rob Herring, NeilBrown

On Fri, Jun 29, 2018 at 3:31 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> Looks pretty clean to me.  Sorry for not reviewing v1.  Smatch (private
> devel version) points out a little bit of dead code.
>
> drivers/staging/mt7621-gpio/gpio-mt7621.c:200 mediatek_gpio_irq_handler() warn: address of 'gpio_data->gc_map[i]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:225 mediatek_gpio_irq_unmask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:246 mediatek_gpio_irq_mask() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
> drivers/staging/mt7621-gpio/gpio-mt7621.c:266 mediatek_gpio_irq_type() warn: address of 'gpio_data->gc_map[bank]' is non-NULL
>
> But that's harmless and very minor.

That warnings should not being in the staging version. Last patch
series was applied yesterday... Maybe you have not run against the
updated tree?

This patch fix them:

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git/commit/?h=staging-testing&id=bfb623c5b0935a2e4b5fe86eab79a37a37b67209

>
> regards,
> dan carpenter

Thanks.

Best regards,
    Sergio Paracuellos
>
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 12:43   ` Sergio Paracuellos
  (?)
  (?)
@ 2018-06-29 16:43   ` kbuild test robot
  2018-06-29 16:52       ` Sergio Paracuellos
  -1 siblings, 1 reply; 19+ messages in thread
From: kbuild test robot @ 2018-06-29 16:43 UTC (permalink / raw)
  To: Sergio Paracuellos
  Cc: devicetree, gregkh, linus.walleij, driverdev-devel, linux-gpio,
	robh+dt, kbuild-all, neil

[-- Attachment #1: Type: text/plain, Size: 3634 bytes --]

Hi Sergio,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on gpio/for-next]
[also build test ERROR on v4.18-rc2 next-20180629]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Sergio-Paracuellos/gpio-mediatek-driver-for-gpio-chip-in-MT7621-SoC/20180629-225420
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
config: x86_64-randconfig-s0-06292230 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/gpio/gpio-mt7621.c: In function 'mediatek_gpio_bank_probe':
>> drivers/gpio/gpio-mt7621.c:221:10: error: 'struct gpio_chip' has no member named 'of_node'
     rg->chip.of_node = node;
             ^

vim +221 drivers/gpio/gpio-mt7621.c

   207	
   208	static int
   209	mediatek_gpio_bank_probe(struct platform_device *pdev,
   210				 struct device_node *node, int bank)
   211	{
   212		struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
   213		struct mtk_gc *rg;
   214		void __iomem *dat, *set, *ctrl, *diro;
   215		int ret;
   216	
   217		rg = &gpio->gc_map[bank];
   218		memset(rg, 0, sizeof(*rg));
   219	
   220		spin_lock_init(&rg->lock);
 > 221		rg->chip.of_node = node;
   222		rg->bank = bank;
   223		rg->chip.label = mediatek_gpio_bank_name(rg->bank);
   224	
   225		dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
   226		set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
   227		ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
   228		diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
   229	
   230		ret = bgpio_init(&rg->chip, &pdev->dev, 4,
   231				 dat, set, ctrl, diro, NULL, 0);
   232		if (ret) {
   233			dev_err(&pdev->dev, "bgpio_init() failed\n");
   234			return ret;
   235		}
   236	
   237		ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
   238		if (ret < 0) {
   239			dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
   240				rg->chip.ngpio, ret);
   241			return ret;
   242		}
   243	
   244		if (gpio->gpio_irq) {
   245			/*
   246			 * Manually request the irq here instead of passing
   247			 * a flow-handler to gpiochip_set_chained_irqchip,
   248			 * because the irq is shared.
   249			 */
   250			ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
   251					       mediatek_gpio_irq_handler, IRQF_SHARED,
   252					       rg->chip.label, &rg->chip);
   253	
   254			if (ret) {
   255				dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
   256					gpio->gpio_irq, ret);
   257				return ret;
   258			}
   259	
   260			mediatek_gpio_irq_chip.name = rg->chip.label;
   261			ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
   262						   0, handle_simple_irq, IRQ_TYPE_NONE);
   263			if (ret) {
   264				dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
   265				return ret;
   266			}
   267	
   268			gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
   269						     gpio->gpio_irq, NULL);
   270		}
   271	
   272		/* set polarity to low for all gpios */
   273		mtk_gpio_w32(rg, GPIO_REG_POL, 0);
   274	
   275		dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
   276	
   277		return 0;
   278	}
   279	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27994 bytes --]

[-- Attachment #3: Type: text/plain, Size: 169 bytes --]

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 16:43   ` kbuild test robot
@ 2018-06-29 16:52       ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 16:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, Linus Walleij, driverdev-devel,
	open list:GPIO SUBSYSTEM, Rob Herring, kbuild-all, NeilBrown

On Fri, Jun 29, 2018 at 6:43 PM, kbuild test robot <lkp@intel.com> wrote:
> Hi Sergio,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on gpio/for-next]
> [also build test ERROR on v4.18-rc2 next-20180629]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Sergio-Paracuellos/gpio-mediatek-driver-for-gpio-chip-in-MT7621-SoC/20180629-225420
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
> config: x86_64-randconfig-s0-06292230 (attached as .config)
> compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    drivers/gpio/gpio-mt7621.c: In function 'mediatek_gpio_bank_probe':
>>> drivers/gpio/gpio-mt7621.c:221:10: error: 'struct gpio_chip' has no member named 'of_node'
>      rg->chip.of_node = node;
>              ^

Should I have to add #ifdef CONFIG_OF_GPIO for this line? Is kind of
ugly hack... Does exist another way to fix this?

Thanks,
    Sergio Paracuellos

>
> vim +221 drivers/gpio/gpio-mt7621.c
>
>    207
>    208  static int
>    209  mediatek_gpio_bank_probe(struct platform_device *pdev,
>    210                           struct device_node *node, int bank)
>    211  {
>    212          struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
>    213          struct mtk_gc *rg;
>    214          void __iomem *dat, *set, *ctrl, *diro;
>    215          int ret;
>    216
>    217          rg = &gpio->gc_map[bank];
>    218          memset(rg, 0, sizeof(*rg));
>    219
>    220          spin_lock_init(&rg->lock);
>  > 221          rg->chip.of_node = node;
>    222          rg->bank = bank;
>    223          rg->chip.label = mediatek_gpio_bank_name(rg->bank);
>    224
>    225          dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
>    226          set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
>    227          ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
>    228          diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
>    229
>    230          ret = bgpio_init(&rg->chip, &pdev->dev, 4,
>    231                           dat, set, ctrl, diro, NULL, 0);
>    232          if (ret) {
>    233                  dev_err(&pdev->dev, "bgpio_init() failed\n");
>    234                  return ret;
>    235          }
>    236
>    237          ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
>    238          if (ret < 0) {
>    239                  dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
>    240                          rg->chip.ngpio, ret);
>    241                  return ret;
>    242          }
>    243
>    244          if (gpio->gpio_irq) {
>    245                  /*
>    246                   * Manually request the irq here instead of passing
>    247                   * a flow-handler to gpiochip_set_chained_irqchip,
>    248                   * because the irq is shared.
>    249                   */
>    250                  ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
>    251                                         mediatek_gpio_irq_handler, IRQF_SHARED,
>    252                                         rg->chip.label, &rg->chip);
>    253
>    254                  if (ret) {
>    255                          dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
>    256                                  gpio->gpio_irq, ret);
>    257                          return ret;
>    258                  }
>    259
>    260                  mediatek_gpio_irq_chip.name = rg->chip.label;
>    261                  ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
>    262                                             0, handle_simple_irq, IRQ_TYPE_NONE);
>    263                  if (ret) {
>    264                          dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
>    265                          return ret;
>    266                  }
>    267
>    268                  gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
>    269                                               gpio->gpio_irq, NULL);
>    270          }
>    271
>    272          /* set polarity to low for all gpios */
>    273          mtk_gpio_w32(rg, GPIO_REG_POL, 0);
>    274
>    275          dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
>    276
>    277          return 0;
>    278  }
>    279
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-29 16:52       ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 16:52 UTC (permalink / raw)
  To: kbuild test robot
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, Linus Walleij, driverdev-devel,
	open list:GPIO SUBSYSTEM, Rob Herring, kbuild-all, NeilBrown

On Fri, Jun 29, 2018 at 6:43 PM, kbuild test robot <lkp@intel.com> wrote:
> Hi Sergio,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on gpio/for-next]
> [also build test ERROR on v4.18-rc2 next-20180629]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Sergio-Paracuellos/gpio-mediatek-driver-for-gpio-chip-in-MT7621-SoC/20180629-225420
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
> config: x86_64-randconfig-s0-06292230 (attached as .config)
> compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    drivers/gpio/gpio-mt7621.c: In function 'mediatek_gpio_bank_probe':
>>> drivers/gpio/gpio-mt7621.c:221:10: error: 'struct gpio_chip' has no member named 'of_node'
>      rg->chip.of_node = node;
>              ^

Should I have to add #ifdef CONFIG_OF_GPIO for this line? Is kind of
ugly hack... Does exist another way to fix this?

Thanks,
    Sergio Paracuellos

>
> vim +221 drivers/gpio/gpio-mt7621.c
>
>    207
>    208  static int
>    209  mediatek_gpio_bank_probe(struct platform_device *pdev,
>    210                           struct device_node *node, int bank)
>    211  {
>    212          struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
>    213          struct mtk_gc *rg;
>    214          void __iomem *dat, *set, *ctrl, *diro;
>    215          int ret;
>    216
>    217          rg = &gpio->gc_map[bank];
>    218          memset(rg, 0, sizeof(*rg));
>    219
>    220          spin_lock_init(&rg->lock);
>  > 221          rg->chip.of_node = node;
>    222          rg->bank = bank;
>    223          rg->chip.label = mediatek_gpio_bank_name(rg->bank);
>    224
>    225          dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
>    226          set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
>    227          ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
>    228          diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
>    229
>    230          ret = bgpio_init(&rg->chip, &pdev->dev, 4,
>    231                           dat, set, ctrl, diro, NULL, 0);
>    232          if (ret) {
>    233                  dev_err(&pdev->dev, "bgpio_init() failed\n");
>    234                  return ret;
>    235          }
>    236
>    237          ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
>    238          if (ret < 0) {
>    239                  dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
>    240                          rg->chip.ngpio, ret);
>    241                  return ret;
>    242          }
>    243
>    244          if (gpio->gpio_irq) {
>    245                  /*
>    246                   * Manually request the irq here instead of passing
>    247                   * a flow-handler to gpiochip_set_chained_irqchip,
>    248                   * because the irq is shared.
>    249                   */
>    250                  ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
>    251                                         mediatek_gpio_irq_handler, IRQF_SHARED,
>    252                                         rg->chip.label, &rg->chip);
>    253
>    254                  if (ret) {
>    255                          dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
>    256                                  gpio->gpio_irq, ret);
>    257                          return ret;
>    258                  }
>    259
>    260                  mediatek_gpio_irq_chip.name = rg->chip.label;
>    261                  ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
>    262                                             0, handle_simple_irq, IRQ_TYPE_NONE);
>    263                  if (ret) {
>    264                          dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
>    265                          return ret;
>    266                  }
>    267
>    268                  gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
>    269                                               gpio->gpio_irq, NULL);
>    270          }
>    271
>    272          /* set polarity to low for all gpios */
>    273          mtk_gpio_w32(rg, GPIO_REG_POL, 0);
>    274
>    275          dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
>    276
>    277          return 0;
>    278  }
>    279
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 16:52       ` Sergio Paracuellos
@ 2018-06-29 19:30         ` Sergio Paracuellos
  -1 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 19:30 UTC (permalink / raw)
  To: kbuild test robot
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, Linus Walleij, driverdev-devel,
	open list:GPIO SUBSYSTEM, Rob Herring, kbuild-all, NeilBrown

On Fri, Jun 29, 2018 at 6:52 PM, Sergio Paracuellos
<sergio.paracuellos@gmail.com> wrote:
> On Fri, Jun 29, 2018 at 6:43 PM, kbuild test robot <lkp@intel.com> wrote:
>> Hi Sergio,
>>
>> Thank you for the patch! Yet something to improve:
>>
>> [auto build test ERROR on gpio/for-next]
>> [also build test ERROR on v4.18-rc2 next-20180629]
>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>
>> url:    https://github.com/0day-ci/linux/commits/Sergio-Paracuellos/gpio-mediatek-driver-for-gpio-chip-in-MT7621-SoC/20180629-225420
>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
>> config: x86_64-randconfig-s0-06292230 (attached as .config)
>> compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    drivers/gpio/gpio-mt7621.c: In function 'mediatek_gpio_bank_probe':
>>>> drivers/gpio/gpio-mt7621.c:221:10: error: 'struct gpio_chip' has no member named 'of_node'
>>      rg->chip.of_node = node;
>>              ^
>
> Should I have to add #ifdef CONFIG_OF_GPIO for this line? Is kind of
> ugly hack... Does exist another way to fix this?
>

Ah, this is v2 where the Makefile was wrong... I though it was v3. I
think we can ignore this and see what happen with likely correct v3.

Best regards,
    Sergio Paracuellos

> Thanks,
>     Sergio Paracuellos
>
>>
>> vim +221 drivers/gpio/gpio-mt7621.c
>>
>>    207
>>    208  static int
>>    209  mediatek_gpio_bank_probe(struct platform_device *pdev,
>>    210                           struct device_node *node, int bank)
>>    211  {
>>    212          struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
>>    213          struct mtk_gc *rg;
>>    214          void __iomem *dat, *set, *ctrl, *diro;
>>    215          int ret;
>>    216
>>    217          rg = &gpio->gc_map[bank];
>>    218          memset(rg, 0, sizeof(*rg));
>>    219
>>    220          spin_lock_init(&rg->lock);
>>  > 221          rg->chip.of_node = node;
>>    222          rg->bank = bank;
>>    223          rg->chip.label = mediatek_gpio_bank_name(rg->bank);
>>    224
>>    225          dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
>>    226          set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
>>    227          ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
>>    228          diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
>>    229
>>    230          ret = bgpio_init(&rg->chip, &pdev->dev, 4,
>>    231                           dat, set, ctrl, diro, NULL, 0);
>>    232          if (ret) {
>>    233                  dev_err(&pdev->dev, "bgpio_init() failed\n");
>>    234                  return ret;
>>    235          }
>>    236
>>    237          ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
>>    238          if (ret < 0) {
>>    239                  dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
>>    240                          rg->chip.ngpio, ret);
>>    241                  return ret;
>>    242          }
>>    243
>>    244          if (gpio->gpio_irq) {
>>    245                  /*
>>    246                   * Manually request the irq here instead of passing
>>    247                   * a flow-handler to gpiochip_set_chained_irqchip,
>>    248                   * because the irq is shared.
>>    249                   */
>>    250                  ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
>>    251                                         mediatek_gpio_irq_handler, IRQF_SHARED,
>>    252                                         rg->chip.label, &rg->chip);
>>    253
>>    254                  if (ret) {
>>    255                          dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
>>    256                                  gpio->gpio_irq, ret);
>>    257                          return ret;
>>    258                  }
>>    259
>>    260                  mediatek_gpio_irq_chip.name = rg->chip.label;
>>    261                  ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
>>    262                                             0, handle_simple_irq, IRQ_TYPE_NONE);
>>    263                  if (ret) {
>>    264                          dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
>>    265                          return ret;
>>    266                  }
>>    267
>>    268                  gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
>>    269                                               gpio->gpio_irq, NULL);
>>    270          }
>>    271
>>    272          /* set polarity to low for all gpios */
>>    273          mtk_gpio_w32(rg, GPIO_REG_POL, 0);
>>    274
>>    275          dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
>>    276
>>    277          return 0;
>>    278  }
>>    279
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-29 19:30         ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-29 19:30 UTC (permalink / raw)
  To: kbuild test robot
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, Linus Walleij, driverdev-devel,
	open list:GPIO SUBSYSTEM, Rob Herring, kbuild-all, NeilBrown

On Fri, Jun 29, 2018 at 6:52 PM, Sergio Paracuellos
<sergio.paracuellos@gmail.com> wrote:
> On Fri, Jun 29, 2018 at 6:43 PM, kbuild test robot <lkp@intel.com> wrote:
>> Hi Sergio,
>>
>> Thank you for the patch! Yet something to improve:
>>
>> [auto build test ERROR on gpio/for-next]
>> [also build test ERROR on v4.18-rc2 next-20180629]
>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>
>> url:    https://github.com/0day-ci/linux/commits/Sergio-Paracuellos/gpio-mediatek-driver-for-gpio-chip-in-MT7621-SoC/20180629-225420
>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
>> config: x86_64-randconfig-s0-06292230 (attached as .config)
>> compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    drivers/gpio/gpio-mt7621.c: In function 'mediatek_gpio_bank_probe':
>>>> drivers/gpio/gpio-mt7621.c:221:10: error: 'struct gpio_chip' has no member named 'of_node'
>>      rg->chip.of_node = node;
>>              ^
>
> Should I have to add #ifdef CONFIG_OF_GPIO for this line? Is kind of
> ugly hack... Does exist another way to fix this?
>

Ah, this is v2 where the Makefile was wrong... I though it was v3. I
think we can ignore this and see what happen with likely correct v3.

Best regards,
    Sergio Paracuellos

> Thanks,
>     Sergio Paracuellos
>
>>
>> vim +221 drivers/gpio/gpio-mt7621.c
>>
>>    207
>>    208  static int
>>    209  mediatek_gpio_bank_probe(struct platform_device *pdev,
>>    210                           struct device_node *node, int bank)
>>    211  {
>>    212          struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
>>    213          struct mtk_gc *rg;
>>    214          void __iomem *dat, *set, *ctrl, *diro;
>>    215          int ret;
>>    216
>>    217          rg = &gpio->gc_map[bank];
>>    218          memset(rg, 0, sizeof(*rg));
>>    219
>>    220          spin_lock_init(&rg->lock);
>>  > 221          rg->chip.of_node = node;
>>    222          rg->bank = bank;
>>    223          rg->chip.label = mediatek_gpio_bank_name(rg->bank);
>>    224
>>    225          dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
>>    226          set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
>>    227          ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
>>    228          diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
>>    229
>>    230          ret = bgpio_init(&rg->chip, &pdev->dev, 4,
>>    231                           dat, set, ctrl, diro, NULL, 0);
>>    232          if (ret) {
>>    233                  dev_err(&pdev->dev, "bgpio_init() failed\n");
>>    234                  return ret;
>>    235          }
>>    236
>>    237          ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
>>    238          if (ret < 0) {
>>    239                  dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
>>    240                          rg->chip.ngpio, ret);
>>    241                  return ret;
>>    242          }
>>    243
>>    244          if (gpio->gpio_irq) {
>>    245                  /*
>>    246                   * Manually request the irq here instead of passing
>>    247                   * a flow-handler to gpiochip_set_chained_irqchip,
>>    248                   * because the irq is shared.
>>    249                   */
>>    250                  ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
>>    251                                         mediatek_gpio_irq_handler, IRQF_SHARED,
>>    252                                         rg->chip.label, &rg->chip);
>>    253
>>    254                  if (ret) {
>>    255                          dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
>>    256                                  gpio->gpio_irq, ret);
>>    257                          return ret;
>>    258                  }
>>    259
>>    260                  mediatek_gpio_irq_chip.name = rg->chip.label;
>>    261                  ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
>>    262                                             0, handle_simple_irq, IRQ_TYPE_NONE);
>>    263                  if (ret) {
>>    264                          dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
>>    265                          return ret;
>>    266                  }
>>    267
>>    268                  gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
>>    269                                               gpio->gpio_irq, NULL);
>>    270          }
>>    271
>>    272          /* set polarity to low for all gpios */
>>    273          mtk_gpio_w32(rg, GPIO_REG_POL, 0);
>>    274
>>    275          dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
>>    276
>>    277          return 0;
>>    278  }
>>    279
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
  2018-06-29 12:43   ` Sergio Paracuellos
@ 2018-06-30  6:12     ` Sergio Paracuellos
  -1 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-30  6:12 UTC (permalink / raw)
  To: Linus Walleij
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, driverdev-devel, open list:GPIO SUBSYSTEM, Rob Herring,
	NeilBrown

On Fri, Jun 29, 2018 at 2:43 PM, Sergio Paracuellos
<sergio.paracuellos@gmail.com> wrote:
> Add driver support for gpio of MT7621 SoC.
>
> Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
> ---
>  drivers/gpio/Kconfig       |   8 ++
>  drivers/gpio/Makefile      |   1 +
>  drivers/gpio/gpio-mt7621.c | 320 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 329 insertions(+)
>  create mode 100644 drivers/gpio/gpio-mt7621.c

Hi all,

Sorry for the noise. Ignore this and v3 for now. It seems the "only
one node" approach for the gpio in the device tree is not working
properly.
I thought it was but Neil points out here it was not:

http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-June/122621.html

We'll send v4 with all properly working.

Thanks in advance and sorry again.

Best regards,
    Sergio Paracuellos

>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 71c0ab4..836aa21 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -359,6 +359,14 @@ config GPIO_MPC8XXX
>           Say Y here if you're going to use hardware that connects to the
>           MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs.
>
> +config GPIO_MT7621
> +       bool "Mediatek MT7621 GPIO Support"
> +       depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST
> +       select GPIO_GENERIC
> +       select GPIOLIB_IRQCHIP
> +       help
> +         Say yes here to support the Mediatek MT7621 SoC GPIO device
> +
>  config GPIO_MVEBU
>         def_bool y
>         depends on PLAT_ORION || ARCH_MVEBU
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 1324c8f..b264426 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_MOCKUP)      += gpio-mockup.o
>  obj-$(CONFIG_GPIO_MPC5200)     += gpio-mpc5200.o
>  obj-$(CONFIG_GPIO_MPC8XXX)     += gpio-mpc8xxx.o
>  obj-$(CONFIG_GPIO_MSIC)                += gpio-msic.o
> +obj-$(CONFIG_GPIO_MSIC)                += gpio-mt7621.o
>  obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
>  obj-$(CONFIG_GPIO_MXC)         += gpio-mxc.o
>  obj-$(CONFIG_GPIO_MXS)         += gpio-mxs.o
> diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
> new file mode 100644
> index 0000000..281e621
> --- /dev/null
> +++ b/drivers/gpio/gpio-mt7621.c
> @@ -0,0 +1,320 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
> + * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
> + */
> +
> +#include <linux/err.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +
> +#define MTK_BANK_CNT   3
> +#define MTK_BANK_WIDTH 32
> +
> +#define GPIO_BANK_WIDE 0x04
> +#define GPIO_REG_CTRL  0x00
> +#define GPIO_REG_POL   0x10
> +#define GPIO_REG_DATA  0x20
> +#define GPIO_REG_DSET  0x30
> +#define GPIO_REG_DCLR  0x40
> +#define GPIO_REG_REDGE 0x50
> +#define GPIO_REG_FEDGE 0x60
> +#define GPIO_REG_HLVL  0x70
> +#define GPIO_REG_LLVL  0x80
> +#define GPIO_REG_STAT  0x90
> +#define GPIO_REG_EDGE  0xA0
> +
> +struct mtk_gc {
> +       struct gpio_chip chip;
> +       spinlock_t lock;
> +       int bank;
> +       u32 rising;
> +       u32 falling;
> +       u32 hlevel;
> +       u32 llevel;
> +};
> +
> +/**
> + * struct mtk_data - state container for
> + * data of the platform driver. It is 3
> + * separate gpio-chip each one with its
> + * own irq_chip.
> + * @dev: device instance
> + * @gpio_membase: memory base address
> + * @gpio_irq: irq number from the device tree
> + * @gc_map: array of the gpio chips
> + */
> +struct mtk_data {
> +       struct device *dev;
> +       void __iomem *gpio_membase;
> +       int gpio_irq;
> +       struct mtk_gc gc_map[MTK_BANK_CNT];
> +};
> +
> +static inline struct mtk_gc *
> +to_mediatek_gpio(struct gpio_chip *chip)
> +{
> +       return container_of(chip, struct mtk_gc, chip);
> +}
> +
> +static inline void
> +mtk_gpio_w32(struct mtk_gc *rg, u32 offset, u32 val)
> +{
> +       struct gpio_chip *gc = &rg->chip;
> +       struct mtk_data *gpio_data = gpiochip_get_data(gc);
> +
> +       offset = (rg->bank * GPIO_BANK_WIDE) + offset;
> +       gc->write_reg(gpio_data->gpio_membase + offset, val);
> +}
> +
> +static inline u32
> +mtk_gpio_r32(struct mtk_gc *rg, u32 offset)
> +{
> +       struct gpio_chip *gc = &rg->chip;
> +       struct mtk_data *gpio_data = gpiochip_get_data(gc);
> +
> +       offset = (rg->bank * GPIO_BANK_WIDE) + offset;
> +       return gc->read_reg(gpio_data->gpio_membase + offset);
> +}
> +
> +static irqreturn_t
> +mediatek_gpio_irq_handler(int irq, void *data)
> +{
> +       struct gpio_chip *gc = data;
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       irqreturn_t ret = IRQ_NONE;
> +       unsigned long pending;
> +       int bit;
> +
> +       pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
> +
> +       for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
> +               u32 map = irq_find_mapping(gc->irq.domain, bit);
> +
> +               generic_handle_irq(map);
> +               mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
> +               ret |= IRQ_HANDLED;
> +       }
> +
> +       return ret;
> +}
> +
> +static void
> +mediatek_gpio_irq_unmask(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       int pin = d->hwirq;
> +       unsigned long flags;
> +       u32 rise, fall, high, low;
> +
> +       spin_lock_irqsave(&rg->lock, flags);
> +       rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
> +       fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
> +       high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
> +       low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
> +       mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(pin) & rg->rising));
> +       mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(pin) & rg->falling));
> +       mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (BIT(pin) & rg->hlevel));
> +       mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (BIT(pin) & rg->llevel));
> +       spin_unlock_irqrestore(&rg->lock, flags);
> +}
> +
> +static void
> +mediatek_gpio_irq_mask(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       int pin = d->hwirq;
> +       unsigned long flags;
> +       u32 rise, fall, high, low;
> +
> +       spin_lock_irqsave(&rg->lock, flags);
> +       rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
> +       fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
> +       high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
> +       low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
> +       mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
> +       mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
> +       mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
> +       mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
> +       spin_unlock_irqrestore(&rg->lock, flags);
> +}
> +
> +static int
> +mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       int pin = d->hwirq;
> +       u32 mask = BIT(pin);
> +
> +       if (type == IRQ_TYPE_PROBE) {
> +               if ((rg->rising | rg->falling |
> +                    rg->hlevel | rg->llevel) & mask)
> +                       return 0;
> +
> +               type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
> +       }
> +
> +       rg->rising &= ~mask;
> +       rg->falling &= ~mask;
> +       rg->hlevel &= ~mask;
> +       rg->llevel &= ~mask;
> +
> +       switch (type & IRQ_TYPE_SENSE_MASK) {
> +       case IRQ_TYPE_EDGE_BOTH:
> +               rg->rising |= mask;
> +               rg->falling |= mask;
> +               break;
> +       case IRQ_TYPE_EDGE_RISING:
> +               rg->rising |= mask;
> +               break;
> +       case IRQ_TYPE_EDGE_FALLING:
> +               rg->falling |= mask;
> +               break;
> +       case IRQ_TYPE_LEVEL_HIGH:
> +               rg->hlevel |= mask;
> +               break;
> +       case IRQ_TYPE_LEVEL_LOW:
> +               rg->llevel |= mask;
> +               break;
> +       }
> +
> +       return 0;
> +}
> +
> +static struct irq_chip mediatek_gpio_irq_chip = {
> +       .irq_unmask             = mediatek_gpio_irq_unmask,
> +       .irq_mask               = mediatek_gpio_irq_mask,
> +       .irq_mask_ack           = mediatek_gpio_irq_mask,
> +       .irq_set_type           = mediatek_gpio_irq_type,
> +};
> +
> +static inline const char * const mediatek_gpio_bank_name(int bank)
> +{
> +       static const char * const bank_names[] = {
> +               "mt7621-bank0", "mt7621-bank1", "mt7621-bank2",
> +       };
> +
> +       return bank_names[bank];
> +}
> +
> +static int
> +mediatek_gpio_bank_probe(struct platform_device *pdev,
> +                        struct device_node *node, int bank)
> +{
> +       struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
> +       struct mtk_gc *rg;
> +       void __iomem *dat, *set, *ctrl, *diro;
> +       int ret;
> +
> +       rg = &gpio->gc_map[bank];
> +       memset(rg, 0, sizeof(*rg));
> +
> +       spin_lock_init(&rg->lock);
> +       rg->chip.of_node = node;
> +       rg->bank = bank;
> +       rg->chip.label = mediatek_gpio_bank_name(rg->bank);
> +
> +       dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
> +       set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
> +       ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
> +       diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
> +
> +       ret = bgpio_init(&rg->chip, &pdev->dev, 4,
> +                        dat, set, ctrl, diro, NULL, 0);
> +       if (ret) {
> +               dev_err(&pdev->dev, "bgpio_init() failed\n");
> +               return ret;
> +       }
> +
> +       ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
> +                       rg->chip.ngpio, ret);
> +               return ret;
> +       }
> +
> +       if (gpio->gpio_irq) {
> +               /*
> +                * Manually request the irq here instead of passing
> +                * a flow-handler to gpiochip_set_chained_irqchip,
> +                * because the irq is shared.
> +                */
> +               ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
> +                                      mediatek_gpio_irq_handler, IRQF_SHARED,
> +                                      rg->chip.label, &rg->chip);
> +
> +               if (ret) {
> +                       dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
> +                               gpio->gpio_irq, ret);
> +                       return ret;
> +               }
> +
> +               mediatek_gpio_irq_chip.name = rg->chip.label;
> +               ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
> +                                          0, handle_simple_irq, IRQ_TYPE_NONE);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
> +                       return ret;
> +               }
> +
> +               gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
> +                                            gpio->gpio_irq, NULL);
> +       }
> +
> +       /* set polarity to low for all gpios */
> +       mtk_gpio_w32(rg, GPIO_REG_POL, 0);
> +
> +       dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
> +
> +       return 0;
> +}
> +
> +static int
> +mediatek_gpio_probe(struct platform_device *pdev)
> +{
> +       struct device_node *np = pdev->dev.of_node;
> +       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       struct mtk_data *gpio_data;
> +       int i;
> +
> +       gpio_data = devm_kzalloc(&pdev->dev, sizeof(*gpio_data), GFP_KERNEL);
> +       if (!gpio_data)
> +               return -ENOMEM;
> +
> +       gpio_data->gpio_membase = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(gpio_data->gpio_membase))
> +               return PTR_ERR(gpio_data->gpio_membase);
> +
> +       gpio_data->gpio_irq = irq_of_parse_and_map(np, 0);
> +       gpio_data->dev = &pdev->dev;
> +       platform_set_drvdata(pdev, gpio_data);
> +
> +       for (i = 0; i < MTK_BANK_CNT; i++)
> +               mediatek_gpio_bank_probe(pdev, np, i);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id mediatek_gpio_match[] = {
> +       { .compatible = "mediatek,mt7621-gpio" },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
> +
> +static struct platform_driver mediatek_gpio_driver = {
> +       .probe = mediatek_gpio_probe,
> +       .driver = {
> +               .name = "mt7621_gpio",
> +               .of_match_table = mediatek_gpio_match,
> +       },
> +};
> +
> +builtin_platform_driver(mediatek_gpio_driver);
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 1/2] gpio: mediatek: add driver for MT7621
@ 2018-06-30  6:12     ` Sergio Paracuellos
  0 siblings, 0 replies; 19+ messages in thread
From: Sergio Paracuellos @ 2018-06-30  6:12 UTC (permalink / raw)
  To: Linus Walleij
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Greg KH, driverdev-devel, open list:GPIO SUBSYSTEM, Rob Herring,
	NeilBrown

On Fri, Jun 29, 2018 at 2:43 PM, Sergio Paracuellos
<sergio.paracuellos@gmail.com> wrote:
> Add driver support for gpio of MT7621 SoC.
>
> Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
> ---
>  drivers/gpio/Kconfig       |   8 ++
>  drivers/gpio/Makefile      |   1 +
>  drivers/gpio/gpio-mt7621.c | 320 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 329 insertions(+)
>  create mode 100644 drivers/gpio/gpio-mt7621.c

Hi all,

Sorry for the noise. Ignore this and v3 for now. It seems the "only
one node" approach for the gpio in the device tree is not working
properly.
I thought it was but Neil points out here it was not:

http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2018-June/122621.html

We'll send v4 with all properly working.

Thanks in advance and sorry again.

Best regards,
    Sergio Paracuellos

>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 71c0ab4..836aa21 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -359,6 +359,14 @@ config GPIO_MPC8XXX
>           Say Y here if you're going to use hardware that connects to the
>           MPC512x/831x/834x/837x/8572/8610/QorIQ GPIOs.
>
> +config GPIO_MT7621
> +       bool "Mediatek MT7621 GPIO Support"
> +       depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST
> +       select GPIO_GENERIC
> +       select GPIOLIB_IRQCHIP
> +       help
> +         Say yes here to support the Mediatek MT7621 SoC GPIO device
> +
>  config GPIO_MVEBU
>         def_bool y
>         depends on PLAT_ORION || ARCH_MVEBU
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 1324c8f..b264426 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_MOCKUP)      += gpio-mockup.o
>  obj-$(CONFIG_GPIO_MPC5200)     += gpio-mpc5200.o
>  obj-$(CONFIG_GPIO_MPC8XXX)     += gpio-mpc8xxx.o
>  obj-$(CONFIG_GPIO_MSIC)                += gpio-msic.o
> +obj-$(CONFIG_GPIO_MSIC)                += gpio-mt7621.o
>  obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
>  obj-$(CONFIG_GPIO_MXC)         += gpio-mxc.o
>  obj-$(CONFIG_GPIO_MXS)         += gpio-mxs.o
> diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
> new file mode 100644
> index 0000000..281e621
> --- /dev/null
> +++ b/drivers/gpio/gpio-mt7621.c
> @@ -0,0 +1,320 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
> + * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
> + */
> +
> +#include <linux/err.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +
> +#define MTK_BANK_CNT   3
> +#define MTK_BANK_WIDTH 32
> +
> +#define GPIO_BANK_WIDE 0x04
> +#define GPIO_REG_CTRL  0x00
> +#define GPIO_REG_POL   0x10
> +#define GPIO_REG_DATA  0x20
> +#define GPIO_REG_DSET  0x30
> +#define GPIO_REG_DCLR  0x40
> +#define GPIO_REG_REDGE 0x50
> +#define GPIO_REG_FEDGE 0x60
> +#define GPIO_REG_HLVL  0x70
> +#define GPIO_REG_LLVL  0x80
> +#define GPIO_REG_STAT  0x90
> +#define GPIO_REG_EDGE  0xA0
> +
> +struct mtk_gc {
> +       struct gpio_chip chip;
> +       spinlock_t lock;
> +       int bank;
> +       u32 rising;
> +       u32 falling;
> +       u32 hlevel;
> +       u32 llevel;
> +};
> +
> +/**
> + * struct mtk_data - state container for
> + * data of the platform driver. It is 3
> + * separate gpio-chip each one with its
> + * own irq_chip.
> + * @dev: device instance
> + * @gpio_membase: memory base address
> + * @gpio_irq: irq number from the device tree
> + * @gc_map: array of the gpio chips
> + */
> +struct mtk_data {
> +       struct device *dev;
> +       void __iomem *gpio_membase;
> +       int gpio_irq;
> +       struct mtk_gc gc_map[MTK_BANK_CNT];
> +};
> +
> +static inline struct mtk_gc *
> +to_mediatek_gpio(struct gpio_chip *chip)
> +{
> +       return container_of(chip, struct mtk_gc, chip);
> +}
> +
> +static inline void
> +mtk_gpio_w32(struct mtk_gc *rg, u32 offset, u32 val)
> +{
> +       struct gpio_chip *gc = &rg->chip;
> +       struct mtk_data *gpio_data = gpiochip_get_data(gc);
> +
> +       offset = (rg->bank * GPIO_BANK_WIDE) + offset;
> +       gc->write_reg(gpio_data->gpio_membase + offset, val);
> +}
> +
> +static inline u32
> +mtk_gpio_r32(struct mtk_gc *rg, u32 offset)
> +{
> +       struct gpio_chip *gc = &rg->chip;
> +       struct mtk_data *gpio_data = gpiochip_get_data(gc);
> +
> +       offset = (rg->bank * GPIO_BANK_WIDE) + offset;
> +       return gc->read_reg(gpio_data->gpio_membase + offset);
> +}
> +
> +static irqreturn_t
> +mediatek_gpio_irq_handler(int irq, void *data)
> +{
> +       struct gpio_chip *gc = data;
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       irqreturn_t ret = IRQ_NONE;
> +       unsigned long pending;
> +       int bit;
> +
> +       pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
> +
> +       for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
> +               u32 map = irq_find_mapping(gc->irq.domain, bit);
> +
> +               generic_handle_irq(map);
> +               mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
> +               ret |= IRQ_HANDLED;
> +       }
> +
> +       return ret;
> +}
> +
> +static void
> +mediatek_gpio_irq_unmask(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       int pin = d->hwirq;
> +       unsigned long flags;
> +       u32 rise, fall, high, low;
> +
> +       spin_lock_irqsave(&rg->lock, flags);
> +       rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
> +       fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
> +       high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
> +       low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
> +       mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(pin) & rg->rising));
> +       mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(pin) & rg->falling));
> +       mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (BIT(pin) & rg->hlevel));
> +       mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (BIT(pin) & rg->llevel));
> +       spin_unlock_irqrestore(&rg->lock, flags);
> +}
> +
> +static void
> +mediatek_gpio_irq_mask(struct irq_data *d)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       int pin = d->hwirq;
> +       unsigned long flags;
> +       u32 rise, fall, high, low;
> +
> +       spin_lock_irqsave(&rg->lock, flags);
> +       rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
> +       fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
> +       high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
> +       low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
> +       mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
> +       mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
> +       mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
> +       mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
> +       spin_unlock_irqrestore(&rg->lock, flags);
> +}
> +
> +static int
> +mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
> +{
> +       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> +       struct mtk_gc *rg = to_mediatek_gpio(gc);
> +       int pin = d->hwirq;
> +       u32 mask = BIT(pin);
> +
> +       if (type == IRQ_TYPE_PROBE) {
> +               if ((rg->rising | rg->falling |
> +                    rg->hlevel | rg->llevel) & mask)
> +                       return 0;
> +
> +               type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
> +       }
> +
> +       rg->rising &= ~mask;
> +       rg->falling &= ~mask;
> +       rg->hlevel &= ~mask;
> +       rg->llevel &= ~mask;
> +
> +       switch (type & IRQ_TYPE_SENSE_MASK) {
> +       case IRQ_TYPE_EDGE_BOTH:
> +               rg->rising |= mask;
> +               rg->falling |= mask;
> +               break;
> +       case IRQ_TYPE_EDGE_RISING:
> +               rg->rising |= mask;
> +               break;
> +       case IRQ_TYPE_EDGE_FALLING:
> +               rg->falling |= mask;
> +               break;
> +       case IRQ_TYPE_LEVEL_HIGH:
> +               rg->hlevel |= mask;
> +               break;
> +       case IRQ_TYPE_LEVEL_LOW:
> +               rg->llevel |= mask;
> +               break;
> +       }
> +
> +       return 0;
> +}
> +
> +static struct irq_chip mediatek_gpio_irq_chip = {
> +       .irq_unmask             = mediatek_gpio_irq_unmask,
> +       .irq_mask               = mediatek_gpio_irq_mask,
> +       .irq_mask_ack           = mediatek_gpio_irq_mask,
> +       .irq_set_type           = mediatek_gpio_irq_type,
> +};
> +
> +static inline const char * const mediatek_gpio_bank_name(int bank)
> +{
> +       static const char * const bank_names[] = {
> +               "mt7621-bank0", "mt7621-bank1", "mt7621-bank2",
> +       };
> +
> +       return bank_names[bank];
> +}
> +
> +static int
> +mediatek_gpio_bank_probe(struct platform_device *pdev,
> +                        struct device_node *node, int bank)
> +{
> +       struct mtk_data *gpio = dev_get_drvdata(&pdev->dev);
> +       struct mtk_gc *rg;
> +       void __iomem *dat, *set, *ctrl, *diro;
> +       int ret;
> +
> +       rg = &gpio->gc_map[bank];
> +       memset(rg, 0, sizeof(*rg));
> +
> +       spin_lock_init(&rg->lock);
> +       rg->chip.of_node = node;
> +       rg->bank = bank;
> +       rg->chip.label = mediatek_gpio_bank_name(rg->bank);
> +
> +       dat = gpio->gpio_membase + GPIO_REG_DATA + (rg->bank * GPIO_BANK_WIDE);
> +       set = gpio->gpio_membase + GPIO_REG_DSET + (rg->bank * GPIO_BANK_WIDE);
> +       ctrl = gpio->gpio_membase + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_WIDE);
> +       diro = gpio->gpio_membase + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_WIDE);
> +
> +       ret = bgpio_init(&rg->chip, &pdev->dev, 4,
> +                        dat, set, ctrl, diro, NULL, 0);
> +       if (ret) {
> +               dev_err(&pdev->dev, "bgpio_init() failed\n");
> +               return ret;
> +       }
> +
> +       ret = devm_gpiochip_add_data(&pdev->dev, &rg->chip, gpio);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Could not register gpio %d, ret=%d\n",
> +                       rg->chip.ngpio, ret);
> +               return ret;
> +       }
> +
> +       if (gpio->gpio_irq) {
> +               /*
> +                * Manually request the irq here instead of passing
> +                * a flow-handler to gpiochip_set_chained_irqchip,
> +                * because the irq is shared.
> +                */
> +               ret = devm_request_irq(&pdev->dev, gpio->gpio_irq,
> +                                      mediatek_gpio_irq_handler, IRQF_SHARED,
> +                                      rg->chip.label, &rg->chip);
> +
> +               if (ret) {
> +                       dev_err(&pdev->dev, "Error requesting IRQ %d: %d\n",
> +                               gpio->gpio_irq, ret);
> +                       return ret;
> +               }
> +
> +               mediatek_gpio_irq_chip.name = rg->chip.label;
> +               ret = gpiochip_irqchip_add(&rg->chip, &mediatek_gpio_irq_chip,
> +                                          0, handle_simple_irq, IRQ_TYPE_NONE);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n");
> +                       return ret;
> +               }
> +
> +               gpiochip_set_chained_irqchip(&rg->chip, &mediatek_gpio_irq_chip,
> +                                            gpio->gpio_irq, NULL);
> +       }
> +
> +       /* set polarity to low for all gpios */
> +       mtk_gpio_w32(rg, GPIO_REG_POL, 0);
> +
> +       dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
> +
> +       return 0;
> +}
> +
> +static int
> +mediatek_gpio_probe(struct platform_device *pdev)
> +{
> +       struct device_node *np = pdev->dev.of_node;
> +       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       struct mtk_data *gpio_data;
> +       int i;
> +
> +       gpio_data = devm_kzalloc(&pdev->dev, sizeof(*gpio_data), GFP_KERNEL);
> +       if (!gpio_data)
> +               return -ENOMEM;
> +
> +       gpio_data->gpio_membase = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(gpio_data->gpio_membase))
> +               return PTR_ERR(gpio_data->gpio_membase);
> +
> +       gpio_data->gpio_irq = irq_of_parse_and_map(np, 0);
> +       gpio_data->dev = &pdev->dev;
> +       platform_set_drvdata(pdev, gpio_data);
> +
> +       for (i = 0; i < MTK_BANK_CNT; i++)
> +               mediatek_gpio_bank_probe(pdev, np, i);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id mediatek_gpio_match[] = {
> +       { .compatible = "mediatek,mt7621-gpio" },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
> +
> +static struct platform_driver mediatek_gpio_driver = {
> +       .probe = mediatek_gpio_probe,
> +       .driver = {
> +               .name = "mt7621_gpio",
> +               .of_match_table = mediatek_gpio_match,
> +       },
> +};
> +
> +builtin_platform_driver(mediatek_gpio_driver);
> --
> 2.7.4
>
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2018-06-30  6:12 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-29 12:43 [PATCH v2 0/2] gpio: mediatek: driver for gpio chip in MT7621 SoC Sergio Paracuellos
2018-06-29 12:43 ` Sergio Paracuellos
2018-06-29 12:43 ` [PATCH v2 1/2] gpio: mediatek: add driver for MT7621 Sergio Paracuellos
2018-06-29 12:43   ` Sergio Paracuellos
2018-06-29 13:31   ` Dan Carpenter
2018-06-29 13:31     ` Dan Carpenter
2018-06-29 13:34     ` Dan Carpenter
2018-06-29 13:34       ` Dan Carpenter
2018-06-29 13:51     ` Sergio Paracuellos
2018-06-29 13:51       ` Sergio Paracuellos
2018-06-29 16:43   ` kbuild test robot
2018-06-29 16:52     ` Sergio Paracuellos
2018-06-29 16:52       ` Sergio Paracuellos
2018-06-29 19:30       ` Sergio Paracuellos
2018-06-29 19:30         ` Sergio Paracuellos
2018-06-30  6:12   ` Sergio Paracuellos
2018-06-30  6:12     ` Sergio Paracuellos
2018-06-29 12:43 ` [PATCH v2 2/2] dt-bindings: document gpio-mt7621 bindings Sergio Paracuellos
2018-06-29 12:43   ` Sergio Paracuellos

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.