summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig46
-rw-r--r--drivers/gpio/Makefile5
-rw-r--r--drivers/gpio/devres.c2
-rw-r--r--drivers/gpio/gpio-104-dio-48e.c38
-rw-r--r--drivers/gpio/gpio-104-idi-48.c18
-rw-r--r--drivers/gpio/gpio-104-idio-16.c24
-rw-r--r--drivers/gpio/gpio-altera.c24
-rw-r--r--drivers/gpio/gpio-arizona.c30
-rw-r--r--drivers/gpio/gpio-aspeed.c285
-rw-r--r--drivers/gpio/gpio-ath79.c28
-rw-r--r--drivers/gpio/gpio-bcm-kona.c48
-rw-r--r--drivers/gpio/gpio-bd9571mwv.c144
-rw-r--r--drivers/gpio/gpio-davinci.c2
-rw-r--r--drivers/gpio/gpio-dwapb.c93
-rw-r--r--drivers/gpio/gpio-etraxfs.c24
-rw-r--r--drivers/gpio/gpio-exar.c23
-rw-r--r--drivers/gpio/gpio-f7188x.c24
-rw-r--r--drivers/gpio/gpio-ftgpio010.c (renamed from drivers/gpio/gpio-gemini.c)72
-rw-r--r--drivers/gpio/gpio-merrifield.c2
-rw-r--r--drivers/gpio/gpio-ml-ioh.c28
-rw-r--r--drivers/gpio/gpio-mmio.c1
-rw-r--r--drivers/gpio/gpio-mockup.c16
-rw-r--r--drivers/gpio/gpio-moxart.c84
-rw-r--r--drivers/gpio/gpio-mvebu.c435
-rw-r--r--drivers/gpio/gpio-mxc.c6
-rw-r--r--drivers/gpio/gpio-mxs.c6
-rw-r--r--drivers/gpio/gpio-omap.c26
-rw-r--r--drivers/gpio/gpio-pca953x.c38
-rw-r--r--drivers/gpio/gpio-pcf857x.c2
-rw-r--r--drivers/gpio/gpio-pch.c14
-rw-r--r--drivers/gpio/gpio-pci-idio-16.c28
-rw-r--r--drivers/gpio/gpio-pl061.c28
-rw-r--r--drivers/gpio/gpio-pxa.c2
-rw-r--r--drivers/gpio/gpio-reg.c185
-rw-r--r--drivers/gpio/gpio-sa1100.c216
-rw-r--r--drivers/gpio/gpio-sodaville.c28
-rw-r--r--drivers/gpio/gpio-sta2x11.c17
-rw-r--r--drivers/gpio/gpio-twl4030.c3
-rw-r--r--drivers/gpio/gpio-wcove.c8
-rw-r--r--drivers/gpio/gpio-ws16c48.c46
-rw-r--r--drivers/gpio/gpio-xlp.c9
-rw-r--r--drivers/gpio/gpio-zx.c24
-rw-r--r--drivers/gpio/gpiolib-acpi.c53
-rw-r--r--drivers/gpio/gpiolib-of.c2
-rw-r--r--drivers/gpio/gpiolib.c16
45 files changed, 1648 insertions, 605 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 9b1bcb4d0df7..23ca51ee6b28 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -204,14 +204,15 @@ config GPIO_GE_FPGA
and write pin state) for GPIO implemented in a number of GE single
board computers.
-config GPIO_GEMINI
- bool "Gemini GPIO"
- depends on ARCH_GEMINI
+config GPIO_FTGPIO010
+ bool "Faraday FTGPIO010 GPIO"
depends on OF_GPIO
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
+ default (ARCH_GEMINI || ARCH_MOXART)
help
- Support for common GPIOs found in Cortina systems Gemini platforms.
+ Support for common GPIOs from the Faraday FTGPIO010 IP core, found in
+ Cortina systems Gemini platforms, Moxa ART and others.
config GPIO_GENERIC_PLATFORM
tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
@@ -308,14 +309,6 @@ config GPIO_MOCKUP
tools/testing/selftests/gpio/gpio-mockup.sh. Reference the usage in
it.
-config GPIO_MOXART
- bool "MOXART GPIO support"
- depends on ARCH_MOXART || COMPILE_TEST
- select GPIO_GENERIC
- help
- Select this option to enable GPIO driver for
- MOXA ART SoC devices.
-
config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
@@ -387,6 +380,12 @@ config GPIO_RCAR
help
Say yes here to support GPIO on Renesas R-Car SoCs.
+config GPIO_REG
+ bool
+ help
+ A 32-bit single register GPIO fixed in/out implementation. This
+ can be used to represent any register as a set of GPIO signals.
+
config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR
@@ -505,7 +504,7 @@ config GPIO_XILINX
config GPIO_XLP
tristate "Netlogic XLP GPIO support"
- depends on OF_GPIO && (CPU_XLP || ARCH_VULCAN || COMPILE_TEST)
+ depends on OF_GPIO && (CPU_XLP || ARCH_VULCAN || ARCH_THUNDER2 || COMPILE_TEST)
select GPIOLIB_IRQCHIP
help
This driver provides support for GPIO interface on Netlogic XLP MIPS64
@@ -557,7 +556,7 @@ menu "Port-mapped I/O GPIO drivers"
config GPIO_104_DIO_48E
tristate "ACCES 104-DIO-48E GPIO support"
- depends on ISA_BUS_API
+ depends on PC104 && ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E,
@@ -567,7 +566,7 @@ config GPIO_104_DIO_48E
config GPIO_104_IDIO_16
tristate "ACCES 104-IDIO-16 GPIO support"
- depends on ISA_BUS_API
+ depends on PC104 && ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-IDIO-16 family (104-IDIO-16,
@@ -578,7 +577,7 @@ config GPIO_104_IDIO_16
config GPIO_104_IDI_48
tristate "ACCES 104-IDI-48 GPIO support"
- depends on ISA_BUS_API
+ depends on PC104 && ISA_BUS_API
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-IDI-48 family (104-IDI-48A,
@@ -598,7 +597,7 @@ config GPIO_F7188X
config GPIO_GPIO_MM
tristate "Diamond Systems GPIO-MM GPIO support"
- depends on ISA_BUS_API
+ depends on PC104 && ISA_BUS_API
help
Enables GPIO support for the Diamond Systems GPIO-MM and GPIO-MM-12.
@@ -753,7 +752,7 @@ config GPIO_PCA953X
4 bits: pca9536, pca9537
8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554,
- pca9556, pca9557, pca9574, tca6408, xra1202
+ pca9556, pca9557, pca9574, tca6408, tca9554, xra1202
16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575,
tca6416
@@ -845,6 +844,17 @@ config GPIO_ARIZONA
help
Support for GPIOs on Wolfson Arizona class devices.
+config GPIO_BD9571MWV
+ tristate "ROHM BD9571 GPIO support"
+ depends on MFD_BD9571MWV
+ help
+ Support for GPIOs on ROHM BD9571 PMIC. There are two GPIOs
+ available on the ROHM PMIC in total, both of which can also
+ generate interrupts.
+
+ This driver can also be built as a module. If so, the module
+ will be called gpio-bd9571mwv.
+
config GPIO_CRYSTAL_COVE
tristate "GPIO support for Crystal Cove PMIC"
depends on (X86 || COMPILE_TEST) && INTEL_SOC_PMIC
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index becb96c724fe..68b96277d9fa 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
obj-$(CONFIG_GPIO_AXP209) += gpio-axp209.o
obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
+obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o
obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
@@ -48,8 +49,8 @@ obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_ETRAXFS) += gpio-etraxfs.o
obj-$(CONFIG_GPIO_EXAR) += gpio-exar.o
obj-$(CONFIG_GPIO_F7188X) += gpio-f7188x.o
+obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
-obj-$(CONFIG_GPIO_GEMINI) += gpio-gemini.o
obj-$(CONFIG_GPIO_GPIO_MM) += gpio-gpio-mm.o
obj-$(CONFIG_GPIO_GRGPIO) += gpio-grgpio.o
obj-$(CONFIG_HTC_EGPIO) += gpio-htc-egpio.o
@@ -80,7 +81,6 @@ obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o
obj-$(CONFIG_GPIO_MOCKUP) += gpio-mockup.o
-obj-$(CONFIG_GPIO_MOXART) += gpio-moxart.o
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o
@@ -99,6 +99,7 @@ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
+obj-$(CONFIG_GPIO_REG) += gpio-reg.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
index 7031eea165c9..a75511d1ea5d 100644
--- a/drivers/gpio/devres.c
+++ b/drivers/gpio/devres.c
@@ -136,7 +136,7 @@ EXPORT_SYMBOL(devm_gpiod_get_index);
* GPIO descriptors returned from this function are automatically disposed on
* driver detach.
*
- * On successfull request the GPIO pin is configured in accordance with
+ * On successful request the GPIO pin is configured in accordance with
* provided @flags.
*/
struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev,
diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c
index 17bd2ab4ebe2..61b50c40b87b 100644
--- a/drivers/gpio/gpio-104-dio-48e.c
+++ b/drivers/gpio/gpio-104-dio-48e.c
@@ -55,7 +55,7 @@ struct dio48e_gpio {
unsigned char io_state[6];
unsigned char out_state[6];
unsigned char control[2];
- spinlock_t lock;
+ raw_spinlock_t lock;
unsigned base;
unsigned char irq_mask;
};
@@ -78,7 +78,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned control;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* Check if configuring Port C */
if (io_port == 2 || io_port == 5) {
@@ -103,7 +103,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
control &= ~BIT(7);
outb(control, control_addr);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return 0;
}
@@ -120,7 +120,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
unsigned long flags;
unsigned control;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* Check if configuring Port C */
if (io_port == 2 || io_port == 5) {
@@ -153,7 +153,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
control &= ~BIT(7);
outb(control, control_addr);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return 0;
}
@@ -167,17 +167,17 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned port_state;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* ensure that GPIO is set for input */
if (!(dio48egpio->io_state[port] & mask)) {
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return -EINVAL;
}
port_state = inb(dio48egpio->base + in_port);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return !!(port_state & mask);
}
@@ -190,7 +190,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
const unsigned out_port = (port > 2) ? port + 1 : port;
unsigned long flags;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
if (value)
dio48egpio->out_state[port] |= mask;
@@ -199,7 +199,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
@@ -225,14 +225,14 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
out_port = (port > 2) ? port + 1 : port;
bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* update output state data and set device gpio register */
dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)];
dio48egpio->out_state[port] |= bitmask;
outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
/* prepare for next gpio register set */
mask[BIT_WORD(i)] >>= gpio_reg_size;
@@ -255,7 +255,7 @@ static void dio48e_irq_mask(struct irq_data *data)
if (offset != 19 && offset != 43)
return;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
if (offset == 19)
dio48egpio->irq_mask &= ~BIT(0);
@@ -266,7 +266,7 @@ static void dio48e_irq_mask(struct irq_data *data)
/* disable interrupts */
inb(dio48egpio->base + 0xB);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
static void dio48e_irq_unmask(struct irq_data *data)
@@ -280,7 +280,7 @@ static void dio48e_irq_unmask(struct irq_data *data)
if (offset != 19 && offset != 43)
return;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
if (!dio48egpio->irq_mask) {
/* enable interrupts */
@@ -293,7 +293,7 @@ static void dio48e_irq_unmask(struct irq_data *data)
else
dio48egpio->irq_mask |= BIT(1);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type)
@@ -329,11 +329,11 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
generic_handle_irq(irq_find_mapping(chip->irqdomain,
19 + gpio*24));
- spin_lock(&dio48egpio->lock);
+ raw_spin_lock(&dio48egpio->lock);
outb(0x00, dio48egpio->base + 0xF);
- spin_unlock(&dio48egpio->lock);
+ raw_spin_unlock(&dio48egpio->lock);
return IRQ_HANDLED;
}
@@ -388,7 +388,7 @@ static int dio48e_probe(struct device *dev, unsigned int id)
dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
dio48egpio->base = base[id];
- spin_lock_init(&dio48egpio->lock);
+ raw_spin_lock_init(&dio48egpio->lock);
err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
if (err) {
diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c
index 568375a7ebc2..337c048168d8 100644
--- a/drivers/gpio/gpio-104-idi-48.c
+++ b/drivers/gpio/gpio-104-idi-48.c
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(irq, "ACCES 104-IDI-48 interrupt line numbers");
*/
struct idi_48_gpio {
struct gpio_chip chip;
- spinlock_t lock;
+ raw_spinlock_t lock;
spinlock_t ack_lock;
unsigned char irq_mask[6];
unsigned base;
@@ -112,11 +112,12 @@ static void idi_48_irq_mask(struct irq_data *data)
if (!idi48gpio->irq_mask[boundary]) {
idi48gpio->cos_enb &= ~BIT(boundary);
- spin_lock_irqsave(&idi48gpio->lock, flags);
+ raw_spin_lock_irqsave(&idi48gpio->lock, flags);
outb(idi48gpio->cos_enb, idi48gpio->base + 7);
- spin_unlock_irqrestore(&idi48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&idi48gpio->lock,
+ flags);
}
return;
@@ -145,11 +146,12 @@ static void idi_48_irq_unmask(struct irq_data *data)
if (!prev_irq_mask) {
idi48gpio->cos_enb |= BIT(boundary);
- spin_lock_irqsave(&idi48gpio->lock, flags);
+ raw_spin_lock_irqsave(&idi48gpio->lock, flags);
outb(idi48gpio->cos_enb, idi48gpio->base + 7);
- spin_unlock_irqrestore(&idi48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&idi48gpio->lock,
+ flags);
}
return;
@@ -186,11 +188,11 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
spin_lock(&idi48gpio->ack_lock);
- spin_lock(&idi48gpio->lock);
+ raw_spin_lock(&idi48gpio->lock);
cos_status = inb(idi48gpio->base + 7);
- spin_unlock(&idi48gpio->lock);
+ raw_spin_unlock(&idi48gpio->lock);
/* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */
if (cos_status & BIT(6)) {
@@ -256,7 +258,7 @@ static int idi_48_probe(struct device *dev, unsigned int id)
idi48gpio->chip.get = idi_48_gpio_get;
idi48gpio->base = base[id];
- spin_lock_init(&idi48gpio->lock);
+ raw_spin_lock_init(&idi48gpio->lock);
spin_lock_init(&idi48gpio->ack_lock);
err = devm_gpiochip_add_data(dev, &idi48gpio->chip, idi48gpio);
diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c
index 7053cf736648..5281e1cedb01 100644
--- a/drivers/gpio/gpio-104-idio-16.c
+++ b/drivers/gpio/gpio-104-idio-16.c
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
*/
struct idio_16_gpio {
struct gpio_chip chip;
- spinlock_t lock;
+ raw_spinlock_t lock;
unsigned long irq_mask;
unsigned base;
unsigned out_state;
@@ -99,7 +99,7 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
if (offset > 15)
return;
- spin_lock_irqsave(&idio16gpio->lock, flags);
+ raw_spin_lock_irqsave(&idio16gpio->lock, flags);
if (value)
idio16gpio->out_state |= mask;
@@ -111,7 +111,7 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
else
outb(idio16gpio->out_state, idio16gpio->base);
- spin_unlock_irqrestore(&idio16gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
@@ -120,7 +120,7 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
unsigned long flags;
- spin_lock_irqsave(&idio16gpio->lock, flags);
+ raw_spin_lock_irqsave(&idio16gpio->lock, flags);
idio16gpio->out_state &= ~*mask;
idio16gpio->out_state |= *mask & *bits;
@@ -130,7 +130,7 @@ static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
if ((*mask >> 8) & 0xFF)
outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
- spin_unlock_irqrestore(&idio16gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
static void idio_16_irq_ack(struct irq_data *data)
@@ -147,11 +147,11 @@ static void idio_16_irq_mask(struct irq_data *data)
idio16gpio->irq_mask &= ~mask;
if (!idio16gpio->irq_mask) {
- spin_lock_irqsave(&idio16gpio->lock, flags);
+ raw_spin_lock_irqsave(&idio16gpio->lock, flags);
outb(0, idio16gpio->base + 2);
- spin_unlock_irqrestore(&idio16gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
}
@@ -166,11 +166,11 @@ static void idio_16_irq_unmask(struct irq_data *data)
idio16gpio->irq_mask |= mask;
if (!prev_irq_mask) {
- spin_lock_irqsave(&idio16gpio->lock, flags);
+ raw_spin_lock_irqsave(&idio16gpio->lock, flags);
inb(idio16gpio->base + 2);
- spin_unlock_irqrestore(&idio16gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
}
@@ -201,11 +201,11 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio));
- spin_lock(&idio16gpio->lock);
+ raw_spin_lock(&idio16gpio->lock);
outb(0, idio16gpio->base + 1);
- spin_unlock(&idio16gpio->lock);
+ raw_spin_unlock(&idio16gpio->lock);
return IRQ_HANDLED;
}
@@ -249,7 +249,7 @@ static int idio_16_probe(struct device *dev, unsigned int id)
idio16gpio->base = base[id];
idio16gpio->out_state = 0xFFFF;
- spin_lock_init(&idio16gpio->lock);
+ raw_spin_lock_init(&idio16gpio->lock);
err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
if (err) {
diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c
index 3fe6a21e05a5..17485dc20384 100644
--- a/drivers/gpio/gpio-altera.c
+++ b/drivers/gpio/gpio-altera.c
@@ -38,7 +38,7 @@
*/
struct altera_gpio_chip {
struct of_mm_gpio_chip mmchip;
- spinlock_t gpio_lock;
+ raw_spinlock_t gpio_lock;
int interrupt_trigger;
int mapped_irq;
};
@@ -53,12 +53,12 @@ static void altera_gpio_irq_unmask(struct irq_data *d)
altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
mm_gc = &altera_gc->mmchip;
- spin_lock_irqsave(&altera_gc->gpio_lock, flags);
+ raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);
intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
/* Set ALTERA_GPIO_IRQ_MASK bit to unmask */
intmask |= BIT(irqd_to_hwirq(d));
writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
- spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
}
static void altera_gpio_irq_mask(struct irq_data *d)
@@ -71,12 +71,12 @@ static void altera_gpio_irq_mask(struct irq_data *d)
altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
mm_gc = &altera_gc->mmchip;
- spin_lock_irqsave(&altera_gc->gpio_lock, flags);
+ raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);
intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
/* Clear ALTERA_GPIO_IRQ_MASK bit to mask */
intmask &= ~BIT(irqd_to_hwirq(d));
writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
- spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
}
/**
@@ -140,14 +140,14 @@ static void altera_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
mm_gc = to_of_mm_gpio_chip(gc);
chip = gpiochip_get_data(gc);
- spin_lock_irqsave(&chip->gpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->gpio_lock, flags);
data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
if (value)
data_reg |= BIT(offset);
else
data_reg &= ~BIT(offset);
writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA);
- spin_unlock_irqrestore(&chip->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
}
static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
@@ -160,12 +160,12 @@ static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
mm_gc = to_of_mm_gpio_chip(gc);
chip = gpiochip_get_data(gc);
- spin_lock_irqsave(&chip->gpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->gpio_lock, flags);
/* Set pin as input, assumes software controlled IP */
gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
gpio_ddr &= ~BIT(offset);
writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
- spin_unlock_irqrestore(&chip->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
return 0;
}
@@ -181,7 +181,7 @@ static int altera_gpio_direction_output(struct gpio_chip *gc,
mm_gc = to_of_mm_gpio_chip(gc);
chip = gpiochip_get_data(gc);
- spin_lock_irqsave(&chip->gpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->gpio_lock, flags);
/* Sets the GPIO value */
data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
if (value)
@@ -194,7 +194,7 @@ static int altera_gpio_direction_output(struct gpio_chip *gc,
gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
gpio_ddr |= BIT(offset);
writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
- spin_unlock_irqrestore(&chip->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
return 0;
}
@@ -262,7 +262,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
if (!altera_gc)
return -ENOMEM;
- spin_lock_init(&altera_gc->gpio_lock);
+ raw_spin_lock_init(&altera_gc->gpio_lock);
if (of_property_read_u32(node, "altr,ngpio", &reg))
/* By default assume maximum ngpio */
diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c
index 1f91557717a6..cd23fd727f95 100644
--- a/drivers/gpio/gpio-arizona.c
+++ b/drivers/gpio/gpio-arizona.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/seq_file.h>
#include <linux/mfd/arizona/core.h>
@@ -41,13 +42,38 @@ static int arizona_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct arizona_gpio *arizona_gpio = gpiochip_get_data(chip);
struct arizona *arizona = arizona_gpio->arizona;
- unsigned int val;
+ unsigned int reg, val;
int ret;
- ret = regmap_read(arizona->regmap, ARIZONA_GPIO1_CTRL + offset, &val);
+ reg = ARIZONA_GPIO1_CTRL + offset;
+ ret = regmap_read(arizona->regmap, reg, &val);
if (ret < 0)
return ret;
+ /* Resume to read actual registers for input pins */
+ if (val & ARIZONA_GPN_DIR) {
+ ret = pm_runtime_get_sync(chip->parent);
+ if (ret < 0) {
+ dev_err(chip->parent, "Failed to resume: %d\n", ret);
+ return ret;
+ }
+
+ /* Register is cached, drop it to ensure a physical read */
+ ret = regcache_drop_region(arizona->regmap, reg, reg);
+ if (ret < 0) {
+ dev_err(chip->parent, "Failed to drop cache: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = regmap_read(arizona->regmap, reg, &val);
+ if (ret < 0)
+ return ret;
+
+ pm_runtime_mark_last_busy(chip->parent);