gpio updates for v5.19

- use ioread()/iowrite() interfaces instead of raw inb()/outb() in drivers
 - make irqchips immutable due to the new warning popping up when drivers try to
   modify the irqchip structures
 - add new compatibles to dt-bindings for realtek-otto, renesas-rcar and pca95xx
 - add support for new models to gpio-rcar, gpio-pca953x & gpio-realtek-otto
 - allow parsing of GPIO hogs represented as children nodes of gpio-uniphier
 - define a set of common GPIO consumer strings in dt-bindings
 - shrink code in gpio-ml-ioh by using more devres interfaces
 - pass arguments to devm_kcalloc() in correct order in gpio-sim
 - add new helpers for iterating over GPIO firmware nodes and descriptors to
   gpiolib core and use it in several drivers
 - drop unused syscon_regmap_lookup_by_compatible() function
 - correct format specifiers and signedness of variables in GPIO ACPI
 - drop unneeded error checks in gpio-ftgpio
 - stop using the deprecated of_gpio.h header in gpio-zevio
 - drop platform_data support in gpio-max732x
 - simplify Kconfig dependencies in gpio-vf610
 - use raw spinlocks where needed to make PREEMPT_RT happy
 - fix return values in board files using gpio-pcf857x
 - convert more drivers to using fwnode instead of of_node
 - minor fixes and improvements in gpiolib core
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAmKOU9gACgkQEacuoBRx
 13L6+g//axfOCo1VFtrIZR3Sh8F3Zt6t5DfdWn7DU5OqKL9xQzF7o6dB5nqOa4ua
 k8cgXAlMj3EnlFAxWalArCw3Lu3ntInXfl2EAgFOfhya3DLCjQRayoz7EGTMlGrA
 XLZWNc+kUEDNOfN0L+fLHRopgi9jOtlS4XODaVMJKH31jVxufAwoQrFZF4d7pMvW
 XC4vuSYmRfLrNCm77CqznBjw5hD44v5bxxkGyGmKhE+VmuFcLX1feSTKkttZ+ZMC
 CP/Rp0/KSzJU4/1+9uPPrNY8NJGsBN9Uo+BQzH6nuSQrrO2MuOj5JA6UqgR+MHjI
 9a/b/iftiPnsxSzbE8PKj/jWcswmScp7tvGqwCa0Q7Fh502+p+8RtEVKugy5nYEG
 xNPONhQusu21Hw2ySHZZVjuxfQKi09uDEIZN55V5etsURHXiUB6RtZJwlgXWOYp5
 8/h/TPemAZsfvAs/9OZwck171oQBUnX1K+gdbQ/5t4QoW+VxQCuGP0uTPB5kTxSV
 yfVjeD2tpEdpjEAwmKrSLug4xLRlB4ed17DeEstFbFARUdOQZSLBiXln2KBg/d6Y
 ofnAPvqZyMf0/MFSKBoXIb/aKw8svbTKDwy0HvU3Tf0lOGix4F/w9ih6VzUo/yVt
 Aj9oqQyfK9E7EvPEQnZqn3h/3fmXvqDGrryABmuOmiy3N6RFGho=
 =tj/B
 -----END PGP SIGNATURE-----

Merge tag 'gpio-updates-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio updates from Bartosz Golaszewski:
 "We have lots of small changes all over the place, but no huge reworks
  or new drivers:

   - use ioread()/iowrite() interfaces instead of raw inb()/outb() in
     drivers

   - make irqchips immutable due to the new warning popping up when
     drivers try to modify the irqchip structures

   - add new compatibles to dt-bindings for realtek-otto, renesas-rcar
     and pca95xx

   - add support for new models to gpio-rcar, gpio-pca953x &
     gpio-realtek-otto

   - allow parsing of GPIO hogs represented as children nodes of
     gpio-uniphier

   - define a set of common GPIO consumer strings in dt-bindings

   - shrink code in gpio-ml-ioh by using more devres interfaces

   - pass arguments to devm_kcalloc() in correct order in gpio-sim

   - add new helpers for iterating over GPIO firmware nodes and
     descriptors to gpiolib core and use it in several drivers

   - drop unused syscon_regmap_lookup_by_compatible() function

   - correct format specifiers and signedness of variables in GPIO ACPI

   - drop unneeded error checks in gpio-ftgpio

   - stop using the deprecated of_gpio.h header in gpio-zevio

   - drop platform_data support in gpio-max732x

   - simplify Kconfig dependencies in gpio-vf610

   - use raw spinlocks where needed to make PREEMPT_RT happy

   - fix return values in board files using gpio-pcf857x

   - convert more drivers to using fwnode instead of of_node

   - minor fixes and improvements in gpiolib core"

* tag 'gpio-updates-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (55 commits)
  gpio: sifive: Make the irqchip immutable
  gpio: rcar: Make the irqchip immutable
  gpio: pcf857x: Make the irqchip immutable
  gpio: pca953x: Make the irqchip immutable
  gpio: dwapb: Make the irqchip immutable
  gpio: sim: Use correct order for the parameters of devm_kcalloc()
  gpio: ml-ioh: Convert to use managed functions pcim* and devm_*
  gpio: ftgpio: Remove unneeded ERROR check before clk_disable_unprepare
  gpio: ws16c48: Utilize iomap interface
  gpio: gpio-mm: Utilize iomap interface
  gpio: 104-idio-16: Utilize iomap interface
  gpio: 104-idi-48: Utilize iomap interface
  gpio: 104-dio-48e: Utilize iomap interface
  gpio: zevio: drop of_gpio.h header
  gpio: max77620: Make the irqchip immutable
  dt-bindings: gpio: pca95xx: add entry for pca6408
  gpio: pca953xx: Add support for pca6408
  gpio: max732x: Drop unused support for irq and setup code via platform data
  gpio: vf610: drop the SOC_VF610 dependency for GPIO_VF610
  gpio: syscon: Remove usage of syscon_regmap_lookup_by_compatible
  ...
This commit is contained in:
Linus Torvalds 2022-05-26 14:51:38 -07:00
commit 7182e89769
61 changed files with 959 additions and 955 deletions

View File

@ -0,0 +1,64 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/gpio/gpio-consumer-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Common GPIO lines
maintainers:
- Bartosz Golaszewski <brgl@bgdev.pl>
- Linus Walleij <linus.walleij@linaro.org>
description:
Pay attention to using proper GPIO flag (e.g. GPIO_ACTIVE_LOW) for the GPIOs
using inverted signal (e.g. RESETN).
select: true
properties:
enable-gpios:
maxItems: 1
description:
GPIO connected to the enable control pin.
reset-gpios:
description:
GPIO (or GPIOs for power sequence) connected to the device reset pin
(e.g. RESET or RESETN).
powerdown-gpios:
maxItems: 1
description:
GPIO connected to the power down pin (hardware power down or power cut,
e.g. PD or PWDN).
pwdn-gpios:
maxItems: 1
description: Use powerdown-gpios
deprecated: true
wakeup-gpios:
maxItems: 1
description:
GPIO connected to the pin waking up the device from suspend or other
power-saving modes.
allOf:
- if:
properties:
compatible:
contains:
enum:
- mmc-pwrseq-simple
then:
properties:
reset-gpios:
minItems: 1
maxItems: 32
else:
properties:
reset-gpios:
maxItems: 1
additionalProperties: true

View File

@ -30,6 +30,7 @@ properties:
- maxim,max7325
- maxim,max7326
- maxim,max7327
- nxp,pca6408
- nxp,pca6416
- nxp,pca9505
- nxp,pca9506

View File

@ -28,10 +28,11 @@ properties:
- enum:
- realtek,rtl8380-gpio
- realtek,rtl8390-gpio
- realtek,rtl9300-gpio
- realtek,rtl9310-gpio
- const: realtek,otto-gpio
reg:
maxItems: 1
reg: true
"#gpio-cells":
const: 2
@ -50,6 +51,23 @@ properties:
interrupts:
maxItems: 1
if:
properties:
compatible:
contains:
const: realtek,rtl9300-gpio
then:
properties:
reg:
items:
- description: GPIO and interrupt control
- description: interrupt CPU map
else:
properties:
reg:
items:
- description: GPIO and interrupt control
required:
- compatible
- reg
@ -74,5 +92,17 @@ examples:
interrupt-parent = <&rtlintc>;
interrupts = <23>;
};
- |
gpio@3300 {
compatible = "realtek,rtl9300-gpio", "realtek,otto-gpio";
reg = <0x3300 0x1c>, <0x3338 0x8>;
gpio-controller;
#gpio-cells = <2>;
ngpios = <24>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&rtlintc>;
interrupts = <13>;
};
...

View File

@ -51,6 +51,11 @@ properties:
- items:
- const: renesas,gpio-r8a779a0 # R-Car V3U
- items:
- enum:
- renesas,gpio-r8a779f0 # R-Car S4-8
- const: renesas,rcar-gen4-gpio # R-Car Gen4
reg:
maxItems: 1

View File

@ -52,6 +52,23 @@ properties:
<child-interrupt-base parent-interrupt-base length> triplets.
$ref: /schemas/types.yaml#/definitions/uint32-matrix
patternProperties:
"^.+-hog(-[0-9]+)?$":
type: object
properties:
gpio-hog: true
gpios: true
input: true
output-high: true
output-low: true
line-name: true
required:
- gpio-hog
- gpios
additionalProperties: false
required:
- compatible
- reg

View File

@ -472,11 +472,10 @@ static int __init da830_evm_ui_expander_setup(struct i2c_client *client,
return 0;
}
static int da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio,
static void da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio,
unsigned ngpio, void *context)
{
gpio_free(gpio + 6);
return 0;
}
static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = {

View File

@ -365,14 +365,13 @@ evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
return status;
}
static int
static void
evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
{
if (evm_led_dev) {
platform_device_unregister(evm_led_dev);
evm_led_dev = NULL;
}
return 0;
}
static struct pcf857x_platform_data pcf_data_u2 = {
@ -427,7 +426,7 @@ evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
return 0;
}
static int
static void
evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
{
gpio_free(gpio + 1);
@ -438,7 +437,6 @@ evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
device_remove_file(&client->dev, &dev_attr_user_sw);
gpio_free(sw_gpio);
}
return 0;
}
static struct pcf857x_platform_data pcf_data_u18 = {
@ -487,7 +485,7 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
return 0;
}
static int
static void
evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
{
gpio_free(gpio + 7);
@ -497,7 +495,6 @@ evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
gpio_free(gpio + 2);
gpio_free(gpio + 1);
gpio_free(gpio + 0);
return 0;
}
static struct pcf857x_platform_data pcf_data_u35 = {

View File

@ -314,15 +314,13 @@ static int evm_pcf_setup(struct i2c_client *client, int gpio,
return evm_led_setup(client, gpio+4, 4, c);
}
static int evm_pcf_teardown(struct i2c_client *client, int gpio,
static void evm_pcf_teardown(struct i2c_client *client, int gpio,
unsigned int ngpio, void *c)
{
BUG_ON(ngpio < 8);
evm_sw_teardown(client, gpio, 4, c);
evm_led_teardown(client, gpio+4, 4, c);
return 0;
}
static struct pcf857x_platform_data pcf_data = {

View File

@ -353,8 +353,8 @@ config GPIO_IOP
config GPIO_IXP4XX
bool "Intel IXP4xx GPIO"
depends on ARM # For <asm/mach-types.h>
depends on ARCH_IXP4XX
depends on OF
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
select IRQ_DOMAIN_HIERARCHY
@ -363,6 +363,7 @@ config GPIO_IXP4XX
IXP4xx series of chips.
If unsure, say N.
config GPIO_LOGICVC
tristate "Xylon LogiCVC GPIO support"
depends on MFD_SYSCON && OF
@ -674,10 +675,10 @@ config GPIO_UNIPHIER
config GPIO_VF610
def_bool y
depends on ARCH_MXC && SOC_VF610
depends on ARCH_MXC
select GPIOLIB_IRQCHIP
help
Say yes here to support Vybrid vf610 GPIOs.
Say yes here to support i.MX or Vybrid vf610 GPIOs.
config GPIO_VISCONTI
tristate "Toshiba Visconti GPIO support"

View File

@ -49,7 +49,7 @@ struct dio48e_gpio {
unsigned char out_state[6];
unsigned char control[2];
raw_spinlock_t lock;
unsigned int base;
void __iomem *base;
unsigned char irq_mask;
};
@ -70,7 +70,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned int offs
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
const unsigned int io_port = offset / 8;
const unsigned int control_port = io_port / 3;
const unsigned int control_addr = dio48egpio->base + 3 + control_port * 4;
void __iomem *const control_addr = dio48egpio->base + 3 + control_port * 4;
unsigned long flags;
unsigned int control;
@ -95,9 +95,9 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned int offs
}
control = BIT(7) | dio48egpio->control[control_port];
outb(control, control_addr);
iowrite8(control, control_addr);
control &= ~BIT(7);
outb(control, control_addr);
iowrite8(control, control_addr);
raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
@ -111,7 +111,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned int off
const unsigned int io_port = offset / 8;
const unsigned int control_port = io_port / 3;
const unsigned int mask = BIT(offset % 8);
const unsigned int control_addr = dio48egpio->base + 3 + control_port * 4;
void __iomem *const control_addr = dio48egpio->base + 3 + control_port * 4;
const unsigned int out_port = (io_port > 2) ? io_port + 1 : io_port;
unsigned long flags;
unsigned int control;
@ -142,12 +142,12 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned int off
dio48egpio->out_state[io_port] &= ~mask;
control = BIT(7) | dio48egpio->control[control_port];
outb(control, control_addr);
iowrite8(control, control_addr);
outb(dio48egpio->out_state[io_port], dio48egpio->base + out_port);
iowrite8(dio48egpio->out_state[io_port], dio48egpio->base + out_port);
control &= ~BIT(7);
outb(control, control_addr);
iowrite8(control, control_addr);
raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
@ -171,7 +171,7 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned int offset)
return -EINVAL;
}
port_state = inb(dio48egpio->base + in_port);
port_state = ioread8(dio48egpio->base + in_port);
raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
@ -186,7 +186,7 @@ static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
unsigned long offset;
unsigned long gpio_mask;
unsigned int port_addr;
void __iomem *port_addr;
unsigned long port_state;
/* clear bits array to a clean slate */
@ -194,7 +194,7 @@ static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
port_addr = dio48egpio->base + ports[offset / 8];
port_state = inb(port_addr) & gpio_mask;
port_state = ioread8(port_addr) & gpio_mask;
bitmap_set_value8(bits, port_state, offset);
}
@ -217,7 +217,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned int offset, int val
else
dio48egpio->out_state[port] &= ~mask;
outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
iowrite8(dio48egpio->out_state[port], dio48egpio->base + out_port);
raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
@ -229,7 +229,7 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
unsigned long offset;
unsigned long gpio_mask;
size_t index;
unsigned int port_addr;
void __iomem *port_addr;
unsigned long bitmask;
unsigned long flags;
@ -244,7 +244,7 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
/* update output state data and set device gpio register */
dio48egpio->out_state[index] &= ~gpio_mask;
dio48egpio->out_state[index] |= bitmask;
outb(dio48egpio->out_state[index], port_addr);
iowrite8(dio48egpio->out_state[index], port_addr);
raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
@ -274,7 +274,7 @@ static void dio48e_irq_mask(struct irq_data *data)
if (!dio48egpio->irq_mask)
/* disable interrupts */
inb(dio48egpio->base + 0xB);
ioread8(dio48egpio->base + 0xB);
raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
@ -294,8 +294,8 @@ static void dio48e_irq_unmask(struct irq_data *data)
if (!dio48egpio->irq_mask) {
/* enable interrupts */
outb(0x00, dio48egpio->base + 0xF);
outb(0x00, dio48egpio->base + 0xB);
iowrite8(0x00, dio48egpio->base + 0xF);
iowrite8(0x00, dio48egpio->base + 0xB);
}
if (offset == 19)
@ -341,7 +341,7 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
raw_spin_lock(&dio48egpio->lock);
outb(0x00, dio48egpio->base + 0xF);
iowrite8(0x00, dio48egpio->base + 0xF);
raw_spin_unlock(&dio48egpio->lock);
@ -373,7 +373,7 @@ static int dio48e_irq_init_hw(struct gpio_chip *gc)
struct dio48e_gpio *const dio48egpio = gpiochip_get_data(gc);
/* Disable IRQ by default */
inb(dio48egpio->base + 0xB);
ioread8(dio48egpio->base + 0xB);
return 0;
}
@ -395,6 +395,10 @@ static int dio48e_probe(struct device *dev, unsigned int id)
return -EBUSY;
}
dio48egpio->base = devm_ioport_map(dev, base[id], DIO48E_EXTENT);
if (!dio48egpio->base)
return -ENOMEM;
dio48egpio->chip.label = name;
dio48egpio->chip.parent = dev;
dio48egpio->chip.owner = THIS_MODULE;
@ -408,7 +412,6 @@ static int dio48e_probe(struct device *dev, unsigned int id)
dio48egpio->chip.get_multiple = dio48e_gpio_get_multiple;
dio48egpio->chip.set = dio48e_gpio_set;
dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
dio48egpio->base = base[id];
girq = &dio48egpio->chip.irq;
girq->chip = &dio48e_irqchip;
@ -423,16 +426,16 @@ static int dio48e_probe(struct device *dev, unsigned int id)
raw_spin_lock_init(&dio48egpio->lock);
/* initialize all GPIO as output */
outb(0x80, base[id] + 3);
outb(0x00, base[id]);
outb(0x00, base[id] + 1);
outb(0x00, base[id] + 2);
outb(0x00, base[id] + 3);
outb(0x80, base[id] + 7);
outb(0x00, base[id] + 4);
outb(0x00, base[id] + 5);
outb(0x00, base[id] + 6);
outb(0x00, base[id] + 7);
iowrite8(0x80, dio48egpio->base + 3);
iowrite8(0x00, dio48egpio->base);
iowrite8(0x00, dio48egpio->base + 1);
iowrite8(0x00, dio48egpio->base + 2);
iowrite8(0x00, dio48egpio->base + 3);
iowrite8(0x80, dio48egpio->base + 7);
iowrite8(0x00, dio48egpio->base + 4);
iowrite8(0x00, dio48egpio->base + 5);
iowrite8(0x00, dio48egpio->base + 6);
iowrite8(0x00, dio48egpio->base + 7);
err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
if (err) {

View File

@ -47,7 +47,7 @@ struct idi_48_gpio {
raw_spinlock_t lock;
spinlock_t ack_lock;
unsigned char irq_mask[6];
unsigned base;
void __iomem *base;
unsigned char cos_enb;
};
@ -66,15 +66,15 @@ static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)
struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
unsigned i;
static const unsigned int register_offset[6] = { 0, 1, 2, 4, 5, 6 };
unsigned base_offset;
void __iomem *port_addr;
unsigned mask;
for (i = 0; i < 48; i += 8)
if (offset < i + 8) {
base_offset = register_offset[i / 8];
port_addr = idi48gpio->base + register_offset[i / 8];
mask = BIT(offset - i);
return !!(inb(idi48gpio->base + base_offset) & mask);
return !!(ioread8(port_addr) & mask);
}
/* The following line should never execute since offset < 48 */
@ -88,7 +88,7 @@ static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
unsigned long offset;
unsigned long gpio_mask;
static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
unsigned int port_addr;
void __iomem *port_addr;
unsigned long port_state;
/* clear bits array to a clean slate */
@ -96,7 +96,7 @@ static int idi_48_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
port_addr = idi48gpio->base + ports[offset / 8];
port_state = inb(port_addr) & gpio_mask;
port_state = ioread8(port_addr) & gpio_mask;
bitmap_set_value8(bits, port_state, offset);
}
@ -130,7 +130,7 @@ static void idi_48_irq_mask(struct irq_data *data)
raw_spin_lock_irqsave(&idi48gpio->lock, flags);
outb(idi48gpio->cos_enb, idi48gpio->base + 7);
iowrite8(idi48gpio->cos_enb, idi48gpio->base + 7);
raw_spin_unlock_irqrestore(&idi48gpio->lock, flags);
}
@ -163,7 +163,7 @@ static void idi_48_irq_unmask(struct irq_data *data)
raw_spin_lock_irqsave(&idi48gpio->lock, flags);
outb(idi48gpio->cos_enb, idi48gpio->base + 7);
iowrite8(idi48gpio->cos_enb, idi48gpio->base + 7);
raw_spin_unlock_irqrestore(&idi48gpio->lock, flags);
}
@ -204,7 +204,7 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
raw_spin_lock(&idi48gpio->lock);
cos_status = inb(idi48gpio->base + 7);
cos_status = ioread8(idi48gpio->base + 7);
raw_spin_unlock(&idi48gpio->lock);
@ -250,8 +250,8 @@ static int idi_48_irq_init_hw(struct gpio_chip *gc)
struct idi_48_gpio *const idi48gpio = gpiochip_get_data(gc);
/* Disable IRQ by default */
outb(0, idi48gpio->base + 7);
inb(idi48gpio->base + 7);
iowrite8(0, idi48gpio->base + 7);
ioread8(idi48gpio->base + 7);
return 0;
}
@ -273,6 +273,10 @@ static int idi_48_probe(struct device *dev, unsigned int id)
return -EBUSY;
}
idi48gpio->base = devm_ioport_map(dev, base[id], IDI_48_EXTENT);
if (!idi48gpio->base)
return -ENOMEM;
idi48gpio->chip.label = name;
idi48gpio->chip.parent = dev;
idi48gpio->chip.owner = THIS_MODULE;
@ -283,7 +287,6 @@ static int idi_48_probe(struct device *dev, unsigned int id)
idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
idi48gpio->chip.get = idi_48_gpio_get;
idi48gpio->chip.get_multiple = idi_48_gpio_get_multiple;
idi48gpio->base = base[id];
girq = &idi48gpio->chip.irq;
girq->chip = &idi_48_irqchip;

