From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Rob Herring <robh+dt@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Linus Walleij <linus.walleij@linaro.org>,
Dmitry Torokhov <dmitry.torokhov@gmail.com>,
Jacek Anaszewski <jacek.anaszewski@gmail.com>,
Pavel Machek <pavel@ucw.cz>, Lee Jones <lee.jones@linaro.org>,
Sebastian Reichel <sre@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-input@vger.kernel.org,
linux-leds@vger.kernel.org, linux-pm@vger.kernel.org,
Bartosz Golaszewski <bgolaszewski@baylibre.com>
Subject: [PATCH] gpio fixup domain
Date: Tue, 29 Jan 2019 14:35:33 +0100 [thread overview]
Message-ID: <20190129133545.1931-3-brgl@bgdev.pl> (raw)
In-Reply-To: <20190129133545.1931-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
arch/arm/boot/dts/am335x-bone-common.dtsi | 4 +
drivers/gpio/gpio-max77650.c | 138 +++++++++++++++++++++-
2 files changed, 136 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 62f7f2ac191c..320b4c21fdf3 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -276,6 +276,10 @@
gpio-controller;
#gpio-cells = <2>;
+
+ interrupt-parent = <&pmic>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "GPI";
};
leds {
diff --git a/drivers/gpio/gpio-max77650.c b/drivers/gpio/gpio-max77650.c
index 3f03f4e8956c..03a5a2ed07f8 100644
--- a/drivers/gpio/gpio-max77650.c
+++ b/drivers/gpio/gpio-max77650.c
@@ -9,6 +9,7 @@
#include <linux/i2c.h>
#include <linux/mfd/max77650.h>
#include <linux/module.h>
+#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -34,7 +35,8 @@
struct max77650_gpio_chip {
struct regmap *map;
struct gpio_chip gc;
- int irq;
+ struct fwnode_handle *fwnode;
+ struct irq_domain *domain;
};
static int max77650_gpio_direction_input(struct gpio_chip *gc,
@@ -130,20 +132,114 @@ static int max77650_gpio_set_config(struct gpio_chip *gc,
}
}
+static struct irq_chip max77650_gpio_irq_chip = {
+ .name = "max77650-gpio",
+ .irq_ack = irq_chip_ack_parent,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_set_type = irq_chip_set_type_parent,
+};
+
+static int max77650_gpio_irq_domain_activate(struct irq_domain *domain,
+ struct irq_data *data,
+ bool reserve)
+{
+ struct max77650_gpio_chip *chip = domain->host_data;
+
+ return gpiochip_lock_as_irq(&chip->gc, data->hwirq);
+}
+
+static void max77650_gpio_irq_domain_deactivate(struct irq_domain *domain,
+ struct irq_data *data)
+{
+ struct max77650_gpio_chip *chip = domain->host_data;
+
+ return gpiochip_unlock_as_irq(&chip->gc, data->hwirq);
+}
+
+static int max77650_gpio_domain_translate(struct irq_domain *domain,
+ struct irq_fwspec *fwspec,
+ unsigned long *hwirq,
+ unsigned int *type)
+{
+ struct max77650_gpio_chip *chip = domain->host_data;
+
+ if (fwspec->param_count != 2 || fwspec->param[0] >= chip->gc.ngpio)
+ return -EINVAL;
+
+ *hwirq = fwspec->param[0];
+ *type = fwspec->param[1];
+
+ return 0;
+}
+
+static int max77650_gpio_domain_alloc(struct irq_domain *domain,
+ unsigned int virq,
+ unsigned int nr_irqs, void *data)
+{
+ struct max77650_gpio_chip *chip = domain->host_data;
+ struct irq_fwspec *fwspec = data;
+ struct irq_fwspec parent_fwspec;
+ irq_hw_number_t hwirq;
+ unsigned int type;
+ int ret;
+
+ if (nr_irqs != 1)
+ return -EINVAL;
+
+ ret = max77650_gpio_domain_translate(domain, fwspec, &hwirq, &type);
+ if (ret)
+ return ret;
+
+ irq_domain_set_info(domain, virq, hwirq,
+ &max77650_gpio_irq_chip, chip,
+ handle_level_irq, NULL, NULL);
+
+ parent_fwspec.fwnode = domain->parent->fwnode;
+ parent_fwspec.param_count = 4;
+ parent_fwspec.param[0] = 0;
+ parent_fwspec.param[1] = hwirq;
+ parent_fwspec.param[2] = 0;
+ parent_fwspec.param[3] = fwspec->param[1];
+
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
+ &parent_fwspec);
+
+ return 0;
+}
+
+static const struct irq_domain_ops max77650_gpio_irq_domain_ops = {
+ .activate = max77650_gpio_irq_domain_activate,
+ .deactivate = max77650_gpio_irq_domain_deactivate,
+ .alloc = max77650_gpio_domain_alloc,
+ .free = irq_domain_free_irqs_common,
+ .translate = max77650_gpio_domain_translate,
+};
+
static int max77650_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
{
struct max77650_gpio_chip *chip = gpiochip_get_data(gc);
+ struct irq_fwspec fwspec;
+
+ fwspec.fwnode = chip->fwnode;
+ fwspec.param_count = 2;
+ fwspec.param[0] = 0;
+ fwspec.param[1] = IRQ_TYPE_LEVEL_LOW;
- return chip->irq;
+ return irq_create_fwspec_mapping(&fwspec);
}
static int max77650_gpio_probe(struct platform_device *pdev)
{
+ struct device_node *of_node, *parent_node;
+ struct irq_domain *parent_domain;
struct max77650_gpio_chip *chip;
struct device *dev, *parent;
struct i2c_client *i2c;
+ int rv;
dev = &pdev->dev;
+ of_node = dev->of_node;
parent = dev->parent;
i2c = to_i2c_client(parent);
@@ -151,13 +247,29 @@ static int max77650_gpio_probe(struct platform_device *pdev)
if (!chip)
return -ENOMEM;
+ chip->fwnode = dev->fwnode;
+ platform_set_drvdata(pdev, chip);
+
chip->map = dev_get_regmap(parent, NULL);
if (!chip->map)
return -ENODEV;
- chip->irq = platform_get_irq_byname(pdev, "GPI");
- if (chip->irq < 0)
- return chip->irq;
+ parent_node = of_irq_find_parent(of_node);
+ if (!parent_node)
+ return -ENXIO;
+
+ parent_domain = irq_find_host(parent_node);
+ of_node_put(parent_node);
+ if (!parent_domain)
+ return -ENXIO;
+
+ chip->fwnode = of_node_to_fwnode(of_node);
+ chip->domain = irq_domain_create_hierarchy(parent_domain, 0, 1,
+ chip->fwnode,
+ &max77650_gpio_irq_domain_ops,
+ chip);
+ if (!chip->domain)
+ return -ENODEV;
chip->gc.base = -1;
chip->gc.ngpio = 1;
@@ -174,7 +286,20 @@ static int max77650_gpio_probe(struct platform_device *pdev)
chip->gc.set_config = max77650_gpio_set_config;
chip->gc.to_irq = max77650_gpio_to_irq;
- return devm_gpiochip_add_data(dev, &chip->gc, chip);
+ rv = devm_gpiochip_add_data(dev, &chip->gc, chip);
+ if (rv)
+ irq_domain_remove(chip->domain);
+
+ return rv;
+}
+
+static int max77650_gpio_remove(struct platform_device *pdev)
+{
+ struct max77650_gpio_chip *chip = platform_get_drvdata(pdev);
+
+ irq_domain_remove(chip->domain);
+
+ return 0;
}
static struct platform_driver max77650_gpio_driver = {
@@ -182,6 +307,7 @@ static struct platform_driver max77650_gpio_driver = {
.name = "max77650-gpio",
},
.probe = max77650_gpio_probe,
+ .remove = max77650_gpio_remove,
};
module_platform_driver(max77650_gpio_driver);
--
2.20.1
next prev parent reply other threads:[~2019-01-29 13:35 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-29 13:35 [PATCH v2 00/13] mfd: add support for max77650 PMIC Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 01/13] dt-bindings: mfd: add DT bindings for max77650 Bartosz Golaszewski
2019-01-29 13:35 ` Bartosz Golaszewski [this message]
2019-01-29 13:39 ` [PATCH] gpio fixup domain Bartosz Golaszewski
2019-01-30 9:42 ` Linus Walleij
2019-01-29 13:35 ` [PATCH v2 02/13] dt-bindings: regulator: add DT bindings for max77650 Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 03/13] dt-bindings: power: supply: " Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 04/13] dt-bindings: gpio: " Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 05/13] dt-bindings: leds: " Bartosz Golaszewski
2019-01-30 19:58 ` Jacek Anaszewski
2019-01-29 13:35 ` [PATCH v2 06/13] dt-bindings: input: " Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 07/13] mfd: max77650: new core mfd driver Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 08/13] regulator: max77650: add regulator support Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 09/13] power: supply: max77650: add support for battery charger Bartosz Golaszewski
2019-01-29 13:35 ` [PATCH v2 10/13] gpio: max77650: add GPIO support Bartosz Golaszewski
2019-01-30 9:40 ` Linus Walleij
2019-01-30 9:40 ` Linus Walleij
2019-01-29 13:35 ` [PATCH v2 11/13] leds: max77650: add LEDs support Bartosz Golaszewski
2019-01-30 19:59 ` Jacek Anaszewski
2019-01-29 13:35 ` [PATCH v2 12/13] input: max77650: add onkey support Bartosz Golaszewski
2019-01-30 18:53 ` Dmitry Torokhov
2019-01-31 8:15 ` Bartosz Golaszewski
2019-01-31 12:28 ` Mark Brown
2019-01-31 19:18 ` Dmitry Torokhov
2019-02-01 9:11 ` Lee Jones
2019-01-29 13:35 ` [PATCH v2 13/13] MAINTAINERS: add an entry for max77650 mfd driver Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190129133545.1931-3-brgl@bgdev.pl \
--to=brgl@bgdev.pl \
--cc=bgolaszewski@baylibre.com \
--cc=broonie@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=jacek.anaszewski@gmail.com \
--cc=lee.jones@linaro.org \
--cc=lgirdwood@gmail.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=pavel@ucw.cz \
--cc=robh+dt@kernel.org \
--cc=sre@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.