gpio: Implement and utilize register structures for ISA drivers
Subsystems (7)
v4 cover gpio: Implement and utilize register structures for ISA drivers
Rebased onto the gpio/for-next branch.
Changes in v4:
- Cleanup superfluous header includes from drivers
- Add note to CONFIG_GPIO_I8255 Kconfig that if built as a module the name will be 'gpio-i8255'
- Remove 'const' from '__iomem' pointers
- Replace ambiguous 'group' terminology with more understandable 'bank'
- Use more natural '>= 4' expression to represent upper nibble
- Refactor i8255_set_port() to take more common pattern of mask and bits
The PC104/ISA drivers were updated to use I/O memory accessor calls such as ioread8()/iowrite8() in a previous patch series [0]. This patchset is a continuation of the effort to improve the code readability and reduce magic numbers by implementing and utilizing named register data structures.
One of the benefits is that we can now observe more easily similarities in devices that share similar interfaces; such as the i8255 interfaces used by the 104-DIO-48E, 104-IDI-48, and GPIO-MM drivers -- as well as the similar interface used by the 104-IDIO-16 and PCI-IDIO-16 drivers.
A new module supporting the Intel 8255 interface is introduced to consolidate the common code found among the 104-DIO-48E, 104-IDI-48, and GPIO-MM drivers.
[0] https://lore.kernel.org/all/[email protected]/
William Breathitt Gray (6):
gpio: ws16c48: Implement and utilize register structures
gpio: 104-idio-16: Implement and utilize register structures
gpio: i8255: Introduce the Intel 8255 interface library module
gpio: 104-dio-48e: Implement and utilize register structures
gpio: 104-idi-48: Implement and utilize register structures
gpio: gpio-mm: Implement and utilize register structures
MAINTAINERS | 6 + drivers/gpio/Kconfig | 15 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-104-dio-48e.c | 249 ++++++++------------------- drivers/gpio/gpio-104-idi-48.c | 143 +++++++--------- drivers/gpio/gpio-104-idio-16.c | 60 +++++-- drivers/gpio/gpio-gpio-mm.c | 202 +++++----------------- drivers/gpio/gpio-i8255.c | 287 ++++++++++++++++++++++++++++++++ drivers/gpio/gpio-i8255.h | 46 +++++ drivers/gpio/gpio-ws16c48.c | 120 +++++++++---- 10 files changed, 654 insertions(+), 475 deletions(-) create mode 100644 drivers/gpio/gpio-i8255.c create mode 100644 drivers/gpio/gpio-i8255.h
base-commit: c4371c56397340134c1827ab70dbf817dbb1b99b
Signature · 1 line
2.36.1
PATCH RESEND v4 1/6 gpio: ws16c48: Implement and utilize register structures
Reduce magic numbers and improve code readability by implementing and utilizing named register data structures.
---
Changes in v4:
- Remove superfluous <linux/bitops.h> include
drivers/gpio/gpio-ws16c48.c | 120 +++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 36 deletions(-)
drivers/gpio/gpio-ws16c48.c +84 -36
@@ -4,7 +4,6 @@* Copyright (C) 2016 William Breathitt Gray */ #include <linux/bitmap.h> -#include <linux/bitops.h> #include <linux/device.h> #include <linux/errno.h> #include <linux/gpio/driver.h>
@@ -17,8 +16,9 @@#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/spinlock.h> +#include <linux/types.h> -#define WS16C48_EXTENT 16 +#define WS16C48_EXTENT 10#define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT)static unsigned int base[MAX_NUM_WS16C48 ];
@@ -30,6 +30,20 @@ static unsigned int irq[MAX_NUM_WS16C48];module_param_hw_array (irq, uint, irq,NULL ,0 );MODULE_PARM_DESC (irq,"WinSystems WS16C48 interrupt line numbers" ); +/** +* struct ws16c48_reg - device register structure +* @port: Port 0 through 5 I/O +* @int_pending: Interrupt Pending +* @page_lock: Register page (Bits 7-6) and I/O port lock (Bits 5-0) +* @pol_enab_int_id: Interrupt polarity, enable, and ID +*/ +struct ws16c48_reg { +u8 port[6 ]; +u8 int_pending; +u8 page_lock; +u8 pol_enab_int_id[3 ]; +}; +/** * struct ws16c48_gpio - GPIO device private data structure * @chip: instance of the gpio_chip
@@ -38,7 +52,7 @@ MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers");* @lock: synchronization lock to prevent I/O race conditions * @irq_mask: I/O bits affected by interrupts * @flow_mask: IRQ flow type mask for the respective I/O bits -* @base: base port address of the GPIO device +* @reg: I/O address offset for the device registers */ struct ws16c48_gpio {struct gpio_chip chip;
@@ -47,7 +61,7 @@ struct ws16c48_gpio {raw_spinlock_t lock;unsigned long irq_mask;unsigned long flow_mask; -void __iomem *base; +struct ws16c48_reg __iomem *reg; };static int ws16c48_gpio_get_direction (struct gpio_chip *chip,unsigned offset)
@@ -73,7 +87,7 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ws16c48gpio->io_state[port] |= mask; ws16c48gpio->out_state[port] &= ~mask; -iowrite8 (ws16c48gpio->out_state[port], ws16c48gpio->base + port); +iowrite8 (ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags);
@@ -95,7 +109,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip, ws16c48gpio->out_state[port] |= mask; else ws16c48gpio->out_state[port] &= ~mask; -iowrite8 (ws16c48gpio->out_state[port], ws16c48gpio->base + port); +iowrite8 (ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags);
@@ -118,7 +132,7 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)return -EINVAL ; } - port_state =ioread8 (ws16c48gpio->base + port); + port_state =ioread8 (ws16c48gpio->reg->port + port);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags);
@@ -131,14 +145,16 @@ static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,struct ws16c48_gpio *const ws16c48gpio =gpiochip_get_data (chip);unsigned long offset;unsigned long gpio_mask; -void __iomem *port_addr; +size_t index; +u8 __iomem *port_addr;unsigned long port_state;/* clear bits array to a clean slate */ bitmap_zero (bits, chip->ngpio);for_each_set_clump8 (offset, gpio_mask, mask, chip->ngpio) { - port_addr = ws16c48gpio->base + offset /8 ; + index = offset /8 ; + port_addr = ws16c48gpio->reg->port + index; port_state =ioread8 (port_addr) & gpio_mask;bitmap_set_value8 (bits, port_state, offset);
@@ -166,7 +182,7 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ws16c48gpio->out_state[port] |= mask; else ws16c48gpio->out_state[port] &= ~mask; -iowrite8 (ws16c48gpio->out_state[port], ws16c48gpio->base + port); +iowrite8 (ws16c48gpio->out_state[port], ws16c48gpio->reg->port + port);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags); }
@@ -178,13 +194,13 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,unsigned long offset;unsigned long gpio_mask;size_t index; -void __iomem *port_addr; +u8 __iomem *port_addr;unsigned long bitmask;unsigned long flags;for_each_set_clump8 (offset, gpio_mask, mask, chip->ngpio) { index = offset /8 ; - port_addr = ws16c48gpio->base + index; + port_addr = ws16c48gpio->reg->port + index;/* mask out GPIO configured for input */ gpio_mask &= ~ws16c48gpio->io_state[index];
@@ -219,10 +235,15 @@ static void ws16c48_irq_ack(struct irq_data *data) port_state = ws16c48gpio->irq_mask >> (8 *port); -iowrite8 (0x80 , ws16c48gpio->base +7 ); -iowrite8 (port_state & ~mask, ws16c48gpio->base +8 + port); -iowrite8 (port_state | mask, ws16c48gpio->base +8 + port); -iowrite8 (0xC0 , ws16c48gpio->base +7 ); +/* Select Register Page 2; Unlock all I/O ports */ +iowrite8 (0x80 , &ws16c48gpio->reg->page_lock); + +/* Clear pending interrupt */ +iowrite8 (port_state & ~mask, ws16c48gpio->reg->pol_enab_int_id + port); +iowrite8 (port_state | mask, ws16c48gpio->reg->pol_enab_int_id + port); + +/* Select Register Page 3; Unlock all I/O ports */ +iowrite8 (0xC0 , &ws16c48gpio->reg->page_lock);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags); }
@@ -235,6 +256,7 @@ static void ws16c48_irq_mask(struct irq_data *data)const unsigned long mask =BIT (offset);const unsigned port = offset /8 ;unsigned long flags; +unsigned long port_state;/* only the first 3 ports support interrupts */ if (port >2 )
@@ -243,10 +265,16 @@ static void ws16c48_irq_mask(struct irq_data *data)raw_spin_lock_irqsave (&ws16c48gpio->lock, flags); ws16c48gpio->irq_mask &= ~mask; + port_state = ws16c48gpio->irq_mask >> (8 * port); + +/* Select Register Page 2; Unlock all I/O ports */ +iowrite8 (0x80 , &ws16c48gpio->reg->page_lock); -iowrite8 (0x80 , ws16c48gpio->base +7 ); -iowrite8 (ws16c48gpio->irq_mask >> (8 *port), ws16c48gpio->base +8 + port); -iowrite8 (0xC0 , ws16c48gpio->base +7 ); +/* Disable interrupt */ +iowrite8 (port_state, ws16c48gpio->reg->pol_enab_int_id + port); + +/* Select Register Page 3; Unlock all I/O ports */ +iowrite8 (0xC0 , &ws16c48gpio->reg->page_lock);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags); }
@@ -259,6 +287,7 @@ static void ws16c48_irq_unmask(struct irq_data *data)const unsigned long mask =BIT (offset);const unsigned port = offset /8 ;unsigned long flags; +unsigned long port_state;/* only the first 3 ports support interrupts */ if (port >2 )
@@ -267,10 +296,16 @@ static void ws16c48_irq_unmask(struct irq_data *data)raw_spin_lock_irqsave (&ws16c48gpio->lock, flags); ws16c48gpio->irq_mask |= mask; + port_state = ws16c48gpio->irq_mask >> (8 * port); + +/* Select Register Page 2; Unlock all I/O ports */ +iowrite8 (0x80 , &ws16c48gpio->reg->page_lock); -iowrite8 (0x80 , ws16c48gpio->base +7 ); -iowrite8 (ws16c48gpio->irq_mask >> (8 *port), ws16c48gpio->base +8 + port); -iowrite8 (0xC0 , ws16c48gpio->base +7 ); +/* Enable interrupt */ +iowrite8 (port_state, ws16c48gpio->reg->pol_enab_int_id + port); + +/* Select Register Page 3; Unlock all I/O ports */ +iowrite8 (0xC0 , &ws16c48gpio->reg->page_lock);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags); }
@@ -283,6 +318,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)const unsigned long mask =BIT (offset);const unsigned port = offset /8 ;unsigned long flags; +unsigned long port_state;/* only the first 3 ports support interrupts */ if (port >2 )
@@ -304,9 +340,16 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)return -EINVAL ; } -iowrite8 (0x40 , ws16c48gpio->base +7 ); -iowrite8 (ws16c48gpio->flow_mask >> (8 *port), ws16c48gpio->base +8 + port); -iowrite8 (0xC0 , ws16c48gpio->base +7 ); + port_state = ws16c48gpio->flow_mask >> (8 * port); + +/* Select Register Page 1; Unlock all I/O ports */ +iowrite8 (0x40 , &ws16c48gpio->reg->page_lock); + +/* Set interrupt polarity */ +iowrite8 (port_state, ws16c48gpio->reg->pol_enab_int_id + port); + +/* Select Register Page 3; Unlock all I/O ports */ +iowrite8 (0xC0 , &ws16c48gpio->reg->page_lock);raw_spin_unlock_irqrestore (&ws16c48gpio->lock, flags);
@@ -325,25 +368,26 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id) {struct ws16c48_gpio *const ws16c48gpio = dev_id;struct gpio_chip *const chip = &ws16c48gpio->chip; +struct ws16c48_reg __iomem *const reg = ws16c48gpio->reg;unsigned long int_pending;unsigned long port;unsigned long int_id;unsigned long gpio; - int_pending =ioread8 (ws16c48gpio->base +6 ) &0x7 ; + int_pending =ioread8 (®->int_pending) &0x7 ;if (!int_pending)return IRQ_NONE ;/* loop until all pending interrupts are handled */ do {for_each_set_bit (port, &int_pending,3 ) { - int_id =ioread8 (ws16c48gpio->base +8 + port); + int_id =ioread8 (reg->pol_enab_int_id + port);for_each_set_bit (gpio, &int_id,8 )generic_handle_domain_irq (chip->irq.domain, gpio +8 *port); } - int_pending =ioread8 (ws16c48gpio->base +6 ) &0x7 ; + int_pending =ioread8 (®->int_pending) &0x7 ; }while (int_pending);return IRQ_HANDLED ;
@@ -369,12 +413,16 @@ static int ws16c48_irq_init_hw(struct gpio_chip *gc) {struct ws16c48_gpio *const ws16c48gpio =gpiochip_get_data (gc); -/* Disable IRQ by default */ -iowrite8 (0x80 , ws16c48gpio->base +7 ); -iowrite8 (0 , ws16c48gpio->base +8 ); -iowrite8 (0 , ws16c48gpio->base +9 ); -iowrite8 (0 , ws16c48gpio->base +10 ); -iowrite8 (0xC0 , ws16c48gpio->base +7 ); +/* Select Register Page 2; Unlock all I/O ports */ +iowrite8 (0x80 , &ws16c48gpio->reg->page_lock); + +/* Disable interrupts for all lines */ +iowrite8 (0 , &ws16c48gpio->reg->pol_enab_int_id[0 ]); +iowrite8 (0 , &ws16c48gpio->reg->pol_enab_int_id[1 ]); +iowrite8 (0 , &ws16c48gpio->reg->pol_enab_int_id[2 ]); + +/* Select Register Page 3; Unlock all I/O ports */ +iowrite8 (0xC0 , &ws16c48gpio->reg->page_lock);return 0 ; }
@@ -396,8 +444,8 @@ static int ws16c48_probe(struct device *dev, unsigned int id)return -EBUSY ; } - ws16c48gpio->base =devm_ioport_map (dev, base[id],WS16C48_EXTENT ); -if (!ws16c48gpio->base) + ws16c48gpio->reg =devm_ioport_map (dev, base[id],WS16C48_EXTENT ); +if (!ws16c48gpio->reg)return -ENOMEM ; ws16c48gpio->chip.label = name;
Signature · 1 line
2.36.1
PATCH RESEND v4 2/6 gpio: 104-idio-16: Implement and utilize register structures
In reply to William Breathitt GrayReduce magic numbers and improve code readability by implementing and utilizing named register data structures.
---
Changes in v4:
- Replace superfluous <linux/bitops.h> include with <linux/bits.h>
drivers/gpio/gpio-104-idio-16.c | 60 +++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-)
drivers/gpio/gpio-104-idio-16.c +42 -18
@@ -6,7 +6,7 @@* This driver supports the following ACCES devices: 104-IDIO-16, * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8. */ -#include <linux/bitops.h> +#include <linux/bits.h> #include <linux/device.h> #include <linux/errno.h> #include <linux/gpio/driver.h>
@@ -19,6 +19,7 @@#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/spinlock.h> +#include <linux/types.h> #define IDIO_16_EXTENT 8#define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT)
@@ -32,19 +33,42 @@ static unsigned int irq[MAX_NUM_IDIO_16];module_param_hw_array (irq, uint, irq,NULL ,0 );MODULE_PARM_DESC (irq,"ACCES 104-IDIO-16 interrupt line numbers" ); +/** +* struct idio_16_reg - device registers structure +* @out0_7: Read: N/A +* Write: FET Drive Outputs 0-7 +* @in0_7: Read: Isolated Inputs 0-7 +* Write: Clear Interrupt +* @irq_ctl: Read: Enable IRQ +* Write: Disable IRQ +* @unused: N/A +* @out8_15: Read: N/A +* Write: FET Drive Outputs 8-15 +* @in8_15: Read: Isolated Inputs 8-15 +* Write: N/A +*/ +struct idio_16_reg { +u8 out0_7; +u8 in0_7; +u8 irq_ctl; +u8 unused; +u8 out8_15; +u8 in8_15; +}; +/** * struct idio_16_gpio - GPIO device private data structure * @chip: instance of the gpio_chip * @lock: synchronization lock to prevent I/O race conditions * @irq_mask: I/O bits affected by interrupts -* @base: base port address of the GPIO device +* @reg: I/O address offset for the device registers * @out_state: output bits state */ struct idio_16_gpio {struct gpio_chip chip;raw_spinlock_t lock;unsigned long irq_mask; -void __iomem *base; +struct idio_16_reg __iomem *reg;unsigned int out_state; };
@@ -79,9 +103,9 @@ static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)return -EINVAL ;if (offset <24 ) -return !!(ioread8 (idio16gpio->base +1 ) & mask); +return !!(ioread8 (&idio16gpio->reg->in0_7) & mask); -return !!(ioread8 (idio16gpio->base +5 ) & (mask>>8 )); +return !!(ioread8 (&idio16gpio->reg->in8_15) & (mask>>8 )); } static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
@@ -91,9 +115,9 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip, *bits =0 ;if (*mask &GENMASK (23 ,16 )) - *bits |= (unsigned long )ioread8 (idio16gpio->base +1 ) <<16 ; + *bits |= (unsigned long )ioread8 (&idio16gpio->reg->in0_7) <<16 ;if (*mask &GENMASK (31 ,24 )) - *bits |= (unsigned long )ioread8 (idio16gpio->base +5 ) <<24 ; + *bits |= (unsigned long )ioread8 (&idio16gpio->reg->in8_15) <<24 ;return 0 ; }
@@ -116,9 +140,9 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, idio16gpio->out_state &= ~mask;if (offset >7 ) -iowrite8 (idio16gpio->out_state >>8 , idio16gpio->base +4 ); +iowrite8 (idio16gpio->out_state >>8 , &idio16gpio->reg->out8_15);else -iowrite8 (idio16gpio->out_state, idio16gpio->base); +iowrite8 (idio16gpio->out_state, &idio16gpio->reg->out0_7);raw_spin_unlock_irqrestore (&idio16gpio->lock, flags); }
@@ -135,9 +159,9 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip, idio16gpio->out_state |= *mask & *bits;if (*mask &0xFF ) -iowrite8 (idio16gpio->out_state, idio16gpio->base); +iowrite8 (idio16gpio->out_state, &idio16gpio->reg->out0_7);if ((*mask >>8 ) &0xFF ) -iowrite8 (idio16gpio->out_state >>8 , idio16gpio->base +4 ); +iowrite8 (idio16gpio->out_state >>8 , &idio16gpio->reg->out8_15);raw_spin_unlock_irqrestore (&idio16gpio->lock, flags); }
@@ -158,7 +182,7 @@ static void idio_16_irq_mask(struct irq_data *data)if (!idio16gpio->irq_mask) {raw_spin_lock_irqsave (&idio16gpio->lock, flags); -iowrite8 (0 , idio16gpio->base +2 ); +iowrite8 (0 , &idio16gpio->reg->irq_ctl);raw_spin_unlock_irqrestore (&idio16gpio->lock, flags); }
@@ -177,7 +201,7 @@ static void idio_16_irq_unmask(struct irq_data *data)if (!prev_irq_mask) {raw_spin_lock_irqsave (&idio16gpio->lock, flags); -ioread8 (idio16gpio->base +2 ); +ioread8 (&idio16gpio->reg->irq_ctl);raw_spin_unlock_irqrestore (&idio16gpio->lock, flags); }
@@ -212,7 +236,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)raw_spin_lock (&idio16gpio->lock); -iowrite8 (0 , idio16gpio->base +1 ); +iowrite8 (0 , &idio16gpio->reg->in0_7);raw_spin_unlock (&idio16gpio->lock);
@@ -232,8 +256,8 @@ static int idio_16_irq_init_hw(struct gpio_chip *gc)struct idio_16_gpio *const idio16gpio =gpiochip_get_data (gc);/* Disable IRQ by default */ -iowrite8 (0 , idio16gpio->base +2 ); -iowrite8 (0 , idio16gpio->base +1 ); +iowrite8 (0 , &idio16gpio->reg->irq_ctl); +iowrite8 (0 , &idio16gpio->reg->in0_7);return 0 ; }
@@ -255,8 +279,8 @@ static int idio_16_probe(struct device *dev, unsigned int id)return -EBUSY ; } - idio16gpio->base =devm_ioport_map (dev, base[id],IDIO_16_EXTENT ); -if (!idio16gpio->base) + idio16gpio->reg =devm_ioport_map (dev, base[id],IDIO_16_EXTENT ); +if (!idio16gpio->reg)return -ENOMEM ; idio16gpio->chip.label = name;
Signature · 1 line
2.36.1
PATCH RESEND v4 3/6 gpio: i8255: Introduce the Intel 8255 interface library module
In reply to William Breathitt GrayExposes consumer library functions providing support for interfaces compatible with the venerable Intel 8255 Programmable Peripheral Interface (PPI).
The Intel 8255 PPI first appeared in the early 1970s, initially for the Intel 8080 and later appearing in the original IBM-PC. The popularity of the original Intel 8255 chip led to many subsequent variants and clones of the interface in various chips and integrated circuits. Although still popular, interfaces compatible with the Intel 8255 PPI are nowdays typically found embedded in larger VLSI processing chips and FPGA components rather than as discrete ICs.
A CONFIG_GPIO_I8255 Kconfig option is introduced by this patch. Modules wanting access to these i8255 library functions should select this Kconfig option, and import the I8255 symbol namespace.
---
Changes in v4:
- Add note to CONFIG_GPIO_I8255 Kconfig that if built as a module the name will be 'gpio-i8255'
- Remove 'const' from '__iomem' pointers
- Replace ambiguous 'group' terminology with more understandable 'bank'
- Use more natural '>= 4' expression to represent upper nibble
- Refactor i8255_set_port() to take more common pattern of mask and bits
MAINTAINERS | 6 + drivers/gpio/Kconfig | 12 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-i8255.c | 287 ++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpio-i8255.h | 46 ++++++ 5 files changed, 352 insertions(+) create mode 100644 drivers/gpio/gpio-i8255.c create mode 100644 drivers/gpio/gpio-i8255.h
MAINTAINERS +6 -0
@@ -9902,6 +9902,12 @@ L: [email protected] S: Maintained F: drivers/video/fbdev/i810/ +INTEL 8255 GPIO DRIVER +M: William Breathitt Gray <[email protected]> +L: [email protected] +S: Maintained +F: drivers/gpio/gpio-i8255.c + INTEL ASoC DRIVERS M: Cezary Rojewski <[email protected]> M: Pierre-Louis Bossart <[email protected]>
drivers/gpio/Kconfig +12 -0
@@ -824,6 +824,18 @@ endmenu menu "Port-mapped I/O GPIO drivers" depends on X86 # Unconditional I/O space access +config GPIO_I8255 + tristate + help + Enables support for the i8255 interface library functions. The i8255 + interface library provides functions to facilitate communication with + interfaces compatible with the venerable Intel 8255 Programmable + Peripheral Interface (PPI). The Intel 8255 PPI chip was first released + in the early 1970s but compatible interfaces are nowadays typically + found embedded in larger VLSI processing chips and FPGA components. + + If built as a module its name will be gpio-i8255. + config GPIO_104_DIO_48E tristate "ACCES 104-DIO-48E GPIO support" depends on PC104
drivers/gpio/Makefile +1 -0
@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_GW_PLD) += gpio-gw-pld.o obj-$(CONFIG_GPIO_HISI) += gpio-hisi.o obj-$(CONFIG_GPIO_HLWD) += gpio-hlwd.o obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o +obj-$(CONFIG_GPIO_I8255) += gpio-i8255.o obj-$(CONFIG_GPIO_ICH) += gpio-ich.o obj-$(CONFIG_GPIO_IDT3243X) += gpio-idt3243x.o obj-$(CONFIG_GPIO_IOP) += gpio-iop.o
drivers/gpio/gpio-i8255.c new file +287 -0
287 lines not on this page · raw message
drivers/gpio/gpio-i8255.h new file +46 -0
46 lines not on this page · raw message
Signature · 1 line
2.36.1
PATCH RESEND v4 4/6 gpio: 104-dio-48e: Implement and utilize register structures
In reply to William Breathitt GrayReduce magic numbers and improve code readability by implementing and utilizing named register data structures. The 104-DIO-48E device features an Intel 8255 compatible GPIO interface, so the i8255 GPIO module is selected and utilized as well.
---
Changes in v4:
- Remove superfluous <linux/bitops.h> include
drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-104-dio-48e.c | 249 ++++++++++---------------------- 2 files changed, 75 insertions(+), 175 deletions(-)
drivers/gpio/Kconfig +1 -0
@@ -841,6 +841,7 @@ config GPIO_104_DIO_48E depends on PC104 select ISA_BUS_API select GPIOLIB_IRQCHIP + select GPIO_I8255 help Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E, 104-DIO-24E). The base port addresses for the devices may be
drivers/gpio/gpio-104-dio-48e.c +74 -175
362 lines not on this page · raw message
Signature · 1 line
2.36.1
PATCH RESEND v4 5/6 gpio: 104-idi-48: Implement and utilize register structures
In reply to William Breathitt GrayReduce magic numbers and improve code readability by implementing and utilizing named register data structures. The 104-IDI-48 device features an Intel 8255 compatible GPIO interface, so the i8255 GPIO module is selected and utilized as well.
---
Changes in v4:
- Replace superfluous <linux/bitops.h> include with <linux/bits.h>
- Remove 'const' from '__iomem' pointers
drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-104-idi-48.c | 143 ++++++++++++++------------------- 2 files changed, 61 insertions(+), 83 deletions(-)
drivers/gpio/Kconfig +1 -0
@@ -865,6 +865,7 @@ config GPIO_104_IDI_48 depends on PC104 select ISA_BUS_API select GPIOLIB_IRQCHIP + select GPIO_I8255 help Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A, 104-IDI-48AC, 104-IDI-48B, 104-IDI-48BC). The base port addresses for
drivers/gpio/gpio-104-idi-48.c +60 -83
247 lines not on this page · raw message
Signature · 1 line
2.36.1
PATCH RESEND v4 6/6 gpio: gpio-mm: Implement and utilize register structures
In reply to William Breathitt GrayReduce magic numbers and improve code readability by implementing and utilizing named register data structures. The GPIO-MM device features an Intel 8255 compatible GPIO interface, so the i8255 GPIO module is selected and utilized as well.
---
Changes in v4:
- Remove superfluous <linux/bitops.h> and <linux/bits.h> includes
drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-gpio-mm.c | 202 +++++++----------------------------- 2 files changed, 40 insertions(+), 163 deletions(-)
drivers/gpio/Kconfig +1 -0
@@ -886,6 +886,7 @@ config GPIO_GPIO_MM tristate "Diamond Systems GPIO-MM GPIO support" depends on PC104 select ISA_BUS_API + select GPIO_I8255 help Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12.
drivers/gpio/gpio-gpio-mm.c +39 -163
298 lines not on this page · raw message
Signature · 1 line
2.36.1
Quoted 24 lines · William Breathitt Gray
Rebased onto the gpio/for-next branch.
Changes in v4:
- Cleanup superfluous header includes from drivers
- Add note toCONFIG_GPIO_I8255Kconfigthat if built as a module the name will be 'gpio-i8255'
- Remove 'const' from '__iomem' pointers
- Replace ambiguous 'group' terminology with more understandable 'bank'
- Use more natural '>= 4' expression to represent upper nibble
- Refactori8255_set_port()to take more common pattern of mask and bitsThe PC104/ISA drivers were updated to use I/O memory accessor calls such as ioread8()/iowrite8() in a previous patch series [0]. This patchset is a continuation of the effort to improve the code readability and reduce magic numbers by implementing and utilizing named register data structures.
One of the benefits is that we can now observe more easily similarities in devices that share similar interfaces; such as the i8255 interfaces used by the 104-DIO-48E, 104-IDI-48, and GPIO-MM drivers -- as well as the similar interface used by the 104-IDIO-16 and PCI-IDIO-16 drivers.
Quoted 6 lines
A new module supporting the Intel 8255 interface is introduced to consolidate the common code found among the 104-DIO-48E, 104-IDI-48, and GPIO-MM drivers.
Series applied, thanks!
Bart