View File

@ -44,7 +44,7 @@ struct idio_16_gpio {
struct gpio_chip chip;
raw_spinlock_t lock;
unsigned long irq_mask;
unsigned int base;
void __iomem *base;
unsigned int out_state;
};
@ -79,9 +79,9 @@ static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
return -EINVAL;
if (offset < 24)
return !!(inb(idio16gpio->base + 1) & mask);
return !!(ioread8(idio16gpio->base + 1) & mask);
return !!(inb(idio16gpio->base + 5) & (mask>>8));
return !!(ioread8(idio16gpio->base + 5) & (mask>>8));
}
static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
@ -91,9 +91,9 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
*bits = 0;
if (*mask & GENMASK(23, 16))
*bits |= (unsigned long)inb(idio16gpio->base + 1) << 16;
*bits |= (unsigned long)ioread8(idio16gpio->base + 1) << 16;
if (*mask & GENMASK(31, 24))
*bits |= (unsigned long)inb(idio16gpio->base + 5) << 24;
*bits |= (unsigned long)ioread8(idio16gpio->base + 5) << 24;
return 0;
}
@ -116,9 +116,9 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
idio16gpio->out_state &= ~mask;
if (offset > 7)
outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
iowrite8(idio16gpio->out_state >> 8, idio16gpio->base + 4);
else
outb(idio16gpio->out_state, idio16gpio->base);
iowrite8(idio16gpio->out_state, idio16gpio->base);
raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
@ -135,9 +135,9 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
idio16gpio->out_state |= *mask & *bits;
if (*mask & 0xFF)
outb(idio16gpio->out_state, idio16gpio->base);
iowrite8(idio16gpio->out_state, idio16gpio->base);
if ((*mask >> 8) & 0xFF)
outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
iowrite8(idio16gpio->out_state >> 8, idio16gpio->base + 4);
raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
@ -158,7 +158,7 @@ static void idio_16_irq_mask(struct irq_data *data)
if (!idio16gpio->irq_mask) {
raw_spin_lock_irqsave(&idio16gpio->lock, flags);
outb(0, idio16gpio->base + 2);
iowrite8(0, idio16gpio->base + 2);
raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
@ -177,7 +177,7 @@ static void idio_16_irq_unmask(struct irq_data *data)
if (!prev_irq_mask) {
raw_spin_lock_irqsave(&idio16gpio->lock, flags);
inb(idio16gpio->base + 2);
ioread8(idio16gpio->base + 2);
raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
@ -212,7 +212,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
raw_spin_lock(&idio16gpio->lock);
outb(0, idio16gpio->base + 1);
iowrite8(0, idio16gpio->base + 1);
raw_spin_unlock(&idio16gpio->lock);
@ -232,8 +232,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 */
outb(0, idio16gpio->base + 2);
outb(0, idio16gpio->base + 1);
iowrite8(0, idio16gpio->base + 2);
iowrite8(0, idio16gpio->base + 1);
return 0;
}
@ -255,6 +255,10 @@ 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)
return -ENOMEM;
idio16gpio->chip.label = name;
idio16gpio->chip.parent = dev;
idio16gpio->chip.owner = THIS_MODULE;
@ -268,7 +272,6 @@ static int idio_16_probe(struct device *dev, unsigned int id)
idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
idio16gpio->chip.set = idio_16_gpio_set;
idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
idio16gpio->base = base[id];
idio16gpio->out_state = 0xFFFF;
girq = &idio16gpio->chip.irq;

View File

@ -36,19 +36,19 @@ static int pt_gpio_request(struct gpio_chip *gc, unsigned offset)
dev_dbg(gc->parent, "pt_gpio_request offset=%x\n", offset);
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);
if (using_pins & BIT(offset)) {
dev_warn(gc->parent, "PT GPIO pin %x reconfigured\n",
offset);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return -EINVAL;
}
writel(using_pins | BIT(offset), pt_gpio->reg_base + PT_SYNC_REG);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
@ -59,13 +59,13 @@ static void pt_gpio_free(struct gpio_chip *gc, unsigned offset)
unsigned long flags;
u32 using_pins;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);
using_pins &= ~BIT(offset);
writel(using_pins, pt_gpio->reg_base + PT_SYNC_REG);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
dev_dbg(gc->parent, "pt_gpio_free offset=%x\n", offset);
}

View File

@ -92,9 +92,9 @@ brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
unsigned long status;
unsigned long flags;
spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
status = __brcmstb_gpio_get_active_irqs(bank);
spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
return status;
}
@ -114,14 +114,14 @@ static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
u32 imask;
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id));
if (enable)
imask |= mask;
else
imask &= ~mask;
gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
@ -204,7 +204,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
iedge_config = bank->gc.read_reg(priv->reg_base +
GIO_EC(bank->id)) & ~mask;
@ -220,7 +220,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
bank->gc.write_reg(priv->reg_base + GIO_LEVEL(bank->id),
ilevel | level);
spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
return 0;
}

View File

@ -41,12 +41,12 @@ static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)
struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&chip->bgpio_lock, flags);
raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),
cgpio->regs + CDNS_GPIO_BYPASS_MODE);
spin_unlock_irqrestore(&chip->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
return 0;
}
@ -55,13 +55,13 @@ static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)
struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
unsigned long flags;
spin_lock_irqsave(&chip->bgpio_lock, flags);
raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |
(BIT(offset) & cgpio->bypass_orig),
cgpio->regs + CDNS_GPIO_BYPASS_MODE);
spin_unlock_irqrestore(&chip->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
}
static void cdns_gpio_irq_mask(struct irq_data *d)
@ -90,7 +90,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
u32 mask = BIT(d->hwirq);
int ret = 0;
spin_lock_irqsave(&chip->bgpio_lock, flags);
raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;
int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask;
@ -115,7 +115,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);
err_irq_type:
spin_unlock_irqrestore(&chip->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
return ret;
}

View File

@ -95,7 +95,6 @@ struct dwapb_context {
#endif
struct dwapb_gpio_port_irqchip {
struct irq_chip irqchip;
unsigned int nr_irqs;
unsigned int irq[DWAPB_MAX_GPIOS];
};
@ -243,35 +242,41 @@ static void dwapb_irq_ack(struct irq_data *d)
u32 val = BIT(irqd_to_hwirq(d));
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
dwapb_write(gpio, GPIO_PORTA_EOI, val);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void dwapb_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
unsigned long flags;
u32 val;
spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTMASK) | BIT(irqd_to_hwirq(d));
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTMASK) | BIT(hwirq);
dwapb_write(gpio, GPIO_INTMASK, val);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
gpiochip_disable_irq(gc, hwirq);
}
static void dwapb_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
unsigned long flags;
u32 val;
spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(irqd_to_hwirq(d));
gpiochip_enable_irq(gc, hwirq);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(hwirq);
dwapb_write(gpio, GPIO_INTMASK, val);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void dwapb_irq_enable(struct irq_data *d)
@ -281,11 +286,11 @@ static void dwapb_irq_enable(struct irq_data *d)
unsigned long flags;
u32 val;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTEN);
val |= BIT(irqd_to_hwirq(d));
dwapb_write(gpio, GPIO_INTEN, val);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void dwapb_irq_disable(struct irq_data *d)
@ -295,11 +300,11 @@ static void dwapb_irq_disable(struct irq_data *d)
unsigned long flags;
u32 val;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = dwapb_read(gpio, GPIO_INTEN);
val &= ~BIT(irqd_to_hwirq(d));
dwapb_write(gpio, GPIO_INTEN, val);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int dwapb_irq_set_type(struct irq_data *d, u32 type)
@ -309,7 +314,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
irq_hw_number_t bit = irqd_to_hwirq(d);
unsigned long level, polarity, flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
polarity = dwapb_read(gpio, GPIO_INT_POLARITY);
@ -344,7 +349,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level);
if (type != IRQ_TYPE_EDGE_BOTH)
dwapb_write(gpio, GPIO_INT_POLARITY, polarity);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
@ -364,8 +369,23 @@ static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)
return 0;
}
#else
#define dwapb_irq_set_wake NULL
#endif
static const struct irq_chip dwapb_irq_chip = {
.name = DWAPB_DRIVER_NAME,
.irq_ack = dwapb_irq_ack,
.irq_mask = dwapb_irq_mask,
.irq_unmask = dwapb_irq_unmask,
.irq_set_type = dwapb_irq_set_type,
.irq_enable = dwapb_irq_enable,
.irq_disable = dwapb_irq_disable,
.irq_set_wake = dwapb_irq_set_wake,
.flags = IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
unsigned offset, unsigned debounce)
{
@ -374,7 +394,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
unsigned long flags, val_deb;
unsigned long mask = BIT(offset);
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
if (debounce)
@ -383,7 +403,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
val_deb &= ~mask;
dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
@ -439,16 +459,6 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
girq->default_type = IRQ_TYPE_NONE;
port->pirq = pirq;
pirq->irqchip.name = DWAPB_DRIVER_NAME;
pirq->irqchip.irq_ack = dwapb_irq_ack;
pirq->irqchip.irq_mask = dwapb_irq_mask;
pirq->irqchip.irq_unmask = dwapb_irq_unmask;
pirq->irqchip.irq_set_type = dwapb_irq_set_type;
pirq->irqchip.irq_enable = dwapb_irq_enable;
pirq->irqchip.irq_disable = dwapb_irq_disable;
#ifdef CONFIG_PM_SLEEP
pirq->irqchip.irq_set_wake = dwapb_irq_set_wake;
#endif
/*
* Intel ACPI-based platforms mostly have the DesignWare APB GPIO
@ -475,7 +485,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
girq->parent_handler = dwapb_irq_handler;
}
girq->chip = &pirq->irqchip;
gpio_irq_chip_set_chip(girq, &dwapb_irq_chip);
return;
@ -738,7 +748,7 @@ static int dwapb_gpio_suspend(struct device *dev)
unsigned long flags;
int i;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
for (i = 0; i < gpio->nr_ports; i++) {
unsigned int offset;
unsigned int idx = gpio->ports[i].idx;
@ -765,7 +775,7 @@ static int dwapb_gpio_suspend(struct device *dev)
dwapb_write(gpio, GPIO_INTMASK, ~ctx->wake_en);
}
}
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
@ -785,7 +795,7 @@ static int dwapb_gpio_resume(struct device *dev)
return err;
}
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
for (i = 0; i < gpio->nr_ports; i++) {
unsigned int offset;
unsigned int idx = gpio->ports[i].idx;
@ -812,7 +822,7 @@ static int dwapb_gpio_resume(struct device *dev)
dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff);
}
}
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}

View File

@ -315,8 +315,8 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)
return 0;
dis_clk:
if (!IS_ERR(g->clk))
clk_disable_unprepare(g->clk);
clk_disable_unprepare(g->clk);
return ret;
}
@ -324,8 +324,8 @@ static int ftgpio_gpio_remove(struct platform_device *pdev)
{
struct ftgpio_gpio *g = platform_get_drvdata(pdev);
if (!IS_ERR(g->clk))
clk_disable_unprepare(g->clk);
clk_disable_unprepare(g->clk);
return 0;
}

View File

@ -42,7 +42,7 @@ struct gpiomm_gpio {
unsigned char out_state[6];
unsigned char control[2];
spinlock_t lock;
unsigned int base;
void __iomem *base;
};
static int gpiomm_gpio_get_direction(struct gpio_chip *chip,
@ -64,7 +64,6 @@ static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
const unsigned int io_port = offset / 8;
const unsigned int control_port = io_port / 3;
const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;
unsigned long flags;
unsigned int control;
@ -89,7 +88,7 @@ static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
}
control = BIT(7) | gpiommgpio->control[control_port];
outb(control, control_addr);
iowrite8(control, gpiommgpio->base + 3 + control_port*4);
spin_unlock_irqrestore(&gpiommgpio->lock, flags);
@ -103,7 +102,6 @@ static int gpiomm_gpio_direction_output(struct gpio_chip *chip,
const unsigned int io_port = offset / 8;
const unsigned int control_port = io_port / 3;
const unsigned int mask = BIT(offset % 8);
const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;
const unsigned int out_port = (io_port > 2) ? io_port + 1 : io_port;
unsigned long flags;
unsigned int control;
@ -134,9 +132,9 @@ static int gpiomm_gpio_direction_output(struct gpio_chip *chip,
gpiommgpio->out_state[io_port] &= ~mask;
control = BIT(7) | gpiommgpio->control[control_port];
outb(control, control_addr);
iowrite8(control, gpiommgpio->base + 3 + control_port*4);
outb(gpiommgpio->out_state[io_port], gpiommgpio->base + out_port);
iowrite8(gpiommgpio->out_state[io_port], gpiommgpio->base + out_port);
spin_unlock_irqrestore(&gpiommgpio->lock, flags);
@ -160,7 +158,7 @@ static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)
return -EINVAL;
}
port_state = inb(gpiommgpio->base + in_port);
port_state = ioread8(gpiommgpio->base + in_port);
spin_unlock_irqrestore(&gpiommgpio->lock, flags);
@ -175,7 +173,7 @@ static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
unsigned long offset;
unsigned long gpio_mask;
unsigned int port_addr;
void __iomem *port_addr;
unsigned long port_state;
/* clear bits array to a clean slate */
@ -183,7 +181,7 @@ static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
port_addr = gpiommgpio->base + ports[offset / 8];
port_state = inb(port_addr) & gpio_mask;
port_state = ioread8(port_addr) & gpio_mask;
bitmap_set_value8(bits, port_state, offset);
}
@ -207,7 +205,7 @@ static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,
else
gpiommgpio->out_state[port] &= ~mask;
outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port);
iowrite8(gpiommgpio->out_state[port], gpiommgpio->base + out_port);
spin_unlock_irqrestore(&gpiommgpio->lock, flags);
}
@ -219,7 +217,7 @@ static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,
unsigned long offset;
unsigned long gpio_mask;
size_t index;
unsigned int port_addr;
void __iomem *port_addr;
unsigned long bitmask;
unsigned long flags;
@ -234,7 +232,7 @@ static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,
/* update output state data and set device gpio register */
gpiommgpio->out_state[index] &= ~gpio_mask;
gpiommgpio->out_state[index] |= bitmask;
outb(gpiommgpio->out_state[index], port_addr);
iowrite8(gpiommgpio->out_state[index], port_addr);
spin_unlock_irqrestore(&gpiommgpio->lock, flags);
}
@ -268,6 +266,10 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
return -EBUSY;
}
gpiommgpio->base = devm_ioport_map(dev, base[id], GPIOMM_EXTENT);
if (!gpiommgpio->base)
return -ENOMEM;
gpiommgpio->chip.label = name;
gpiommgpio->chip.parent = dev;
gpiommgpio->chip.owner = THIS_MODULE;
@ -281,7 +283,6 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple;
gpiommgpio->chip.set = gpiomm_gpio_set;
gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple;
gpiommgpio->base = base[id];
spin_lock_init(&gpiommgpio->lock);
@ -292,14 +293,14 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
}
/* initialize all GPIO as output */
outb(0x80, base[id] + 3);
outb(0x00, base[id]);
outb(0x00, base[id] + 1);
outb(0x00, base[id] + 2);
outb(0x80, base[id] + 7);
outb(0x00, base[id] + 4);
outb(0x00, base[id] + 5);
outb(0x00, base[id] + 6);
iowrite8(0x80, gpiommgpio->base + 3);
iowrite8(0x00, gpiommgpio->base);
iowrite8(0x00, gpiommgpio->base + 1);
iowrite8(0x00, gpiommgpio->base + 2);
iowrite8(0x80, gpiommgpio->base + 7);
iowrite8(0x00, gpiommgpio->base + 4);
iowrite8(0x00, gpiommgpio->base + 5);
iowrite8(0x00, gpiommgpio->base + 6);
return 0;
}

