Skip to contentSkip to conversation

Migrate PCIe-IDIO-24 GPIO driver to the regmap API

PATCH Superseded William Breathitt Gray 1 participant 3 messages Mar 1, 2023

Subsystems (4)

v2 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v2 cover Migrate PCIe-IDIO-24 GPIO driver to the regmap API

Changes in v2:
- Simplify PCIe-IDIO-24 register offset defines to remove superfluous arithmetic
- Check for NULL pointer after chip->irq_drv_data allocation
- Set gpio_regmap drvdata and use gpio_regmap_get_drvdata() to get the regmap in idio_24_reg_map_xlate()

The regmap API supports IO port accessors so we can take advantage of regmap abstractions rather than handling access to the device registers directly in the driver.

A patch to pass the device regmap and irq_drv_data as a parameters for the struct regmap_irq_chip set_type_config() is included. This is needed by idio_24_set_type_config() in order to update the type configuration on the device as well as irq_drv_data for idio_24_handle_mask_sync().

William Breathitt Gray (2):
regmap: Pass regmap and irq_drv_data as parameters for
set_type_config()
gpio: pcie-idio-24: Migrate to the regmap API

 drivers/base/regmap/regmap-irq.c |  13 +-
 drivers/gpio/Kconfig             |   3 +
 drivers/gpio/gpio-pcie-idio-24.c | 693 ++++++++++++-------------------
 include/linux/regmap.h           |  12 +-
 4 files changed, 279 insertions(+), 442 deletions(-)

base-commit: 4827aae061337251bb91801b316157a78b845ec7

Signature · 1 line
2.39.2
#1 lore raw

PATCH v2 1/2 regmap: Pass regmap and irq_drv_data as parameters for set_type_config()

Allow struct regmap_irq_chip set_type_config() callbacks to access the device regmap and irq_drv_data by passing them as parameters.

---
Changes in v2: none

 drivers/base/regmap/regmap-irq.c | 13 +++++++++----
 include/linux/regmap.h           | 12 ++++++++----
 2 files changed, 17 insertions(+), 8 deletions(-)
drivers/base/regmap/regmap-irq.c +9 -4
index a8f185430a07..eac55a3af6d9 100644
@@ -333,8 +333,9 @@ static int regmap_irq_set_type(struct irq_data *data, unsigned int type)
 	}
 
 	if (d->chip->set_type_config) {
-		ret = d->chip->set_type_config(d->config_buf, type,
-					       irq_data, reg);
+		ret = d->chip->set_type_config(map, d->config_buf, type,
+					       irq_data, reg,
+					       d->chip->irq_drv_data);
 		if (ret)
 			return ret;
 	}
@@ -650,18 +651,22 @@ EXPORT_SYMBOL_GPL(regmap_irq_get_irq_reg_linear);
 
 /**
  * regmap_irq_set_type_config_simple() - Simple IRQ type configuration callback.
+ * @map: The regmap for the device.
  * @buf: Buffer containing configuration register values, this is a 2D array of
  *       `num_config_bases` rows, each of `num_config_regs` elements.
  * @type: The requested IRQ type.
  * @irq_data: The IRQ being configured.
  * @idx: Index of the irq's config registers within each array `buf[i]`
+ * @irq_drv_data: Driver specific IRQ data
  *
  * This is a &struct regmap_irq_chip->set_type_config callback suitable for
  * chips with one config register. Register values are updated according to
  * the &struct regmap_irq_type data associated with an IRQ.
  */
