mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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:
commit
7182e89769
@ -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
|
@ -30,6 +30,7 @@ properties:
|
||||
- maxim,max7325
|
||||
- maxim,max7326
|
||||
- maxim,max7327
|
||||
- nxp,pca6408
|
||||
- nxp,pca6416
|
||||
- nxp,pca9505
|
||||
- nxp,pca9506
|
||||
|
@ -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>;
|
||||
};
|
||||
|
||||
...
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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), },
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULLEN, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_PULL, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, pin, MESON_REG_DS, ®, &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, ®, &bit);
|
||||
meson_calc_reg_and_bit(bank, gpio, MESON_REG_IN, ®, &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;
|
||||
|
||||
|
@ -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 }, \
|
||||
}, \
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user