View File

@ -145,7 +145,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
ipol = priv->gc.read_reg(priv->regs + GRGPIO_IPOL) & ~mask;
iedge = priv->gc.read_reg(priv->regs + GRGPIO_IEDGE) & ~mask;
@ -153,7 +153,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)
priv->gc.write_reg(priv->regs + GRGPIO_IPOL, ipol | pol);
priv->gc.write_reg(priv->regs + GRGPIO_IEDGE, iedge | edge);
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
return 0;
}
@ -164,11 +164,11 @@ static void grgpio_irq_mask(struct irq_data *d)
int offset = d->hwirq;
unsigned long flags;
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
grgpio_set_imask(priv, offset, 0);
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
}
static void grgpio_irq_unmask(struct irq_data *d)
@ -177,11 +177,11 @@ static void grgpio_irq_unmask(struct irq_data *d)
int offset = d->hwirq;
unsigned long flags;
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
grgpio_set_imask(priv, offset, 1);
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
}
static struct irq_chip grgpio_irq_chip = {
@ -199,7 +199,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)
int i;
int match = 0;
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
/*
* For each gpio line, call its interrupt handler if it its underlying
@ -215,7 +215,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)
}
}
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
if (!match)
dev_warn(priv->dev, "No gpio line matched irq %d\n", irq);
@ -247,13 +247,13 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
dev_dbg(priv->dev, "Mapping irq %d for gpio line %d\n",
irq, offset);
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
/* Request underlying irq if not already requested */
lirq->irq = irq;
uirq = &priv->uirqs[lirq->index];
if (uirq->refcnt == 0) {
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
dev_name(priv->dev), priv);
if (ret) {
@ -262,11 +262,11 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
uirq->uirq);
return ret;
}
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
}
uirq->refcnt++;
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
/* Setup irq */
irq_set_chip_data(irq, priv);
@ -290,7 +290,7 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
irq_set_chip_and_handler(irq, NULL, NULL);
irq_set_chip_data(irq, NULL);
spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
/* Free underlying irq if last user unmapped */
index = -1;
@ -309,13 +309,13 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
uirq = &priv->uirqs[lirq->index];
uirq->refcnt--;
if (uirq->refcnt == 0) {
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
free_irq(uirq->uirq, priv);
return;
}
}
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
}
static const struct irq_domain_ops grgpio_irq_domain_ops = {

View File

@ -65,7 +65,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
int hwirq;
u32 emulated_pending;
spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
pending = ioread32be(hlwd->regs + HW_GPIOB_INTFLAG);
pending &= ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
@ -93,7 +93,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
/* Mark emulated interrupts as pending */
pending |= rising | falling;
}
spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
chained_irq_enter(chip, desc);
@ -118,11 +118,11 @@ static void hlwd_gpio_irq_mask(struct irq_data *data)
unsigned long flags;
u32 mask;
spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
mask &= ~BIT(data->hwirq);
iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
}
static void hlwd_gpio_irq_unmask(struct irq_data *data)
@ -132,11 +132,11 @@ static void hlwd_gpio_irq_unmask(struct irq_data *data)
unsigned long flags;
u32 mask;
spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
mask |= BIT(data->hwirq);
iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
}
static void hlwd_gpio_irq_enable(struct irq_data *data)
@ -173,7 +173,7 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
unsigned long flags;
u32 level;
spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
hlwd->edge_emulation &= ~BIT(data->hwirq);
@ -194,11 +194,11 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
hlwd_gpio_irq_setup_emulation(hlwd, data->hwirq, flow_type);
break;
default:
spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
return -EINVAL;
}
spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
return 0;
}

View File

@ -57,7 +57,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))
return -EINVAL;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
if (sense & IRQ_TYPE_LEVEL_HIGH)
@ -68,7 +68,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
irq_set_handler_locked(d, handle_level_irq);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
@ -86,12 +86,12 @@ static void idt_gpio_mask(struct irq_data *d)
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
ctrl->mask_cache |= BIT(d->hwirq);
writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void idt_gpio_unmask(struct irq_data *d)
@ -100,12 +100,12 @@ static void idt_gpio_unmask(struct irq_data *d)
struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
ctrl->mask_cache &= ~BIT(d->hwirq);
writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int idt_gpio_irq_init_hw(struct gpio_chip *gc)

View File

@ -14,10 +14,6 @@
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/bitops.h>
/* Include that go away with DT transition */
#include <linux/irqchip/irq-ixp4xx.h>
#include <asm/mach-types.h>
#define IXP4XX_REG_GPOUT 0x00
#define IXP4XX_REG_GPOE 0x04
@ -128,7 +124,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
int_reg = IXP4XX_REG_GPIT1;
}
spin_lock_irqsave(&g->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&g->gc.bgpio_lock, flags);
/* Clear the style for the appropriate pin */
val = __raw_readl(g->base + int_reg);
@ -147,7 +143,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
val |= BIT(d->hwirq);
__raw_writel(val, g->base + IXP4XX_REG_GPOE);
spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
/* This parent only accept level high (asserted) */
return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
@ -195,6 +191,7 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct ixp4xx_gpio *g;
struct gpio_irq_chip *girq;
struct device_node *irq_parent;
int ret;
g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL);
@ -207,40 +204,24 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
if (IS_ERR(g->base))
return PTR_ERR(g->base);
/*
* When we convert to device tree we will simply look up the
* parent irqdomain using irq_find_host(parent) as parent comes
* from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get
* the fwnode. For now we need this boardfile style code.
*/
if (np) {
struct device_node *irq_parent;
irq_parent = of_irq_find_parent(np);
if (!irq_parent) {
dev_err(dev, "no IRQ parent node\n");
return -ENODEV;
}
parent = irq_find_host(irq_parent);
if (!parent) {
dev_err(dev, "no IRQ parent domain\n");
return -ENODEV;
}
g->fwnode = of_node_to_fwnode(np);
} else {
parent = ixp4xx_get_irq_domain();
g->fwnode = irq_domain_alloc_fwnode(&res->start);
if (!g->fwnode) {
dev_err(dev, "no domain base\n");
return -ENODEV;
}
irq_parent = of_irq_find_parent(np);
if (!irq_parent) {
dev_err(dev, "no IRQ parent node\n");
return -ENODEV;
}
parent = irq_find_host(irq_parent);
if (!parent) {
dev_err(dev, "no IRQ parent domain\n");
return -ENODEV;
}
g->fwnode = of_node_to_fwnode(np);
/*
* Make sure GPIO 14 and 15 are NOT used as clocks but GPIO on
* specific machines.
*/
if (machine_is_dsmg600() || machine_is_nas100d())
if (of_machine_is_compatible("dlink,dsm-g600-a") ||
of_machine_is_compatible("iom,nas-100d"))
__raw_writel(0x0, g->base + IXP4XX_REG_GPCLK);
/*

View File

@ -25,10 +25,10 @@ static int ls1x_gpio_request(struct gpio_chip *gc, unsigned int offset)
{
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
__raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) | BIT(offset),
gpio_reg_base + GPIO_CFG);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
@ -37,10 +37,10 @@ static void ls1x_gpio_free(struct gpio_chip *gc, unsigned int offset)
{
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
__raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) & ~BIT(offset),
gpio_reg_base + GPIO_CFG);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int ls1x_gpio_probe(struct platform_device *pdev)

View File

@ -496,17 +496,13 @@ static int max732x_irq_setup(struct max732x_chip *chip,
const struct i2c_device_id *id)
{
struct i2c_client *client = chip->client;
struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
int has_irq = max732x_features[id->driver_data] >> 32;
int irq_base = 0;
int ret;
if (((pdata && pdata->irq_base) || client->irq)
&& has_irq != INT_NONE) {
if (client->irq && has_irq != INT_NONE) {
struct gpio_irq_chip *girq;
if (pdata)
irq_base = pdata->irq_base;
chip->irq_features = has_irq;
mutex_init(&chip->irq_lock);
@ -540,10 +536,9 @@ static int max732x_irq_setup(struct max732x_chip *chip,
const struct i2c_device_id *id)
{
struct i2c_client *client = chip->client;
struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
int has_irq = max732x_features[id->driver_data] >> 32;
if (((pdata && pdata->irq_base) || client->irq) && has_irq != INT_NONE)
if (client->irq && has_irq != INT_NONE)
dev_warn(&client->dev, "interrupt support not compiled in\n");
return 0;
@ -703,44 +698,16 @@ static int max732x_probe(struct i2c_client *client,
if (ret)
return ret;
if (pdata->setup) {
ret = pdata->setup(client, chip->gpio_chip.base,
chip->gpio_chip.ngpio, pdata->context);
if (ret < 0)
dev_warn(&client->dev, "setup failed, %d\n", ret);
}
i2c_set_clientdata(client, chip);
return 0;
}
static int max732x_remove(struct i2c_client *client)
{
struct max732x_platform_data *pdata = dev_get_platdata(&client->dev);
struct max732x_chip *chip = i2c_get_clientdata(client);
if (pdata && pdata->teardown) {
int ret;
ret = pdata->teardown(client, chip->gpio_chip.base,
chip->gpio_chip.ngpio, pdata->context);
if (ret < 0) {
dev_err(&client->dev, "%s failed, %d\n",
"teardown", ret);
return ret;
}
}
return 0;
}
static struct i2c_driver max732x_driver = {
.driver = {
.name = "max732x",
.of_match_table = of_match_ptr(max732x_of_table),
},
.probe = max732x_probe,
.remove = max732x_remove,
.id_table = max732x_id,
};

View File

@ -54,6 +54,7 @@ static void max77620_gpio_irq_mask(struct irq_data *data)
struct max77620_gpio *gpio = gpiochip_get_data(chip);
gpio->irq_enabled[data->hwirq] = false;
gpiochip_disable_irq(chip, data->hwirq);
}
static void max77620_gpio_irq_unmask(struct irq_data *data)
@ -61,6 +62,7 @@ static void max77620_gpio_irq_unmask(struct irq_data *data)
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct max77620_gpio *gpio = gpiochip_get_data(chip);
gpiochip_enable_irq(chip, data->hwirq);
gpio->irq_enabled[data->hwirq] = true;
}
@ -119,14 +121,15 @@ static void max77620_gpio_bus_sync_unlock(struct irq_data *data)
mutex_unlock(&gpio->buslock);
}
static struct irq_chip max77620_gpio_irqchip = {
static const struct irq_chip max77620_gpio_irqchip = {
.name = "max77620-gpio",
.irq_mask = max77620_gpio_irq_mask,
.irq_unmask = max77620_gpio_irq_unmask,
.irq_set_type = max77620_gpio_set_irq_type,
.irq_bus_lock = max77620_gpio_bus_lock,
.irq_bus_sync_unlock = max77620_gpio_bus_sync_unlock,
.flags = IRQCHIP_MASK_ON_SUSPEND,
.flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static int max77620_gpio_dir_input(struct gpio_chip *gc, unsigned int offset)
@ -318,7 +321,7 @@ static int max77620_gpio_probe(struct platform_device *pdev)
mgpio->gpio_chip.base = -1;
girq = &mgpio->gpio_chip.irq;
girq->chip = &max77620_gpio_irqchip;
gpio_irq_chip_set_chip(girq, &max77620_gpio_irqchip);
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;

View File

@ -64,7 +64,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
debounce /= 50;
}
spin_lock(&gc->bgpio_lock);
raw_spin_lock(&gc->bgpio_lock);
db_en = readl(priv->reg_base + MEN_Z127_DBER);
@ -79,7 +79,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
writel(db_en, priv->reg_base + MEN_Z127_DBER);
writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio));
spin_unlock(&gc->bgpio_lock);
raw_spin_unlock(&gc->bgpio_lock);
return 0;
}
@ -91,7 +91,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,
struct men_z127_gpio *priv = gpiochip_get_data(gc);
u32 od_en;
spin_lock(&gc->bgpio_lock);
raw_spin_lock(&gc->bgpio_lock);
od_en = readl(priv->reg_base + MEN_Z127_ODER);
if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
@ -101,7 +101,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,
od_en &= ~BIT(offset);
writel(od_en, priv->reg_base + MEN_Z127_ODER);
spin_unlock(&gc->bgpio_lock);
raw_spin_unlock(&gc->bgpio_lock);
return 0;
}

View File

@ -409,29 +409,27 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
void *chip_save;
int irq_base;
ret = pci_enable_device(pdev);
ret = pcim_enable_device(pdev);
if (ret) {
dev_err(dev, "%s : pci_enable_device failed", __func__);
goto err_pci_enable;
dev_err(dev, "%s : pcim_enable_device failed", __func__);
return ret;
}
ret = pci_request_regions(pdev, KBUILD_MODNAME);
ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME);
if (ret) {
dev_err(dev, "pci_request_regions failed-%d", ret);
goto err_request_regions;
dev_err(dev, "pcim_iomap_regions failed-%d", ret);
return ret;
}
base = pci_iomap(pdev, 1, 0);
base = pcim_iomap_table(pdev)[1];
if (!base) {
dev_err(dev, "%s : pci_iomap failed", __func__);
ret = -ENOMEM;
goto err_iomap;
dev_err(dev, "%s : pcim_iomap_table failed", __func__);
return -ENOMEM;
}
chip_save = kcalloc(8, sizeof(*chip), GFP_KERNEL);
chip_save = devm_kcalloc(dev, 8, sizeof(*chip), GFP_KERNEL);
if (chip_save == NULL) {
ret = -ENOMEM;
goto err_kzalloc;
return -ENOMEM;
}
chip = chip_save;
@ -442,10 +440,10 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
chip->ch = i;
spin_lock_init(&chip->spinlock);
ioh_gpio_setup(chip, num_ports[i]);
ret = gpiochip_add_data(&chip->gpio, chip);
ret = devm_gpiochip_add_data(dev, &chip->gpio, chip);
if (ret) {
dev_err(dev, "IOH gpio: Failed to register GPIO\n");
goto err_gpiochip_add;
return ret;
}
}
@ -456,15 +454,14 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
if (irq_base < 0) {
dev_warn(dev,
"ml_ioh_gpio: Failed to get IRQ base num\n");
ret = irq_base;
goto err_gpiochip_add;
return irq_base;
}
chip->irq_base = irq_base;
ret = ioh_gpio_alloc_generic_chip(chip,
irq_base, num_ports[j]);
if (ret)
goto err_gpiochip_add;
return ret;
}
chip = chip_save;
@ -472,52 +469,12 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
IRQF_SHARED, KBUILD_MODNAME, chip);
if (ret != 0) {
dev_err(dev, "%s request_irq failed\n", __func__);
goto err_gpiochip_add;
return ret;
}
pci_set_drvdata(pdev, chip);
return 0;
err_gpiochip_add:
chip = chip_save;
while (--i >= 0) {
gpiochip_remove(&chip->gpio);
chip++;
}
kfree(chip_save);
err_kzalloc:
pci_iounmap(pdev, base);
err_iomap:
pci_release_regions(pdev);
err_request_regions:
pci_disable_device(pdev);
err_pci_enable:
dev_err(dev, "%s Failed returns %d\n", __func__, ret);
return ret;
}
static void ioh_gpio_remove(struct pci_dev *pdev)
{
int i;
struct ioh_gpio *chip = pci_get_drvdata(pdev);
void *chip_save;
chip_save = chip;
for (i = 0; i < 8; i++, chip++)
gpiochip_remove(&chip->gpio);
chip = chip_save;
pci_iounmap(pdev, chip->base);
pci_release_regions(pdev);
pci_disable_device(pdev);
kfree(chip);
}
static int __maybe_unused ioh_gpio_suspend(struct device *dev)
@ -558,7 +515,6 @@ static struct pci_driver ioh_gpio_driver = {
.name = "ml_ioh_gpio",
.id_table = ioh_gpio_pcidev_id,
.probe = ioh_gpio_probe,
.remove = ioh_gpio_remove,
.driver = {
.pm = &ioh_gpio_pm_ops,
},

View File

@ -131,7 +131,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
u32 arm_gpio_lock_val;
mutex_lock(yu_arm_gpio_lock_param.lock);
spin_lock(&gs->gc.bgpio_lock);
raw_spin_lock(&gs->gc.bgpio_lock);
arm_gpio_lock_val = readl(yu_arm_gpio_lock_param.io);
@ -139,7 +139,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
* When lock active bit[31] is set, ModeX is write enabled
*/
if (YU_LOCK_ACTIVE_BIT(arm_gpio_lock_val)) {
spin_unlock(&gs->gc.bgpio_lock);
raw_spin_unlock(&gs->gc.bgpio_lock);
mutex_unlock(yu_arm_gpio_lock_param.lock);
return -EINVAL;
}
@ -157,7 +157,7 @@ static void mlxbf2_gpio_lock_release(struct mlxbf2_gpio_context *gs)
__releases(yu_arm_gpio_lock_param.lock)
{
writel(YU_ARM_GPIO_LOCK_RELEASE, yu_arm_gpio_lock_param.io);
spin_unlock(&gs->gc.bgpio_lock);
raw_spin_unlock(&gs->gc.bgpio_lock);
mutex_unlock(yu_arm_gpio_lock_param.lock);
}
@ -237,7 +237,7 @@ static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)
unsigned long flags;
u32 val;
spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
val |= BIT(offset);
writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
@ -245,7 +245,7 @@ static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)
val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
val |= BIT(offset);
writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
}
static void mlxbf2_gpio_irq_disable(struct irq_data *irqd)
@ -256,11 +256,11 @@ static void mlxbf2_gpio_irq_disable(struct irq_data *irqd)
unsigned long flags;
u32 val;
spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
val &= ~BIT(offset);
writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
}
static irqreturn_t mlxbf2_gpio_irq_handler(int irq, void *ptr)
@ -307,7 +307,7 @@ mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
return -EINVAL;
}
spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
if (fall) {
val = readl(gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);
val |= BIT(offset);
@ -319,7 +319,7 @@ mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
val |= BIT(offset);
writel(val, gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);
}
spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
return 0;
}

