Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1497246 > unrolled thread
| Started by | Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|---|---|
| First post | 2016-10-07 17:30 +0200 |
| Last post | 2016-10-10 22:30 +0200 |
| Articles | 6 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH 0/4] Introduce Juniper PTXPMB Extended driver Pantelis Antoniou <pantelis.antoniou@konsulko.com> - 2016-10-07 17:30 +0200
[PATCH 4/4] gpio: ptxpmb-ext-cpld: Document bindings of PTXPMB extended CPLD Pantelis Antoniou <pantelis.antoniou@konsulko.com> - 2016-10-07 17:30 +0200
Re: [PATCH 4/4] gpio: ptxpmb-ext-cpld: Document bindings of PTXPMB extended CPLD Rob Herring <robh@kernel.org> - 2016-10-10 22:20 +0200
[PATCH 3/4] gpio: ptxpmb-ext-cpld: Add driver for Juniper's PTXPMB extended CPLD Pantelis Antoniou <pantelis.antoniou@konsulko.com> - 2016-10-07 17:40 +0200
[PATCH 2/4] mfd: ptxpmb-ext-cpld: Add documentation for PTXPMB extended CPLD Pantelis Antoniou <pantelis.antoniou@konsulko.com> - 2016-10-07 17:40 +0200
Re: [PATCH 2/4] mfd: ptxpmb-ext-cpld: Add documentation for PTXPMB extended CPLD Rob Herring <robh@kernel.org> - 2016-10-10 22:30 +0200
| From | Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|---|---|
| Date | 2016-10-07 17:30 +0200 |
| Subject | [PATCH 0/4] Introduce Juniper PTXPMB Extended driver |
| Message-ID | <spFfX-2lv-19@gated-at.bofh.it> |
Add Juniper's PTXPMB Extended FPGA driver. Those FPGAs are present in Juniper's PTX series of routers. The MFD driver provices a gpio device. There are full device tree binding documents for the master mfd driver and for the slave driver. This patchset is against mainline as of today: v4.8-9431-g3477d16 and is dependent on the "Juniper prerequisites" and "Juniper infrastructure" patchsets sent earlier. Georgi Vlaev (2): mfd: ptxpmb-ext-cpld: Add documentation for PTXPMB extended CPLD gpio: ptxpmb-ext-cpld: Document bindings of PTXPMB extended CPLD Guenter Roeck (2): mfd: ptxpmb: Add separate driver for extended CPLD gpio: ptxpmb-ext-cpld: Add driver for Juniper's PTXPMB extended CPLD .../bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt | 36 ++ .../bindings/mfd/jnx-ptxpmb-ext-cpld.txt | 35 ++ drivers/gpio/Kconfig | 11 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-ptxpmb-ext-cpld.c | 430 +++++++++++++++++++++ drivers/mfd/Kconfig | 13 + drivers/mfd/Makefile | 1 + drivers/mfd/ptxpmb-ext-cpld-core.c | 221 +++++++++++ include/linux/mfd/ptxpmb_ext_cpld.h | 42 ++ 9 files changed, 790 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt create mode 100644 drivers/gpio/gpio-ptxpmb-ext-cpld.c create mode 100644 drivers/mfd/ptxpmb-ext-cpld-core.c create mode 100644 include/linux/mfd/ptxpmb_ext_cpld.h -- 1.9.1
[toc] | [next] | [standalone]
| From | Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|---|---|
| Date | 2016-10-07 17:30 +0200 |
| Subject | [PATCH 4/4] gpio: ptxpmb-ext-cpld: Document bindings of PTXPMB extended CPLD |
| Message-ID | <spFfZ-2lv-89@gated-at.bofh.it> |
| In reply to | #1497246 |
From: Georgi Vlaev <gvlaev@juniper.net>
Add device tree bindings document for the GPIO driver of
Juniper's PTXPMB extended CPLD.
Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
.../bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt | 36 ++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt
diff --git a/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt
new file mode 100644
index 0000000..87f01b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt
@@ -0,0 +1,36 @@
+Juniper PTXPMB extended CPLD GPIO block
+
+Required properties:
+
+- compatible:
+ Must be "jnx,gpio-ptxpmb-ext-cpld"
+
+- #gpio-cells:
+ Should be <2>. The first cell is the pin number (within the controller's
+ pin space), and the second is used for the following flags:
+ bit[0]: direction (0 = out, 1 = in)
+ bit[1]: init high
+ bit[2]: active low
+
+- gpio-controller:
+ Specifies that the node is a GPIO controller.
+
+- interrupt-controller:
+ Specifies that the node is an interrupt controller.
+
+Optional properties:
+
+- reg:
+ Address and length of the register set for the device. Usually supplied
+ by the parent MFD device.
+
+
+Example:
+
+gpio_ext_cpld: cpld-ext-gpio {
+ compatible = "jnx,gpio-ptxpmb-ext-cpld";
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+};
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2016-10-10 22:20 +0200 |
| Subject | Re: [PATCH 4/4] gpio: ptxpmb-ext-cpld: Document bindings of PTXPMB extended CPLD |
| Message-ID | <sqPdf-5GQ-1@gated-at.bofh.it> |
| In reply to | #1497251 |
On Fri, Oct 07, 2016 at 06:19:34PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
>
> Add device tree bindings document for the GPIO driver of
> Juniper's PTXPMB extended CPLD.
>
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
> .../bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt | 36 ++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt
>
> diff --git a/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt
> new file mode 100644
> index 0000000..87f01b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/jnx,gpio-ptxpmb-ext-cpld.txt
> @@ -0,0 +1,36 @@
> +Juniper PTXPMB extended CPLD GPIO block
> +
> +Required properties:
> +
> +- compatible:
> + Must be "jnx,gpio-ptxpmb-ext-cpld"
Generally, '-gpio' would be last.
> +
> +- #gpio-cells:
> + Should be <2>. The first cell is the pin number (within the controller's
> + pin space), and the second is used for the following flags:
> + bit[0]: direction (0 = out, 1 = in)
> + bit[1]: init high
> + bit[2]: active low
Same comment as all the other gpio bindings...
> +
> +- gpio-controller:
> + Specifies that the node is a GPIO controller.
> +
> +- interrupt-controller:
> + Specifies that the node is an interrupt controller.
> +
> +Optional properties:
> +
> +- reg:
> + Address and length of the register set for the device. Usually supplied
> + by the parent MFD device.
Make it required.
> +
> +
> +Example:
> +
> +gpio_ext_cpld: cpld-ext-gpio {
> + compatible = "jnx,gpio-ptxpmb-ext-cpld";
> + #gpio-cells = <2>;
> + #interrupt-cells = <2>;
> + gpio-controller;
> + interrupt-controller;
> +};
> --
> 1.9.1
>
[toc] | [prev] | [next] | [standalone]
| From | Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|---|---|
| Date | 2016-10-07 17:40 +0200 |
| Subject | [PATCH 3/4] gpio: ptxpmb-ext-cpld: Add driver for Juniper's PTXPMB extended CPLD |
| Message-ID | <spFpD-2pN-13@gated-at.bofh.it> |
| In reply to | #1497246 |
From: Guenter Roeck <groeck@juniper.net>
This IP block is present in the PTXPMB extended CPLD present on
Junipers PTX series of routers and provides SIB connector status pins
as GPIO pins for use with other drivers.
Signed-off-by: Guenter Roeck <groeck@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
drivers/gpio/Kconfig | 11 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-ptxpmb-ext-cpld.c | 430 ++++++++++++++++++++++++++++++++++++
3 files changed, 442 insertions(+)
create mode 100644 drivers/gpio/gpio-ptxpmb-ext-cpld.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c25dbe9..281029b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -371,6 +371,17 @@ config GPIO_PTXPMB_CPLD
This driver can also be built as a module. If so, the module
will be called gpio-ptxpmb-cpld.
+config GPIO_PTXPMB_EXT_CPLD
+ tristate "PTXPMB Extended CPLD GPIO"
+ depends on MFD_JUNIPER_EXT_CPLD
+ default y if MFD_JUNIPER_EXT_CPLD
+ help
+ This driver exports various bits on the Juniper Control Board
+ Extended CPLD as GPIO pins to userspace.
+
+ This driver can also be built as a module. If so, the module
+ will be called gpio-ptxpmb-ext-cpld.
+
config GPIO_PXA
bool "PXA GPIO support"
depends on ARCH_PXA || ARCH_MMP
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 6691d8c..ec890c7 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_PTXPMB_CPLD) += gpio-ptxpmb-cpld.o
+obj-$(CONFIG_GPIO_PTXPMB_EXT_CPLD) += gpio-ptxpmb-ext-cpld.o
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
diff --git a/drivers/gpio/gpio-ptxpmb-ext-cpld.c b/drivers/gpio/gpio-ptxpmb-ext-cpld.c
new file mode 100644
index 0000000..0152f0b
--- /dev/null
+++ b/drivers/gpio/gpio-ptxpmb-ext-cpld.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2012 Juniper networks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/gpio.h>
+#include <linux/errno.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+
+#include <linux/mfd/ptxpmb_ext_cpld.h>
+
+#define EXT_CPLD_NGPIO 32 /* 0..15: SIB presence bits */
+ /* 16..31: SIB interrupt status */
+
+/**
+ * struct ext_cpld_gpio - GPIO private data structure.
+ * @base: PCI base address of Memory mapped I/O register.
+ * @dev: Pointer to device structure.
+ * @gpio: Data for GPIO infrastructure.
+ */
+struct ext_cpld_gpio {
+ void __iomem *base;
+ struct device *dev;
+ struct gpio_chip gpio;
+ struct mutex irq_lock;
+ struct mutex work_lock;
+ struct irq_domain *domain;
+ int irq;
+ u8 irq_type[EXT_CPLD_NGPIO];
+ u16 sib_presence_cache;
+ u16 sib_presence_irq_enabled;
+ u16 sib_irq_status_cache;
+ u16 sib_irq_enabled;
+ struct delayed_work work;
+};
+
+static int ext_cpld_gpio_get(struct gpio_chip *gpio, unsigned int nr)
+{
+ struct ext_cpld_gpio *chip = container_of(gpio,
+ struct ext_cpld_gpio, gpio);
+ struct pmb_boot_cpld_ext *cpld = chip->base;
+ u16 *addr = nr < 16 ? &cpld->sib_presence : &cpld->sib_irq_status;
+ u16 val;
+
+ val = ioread16(addr);
+ if (nr < 16)
+ chip->sib_presence_cache = val;
+ else
+ chip->sib_irq_status_cache = val;
+
+ return !!(val & (1 << (nr & 15)));
+}
+
+static int ext_cpld_gpio_direction_input(struct gpio_chip *gpio,
+ unsigned int nr)
+{
+ /* all pins are input pins */
+ return 0;
+}
+
+static int ext_cpld_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset)
+{
+ struct ext_cpld_gpio *chip = container_of(gpio,
+ struct ext_cpld_gpio, gpio);
+
+ return irq_create_mapping(chip->domain, offset);
+}
+
+static void ext_cpld_irq_mask(struct irq_data *data)
+{
+ struct ext_cpld_gpio *chip = irq_data_get_irq_chip_data(data);
+ struct pmb_boot_cpld_ext *cpld = chip->base;
+ u16 *addr = data->hwirq < 16 ?
+ &cpld->sib_presence_irq_en : &cpld->sib_irq_en;
+ u16 mask = 1 << (data->hwirq & 0x0f);
+
+ if (chip->irq)
+ iowrite16(ioread16(addr) & ~mask, addr);
+
+ if (data->hwirq < 16)
+ chip->sib_presence_irq_enabled &= ~mask;
+ else
+ chip->sib_irq_enabled &= ~mask;
+}
+
+static void ext_cpld_irq_unmask(struct irq_data *data)
+{
+ struct ext_cpld_gpio *chip = irq_data_get_irq_chip_data(data);
+ struct pmb_boot_cpld_ext *cpld = chip->base;
+ u16 *addr = data->hwirq < 16 ?
+ &cpld->sib_presence_irq_en : &cpld->sib_irq_en;
+ u16 mask = 1 << (data->hwirq & 0x0f);
+
+ if (chip->irq)
+ iowrite16(ioread16(addr) | mask, addr);
+
+ if (data->hwirq < 16)
+ chip->sib_presence_irq_enabled |= mask;
+ else
+ chip->sib_irq_enabled |= mask;
+}
+
+static int ext_cpld_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ struct ext_cpld_gpio *chip = irq_data_get_irq_chip_data(data);
+
+ chip->irq_type[data->hwirq] = type & 0x0f;
+
+ return 0;
+}
+
+static void ext_cpld_irq_bus_lock(struct irq_data *data)
+{
+ struct ext_cpld_gpio *chip = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&chip->irq_lock);
+}
+
+static void ext_cpld_irq_bus_unlock(struct irq_data *data)
+{
+ struct ext_cpld_gpio *chip = irq_data_get_irq_chip_data(data);
+
+ /* Synchronize interrupts to chip */
+
+ mutex_unlock(&chip->irq_lock);
+}
+
+static struct irq_chip ext_cpld_irq_chip = {
+ .name = "gpio-ext-cpld",
+ .irq_mask = ext_cpld_irq_mask,
+ .irq_unmask = ext_cpld_irq_unmask,
+ .irq_set_type = ext_cpld_irq_set_type,
+ .irq_bus_lock = ext_cpld_irq_bus_lock,
+ .irq_bus_sync_unlock = ext_cpld_irq_bus_unlock,
+};
+
+static int ext_cpld_gpio_irq_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ pr_info("ext_cpld_gpio_irq_map irq %d hwirq %d\n", irq, (int)hwirq);
+
+ irq_set_chip_data(irq, domain->host_data);
+ irq_set_chip(irq, &ext_cpld_irq_chip);
+ irq_set_nested_thread(irq, true);
+
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops ext_cpld_gpio_irq_domain_ops = {
+ .map = ext_cpld_gpio_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static void __ext_cpld_gpio_irq_work(struct ext_cpld_gpio *chip,
+ u16 *datap, u16 *cachep,
+ unsigned long enabled, int base)
+{
+ u16 data, cache;
+ unsigned int pos;
+
+ cache = *cachep;
+ data = ioread16(datap);
+
+ for_each_set_bit(pos, &enabled, 16) {
+ u16 mask = 1 << pos;
+ u16 bit;
+ int type;
+
+ bit = data & mask;
+ if (bit == (cache & mask))
+ continue;
+
+ type = chip->irq_type[base + pos];
+ /*
+ * check irq->type for match. Only handle edge triggered
+ * interrupts; anything else doesn't make sense here.
+ * TBD: While this is correct for insertion status interrupts,
+ * we may need to support level triggered interrupts to handle
+ * the irq status register.
+ */
+ if (((type & IRQ_TYPE_EDGE_RISING) && bit) ||
+ ((type & IRQ_TYPE_EDGE_FALLING) && !bit)) {
+ int virq = irq_find_mapping(chip->domain, base + pos);
+
+ handle_nested_irq(virq);
+ }
+ }
+ *cachep = data;
+}
+
+static void ext_cpld_gpio_irq_work(struct ext_cpld_gpio *chip)
+{
+ struct pmb_boot_cpld_ext *cpld = chip->base;
+
+ mutex_lock(&chip->work_lock);
+
+ __ext_cpld_gpio_irq_work(chip, &cpld->sib_presence,
+ &chip->sib_presence_cache,
+ chip->sib_presence_irq_enabled,
+ 0);
+
+ __ext_cpld_gpio_irq_work(chip, &cpld->sib_irq_status,
+ &chip->sib_irq_status_cache,
+ chip->sib_irq_enabled,
+ 16);
+
+ mutex_unlock(&chip->work_lock);
+}
+
+static irqreturn_t ext_cpld_gpio_irq_handler(int irq, void *data)
+{
+ struct ext_cpld_gpio *chip = data;
+ struct pmb_boot_cpld_ext *cpld = chip->base;
+
+ pr_info("ext_cpld got interrupt %d 0x%x:0x%x\n", irq,
+ ioread16(&cpld->sib_presence),
+ ioread16(&cpld->sib_irq_status));
+
+ ext_cpld_gpio_irq_work(chip);
+
+ return IRQ_HANDLED;
+}
+
+static void ext_cpld_gpio_worker(struct work_struct *work)
+{
+ struct ext_cpld_gpio *chip = container_of(work, struct ext_cpld_gpio,
+ work.work);
+
+ ext_cpld_gpio_irq_work(chip);
+ schedule_delayed_work(&chip->work, 1);
+}
+
+static int ext_cpld_gpio_irq_setup(struct device *dev,
+ struct ext_cpld_gpio *chip)
+{
+ int ret;
+
+ chip->domain = irq_domain_add_linear(dev->of_node, EXT_CPLD_NGPIO,
+ &ext_cpld_gpio_irq_domain_ops,
+ chip);
+ if (!chip->domain)
+ return -ENOMEM;
+
+ INIT_DELAYED_WORK(&chip->work, ext_cpld_gpio_worker);
+
+ if (chip->irq) {
+ dev_info(dev, "Setting up interrupt %d\n", chip->irq);
+ ret = devm_request_threaded_irq(dev, chip->irq, NULL,
+ ext_cpld_gpio_irq_handler,
+ IRQF_ONESHOT,
+ dev_name(dev), chip);
+ if (ret)
+ goto out_remove_domain;
+ } else {
+ schedule_delayed_work(&chip->work, 1);
+ }
+
+ chip->gpio.to_irq = ext_cpld_gpio_to_irq;
+
+ return 0;
+
+out_remove_domain:
+ irq_domain_remove(chip->domain);
+ return ret;
+}
+
+static void ext_cpld_gpio_irq_teardown(struct device *dev,
+ struct ext_cpld_gpio *chip)
+{
+ struct pmb_boot_cpld_ext *cpld = chip->base;
+ int i;
+
+ if (chip->irq) {
+ iowrite16(0, &cpld->sib_presence_irq_en);
+ iowrite16(0, &cpld->sib_irq_en);
+ }
+
+ for (i = 0; i < EXT_CPLD_NGPIO; i++) {
+ int irq = irq_find_mapping(chip->domain, i);
+
+ if (irq > 0)
+ irq_dispose_mapping(irq);
+ }
+ irq_domain_remove(chip->domain);
+}
+
+static int ext_cpld_gpio_of_xlate(struct gpio_chip *gpio,
+ const struct of_phandle_args *gpiospec,
+ u32 *flags)
+{
+ if (WARN_ON(gpio->of_gpio_n_cells < 2))
+ return -EINVAL;
+
+ if (WARN_ON(gpiospec->args_count < gpio->of_gpio_n_cells))
+ return -EINVAL;
+
+ if (gpiospec->args[0] > gpio->ngpio)
+ return -EINVAL;
+
+ if (flags)
+ *flags = gpiospec->args[1] >> 16;
+
+ return gpiospec->args[0];
+}
+
+static void ext_cpld_gpio_setup(struct ext_cpld_gpio *chip)
+{
+ struct gpio_chip *gpio = &chip->gpio;
+
+ gpio->label = dev_name(chip->dev);
+ gpio->owner = THIS_MODULE;
+ gpio->get = ext_cpld_gpio_get;
+ gpio->direction_input = ext_cpld_gpio_direction_input;
+ gpio->dbg_show = NULL;
+ gpio->base = -1;
+ gpio->ngpio = EXT_CPLD_NGPIO;
+ gpio->can_sleep = 0;
+ gpio->of_node = chip->dev->of_node;
+ gpio->of_xlate = ext_cpld_gpio_of_xlate;
+ gpio->of_gpio_n_cells = 2;
+}
+
+static int ext_cpld_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pmb_boot_cpld_ext *cpld;
+ struct ext_cpld_gpio *chip;
+ struct resource *res;
+ int ret;
+
+ chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->dev = dev;
+ platform_set_drvdata(pdev, chip);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ chip->base = devm_ioremap(dev, res->start, resource_size(res));
+ if (!chip->base)
+ return -ENOMEM;
+
+ cpld = chip->base;
+ chip->sib_presence_cache = ioread16(&cpld->sib_presence);
+
+ mutex_init(&chip->irq_lock);
+ mutex_init(&chip->work_lock);
+ ext_cpld_gpio_setup(chip);
+
+ ret = ext_cpld_gpio_irq_setup(dev, chip);
+ if (ret < 0)
+ return ret;
+
+ ret = gpiochip_add(&chip->gpio);
+ if (ret) {
+ dev_err(dev, "Extended CPLD gpio: Failed to register GPIO\n");
+ goto teardown;
+ }
+ return 0;
+
+teardown:
+ if (chip->domain)
+ ext_cpld_gpio_irq_teardown(dev, chip);
+ return ret;
+}
+
+static int ext_cpld_gpio_remove(struct platform_device *pdev)
+{
+ struct ext_cpld_gpio *chip = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&chip->work);
+ if (chip->domain)
+ ext_cpld_gpio_irq_teardown(&pdev->dev, chip);
+
+ gpiochip_remove(&chip->gpio);
+
+ return 0;
+}
+
+static const struct of_device_id ext_cpld_gpio_ids[] = {
+ { .compatible = "jnx,gpio-ptxpmb-ext-cpld", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ext_cpld_gpio_ids);
+
+static struct platform_driver ext_cpld_gpio_driver = {
+ .driver = {
+ .name = "gpio-ptxpmb-ext-cpld",
+ .owner = THIS_MODULE,
+ .of_match_table = ext_cpld_gpio_ids,
+ },
+ .probe = ext_cpld_gpio_probe,
+ .remove = ext_cpld_gpio_remove,
+};
+
+static int __init ext_cpld_gpio_init(void)
+{
+ return platform_driver_register(&ext_cpld_gpio_driver);
+}
+module_init(ext_cpld_gpio_init);
+
+static void __exit ext_cpld_gpio_exit(void)
+{
+ platform_driver_unregister(&ext_cpld_gpio_driver);
+}
+module_exit(ext_cpld_gpio_exit);
+
+MODULE_DESCRIPTION("Extended CPLD FPGA GPIO Driver");
+MODULE_LICENSE("GPL");
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Pantelis Antoniou <pantelis.antoniou@konsulko.com> |
|---|---|
| Date | 2016-10-07 17:40 +0200 |
| Subject | [PATCH 2/4] mfd: ptxpmb-ext-cpld: Add documentation for PTXPMB extended CPLD |
| Message-ID | <spFpE-2pN-65@gated-at.bofh.it> |
| In reply to | #1497246 |
From: Georgi Vlaev <gvlaev@juniper.net>
Add DT bindings document for the PTXPMB extended CPLD device.
Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
.../bindings/mfd/jnx-ptxpmb-ext-cpld.txt | 35 ++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt
diff --git a/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt
new file mode 100644
index 0000000..098a548a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt
@@ -0,0 +1,35 @@
+* Device tree bindings for Juniper's PTXPMB Extended CPLD FPGA MFD driver
+
+The device supports a gpio block which is described in the
+jnx-gpio-ptxpmb-ext-cpld document.
+
+Required properties:
+
+- compatible: "jnx,ptxpmb-ext-cpld"
+
+- reg: contains offset/length value for device state control
+ registers space.
+
+Optional properties:
+
+- interrupts: The interrupt line(s) the /IRQ signal(s) for the device is
+ connected to.
+
+- interrupt-parent: The parent interrupt controller.
+
+Example:
+
+ext-cpld@1,0 {
+ compatible = "jnx,ptxpmb-ext-cpld";
+ reg = <0x1 0 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <7 2>, <8 2>;
+
+ gpio_ext_cpld: cpld-ext-gpio {
+ compatible = "jnx,gpio-ptxpmb-ext-cpld";
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ };
+};
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2016-10-10 22:30 +0200 |
| Subject | Re: [PATCH 2/4] mfd: ptxpmb-ext-cpld: Add documentation for PTXPMB extended CPLD |
| Message-ID | <sqPmV-5JU-7@gated-at.bofh.it> |
| In reply to | #1497279 |
On Fri, Oct 07, 2016 at 06:19:32PM +0300, Pantelis Antoniou wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
>
> Add DT bindings document for the PTXPMB extended CPLD device.
>
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
> .../bindings/mfd/jnx-ptxpmb-ext-cpld.txt | 35 ++++++++++++++++++++++
> 1 file changed, 35 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt
> new file mode 100644
> index 0000000..098a548a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/jnx-ptxpmb-ext-cpld.txt
> @@ -0,0 +1,35 @@
> +* Device tree bindings for Juniper's PTXPMB Extended CPLD FPGA MFD driver
> +
> +The device supports a gpio block which is described in the
> +jnx-gpio-ptxpmb-ext-cpld document.
> +
> +Required properties:
> +
> +- compatible: "jnx,ptxpmb-ext-cpld"
> +
> +- reg: contains offset/length value for device state control
> + registers space.
> +
> +Optional properties:
> +
> +- interrupts: The interrupt line(s) the /IRQ signal(s) for the device is
> + connected to.
> +
> +- interrupt-parent: The parent interrupt controller.
> +
> +Example:
> +
> +ext-cpld@1,0 {
> + compatible = "jnx,ptxpmb-ext-cpld";
> + reg = <0x1 0 0x1000>;
What's the bus type here? Unit address is probably wrong.
> + interrupt-parent = <&mpic>;
> + interrupts = <7 2>, <8 2>;
> +
> + gpio_ext_cpld: cpld-ext-gpio {
> + compatible = "jnx,gpio-ptxpmb-ext-cpld";
> + #gpio-cells = <2>;
> + #interrupt-cells = <2>;
> + gpio-controller;
> + interrupt-controller;
> + };
> +};
> --
> 1.9.1
>
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web