-int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
-				      const struct regmap_irq *irq_data, int idx)
+int regmap_irq_set_type_config_simple(struct regmap *map, unsigned int **buf,
+				      unsigned int type,
+				      const struct regmap_irq *irq_data,
+				      int idx, void *irq_drv_data)
 {
 	const struct regmap_irq_type *t = &irq_data->type;
 
include/linux/regmap.h +8 -4
index a3bc695bcca0..49073f5ae87a 100644
@@ -1648,8 +1648,10 @@ struct regmap_irq_chip {
 				unsigned int mask_buf, void *irq_drv_data);
 	int (*set_type_virt)(unsigned int **buf, unsigned int type,
 			     unsigned long hwirq, int reg);
-	int (*set_type_config)(unsigned int **buf, unsigned int type,
-			       const struct regmap_irq *irq_data, int idx);
+	int (*set_type_config)(struct regmap *map, unsigned int **buf,
+			       unsigned int type,
+			       const struct regmap_irq *irq_data, int idx,
+			       void *irq_drv_data);
 	unsigned int (*get_irq_reg)(struct regmap_irq_chip_data *data,
 				    unsigned int base, int index);
 	void *irq_drv_data;
@@ -1657,8 +1659,10 @@ struct regmap_irq_chip {
 
 unsigned int regmap_irq_get_irq_reg_linear(struct regmap_irq_chip_data *data,
 					   unsigned int base, int index);
-int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
-				      const struct regmap_irq *irq_data, int idx);
+int regmap_irq_set_type_config_simple(struct regmap *map, unsigned int **buf,
+				      unsigned int type,
+				      const struct regmap_irq *irq_data,
+				      int idx, void *irq_drv_data);
 
 int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 			int irq_base, const struct regmap_irq_chip *chip,
Signature · 1 line
2.39.2
#2 lore raw

PATCH v2 2/2 gpio: pcie-idio-24: Migrate to the regmap API

In reply to William Breathitt Gray

The regmap API supports IO port accessors so we can take advantage of regmap abstractions rather than handling access to the device registers directly in the driver.

For the PCIe-IDIO-24 series of devices, the following BARs are available:

    BAR[0]: memory mapped PEX8311
    BAR[1]: I/O mapped PEX8311
    BAR[2]: I/O mapped card registers

There are 24 FET Output lines, 24 Isolated Input lines, and 8 TTL/CMOS lines (which may be configured for either output or input). The GPIO lines are exposed by the following card registers:

    Base +0x0-0x2 (Read/Write): FET Outputs
    Base +0xB (Read/Write): TTL/CMOS
    Base +0x4-0x6 (Read): Isolated Inputs
    Base +0x7 (Read): TTL/CMOS

In order for the device to support interrupts, the PLX PEX8311 internal PCI wire interrupt and local interrupt input must first be enabled.

The following card registers for Change-Of-State may be used:

    Base +0x8-0xA (Read): COS Status Inputs
    Base +0x8-0xA (Write): COS Clear Inputs
    Base +0xB (Read): COS Status TTL/CMOS
    Base +0xB (Write): COS Clear TTL/CMOS
    Base +0xE (Read/Write): COS Enable

The COS Enable register is used to enable/disable interrupts and configure the interrupt levels; each bit maps to a group of eight inputs as described below:

Bit 0: IRQ EN Rising Edge IN0-7
Bit 1: IRQ EN Rising Edge IN8-15
Bit 2: IRQ EN Rising Edge IN16-23
Bit 3: IRQ EN Rising Edge TTL0-7
Bit 4: IRQ EN Falling Edge IN0-7
Bit 5: IRQ EN Falling Edge IN8-15
Bit 6: IRQ EN Falling Edge IN16-23
Bit 7: IRQ EN Falling Edge TTL0-7

An interrupt is asserted when a change-of-state matching the interrupt level configuration respective for a particular group of eight inputs with enabled COS is detected.

The COS Status registers may be read to determine which inputs have changed; if interrupts were enabled, an IRQ will be generated for the set bits in these registers. Writing the value read from the COS Status register back to the respective COS Clear register will clear just those interrupts.

Cc Arnaud de Turckheim <[email protected]>
Cc John Hentges <[email protected]>
Cc Jay Dolan <[email protected]>

---
Changes in v2:
- Simplify PCIe-IDIO-24 register offset defines to remove superfluous arithmetic
- Check for NULL pointer after chip->irq_drv_data allocation
- Set gpio_regmap drvdata and use gpio_regmap_get_drvdata() to get the regmap in idio_24_reg_map_xlate()

 drivers/gpio/Kconfig             |   3 +
 drivers/gpio/gpio-pcie-idio-24.c | 693 ++++++++++++-------------------
 2 files changed, 262 insertions(+), 434 deletions(-)
drivers/gpio/Kconfig +3 -0
index 406e8bda487f..06c7a96e6033 100644
@@ -1578,7 +1578,10 @@ config GPIO_PCI_IDIO_16
 
 config GPIO_PCIE_IDIO_24
 	tristate "ACCES PCIe-IDIO-24 GPIO support"
+	select REGMAP_IRQ
+	select REGMAP_MMIO
 	select GPIOLIB_IRQCHIP
+	select GPIO_REGMAP
 	help
 	  Enables GPIO support for the ACCES PCIe-IDIO-24 family (PCIe-IDIO-24,
 	  PCIe-IDI-24, PCIe-IDO-24, PCIe-IDIO-12). An interrupt is generated
drivers/gpio/gpio-pcie-idio-24.c +259 -434

765 lines not on this page · raw message

Signature · 1 line
2.39.2