View File

@ -220,7 +220,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
unsigned long mask = bgpio_line2mask(gc, gpio);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
if (val)
gc->bgpio_data |= mask;
@ -229,7 +229,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
gc->write_reg(gc->reg_dat, gc->bgpio_data);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
@ -248,7 +248,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
unsigned long mask = bgpio_line2mask(gc, gpio);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
if (val)
gc->bgpio_data |= mask;
@ -257,7 +257,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
gc->write_reg(gc->reg_set, gc->bgpio_data);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void bgpio_multiple_get_masks(struct gpio_chip *gc,
@ -286,7 +286,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
unsigned long flags;
unsigned long set_mask, clear_mask;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask);
@ -295,7 +295,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
gc->write_reg(reg, gc->bgpio_data);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
@ -347,7 +347,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
@ -356,7 +356,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
if (gc->reg_dir_out)
gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
return 0;
}
@ -387,7 +387,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
@ -396,7 +396,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
if (gc->reg_dir_out)
gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
@ -610,7 +610,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
if (gc->bgpio_bits > BITS_PER_LONG)
return -EINVAL;
spin_lock_init(&gc->bgpio_lock);
raw_spin_lock_init(&gc->bgpio_lock);
gc->parent = dev;
gc->label = dev_name(dev);
gc->base = -1;

View File

@ -71,6 +71,7 @@
#define PCA_CHIP_TYPE(x) ((x) & PCA_TYPE_MASK)
static const struct i2c_device_id pca953x_id[] = {
{ "pca6408", 8 | PCA953X_TYPE | PCA_INT, },
{ "pca6416", 16 | PCA953X_TYPE | PCA_INT, },
{ "pca9505", 40 | PCA953X_TYPE | PCA_INT, },
{ "pca9506", 40 | PCA953X_TYPE | PCA_INT, },
@ -200,7 +201,6 @@ struct pca953x_chip {
DECLARE_BITMAP(irq_stat, MAX_LINE);
DECLARE_BITMAP(irq_trig_raise, MAX_LINE);
DECLARE_BITMAP(irq_trig_fall, MAX_LINE);
struct irq_chip irq_chip;
#endif
atomic_t wakeup_path;
@ -628,6 +628,7 @@ static void pca953x_irq_mask(struct irq_data *d)
irq_hw_number_t hwirq = irqd_to_hwirq(d);
clear_bit(hwirq, chip->irq_mask);
gpiochip_disable_irq(gc, hwirq);
}
static void pca953x_irq_unmask(struct irq_data *d)
@ -636,6 +637,7 @@ static void pca953x_irq_unmask(struct irq_data *d)
struct pca953x_chip *chip = gpiochip_get_data(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
gpiochip_enable_irq(gc, hwirq);
set_bit(hwirq, chip->irq_mask);
}
@ -720,6 +722,26 @@ static void pca953x_irq_shutdown(struct irq_data *d)
clear_bit(hwirq, chip->irq_trig_fall);
}
static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
seq_printf(p, dev_name(gc->parent));
}
static const struct irq_chip pca953x_irq_chip = {
.irq_mask = pca953x_irq_mask,
.irq_unmask = pca953x_irq_unmask,
.irq_set_wake = pca953x_irq_set_wake,
.irq_bus_lock = pca953x_irq_bus_lock,
.irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock,
.irq_set_type = pca953x_irq_set_type,
.irq_shutdown = pca953x_irq_shutdown,
.irq_print_chip = pca953x_irq_print_chip,
.flags = IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending)
{
struct gpio_chip *gc = &chip->gpio_chip;
@ -811,7 +833,6 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)
{
struct i2c_client *client = chip->client;
struct irq_chip *irq_chip = &chip->irq_chip;
DECLARE_BITMAP(reg_direction, MAX_LINE);
DECLARE_BITMAP(irq_stat, MAX_LINE);
struct gpio_irq_chip *girq;
@ -845,17 +866,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)
bitmap_and(chip->irq_stat, irq_stat, reg_direction, chip->gpio_chip.ngpio);
mutex_init(&chip->irq_lock);
irq_chip->name = dev_name(&client->dev);
irq_chip->irq_mask = pca953x_irq_mask;
irq_chip->irq_unmask = pca953x_irq_unmask;
irq_chip->irq_set_wake = pca953x_irq_set_wake;
irq_chip->irq_bus_lock = pca953x_irq_bus_lock;
irq_chip->irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock;
irq_chip->irq_set_type = pca953x_irq_set_type;
irq_chip->irq_shutdown = pca953x_irq_shutdown;
girq = &chip->gpio_chip.irq;
girq->chip = irq_chip;
gpio_irq_chip_set_chip(girq, &pca953x_irq_chip);
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
@ -1198,6 +1210,7 @@ static int pca953x_resume(struct device *dev)
#define OF_957X(__nrgpio, __int) (void *)(__nrgpio | PCA957X_TYPE | __int)
static const struct of_device_id pca953x_dt_ids[] = {
{ .compatible = "nxp,pca6408", .data = OF_953X(8, PCA_INT), },
{ .compatible = "nxp,pca6416", .data = OF_953X(16, PCA_INT), },
{ .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
{ .compatible = "nxp,pca9506", .data = OF_953X(40, PCA_INT), },

View File

@ -71,7 +71,6 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table);
*/
struct pcf857x {
struct gpio_chip chip;
struct irq_chip irqchip;
struct i2c_client *client;
struct mutex lock; /* protect 'out' */
unsigned out; /* software latch */
@ -203,15 +202,19 @@ static int pcf857x_irq_set_wake(struct irq_data *data, unsigned int on)
static void pcf857x_irq_enable(struct irq_data *data)
{
struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
irq_hw_number_t hwirq = irqd_to_hwirq(data);
gpio->irq_enabled |= (1 << data->hwirq);
gpiochip_enable_irq(&gpio->chip, hwirq);
gpio->irq_enabled |= (1 << hwirq);
}
static void pcf857x_irq_disable(struct irq_data *data)
{
struct pcf857x *gpio = irq_data_get_irq_chip_data(data);
irq_hw_number_t hwirq = irqd_to_hwirq(data);
gpio->irq_enabled &= ~(1 << data->hwirq);
gpio->irq_enabled &= ~(1 << hwirq);
gpiochip_disable_irq(&gpio->chip, hwirq);
}
static void pcf857x_irq_bus_lock(struct irq_data *data)
@ -228,6 +231,20 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)
mutex_unlock(&gpio->lock);
}
static const struct irq_chip pcf857x_irq_chip = {
.name = "pcf857x",
.irq_enable = pcf857x_irq_enable,
.irq_disable = pcf857x_irq_disable,
.irq_ack = noop,
.irq_mask = noop,
.irq_unmask = noop,
.irq_set_wake = pcf857x_irq_set_wake,
.irq_bus_lock = pcf857x_irq_bus_lock,
.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock,
.flags = IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
/*-------------------------------------------------------------------------*/
static int pcf857x_probe(struct i2c_client *client,
@ -338,16 +355,6 @@ static int pcf857x_probe(struct i2c_client *client,
if (client->irq) {
struct gpio_irq_chip *girq;
gpio->irqchip.name = "pcf857x";
gpio->irqchip.irq_enable = pcf857x_irq_enable;
gpio->irqchip.irq_disable = pcf857x_irq_disable;
gpio->irqchip.irq_ack = noop;
gpio->irqchip.irq_mask = noop;
gpio->irqchip.irq_unmask = noop;
gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake;
gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock;
gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock;
status = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf857x_irq, IRQF_ONESHOT |
IRQF_TRIGGER_FALLING | IRQF_SHARED,
@ -356,7 +363,7 @@ static int pcf857x_probe(struct i2c_client *client,
goto fail;
girq = &gpio->chip.irq;
girq->chip = &gpio->irqchip;
gpio_irq_chip_set_chip(girq, &pcf857x_irq_chip);
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
@ -396,20 +403,12 @@ static int pcf857x_remove(struct i2c_client *client)
{
struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev);
struct pcf857x *gpio = i2c_get_clientdata(client);
int status = 0;
if (pdata && pdata->teardown) {
status = pdata->teardown(client,
gpio->chip.base, gpio->chip.ngpio,
if (pdata && pdata->teardown)
pdata->teardown(client, gpio->chip.base, gpio->chip.ngpio,
pdata->context);
if (status < 0) {
dev_err(&client->dev, "%s --> %d\n",
"teardown", status);
return status;
}
}
return status;
return 0;
}
static void pcf857x_shutdown(struct i2c_client *client)

View File

@ -44,7 +44,6 @@ struct gpio_rcar_priv {
spinlock_t lock;
struct device *dev;
struct gpio_chip gpio_chip;
struct irq_chip irq_chip;
unsigned int irq_parent;
atomic_t wakeup_path;
struct gpio_rcar_info info;
@ -96,16 +95,20 @@ static void gpio_rcar_irq_disable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpiochip_get_data(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
gpio_rcar_write(p, INTMSK, ~BIT(irqd_to_hwirq(d)));
gpio_rcar_write(p, INTMSK, ~BIT(hwirq));
gpiochip_disable_irq(gc, hwirq);
}
static void gpio_rcar_irq_enable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpiochip_get_data(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
gpio_rcar_write(p, MSKCLR, BIT(irqd_to_hwirq(d)));
gpiochip_enable_irq(gc, hwirq);
gpio_rcar_write(p, MSKCLR, BIT(hwirq));
}
static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,
@ -203,6 +206,17 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)
return 0;
}
static const struct irq_chip gpio_rcar_irq_chip = {
.name = "gpio-rcar",
.irq_mask = gpio_rcar_irq_disable,
.irq_unmask = gpio_rcar_irq_enable,
.irq_set_type = gpio_rcar_irq_set_type,
.irq_set_wake = gpio_rcar_irq_set_wake,
.flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED |
IRQCHIP_MASK_ON_SUSPEND,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
{
struct gpio_rcar_priv *p = dev_id;
@ -411,7 +425,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen3 = {
.has_inen = false,
};
static const struct gpio_rcar_info gpio_rcar_info_v3u = {
static const struct gpio_rcar_info gpio_rcar_info_gen4 = {
.has_outdtsel = true,
.has_both_edge_trigger = true,
.has_always_in = true,
@ -421,7 +435,7 @@ static const struct gpio_rcar_info gpio_rcar_info_v3u = {
static const struct of_device_id gpio_rcar_of_table[] = {
{
.compatible = "renesas,gpio-r8a779a0",
.data = &gpio_rcar_info_v3u,
.data = &gpio_rcar_info_gen4,
}, {
.compatible = "renesas,rcar-gen1-gpio",
.data = &gpio_rcar_info_gen1,
@ -431,6 +445,9 @@ static const struct of_device_id gpio_rcar_of_table[] = {
}, {
.compatible = "renesas,rcar-gen3-gpio",
.data = &gpio_rcar_info_gen3,
}, {
.compatible = "renesas,rcar-gen4-gpio",
.data = &gpio_rcar_info_gen4,
}, {
.compatible = "renesas,gpio-rcar",
.data = &gpio_rcar_info_gen1,
@ -478,7 +495,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
{
struct gpio_rcar_priv *p;
struct gpio_chip *gpio_chip;
struct irq_chip *irq_chip;
struct gpio_irq_chip *girq;
struct device *dev = &pdev->dev;
const char *name = dev_name(dev);
@ -528,16 +544,8 @@ static int gpio_rcar_probe(struct platform_device *pdev)
gpio_chip->base = -1;
gpio_chip->ngpio = npins;
irq_chip = &p->irq_chip;
irq_chip->name = "gpio-rcar";
irq_chip->irq_mask = gpio_rcar_irq_disable;
irq_chip->irq_unmask = gpio_rcar_irq_enable;
irq_chip->irq_set_type = gpio_rcar_irq_set_type;
irq_chip->irq_set_wake = gpio_rcar_irq_set_wake;
irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;
girq = &gpio_chip->irq;
girq->chip = irq_chip;
gpio_irq_chip_set_chip(girq, &gpio_rcar_irq_chip);
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/gpio/driver.h>
#include <linux/cpumask.h>
#include <linux/irq.h>
#include <linux/minmax.h>
#include <linux/mod_devicetable.h>
@ -55,9 +56,13 @@
struct realtek_gpio_ctrl {
struct gpio_chip gc;
void __iomem *base;
void __iomem *cpumask_base;
struct cpumask cpu_irq_maskable;
raw_spinlock_t lock;
u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK];
u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK];
unsigned int (*port_offset_u8)(unsigned int port);
unsigned int (*port_offset_u16)(unsigned int port);
};
/* Expand with more flags as devices with other quirks are added */
@ -69,6 +74,16 @@ enum realtek_gpio_flags {
* line the IRQ handler was assigned to, causing uncaught interrupts.
*/
GPIO_INTERRUPTS_DISABLED = BIT(0),
/*
* Port order is reversed, meaning DCBA register layout for 1-bit
* fields, and [BA, DC] for 2-bit fields.
*/
GPIO_PORTS_REVERSED = BIT(1),
/*
* Interrupts can be enabled per cpu. This requires a secondary IO
* range, where the per-cpu enable masks are located.
*/
GPIO_INTERRUPTS_PER_CPU = BIT(2),
};
static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)
@ -86,21 +101,50 @@ static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)
* port. The two interrupt mask registers store two bits per GPIO, so use u16
* values.
*/
static unsigned int realtek_gpio_port_offset_u8(unsigned int port)
{
return port;
}
static unsigned int realtek_gpio_port_offset_u16(unsigned int port)
{
return 2 * port;
}
/*
* Reversed port order register access
*
* For registers with one bit per GPIO, all ports are stored as u8-s in one
* register in reversed order. The two interrupt mask registers store two bits
* per GPIO, so use u16 values. The first register contains ports 1 and 0, the
* second ports 3 and 2.
*/
static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port)
{
return 3 - port;
}
static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port)
{
return 2 * (port ^ 1);
}
static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl,
unsigned int port, u16 irq_type, u16 irq_mask)
{
iowrite16(irq_type & irq_mask, ctrl->base + REALTEK_GPIO_REG_IMR + 2 * port);
iowrite16(irq_type & irq_mask,
ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port));
}
static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl,
unsigned int port, u8 mask)
{
iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + port);
iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
}
static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port)
{
return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + port);
return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port));
}
/* Set the rising and falling edge mask bits for a GPIO port pin */
@ -211,14 +255,61 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc)
chained_irq_exit(irq_chip, desc);
}
static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl,
unsigned int port, int cpu)
{
return ctrl->cpumask_base + ctrl->port_offset_u8(port) +
REALTEK_GPIO_PORTS_PER_BANK * cpu;
}
static int realtek_gpio_irq_set_affinity(struct irq_data *data,
const struct cpumask *dest, bool force)
{
struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);
unsigned int line = irqd_to_hwirq(data);
unsigned int port = line / 8;
unsigned int port_pin = line % 8;
void __iomem *irq_cpu_mask;
unsigned long flags;
int cpu;
u8 v;
if (!ctrl->cpumask_base)
return -ENXIO;
raw_spin_lock_irqsave(&ctrl->lock, flags);
for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {
irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu);
v = ioread8(irq_cpu_mask);
if (cpumask_test_cpu(cpu, dest))
v |= BIT(port_pin);
else
v &= ~BIT(port_pin);
iowrite8(v, irq_cpu_mask);
}
raw_spin_unlock_irqrestore(&ctrl->lock, flags);
irq_data_update_effective_affinity(data, dest);
return 0;
}
static int realtek_gpio_irq_init(struct gpio_chip *gc)
{
struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);
unsigned int port;
int cpu;
for (port = 0; (port * 8) < gc->ngpio; port++) {
realtek_gpio_write_imr(ctrl, port, 0, 0);
realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0));
for_each_cpu(cpu, &ctrl->cpu_irq_maskable)
iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu));
}
return 0;
@ -230,6 +321,7 @@ static struct irq_chip realtek_gpio_irq_chip = {
.irq_mask = realtek_gpio_irq_mask,
.irq_unmask = realtek_gpio_irq_unmask,
.irq_set_type = realtek_gpio_irq_set_type,
.irq_set_affinity = realtek_gpio_irq_set_affinity,
};
static const struct of_device_id realtek_gpio_of_match[] = {
@ -243,6 +335,13 @@ static const struct of_device_id realtek_gpio_of_match[] = {
{
.compatible = "realtek,rtl8390-gpio",
},
{
.compatible = "realtek,rtl9300-gpio",
.data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU)
},
{
.compatible = "realtek,rtl9310-gpio",
},
{}
};
MODULE_DEVICE_TABLE(of, realtek_gpio_of_match);
@ -250,11 +349,14 @@ MODULE_DEVICE_TABLE(of, realtek_gpio_of_match);
static int realtek_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
unsigned long bgpio_flags;
unsigned int dev_flags;
struct gpio_irq_chip *girq;
struct realtek_gpio_ctrl *ctrl;
struct resource *res;
u32 ngpios;
int err, irq;
unsigned int nr_cpus;
int cpu, err, irq;
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
@ -277,10 +379,20 @@ static int realtek_gpio_probe(struct platform_device *pdev)
raw_spin_lock_init(&ctrl->lock);
if (dev_flags & GPIO_PORTS_REVERSED) {
bgpio_flags = 0;
ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev;
ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev;
} else {
bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
ctrl->port_offset_u8 = realtek_gpio_port_offset_u8;
ctrl->port_offset_u16 = realtek_gpio_port_offset_u16;
}
err = bgpio_init(&ctrl->gc, dev, 4,
ctrl->base + REALTEK_GPIO_REG_DATA, NULL, NULL,
ctrl->base + REALTEK_GPIO_REG_DIR, NULL,
BGPIOF_BIG_ENDIAN_BYTE_ORDER);
bgpio_flags);
if (err) {
dev_err(dev, "unable to init generic GPIO");
return err;
@ -305,6 +417,21 @@ static int realtek_gpio_probe(struct platform_device *pdev)
girq->init_hw = realtek_gpio_irq_init;
}
cpumask_clear(&ctrl->cpu_irq_maskable);
if ((dev_flags & GPIO_INTERRUPTS_PER_CPU) && irq > 0) {
ctrl->cpumask_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);
if (IS_ERR(ctrl->cpumask_base))
return dev_err_probe(dev, PTR_ERR(ctrl->cpumask_base),
"missing CPU IRQ mask registers");
nr_cpus = resource_size(res) / REALTEK_GPIO_PORTS_PER_BANK;
nr_cpus = min(nr_cpus, num_present_cpus());
for (cpu = 0; cpu < nr_cpus; cpu++)
cpumask_set_cpu(cpu, &ctrl->cpu_irq_maskable);
}
return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
}

View File

@ -44,7 +44,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
unsigned long flags;
unsigned int trigger;
spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;
regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),
(trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0);
@ -54,7 +54,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
(trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);
regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),
(trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0);
spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
}
static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
@ -75,22 +75,24 @@ static void sifive_gpio_irq_enable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct sifive_gpio *chip = gpiochip_get_data(gc);
int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
irq_hw_number_t hwirq = irqd_to_hwirq(d);
int offset = hwirq % SIFIVE_GPIO_MAX;
u32 bit = BIT(offset);
unsigned long flags;
gpiochip_enable_irq(gc, hwirq);
irq_chip_enable_parent(d);
/* Switch to input */
gc->direction_input(gc, offset);
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
/* Clear any sticky pending interrupts */
regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
/* Enable interrupts */
assign_bit(offset, &chip->irq_state, 1);
@ -101,11 +103,13 @@ static void sifive_gpio_irq_disable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct sifive_gpio *chip = gpiochip_get_data(gc);
int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
irq_hw_number_t hwirq = irqd_to_hwirq(d);
int offset = hwirq % SIFIVE_GPIO_MAX;
assign_bit(offset, &chip->irq_state, 0);
sifive_gpio_set_ie(chip, offset);
irq_chip_disable_parent(d);
gpiochip_disable_irq(gc, hwirq);
}
static void sifive_gpio_irq_eoi(struct irq_data *d)
@ -116,13 +120,13 @@ static void sifive_gpio_irq_eoi(struct irq_data *d)
u32 bit = BIT(offset);
unsigned long flags;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
/* Clear all pending interrupts */
regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
irq_chip_eoi_parent(d);
}
@ -137,7 +141,7 @@ static int sifive_gpio_irq_set_affinity(struct irq_data *data,
return -EINVAL;
}
static struct irq_chip sifive_gpio_irqchip = {
static const struct irq_chip sifive_gpio_irqchip = {
.name = "sifive-gpio",
.irq_set_type = sifive_gpio_irq_set_type,
.irq_mask = irq_chip_mask_parent,
@ -146,6 +150,8 @@ static struct irq_chip sifive_gpio_irqchip = {
.irq_disable = sifive_gpio_irq_disable,
.irq_eoi = sifive_gpio_irq_eoi,
.irq_set_affinity = sifive_gpio_irq_set_affinity,
.flags = IRQCHIP_IMMUTABLE,
GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
@ -242,7 +248,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
chip->gc.parent = dev;
chip->gc.owner = THIS_MODULE;
girq = &chip->gc.irq;
girq->chip = &sifive_gpio_irqchip;
gpio_irq_chip_set_chip(girq, &sifive_gpio_irqchip);
girq->fwnode = of_node_to_fwnode(node);
girq->parent_domain = parent;
girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq;

View File

@ -314,8 +314,8 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)
for (i = 0; i < num_lines; i++) {
attr_group = devm_kzalloc(dev, sizeof(*attr_group), GFP_KERNEL);
attrs = devm_kcalloc(dev, sizeof(*attrs),
GPIO_SIM_NUM_ATTRS, GFP_KERNEL);
attrs = devm_kcalloc(dev, GPIO_SIM_NUM_ATTRS, sizeof(*attrs),
GFP_KERNEL);
val_attr = devm_kzalloc(dev, sizeof(*val_attr), GFP_KERNEL);
pull_attr = devm_kzalloc(dev, sizeof(*pull_attr), GFP_KERNEL);
if (!attr_group || !attrs || !val_attr || !pull_attr)

View File

@ -38,7 +38,6 @@
*/
struct syscon_gpio_data {
const char *compatible;
unsigned int flags;
unsigned int bit_count;
unsigned int dat_bit_offset;
@ -125,7 +124,6 @@ static int syscon_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int val)
static const struct syscon_gpio_data clps711x_mctrl_gpio = {
/* ARM CLPS711X SYSFLG1 Bits 8-10 */
.compatible = "cirrus,ep7209-syscon1",
.flags = GPIO_SYSCON_FEAT_IN,
.bit_count = 3,
.dat_bit_offset = 0x40 * 8 + 8,
@ -182,7 +180,6 @@ static void keystone_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
static const struct syscon_gpio_data keystone_dsp_gpio = {
/* ARM Keystone 2 */
.compatible = NULL,
.flags = GPIO_SYSCON_FEAT_OUT,
.bit_count = 28,
.dat_bit_offset = 4,
@ -219,33 +216,25 @@ static int syscon_gpio_probe(struct platform_device *pdev)
priv->data = of_device_get_match_data(dev);
if (priv->data->compatible) {
priv->syscon = syscon_regmap_lookup_by_compatible(
priv->data->compatible);
if (IS_ERR(priv->syscon))
return PTR_ERR(priv->syscon);
} else {
priv->syscon =
syscon_regmap_lookup_by_phandle(np, "gpio,syscon-dev");
if (IS_ERR(priv->syscon) && np->parent)
priv->syscon = syscon_node_to_regmap(np->parent);
if (IS_ERR(priv->syscon))
return PTR_ERR(priv->syscon);
priv->syscon = syscon_regmap_lookup_by_phandle(np, "gpio,syscon-dev");
if (IS_ERR(priv->syscon) && np->parent)
priv->syscon = syscon_node_to_regmap(np->parent);
if (IS_ERR(priv->syscon))
return PTR_ERR(priv->syscon);
ret = of_property_read_u32_index(np, "gpio,syscon-dev", 1,
&priv->dreg_offset);
if (ret)
dev_err(dev, "can't read the data register offset!\n");
ret = of_property_read_u32_index(np, "gpio,syscon-dev", 1,
&priv->dreg_offset);
if (ret)
dev_err(dev, "can't read the data register offset!\n");
priv->dreg_offset <<= 3;
priv->dreg_offset <<= 3;
ret = of_property_read_u32_index(np, "gpio,syscon-dev", 2,
&priv->dir_reg_offset);
if (ret)
dev_dbg(dev, "can't read the dir register offset!\n");
ret = of_property_read_u32_index(np, "gpio,syscon-dev", 2,
&priv->dir_reg_offset);
if (ret)
dev_dbg(dev, "can't read the dir register offset!\n");
priv->dir_reg_offset <<= 3;
}
priv->dir_reg_offset <<= 3;
priv->chip.parent = dev;
priv->chip.owner = THIS_MODULE;

View File

@ -62,14 +62,14 @@ static inline void tb10x_set_bits(struct tb10x_gpio *gpio, unsigned int offs,
u32 r;
unsigned long flags;
spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
raw_spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
r = tb10x_reg_read(gpio, offs);
r = (r & ~mask) | (val & mask);
tb10x_reg_write(gpio, offs, r);
spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
}
static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)

View File

@ -47,7 +47,7 @@ struct ws16c48_gpio {
raw_spinlock_t lock;
unsigned long irq_mask;
unsigned long flow_mask;
unsigned base;
void __iomem *base;
};
static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
@ -73,7 +73,7 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
ws16c48gpio->io_state[port] |= mask;
ws16c48gpio->out_state[port] &= ~mask;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
@ -95,7 +95,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
ws16c48gpio->out_state[port] |= mask;
else
ws16c48gpio->out_state[port] &= ~mask;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
@ -118,7 +118,7 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
return -EINVAL;
}
port_state = inb(ws16c48gpio->base + port);
port_state = ioread8(ws16c48gpio->base + port);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
@ -131,7 +131,7 @@ 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;
unsigned int port_addr;
void __iomem *port_addr;
unsigned long port_state;
/* clear bits array to a clean slate */
@ -139,7 +139,7 @@ static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,
for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
port_addr = ws16c48gpio->base + offset / 8;
port_state = inb(port_addr) & gpio_mask;
port_state = ioread8(port_addr) & gpio_mask;
bitmap_set_value8(bits, port_state, offset);
}
@ -166,7 +166,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;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
iowrite8(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
@ -178,7 +178,7 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
unsigned long offset;
unsigned long gpio_mask;
size_t index;
unsigned int port_addr;
void __iomem *port_addr;
unsigned long bitmask;
unsigned long flags;
@ -195,7 +195,7 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
/* update output state data and set device gpio register */
ws16c48gpio->out_state[index] &= ~gpio_mask;
ws16c48gpio->out_state[index] |= bitmask;
outb(ws16c48gpio->out_state[index], port_addr);
iowrite8(ws16c48gpio->out_state[index], port_addr);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
@ -219,10 +219,10 @@ static void ws16c48_irq_ack(struct irq_data *data)
port_state = ws16c48gpio->irq_mask >> (8*port);
outb(0x80, ws16c48gpio->base + 7);
outb(port_state & ~mask, ws16c48gpio->base + 8 + port);
outb(port_state | mask, ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
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);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
@ -244,9 +244,9 @@ static void ws16c48_irq_mask(struct irq_data *data)
ws16c48gpio->irq_mask &= ~mask;
outb(0x80, ws16c48gpio->base + 7);
outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
iowrite8(0x80, ws16c48gpio->base + 7);
iowrite8(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
iowrite8(0xC0, ws16c48gpio->base + 7);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
@ -268,9 +268,9 @@ static void ws16c48_irq_unmask(struct irq_data *data)
ws16c48gpio->irq_mask |= mask;
outb(0x80, ws16c48gpio->base + 7);
outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
iowrite8(0x80, ws16c48gpio->base + 7);
iowrite8(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
iowrite8(0xC0, ws16c48gpio->base + 7);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
@ -304,9 +304,9 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
return -EINVAL;
}
outb(0x40, ws16c48gpio->base + 7);
outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
iowrite8(0x40, ws16c48gpio->base + 7);
iowrite8(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
iowrite8(0xC0, ws16c48gpio->base + 7);
raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
@ -330,20 +330,20 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
unsigned long int_id;
unsigned long gpio;
int_pending = inb(ws16c48gpio->base + 6) & 0x7;
int_pending = ioread8(ws16c48gpio->base + 6) & 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 = inb(ws16c48gpio->base + 8 + port);
int_id = ioread8(ws16c48gpio->base + 8 + port);
for_each_set_bit(gpio, &int_id, 8)
generic_handle_domain_irq(chip->irq.domain,
gpio + 8*port);
}
int_pending = inb(ws16c48gpio->base + 6) & 0x7;
int_pending = ioread8(ws16c48gpio->base + 6) & 0x7;
} while (int_pending);
return IRQ_HANDLED;
@ -370,11 +370,11 @@ static int ws16c48_irq_init_hw(struct gpio_chip *gc)
struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(gc);
/* Disable IRQ by default */
outb(0x80, ws16c48gpio->base + 7);
outb(0, ws16c48gpio->base + 8);
outb(0, ws16c48gpio->base + 9);
outb(0, ws16c48gpio->base + 10);
outb(0xC0, ws16c48gpio->base + 7);
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);
return 0;
}
@ -396,6 +396,10 @@ 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)
return -ENOMEM;
ws16c48gpio->chip.label = name;
ws16c48gpio->chip.parent = dev;
ws16c48gpio->chip.owner = THIS_MODULE;
@ -409,7 +413,6 @@ static int ws16c48_probe(struct device *dev, unsigned int id)
ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple;
ws16c48gpio->chip.set = ws16c48_gpio_set;
ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
ws16c48gpio->base = base[id];
girq = &ws16c48gpio->chip.irq;
girq->chip = &ws16c48_irqchip;

View File

@ -11,7 +11,6 @@
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/gpio/driver.h>
@ -53,22 +52,23 @@
#define ZEVIO_GPIO_BIT(gpio) (gpio&7)
struct zevio_gpio {
struct gpio_chip chip;
spinlock_t lock;
struct of_mm_gpio_chip chip;
void __iomem *regs;
};
static inline u32 zevio_gpio_port_get(struct zevio_gpio *c, unsigned pin,
unsigned port_offset)
{
unsigned section_offset = ((pin >> 3) & 3)*ZEVIO_GPIO_SECTION_SIZE;
return readl(IOMEM(c->chip.regs + section_offset + port_offset));
return readl(IOMEM(c->regs + section_offset + port_offset));
}
static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin,
unsigned port_offset, u32 val)
{
unsigned section_offset = ((pin >> 3) & 3)*ZEVIO_GPIO_SECTION_SIZE;
writel(val, IOMEM(c->chip.regs + section_offset + port_offset));
writel(val, IOMEM(c->regs + section_offset + port_offset));
}
/* Functions for struct gpio_chip */
@ -178,12 +178,15 @@ static int zevio_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, controller);
/* Copy our reference */
controller->chip.gc = zevio_gpio_chip;
controller->chip.gc.parent = &pdev->dev;
controller->chip = zevio_gpio_chip;
controller->chip.parent = &pdev->dev;
status = of_mm_gpiochip_add_data(pdev->dev.of_node,
&(controller->chip),
controller);
controller->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(controller->regs))
return dev_err_probe(&pdev->dev, PTR_ERR(controller->regs),
"failed to ioremap memory resource\n");
status = devm_gpiochip_add_data(&pdev->dev, &controller->chip, controller);
if (status) {
dev_err(&pdev->dev, "failed to add gpiochip: %d\n", status);
return status;
@ -192,10 +195,10 @@ static int zevio_gpio_probe(struct platform_device *pdev)
spin_lock_init(&controller->lock);
/* Disable interrupts, they only cause errors */
for (i = 0; i < controller->chip.gc.ngpio; i += 8)
for (i = 0; i < controller->chip.ngpio; i += 8)
zevio_gpio_port_set(controller, i, ZEVIO_GPIO_INT_MASK, 0xFF);
dev_dbg(controller->chip.gc.parent, "ZEVIO GPIO controller set up!\n");
dev_dbg(controller->chip.parent, "ZEVIO GPIO controller set up!\n");
return 0;
}

View File

@ -197,16 +197,15 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
void __user *ip = (void __user *)arg;
struct gpiohandle_data ghd;
DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
int i;
unsigned int i;
int ret;
if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
/* NOTE: It's ok to read values of output lines. */
int ret = gpiod_get_array_value_complex(false,
true,
lh->num_descs,
lh->descs,
NULL,
vals);
switch (cmd) {
case GPIOHANDLE_GET_LINE_VALUES_IOCTL:
/* NOTE: It's okay to read values of output lines */
ret = gpiod_get_array_value_complex(false, true,
lh->num_descs, lh->descs,
NULL, vals);
if (ret)
return ret;
@ -218,7 +217,7 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
return 0;
} else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) {
case GPIOHANDLE_SET_LINE_VALUES_IOCTL:
/*
* All line descriptors were created at once with the same
* flags so just check if the first one is really output.
@ -240,10 +239,11 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
lh->descs,
NULL,
vals);
} else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) {
case GPIOHANDLE_SET_CONFIG_IOCTL:
return linehandle_set_config(lh, ip);
default:
return -EINVAL;
}
return -EINVAL;
}
#ifdef CONFIG_COMPAT
@ -1188,14 +1188,16 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,
struct linereq *lr = file->private_data;
void __user *ip = (void __user *)arg;
if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
switch (cmd) {
case GPIO_V2_LINE_GET_VALUES_IOCTL:
return linereq_get_values(lr, ip);
else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL)
case GPIO_V2_LINE_SET_VALUES_IOCTL:
return linereq_set_values(lr, ip);
else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
case GPIO_V2_LINE_SET_CONFIG_IOCTL:
return linereq_set_config(lr, ip);
return -EINVAL;
default:
return -EINVAL;
}
}
#ifdef CONFIG_COMPAT
@ -2113,28 +2115,30 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -ENODEV;
/* Fill in the struct and pass to userspace */
if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
switch (cmd) {
case GPIO_GET_CHIPINFO_IOCTL:
return chipinfo_get(cdev, ip);
#ifdef CONFIG_GPIO_CDEV_V1
} else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) {
case GPIO_GET_LINEHANDLE_IOCTL:
return linehandle_create(gdev, ip);
} else if (cmd == GPIO_GET_LINEEVENT_IOCTL) {
case GPIO_GET_LINEEVENT_IOCTL:
return lineevent_create(gdev, ip);
} else if (cmd == GPIO_GET_LINEINFO_IOCTL ||
cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
return lineinfo_get_v1(cdev, ip,
cmd == GPIO_GET_LINEINFO_WATCH_IOCTL);
case GPIO_GET_LINEINFO_IOCTL:
return lineinfo_get_v1(cdev, ip, false);
case GPIO_GET_LINEINFO_WATCH_IOCTL:
return lineinfo_get_v1(cdev, ip, true);
#endif /* CONFIG_GPIO_CDEV_V1 */
} else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL ||
cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) {
return lineinfo_get(cdev, ip,
cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL);
} else if (cmd == GPIO_V2_GET_LINE_IOCTL) {
case GPIO_V2_GET_LINEINFO_IOCTL:
return lineinfo_get(cdev, ip, false);
case GPIO_V2_GET_LINEINFO_WATCH_IOCTL:
return lineinfo_get(cdev, ip, true);
case GPIO_V2_GET_LINE_IOCTL:
return linereq_create(gdev, ip);
} else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) {
case GPIO_GET_LINEINFO_UNWATCH_IOCTL:
return lineinfo_unwatch(cdev, ip);
default:
return -EINVAL;
}
return -EINVAL;
}
#ifdef CONFIG_COMPAT

View File

@ -712,9 +712,8 @@ static void of_gpiochip_remove_hog(struct gpio_chip *chip,
struct device_node *hog)
{
struct gpio_desc *desc;
unsigned int i;
for_each_gpio_desc_with_flag(i, chip, desc, FLAG_IS_HOGGED)
for_each_gpio_desc_with_flag(chip, desc, FLAG_IS_HOGGED)
if (desc->hog == hog)
gpiochip_free_own_desc(desc);
}

View File

@ -760,7 +760,6 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)
{
struct gpio_desc *desc;
struct gpio_chip *chip = gdev->chip;
unsigned int i;
if (!gdev->mockdev)
return;
@ -773,7 +772,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)
mutex_unlock(&sysfs_lock);
/* unregister gpiod class devices owned by sysfs */
for_each_gpio_desc_with_flag(i, chip, desc, FLAG_SYSFS)
for_each_gpio_desc_with_flag(chip, desc, FLAG_SYSFS)
gpiod_free(desc);
}

View File

@ -189,9 +189,8 @@ static int gpiochip_find_base(int ngpio)
/* found a free space? */
if (gdev->base + gdev->ngpio <= base)
break;
else
/* nope, check the space right before the chip */
base = gdev->base - ngpio;
/* nope, check the space right before the chip */
base = gdev->base - ngpio;
}
if (gpio_is_valid(base)) {
@ -289,7 +288,6 @@ static int gpiodev_add_to_list(struct gpio_device *gdev)
}
}
dev_err(&gdev->dev, "GPIO integer space overlap, cannot add chip\n");
return -EBUSY;
}
@ -310,15 +308,10 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)
spin_lock_irqsave(&gpio_lock, flags);
list_for_each_entry(gdev, &gpio_devices, list) {
int i;
struct gpio_desc *desc;
for (i = 0; i != gdev->ngpio; ++i) {
struct gpio_desc *desc = &gdev->descs[i];
if (!desc->name)
continue;
if (!strcmp(desc->name, name)) {
for_each_gpio_desc(gdev->chip, desc) {
if (desc->name && !strcmp(desc->name, name)) {
spin_unlock_irqrestore(&gpio_lock, flags);
return desc;
}
@ -728,6 +721,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list(gdev);
if (ret) {
spin_unlock_irqrestore(&gpio_lock, flags);
chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
goto err_free_label;
}
@ -2427,8 +2421,7 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
ret = gpiod_direction_input(desc);
goto set_output_flag;
}
}
else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
} else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
ret = gpio_set_config(desc, PIN_CONFIG_DRIVE_OPEN_SOURCE);
if (!ret)
goto set_output_value;
@ -2546,6 +2539,11 @@ void gpiod_toggle_active_low(struct gpio_desc *desc)
}
EXPORT_SYMBOL_GPL(gpiod_toggle_active_low);
static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc)
{
return gc->get ? gc->get(gc, gpio_chip_hwgpio(desc)) : -EIO;
}
/* I/O calls are only valid after configuration completed; the relevant
* "is this a valid GPIO" error checks should already have been done.
*
@ -2571,12 +2569,10 @@ EXPORT_SYMBOL_GPL(gpiod_toggle_active_low);
static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
{
struct gpio_chip *gc;
int offset;
int value;
gc = desc->gdev->chip;
offset = gpio_chip_hwgpio(desc);
value = gc->get ? gc->get(gc, offset) : -EIO;
value = gpio_chip_get_value(gc, desc);
value = value < 0 ? value : !!value;
trace_gpio_value(desc_to_gpio(desc), 1, value);
return value;
@ -2585,9 +2581,9 @@ static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
static int gpio_chip_get_multiple(struct gpio_chip *gc,
unsigned long *mask, unsigned long *bits)
{
if (gc->get_multiple) {
if (gc->get_multiple)
return gc->get_multiple(gc, mask, bits);
} else if (gc->get) {
if (gc->get) {
int i, value;
for_each_set_bit(i, mask, gc->ngpio) {
@ -4147,9 +4143,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
static void gpiochip_free_hogs(struct gpio_chip *gc)
{
struct gpio_desc *desc;
int id;
for_each_gpio_desc_with_flag(id, gc, desc, FLAG_IS_HOGGED)
for_each_gpio_desc_with_flag(gc, desc, FLAG_IS_HOGGED)
gpiochip_free_own_desc(desc);
}
@ -4409,34 +4404,32 @@ core_initcall(gpiolib_dev_init);
static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)
{
unsigned i;
struct gpio_chip *gc = gdev->chip;
struct gpio_desc *desc;
unsigned gpio = gdev->base;
struct gpio_desc *gdesc = &gdev->descs[0];
int value;
bool is_out;
bool is_irq;
bool active_low;
for (i = 0; i < gdev->ngpio; i++, gpio++, gdesc++) {
if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) {
if (gdesc->name) {
seq_printf(s, " gpio-%-3d (%-20.20s)\n",
gpio, gdesc->name);
}
continue;
for_each_gpio_desc(gc, desc) {
if (test_bit(FLAG_REQUESTED, &desc->flags)) {
gpiod_get_direction(desc);
is_out = test_bit(FLAG_IS_OUT, &desc->flags);
value = gpio_chip_get_value(gc, desc);
is_irq = test_bit(FLAG_USED_AS_IRQ, &desc->flags);
active_low = test_bit(FLAG_ACTIVE_LOW, &desc->flags);
seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s\n",
gpio, desc->name ?: "", desc->label,
is_out ? "out" : "in ",
value >= 0 ? (value ? "hi" : "lo") : "? ",
is_irq ? "IRQ " : "",
active_low ? "ACTIVE LOW" : "");
} else if (desc->name) {
seq_printf(s, " gpio-%-3d (%-20.20s)\n", gpio, desc->name);
}
gpiod_get_direction(gdesc);
is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
is_irq = test_bit(FLAG_USED_AS_IRQ, &gdesc->flags);
active_low = test_bit(FLAG_ACTIVE_LOW, &gdesc->flags);
seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s",
gpio, gdesc->name ? gdesc->name : "", gdesc->label,
is_out ? "out" : "in ",
gc->get ? (gc->get(gc, i) ? "hi" : "lo") : "? ",
is_irq ? "IRQ " : "",
active_low ? "ACTIVE LOW" : "");
seq_printf(s, "\n");
gpio++;
}
}

View File

@ -100,10 +100,13 @@ struct gpio_array {
struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, unsigned int hwnum);
#define for_each_gpio_desc_with_flag(i, gc, desc, flag) \
for (i = 0, desc = gpiochip_get_desc(gc, i); \
i < gc->ngpio; \
i++, desc = gpiochip_get_desc(gc, i)) \
#define for_each_gpio_desc(gc, desc) \
for (unsigned int __i = 0; \
__i < gc->ngpio && (desc = gpiochip_get_desc(gc, __i)); \
__i++) \
#define for_each_gpio_desc_with_flag(gc, desc, flag) \
for_each_gpio_desc(gc, desc) \
if (!test_bit(flag, &desc->flags)) {} else
int gpiod_get_array_value_complex(bool raw, bool can_sleep,

View File

@ -13,7 +13,6 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqchip.h>
#include <linux/irqchip/irq-ixp4xx.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_address.h>
@ -106,7 +105,8 @@ static void ixp4xx_irq_unmask(struct irq_data *d)
}
}
asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)
static asmlinkage void __exception_irq_entry
ixp4xx_handle_irq(struct pt_regs *regs)
{
struct ixp4xx_irq *ixi = &ixirq;
unsigned long status;
@ -195,56 +195,6 @@ static const struct irq_domain_ops ixp4xx_irqdomain_ops = {
.free = irq_domain_free_irqs_common,
};
/**
* ixp4xx_get_irq_domain() - retrieve the ixp4xx irq domain
*
* This function will go away when we transition to DT probing.
*/
struct irq_domain *ixp4xx_get_irq_domain(void)
{
struct ixp4xx_irq *ixi = &ixirq;
return ixi->domain;
}
EXPORT_SYMBOL_GPL(ixp4xx_get_irq_domain);
/*
* This is the Linux IRQ to hwirq mapping table. This goes away when
* we have DT support as all IRQ resources are defined in the device
* tree. It will register all the IRQs that are not used by the hierarchical
* GPIO IRQ chip. The "holes" inbetween these IRQs will be requested by
* the GPIO driver using . This is a step-gap solution.
*/
struct ixp4xx_irq_chunk {
int irq;
int hwirq;
int nr_irqs;
};
static const struct ixp4xx_irq_chunk ixp4xx_irq_chunks[] = {
{
.irq = 16,
.hwirq = 0,
.nr_irqs = 6,
},
{
.irq = 24,
.hwirq = 8,
.nr_irqs = 11,
},
{
.irq = 46,
.hwirq = 30,
.nr_irqs = 2,
},
/* Only on the 436 variants */
{
.irq = 48,
.hwirq = 32,
.nr_irqs = 10,
},
};
/**
* ixp4x_irq_setup() - Common setup code for the IXP4xx interrupt controller
* @ixi: State container
@ -298,75 +248,8 @@ static int __init ixp4xx_irq_setup(struct ixp4xx_irq *ixi,
return 0;
}
/**
* ixp4xx_irq_init() - Function to initialize the irqchip from boardfiles
* @irqbase: physical base for the irq controller
* @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant
*/
void __init ixp4xx_irq_init(resource_size_t irqbase,
bool is_356)
{
struct ixp4xx_irq *ixi = &ixirq;
void __iomem *base;
struct fwnode_handle *fwnode;
struct irq_fwspec fwspec;
int nr_chunks;
int ret;
int i;
base = ioremap(irqbase, 0x100);
if (!base) {
pr_crit("IXP4XX: could not ioremap interrupt controller\n");
return;
}
fwnode = irq_domain_alloc_fwnode(&irqbase);
if (!fwnode) {
pr_crit("IXP4XX: no domain handle\n");
return;
}
ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356);
if (ret) {
pr_crit("IXP4XX: failed to set up irqchip\n");
irq_domain_free_fwnode(fwnode);
}
nr_chunks = ARRAY_SIZE(ixp4xx_irq_chunks);
if (!is_356)
nr_chunks--;
/*
* After adding OF support, this is no longer needed: irqs
* will be allocated for the respective fwnodes.
*/
for (i = 0; i < nr_chunks; i++) {
const struct ixp4xx_irq_chunk *chunk = &ixp4xx_irq_chunks[i];
pr_info("Allocate Linux IRQs %d..%d HW IRQs %d..%d\n",
chunk->irq, chunk->irq + chunk->nr_irqs - 1,
chunk->hwirq, chunk->hwirq + chunk->nr_irqs - 1);
fwspec.fwnode = fwnode;
fwspec.param[0] = chunk->hwirq;
fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
fwspec.param_count = 2;
ret = __irq_domain_alloc_irqs(ixi->domain,
chunk->irq,
chunk->nr_irqs,
NUMA_NO_NODE,
&fwspec,
false,
NULL);
if (ret < 0) {
pr_crit("IXP4XX: can not allocate irqs in hierarchy %d\n",
ret);
return;
}
}
}
EXPORT_SYMBOL_GPL(ixp4xx_irq_init);
#ifdef CONFIG_OF
int __init ixp4xx_of_init_irq(struct device_node *np,
struct device_node *parent)
static int __init ixp4xx_of_init_irq(struct device_node *np,
struct device_node *parent)
{
struct ixp4xx_irq *ixi = &ixirq;
void __iomem *base;
@ -400,4 +283,3 @@ IRQCHIP_DECLARE(ixp45x, "intel,ixp45x-interrupt",
ixp4xx_of_init_irq);
IRQCHIP_DECLARE(ixp46x, "intel,ixp46x-interrupt",
ixp4xx_of_init_irq);
#endif

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig PINCTRL_MESON
tristate "Amlogic SoC pinctrl drivers"
depends on ARCH_MESON
depends on ARCH_MESON || COMPILE_TEST
depends on OF
default y
select PINMUX

View File

@ -49,6 +49,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>
@ -218,13 +219,13 @@ static int meson_pinconf_set_output(struct meson_pinctrl *pc,
unsigned int pin,
bool out)
{
return meson_pinconf_set_gpio_bit(pc, pin, REG_DIR, !out);
return meson_pinconf_set_gpio_bit(pc, pin, MESON_REG_DIR, !out);
}
static int meson_pinconf_get_output(struct meson_pinctrl *pc,
unsigned int pin)
{
int ret = meson_pinconf_get_gpio_bit(pc, pin, REG_DIR);
int ret = meson_pinconf_get_gpio_bit(pc, pin, MESON_REG_DIR);
if (ret < 0)
return ret;
@ -236,13 +237,13 @@ static int meson_pinconf_set_drive(struct meson_pinctrl *pc,
unsigned int pin,
bool high)
{
return meson_pinconf_set_gpio_bit(pc, pin, REG_OUT, high);
return meson_pinconf_set_gpio_bit(pc, pin, MESON_REG_OUT, high);
}
static int meson_pinconf_get_drive(struct meson_pinctrl *pc,
unsigned int pin)
{
return meson_pinconf_get_gpio_bit(pc, pin, REG_OUT);
return meson_pinconf_get_gpio_bit(pc, pin, MESON_REG_OUT);
}
static int meson_pinconf_set_output_drive(struct meson_pinctrl *pc,
@ -269,7 +270,7 @@ static int meson_pinconf_disable_bias(struct meson_pinctrl *pc,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), 0);
if (ret)
return ret;
@ -288,7 +289,7 @@ static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, &reg, &bit);
if (pull_up)
val = BIT(bit);
@ -296,7 +297,7 @@ static int meson_pinconf_enable_bias(struct meson_pinctrl *pc, unsigned int pin,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit));
if (ret)
return ret;
@ -321,7 +322,7 @@ static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, &reg, &bit);
if (drive_strength_ua <= 500) {
ds_val = MESON_PINCONF_DRV_500UA;
@ -407,7 +408,7 @@ static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_PULLEN, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, &reg, &bit);
ret = regmap_read(pc->reg_pullen, reg, &val);
if (ret)
@ -416,7 +417,7 @@ static int meson_pinconf_get_pull(struct meson_pinctrl *pc, unsigned int pin)
if (!(val & BIT(bit))) {
conf = PIN_CONFIG_BIAS_DISABLE;
} else {
meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, &reg, &bit);
ret = regmap_read(pc->reg_pull, reg, &val);
if (ret)
@ -447,7 +448,7 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
if (ret)
return ret;
meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, &reg, &bit);
ret = regmap_read(pc->reg_ds, reg, &val);
if (ret)
@ -595,7 +596,7 @@ static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
if (ret)
return ret;
meson_calc_reg_and_bit(bank, gpio, REG_IN, &reg, &bit);
meson_calc_reg_and_bit(bank, gpio, MESON_REG_IN, &reg, &bit);
regmap_read(pc->reg_gpio, reg, &val);
return !!(val & BIT(bit));
@ -662,27 +663,22 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
}
static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc,
struct device_node *node)
static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc)
{
struct device_node *np, *gpio_np = NULL;
struct device_node *gpio_np;
unsigned int chips;
for_each_child_of_node(node, np) {
if (!of_find_property(np, "gpio-controller", NULL))
continue;
if (gpio_np) {
dev_err(pc->dev, "multiple gpio nodes\n");
of_node_put(np);
return -EINVAL;
}
gpio_np = np;
}
if (!gpio_np) {
chips = gpiochip_node_count(pc->dev);
if (!chips) {
dev_err(pc->dev, "no gpio node found\n");
return -EINVAL;
}
if (chips > 1) {
dev_err(pc->dev, "multiple gpio nodes\n");
return -EINVAL;
}
gpio_np = to_of_node(gpiochip_node_get_first(pc->dev));
pc->of_node = gpio_np;
pc->reg_mux = meson_map_resource(pc, gpio_np, "mux");
@ -751,7 +747,7 @@ int meson_pinctrl_probe(struct platform_device *pdev)
pc->dev = dev;
pc->data = (struct meson_pinctrl_data *) of_device_get_match_data(dev);
ret = meson_pinctrl_parse_dt(pc, dev->of_node);
ret = meson_pinctrl_parse_dt(pc);
if (ret)
return ret;

View File

@ -63,13 +63,13 @@ struct meson_reg_desc {
* enum meson_reg_type - type of registers encoded in @meson_reg_desc
*/
enum meson_reg_type {
REG_PULLEN,
REG_PULL,
REG_DIR,
REG_OUT,
REG_IN,
REG_DS,
NUM_REG,
MESON_REG_PULLEN,
MESON_REG_PULL,
MESON_REG_DIR,
MESON_REG_OUT,
MESON_REG_IN,
MESON_REG_DS,
MESON_NUM_REG,
};
/**
@ -102,7 +102,7 @@ struct meson_bank {
unsigned int last;
int irq_first;
int irq_last;
struct meson_reg_desc regs[NUM_REG];
struct meson_reg_desc regs[MESON_NUM_REG];
};
struct meson_pinctrl_data {
@ -150,12 +150,12 @@ struct meson_pinctrl {
.irq_first = fi, \
.irq_last = li, \
.regs = { \
[REG_PULLEN] = { per, peb }, \
[REG_PULL] = { pr, pb }, \
[REG_DIR] = { dr, db }, \
[REG_OUT] = { or, ob }, \
[REG_IN] = { ir, ib }, \
[REG_DS] = { dsr, dsb }, \
[MESON_REG_PULLEN] = { per, peb }, \
[MESON_REG_PULL] = { pr, pb }, \
[MESON_REG_DIR] = { dr, db }, \
[MESON_REG_OUT] = { or, ob }, \
[MESON_REG_IN] = { ir, ib }, \
[MESON_REG_DS] = { dsr, dsb }, \
}, \
}

View File

@ -21,6 +21,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>
@ -726,23 +727,13 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
struct gpio_chip *gc = &info->gpio_chip;
struct irq_chip *irqchip = &info->irq_chip;
struct gpio_irq_chip *girq = &gc->irq;
struct device_node *np = to_of_node(gc->fwnode);
struct device *dev = &pdev->dev;
struct device_node *np;
int ret = -ENODEV, i, nr_irq_parent;
unsigned int i, nr_irq_parent;
/* Check if we have at least one gpio-controller child node */
for_each_child_of_node(dev->of_node, np) {
if (of_property_read_bool(np, "gpio-controller")) {
ret = 0;
break;
}
}
if (ret)
return dev_err_probe(dev, ret, "no gpio-controller child node\n");
nr_irq_parent = of_irq_count(np);
spin_lock_init(&info->irq_lock);
nr_irq_parent = of_irq_count(np);
if (!nr_irq_parent) {
dev_err(dev, "invalid or no IRQ\n");
return 0;
@ -787,18 +778,13 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
struct device *dev = &pdev->dev;
struct device_node *np;
struct fwnode_handle *fwnode;
struct gpio_chip *gc;
int ret = -ENODEV;
int ret;
for_each_child_of_node(dev->of_node, np) {
if (of_find_property(np, "gpio-controller", NULL)) {
ret = 0;
break;
}
}
if (ret)
return ret;
fwnode = gpiochip_node_get_first(dev);
if (!fwnode)
return -ENODEV;
info->gpio_chip = armada_37xx_gpiolib_chip;
@ -806,7 +792,7 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
gc->ngpio = info->data->nr_pins;
gc->parent = dev;
gc->base = -1;
gc->of_node = np;
gc->fwnode = fwnode;
gc->label = info->data->name;
ret = armada_37xx_irqchip_register(pdev, info);

View File

@ -17,6 +17,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
/* GCR registers */
@ -104,12 +105,12 @@ static void npcm_gpio_set(struct gpio_chip *gc, void __iomem *reg,
unsigned long flags;
unsigned long val;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = ioread32(reg) | pinmask;
iowrite32(val, reg);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
@ -118,12 +119,12 @@ static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
unsigned long flags;
unsigned long val;
spin_lock_irqsave(&gc->bgpio_lock, flags);
raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
val = ioread32(reg) & ~pinmask;
iowrite32(val, reg);
spin_unlock_irqrestore(&gc->bgpio_lock, flags);
raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
}
static void npcmgpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
@ -1862,88 +1863,69 @@ static int npcm7xx_gpio_of(struct npcm7xx_pinctrl *pctrl)
{
int ret = -ENXIO;
struct resource res;
int id = 0, irq;
struct device_node *np;
struct of_phandle_args pinspec;
struct device *dev = pctrl->dev;
struct fwnode_reference_args args;
struct fwnode_handle *child;
int id = 0;
for_each_available_child_of_node(pctrl->dev->of_node, np)
if (of_find_property(np, "gpio-controller", NULL)) {
ret = of_address_to_resource(np, 0, &res);
if (ret < 0) {
dev_err(pctrl->dev,
"Resource fail for GPIO bank %u\n", id);
return ret;
}
for_each_gpiochip_node(dev, child) {
struct device_node *np = to_of_node(child);
pctrl->gpio_bank[id].base =
ioremap(res.start, resource_size(&res));
irq = irq_of_parse_and_map(np, 0);
if (irq < 0) {
dev_err(pctrl->dev,
"No IRQ for GPIO bank %u\n", id);
ret = irq;
return ret;
}
ret = bgpio_init(&pctrl->gpio_bank[id].gc,
pctrl->dev, 4,
pctrl->gpio_bank[id].base +
NPCM7XX_GP_N_DIN,
pctrl->gpio_bank[id].base +
NPCM7XX_GP_N_DOUT,
NULL,
NULL,
pctrl->gpio_bank[id].base +
NPCM7XX_GP_N_IEM,
BGPIOF_READ_OUTPUT_REG_SET);
if (ret) {
dev_err(pctrl->dev, "bgpio_init() failed\n");
return ret;
}
ret = of_parse_phandle_with_fixed_args(np,
"gpio-ranges", 3,
0, &pinspec);
if (ret < 0) {
dev_err(pctrl->dev,
"gpio-ranges fail for GPIO bank %u\n",
id);
return ret;
}
pctrl->gpio_bank[id].irq = irq;
pctrl->gpio_bank[id].irq_chip = npcmgpio_irqchip;
pctrl->gpio_bank[id].gc.parent = pctrl->dev;
pctrl->gpio_bank[id].irqbase =
id * NPCM7XX_GPIO_PER_BANK;
pctrl->gpio_bank[id].pinctrl_id = pinspec.args[0];
pctrl->gpio_bank[id].gc.base = pinspec.args[1];
pctrl->gpio_bank[id].gc.ngpio = pinspec.args[2];
pctrl->gpio_bank[id].gc.owner = THIS_MODULE;
pctrl->gpio_bank[id].gc.label =
devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOF",
np);
if (pctrl->gpio_bank[id].gc.label == NULL)
return -ENOMEM;
pctrl->gpio_bank[id].gc.dbg_show = npcmgpio_dbg_show;
pctrl->gpio_bank[id].direction_input =
pctrl->gpio_bank[id].gc.direction_input;
pctrl->gpio_bank[id].gc.direction_input =
npcmgpio_direction_input;
pctrl->gpio_bank[id].direction_output =
pctrl->gpio_bank[id].gc.direction_output;
pctrl->gpio_bank[id].gc.direction_output =
npcmgpio_direction_output;
pctrl->gpio_bank[id].request =
pctrl->gpio_bank[id].gc.request;
pctrl->gpio_bank[id].gc.request = npcmgpio_gpio_request;
pctrl->gpio_bank[id].gc.free = npcmgpio_gpio_free;
pctrl->gpio_bank[id].gc.of_node = np;
id++;
ret = of_address_to_resource(np, 0, &res);
if (ret < 0) {
dev_err(dev, "Resource fail for GPIO bank %u\n", id);
return ret;
}
pctrl->gpio_bank[id].base = ioremap(res.start, resource_size(&res));
ret = bgpio_init(&pctrl->gpio_bank[id].gc, dev, 4,
pctrl->gpio_bank[id].base + NPCM7XX_GP_N_DIN,
pctrl->gpio_bank[id].base + NPCM7XX_GP_N_DOUT,
NULL,
NULL,
pctrl->gpio_bank[id].base + NPCM7XX_GP_N_IEM,
BGPIOF_READ_OUTPUT_REG_SET);
if (ret) {
dev_err(dev, "bgpio_init() failed\n");
return ret;
}
ret = fwnode_property_get_reference_args(child, "gpio-ranges", NULL, 3, 0, &args);
if (ret < 0) {
dev_err(dev, "gpio-ranges fail for GPIO bank %u\n", id);
return ret;
}
ret = irq_of_parse_and_map(np, 0);
if (ret < 0) {
dev_err(dev, "No IRQ for GPIO bank %u\n", id);
return ret;
}
pctrl->gpio_bank[id].irq = ret;
pctrl->gpio_bank[id].irq_chip = npcmgpio_irqchip;
pctrl->gpio_bank[id].irqbase = id * NPCM7XX_GPIO_PER_BANK;
pctrl->gpio_bank[id].pinctrl_id = args.args[0];
pctrl->gpio_bank[id].gc.base = args.args[1];
pctrl->gpio_bank[id].gc.ngpio = args.args[2];
pctrl->gpio_bank[id].gc.owner = THIS_MODULE;
pctrl->gpio_bank[id].gc.parent = dev;
pctrl->gpio_bank[id].gc.fwnode = child;
pctrl->gpio_bank[id].gc.label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", child);
if (pctrl->gpio_bank[id].gc.label == NULL)
return -ENOMEM;
pctrl->gpio_bank[id].gc.dbg_show = npcmgpio_dbg_show;
pctrl->gpio_bank[id].direction_input = pctrl->gpio_bank[id].gc.direction_input;
pctrl->gpio_bank[id].gc.direction_input = npcmgpio_direction_input;
pctrl->gpio_bank[id].direction_output = pctrl->gpio_bank[id].gc.direction_output;
pctrl->gpio_bank[id].gc.direction_output = npcmgpio_direction_output;
pctrl->gpio_bank[id].request = pctrl->gpio_bank[id].gc.request;
pctrl->gpio_bank[id].gc.request = npcmgpio_gpio_request;
pctrl->gpio_bank[id].gc.free = npcmgpio_gpio_free;
id++;
}
pctrl->bank_num = id;
return ret;
}

View File

@ -24,6 +24,7 @@
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/property.h>
#include <linux/slab.h>
#include "../core.h"
@ -1154,21 +1155,6 @@ static const struct pinmux_ops rza1_pinmux_ops = {
* RZ/A1 pin controller driver operations
*/
static unsigned int rza1_count_gpio_chips(struct device_node *np)
{
struct device_node *child;
unsigned int count = 0;
for_each_child_of_node(np, child) {
if (!of_property_read_bool(child, "gpio-controller"))
continue;
count++;
}
return count;
}
/**
* rza1_parse_gpiochip() - parse and register a gpio chip and pin range
*
@ -1176,22 +1162,22 @@ static unsigned int rza1_count_gpio_chips(struct device_node *np)
* defined by gpio device tree binding documentation.
*
* @rza1_pctl: RZ/A1 pin controller device
* @np: of gpio-controller node
* @fwnode: gpio-controller firmware node
* @chip: gpio chip to register to gpiolib
* @range: pin range to register to pinctrl core
*/
static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
struct device_node *np,
struct fwnode_handle *fwnode,
struct gpio_chip *chip,
struct pinctrl_gpio_range *range)
{
const char *list_name = "gpio-ranges";
struct of_phandle_args of_args;
struct fwnode_reference_args args;
unsigned int gpioport;
u32 pinctrl_base;
int ret;
ret = of_parse_phandle_with_fixed_args(np, list_name, 3, 0, &of_args);
ret = fwnode_property_get_reference_args(fwnode, list_name, NULL, 3, 0, &args);
if (ret) {
dev_err(rza1_pctl->dev, "Unable to parse %s list property\n",
list_name);
@ -1202,7 +1188,7 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
* Find out on which port this gpio-chip maps to by inspecting the
* second argument of the "gpio-ranges" property.
*/
pinctrl_base = of_args.args[1];
pinctrl_base = args.args[1];
gpioport = RZA1_PIN_ID_TO_PORT(pinctrl_base);
if (gpioport >= RZA1_NPORTS) {
dev_err(rza1_pctl->dev,
@ -1212,19 +1198,18 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
*chip = rza1_gpiochip_template;
chip->base = -1;
chip->label = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pOFn",
np);
chip->ngpio = args.args[2];
chip->label = devm_kasprintf(rza1_pctl->dev, GFP_KERNEL, "%pfwP", fwnode);
if (!chip->label)
return -ENOMEM;
chip->ngpio = of_args.args[2];
chip->of_node = np;
chip->fwnode = fwnode;
chip->parent = rza1_pctl->dev;
range->id = gpioport;
range->name = chip->label;
range->pin_base = range->base = pinctrl_base;
range->npins = of_args.args[2];
range->npins = args.args[2];
range->gc = chip;
ret = devm_gpiochip_add_data(rza1_pctl->dev, chip,
@ -1247,15 +1232,14 @@ static int rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl,
*/
static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
{
struct device_node *np = rza1_pctl->dev->of_node;
struct pinctrl_gpio_range *gpio_ranges;
struct gpio_chip *gpio_chips;
struct device_node *child;
struct fwnode_handle *child;
unsigned int ngpiochips;
unsigned int i;
int ret;
ngpiochips = rza1_count_gpio_chips(np);
ngpiochips = gpiochip_node_count(rza1_pctl->dev);
if (ngpiochips == 0) {
dev_dbg(rza1_pctl->dev, "No gpiochip registered\n");
return 0;
@ -1269,14 +1253,11 @@ static int rza1_gpio_register(struct rza1_pinctrl *rza1_pctl)
return -ENOMEM;
i = 0;
for_each_child_of_node(np, child) {
if (!of_property_read_bool(child, "gpio-controller"))
continue;
for_each_gpiochip_node(rza1_pctl->dev, child) {
ret = rza1_parse_gpiochip(rza1_pctl, child, &gpio_chips[i],
&gpio_ranges[i]);
if (ret) {
of_node_put(child);
fwnode_handle_put(child);
return ret;
}

View File

@ -307,7 +307,7 @@ __init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
}
bank->irq_chip->chip.name = bank->name;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "gpio irq domain add failed\n");
@ -565,7 +565,7 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
}
bank->irq_chip->chip.name = bank->name;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
bank->nr_pins, &exynos_eint_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");
@ -573,7 +573,7 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
return -ENXIO;
}
if (!of_find_property(bank->of_node, "interrupts", NULL)) {
if (!fwnode_property_present(bank->fwnode, "interrupts")) {
bank->eint_type = EINT_TYPE_WKUP_MUX;
++muxed_banks;
continue;
@ -588,7 +588,7 @@ __init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
}
for (idx = 0; idx < bank->nr_pins; ++idx) {
irq = irq_of_parse_and_map(bank->of_node, idx);
irq = irq_of_parse_and_map(to_of_node(bank->fwnode), idx);
if (!irq) {
dev_err(dev, "irq number for eint-%s-%d not found\n",
bank->name, idx);

View File

@ -525,7 +525,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
: &s3c24xx_gpg_irq_ops;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
bank->nr_pins, ops, ddata);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");

View File

@ -471,7 +471,7 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
mask = bank->eint_mask;
nr_eints = fls(mask);
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
nr_eints, &s3c64xx_gpio_irqd_ops, bank);
if (!bank->irq_domain) {
dev_err(dev, "gpio irq domain add failed\n");
@ -743,7 +743,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
return -ENOMEM;
ddata->bank = bank;
bank->irq_domain = irq_domain_add_linear(bank->of_node,
bank->irq_domain = irq_domain_create_linear(bank->fwnode,
nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
if (!bank->irq_domain) {
dev_err(dev, "wkup irq domain add failed\n");

View File

@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
@ -966,7 +967,7 @@ static int samsung_gpiolib_register(struct platform_device *pdev,
gc->base = bank->grange.base;
gc->ngpio = bank->nr_pins;
gc->parent = &pdev->dev;
gc->of_node = bank->of_node;
gc->fwnode = bank->fwnode;
gc->label = bank->name;
ret = devm_gpiochip_add_data(&pdev->dev, gc, bank);
@ -1002,27 +1003,25 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
return &(of_data->ctrl[id]);
}
static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
static void samsung_banks_node_put(struct samsung_pinctrl_drv_data *d)
{
struct samsung_pin_bank *bank;
unsigned int i;
bank = d->pin_banks;
for (i = 0; i < d->nr_banks; ++i, ++bank)
of_node_put(bank->of_node);
fwnode_handle_put(bank->fwnode);
}
/*
* Iterate over all driver pin banks to find one matching the name of node,
* skipping optional "-gpio" node suffix. When found, assign node to the bank.
*/
static void samsung_banks_of_node_get(struct device *dev,
struct samsung_pinctrl_drv_data *d,
struct device_node *node)
static void samsung_banks_node_get(struct device *dev, struct samsung_pinctrl_drv_data *d)
{
const char *suffix = "-gpio-bank";
struct samsung_pin_bank *bank;
struct device_node *child;
struct fwnode_handle *child;
/* Pin bank names are up to 4 characters */
char node_name[20];
unsigned int i;
@ -1038,17 +1037,17 @@ static void samsung_banks_of_node_get(struct device *dev,
continue;
}
for_each_child_of_node(node, child) {
if (!of_find_property(child, "gpio-controller", NULL))
continue;
if (of_node_name_eq(child, node_name))
for_each_gpiochip_node(dev, child) {
struct device_node *np = to_of_node(child);
if (of_node_name_eq(np, node_name))
break;
else if (of_node_name_eq(child, bank->name))
if (of_node_name_eq(np, bank->name))
break;
}
if (child)
bank->of_node = child;
bank->fwnode = child;
else
dev_warn(dev, "Missing node for bank %s - invalid DTB\n",
bank->name);
@ -1061,7 +1060,6 @@ static const struct samsung_pin_ctrl *
samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
const struct samsung_pin_bank_data *bdata;
const struct samsung_pin_ctrl *ctrl;
struct samsung_pin_bank *bank;
@ -1125,7 +1123,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
*/
d->virt_base = virt_base[0];
samsung_banks_of_node_get(&pdev->dev, d, node);
samsung_banks_node_get(&pdev->dev, d);
d->pin_base = pin_base;
pin_base += d->nr_pins;
@ -1186,7 +1184,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
err_unregister:
samsung_pinctrl_unregister(pdev, drvdata);
err_put_banks:
samsung_banks_of_node_put(drvdata);
samsung_banks_node_put(drvdata);
return ret;
}

View File

@ -165,7 +165,7 @@ struct samsung_pin_bank {
u32 pin_base;
void *soc_priv;
struct device_node *of_node;
struct fwnode_handle *fwnode;
struct samsung_pinctrl_drv_data *drvdata;
struct irq_domain *irq_domain;
struct gpio_chip gpio_chip;

View File

@ -24,6 +24,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@ -1234,13 +1235,12 @@ static const struct pinconf_ops stm32_pconf_ops = {
.pin_config_dbg_show = stm32_pconf_dbg_show,
};
static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
struct device_node *np)
static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode_handle *fwnode)
{
struct stm32_gpio_bank *bank = &pctl->banks[pctl->nbanks];
int bank_ioport_nr;
struct pinctrl_gpio_range *range = &bank->range;
struct of_phandle_args args;
struct fwnode_reference_args args;
struct device *dev = pctl->dev;
struct resource res;
int npins = STM32_GPIO_PINS_PER_BANK;
@ -1249,7 +1249,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
if (!IS_ERR(bank->rstc))
reset_control_deassert(bank->rstc);
if (of_address_to_resource(np, 0, &res))
if (of_address_to_resource(to_of_node(fwnode), 0, &res))
return -ENODEV;
bank->base = devm_ioremap_resource(dev, &res);
@ -1264,15 +1264,15 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
bank->gpio_chip = stm32_gpio_template;
of_property_read_string(np, "st,bank-name", &bank->gpio_chip.label);
fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label);
if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, i, &args)) {
if (!fwnode_property_get_reference_args(fwnode, "gpio-ranges", NULL, 3, i, &args)) {
bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.base = args.args[1];
/* get the last defined gpio line (offset + nb of pins) */
npins = args.args[0] + args.args[2];
while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, ++i, &args))
while (!fwnode_property_get_reference_args(fwnode, "gpio-ranges", NULL, 3, ++i, &args))
npins = max(npins, (int)(args.args[0] + args.args[2]));
} else {
bank_nr = pctl->nbanks;
@ -1287,20 +1287,20 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
&pctl->banks[bank_nr].range);
}
if (of_property_read_u32(np, "st,bank-ioport", &bank_ioport_nr))
if (fwnode_property_read_u32(fwnode, "st,bank-ioport", &bank_ioport_nr))
bank_ioport_nr = bank_nr;
bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.ngpio = npins;
bank->gpio_chip.of_node = np;
bank->gpio_chip.fwnode = fwnode;
bank->gpio_chip.parent = dev;
bank->bank_nr = bank_nr;
bank->bank_ioport_nr = bank_ioport_nr;
spin_lock_init(&bank->lock);
/* create irq hierarchical domain */
bank->fwnode = of_node_to_fwnode(np);
bank->fwnode = fwnode;
bank->domain = irq_domain_create_hierarchy(pctl->domain, 0,
STM32_GPIO_IRQ_LINE, bank->fwnode,
@ -1437,12 +1437,13 @@ static int stm32_pctrl_create_pins_tab(struct stm32_pinctrl *pctl,
int stm32_pctl_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
struct fwnode_handle *child;
const struct of_device_id *match;
struct device *dev = &pdev->dev;
struct stm32_pinctrl *pctl;
struct pinctrl_pin_desc *pins;
int i, ret, hwlock_id, banks = 0;
int i, ret, hwlock_id;
unsigned int banks;
if (!np)
return -EINVAL;
@ -1532,10 +1533,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
return PTR_ERR(pctl->pctl_dev);
}
for_each_available_child_of_node(np, child)
if (of_property_read_bool(child, "gpio-controller"))
banks++;
banks = gpiochip_node_count(dev);
if (!banks) {
dev_err(dev, "at least one GPIO bank is required\n");
return -EINVAL;
@ -1546,40 +1544,34 @@ int stm32_pctl_probe(struct platform_device *pdev)
return -ENOMEM;
i = 0;
for_each_available_child_of_node(np, child) {
for_each_gpiochip_node(dev, child) {
struct stm32_gpio_bank *bank = &pctl->banks[i];
struct device_node *np = to_of_node(child);
if (of_property_read_bool(child, "gpio-controller")) {
bank->rstc = of_reset_control_get_exclusive(child,
NULL);
if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) {
of_node_put(child);
return -EPROBE_DEFER;
}
bank->clk = of_clk_get_by_name(child, NULL);
if (IS_ERR(bank->clk)) {
if (PTR_ERR(bank->clk) != -EPROBE_DEFER)
dev_err(dev,
"failed to get clk (%ld)\n",
PTR_ERR(bank->clk));
of_node_put(child);
return PTR_ERR(bank->clk);
}
i++;
bank->rstc = of_reset_control_get_exclusive(np, NULL);
if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) {
fwnode_handle_put(child);
return -EPROBE_DEFER;
}
bank->clk = of_clk_get_by_name(np, NULL);
if (IS_ERR(bank->clk)) {
if (PTR_ERR(bank->clk) != -EPROBE_DEFER)
dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk));
fwnode_handle_put(child);
return PTR_ERR(bank->clk);
}
i++;
}
for_each_available_child_of_node(np, child) {
if (of_property_read_bool(child, "gpio-controller")) {
ret = stm32_gpiolib_register_bank(pctl, child);
if (ret) {
of_node_put(child);
return ret;
}
pctl->nbanks++;
for_each_gpiochip_node(dev, child) {
ret = stm32_gpiolib_register_bank(pctl, child);
if (ret) {
fwnode_handle_put(child);
return ret;
}
pctl->nbanks++;
}
dev_info(dev, "Pinctrl STM32 initialized\n");

View File

@ -3,13 +3,14 @@
#define __LINUX_GPIO_DRIVER_H
#include <linux/device.h>
#include <linux/types.h>
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/lockdep.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/property.h>
#include <linux/types.h>
struct gpio_desc;
struct of_phandle_args;
@ -445,7 +446,7 @@ struct gpio_chip {
void __iomem *reg_dir_in;
bool bgpio_dir_unreadable;
int bgpio_bits;
spinlock_t bgpio_lock;
raw_spinlock_t bgpio_lock;
unsigned long bgpio_data;
unsigned long bgpio_dir;
#endif /* CONFIG_GPIO_GENERIC */
@ -775,4 +776,29 @@ static inline void gpiochip_unlock_as_irq(struct gpio_chip *gc,
}
#endif /* CONFIG_GPIOLIB */
#define for_each_gpiochip_node(dev, child) \
device_for_each_child_node(dev, child) \
if (!fwnode_property_present(child, "gpio-controller")) {} else
static inline unsigned int gpiochip_node_count(struct device *dev)
{
struct fwnode_handle *child;
unsigned int count = 0;
for_each_gpiochip_node(dev, child)
count++;
return count;
}
static inline struct fwnode_handle *gpiochip_node_get_first(struct device *dev)
{
struct fwnode_handle *fwnode;
for_each_gpiochip_node(dev, fwnode)
return fwnode;
return NULL;
}
#endif /* __LINUX_GPIO_DRIVER_H */

View File

@ -1,12 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __IRQ_IXP4XX_H
#define __IRQ_IXP4XX_H
#include <linux/ioport.h>
struct irq_domain;
void ixp4xx_irq_init(resource_size_t irqbase,
bool is_356);
struct irq_domain *ixp4xx_get_irq_domain(void);
#endif /* __IRQ_IXP4XX_H */

View File

@ -7,17 +7,5 @@
struct max732x_platform_data {
/* number of the first GPIO */
unsigned gpio_base;
/* interrupt base */
int irq_base;
void *context; /* param to setup/teardown */
int (*setup)(struct i2c_client *client,
unsigned gpio, unsigned ngpio,
void *context);
int (*teardown)(struct i2c_client *client,
unsigned gpio, unsigned ngpio,
void *context);
};
#endif /* __LINUX_I2C_MAX732X_H */

View File

@ -36,7 +36,7 @@ struct pcf857x_platform_data {
int (*setup)(struct i2c_client *client,
int gpio, unsigned ngpio,
void *context);
int (*teardown)(struct i2c_client *client,
void (*teardown)(struct i2c_client *client,
int gpio, unsigned ngpio,
void *context);
void *context;