Skip to content

Commit 57f5db7

Browse files
refractionwareBartosz Golaszewski
authored andcommitted
gpio: bcm-kona: Make sure GPIO bits are unlocked when requesting IRQ
The settings for all GPIOs are locked by default in bcm_kona_gpio_reset. The settings for a GPIO are unlocked when requesting it as a GPIO, but not when requesting it as an interrupt, causing the IRQ settings to not get applied. Fix this by making sure to unlock the right bits when an IRQ is requested. To avoid a situation where an IRQ being released causes a lock despite the same GPIO being used by a GPIO request or vice versa, add an unlock counter and only lock if it reaches 0. Fixes: 757651e ("gpio: bcm281xx: Add GPIO driver") Reviewed-by: Florian Fainelli <[email protected]> Reviewed-by: Markus Mayer <[email protected]> Signed-off-by: Artur Weber <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent de1d0d1 commit 57f5db7

File tree

1 file changed

+55
-12
lines changed

1 file changed

+55
-12
lines changed

drivers/gpio/gpio-bcm-kona.c

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,22 @@ struct bcm_kona_gpio {
6969
struct bcm_kona_gpio_bank {
7070
int id;
7171
int irq;
72+
/*
73+
* Used to keep track of lock/unlock operations for each GPIO in the
74+
* bank.
75+
*
76+
* All GPIOs are locked by default (see bcm_kona_gpio_reset), and the
77+
* unlock count for all GPIOs is 0 by default. Each unlock increments
78+
* the counter, and each lock decrements the counter.
79+
*
80+
* The lock function only locks the GPIO once its unlock counter is
81+
* down to 0. This is necessary because the GPIO is unlocked in two
82+
* places in this driver: once for requested GPIOs, and once for
83+
* requested IRQs. Since it is possible for a GPIO to be requested
84+
* as both a GPIO and an IRQ, we need to ensure that we don't lock it
85+
* too early.
86+
*/
87+
u8 gpio_unlock_count[GPIO_PER_BANK];
7288
/* Used in the interrupt handler */
7389
struct bcm_kona_gpio *kona_gpio;
7490
};
@@ -87,14 +103,23 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio,
87103
unsigned long flags;
88104
int bank_id = GPIO_BANK(gpio);
89105
int bit = GPIO_BIT(gpio);
106+
struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id];
90107

91-
raw_spin_lock_irqsave(&kona_gpio->lock, flags);
108+
if (bank->gpio_unlock_count[bit] == 0) {
109+
dev_err(kona_gpio->gpio_chip.parent,
110+
"Unbalanced locks for GPIO %u\n", gpio);
111+
return;
112+
}
92113

93-
val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
94-
val |= BIT(bit);
95-
bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
114+
if (--bank->gpio_unlock_count[bit] == 0) {
115+
raw_spin_lock_irqsave(&kona_gpio->lock, flags);
96116

97-
raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
117+
val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
118+
val |= BIT(bit);
119+
bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
120+
121+
raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
122+
}
98123
}
99124

100125
static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
@@ -104,14 +129,19 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
104129
unsigned long flags;
105130
int bank_id = GPIO_BANK(gpio);
106131
int bit = GPIO_BIT(gpio);
132+
struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id];
107133

108-
raw_spin_lock_irqsave(&kona_gpio->lock, flags);
134+
if (bank->gpio_unlock_count[bit] == 0) {
135+
raw_spin_lock_irqsave(&kona_gpio->lock, flags);
109136

110-
val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
111-
val &= ~BIT(bit);
112-
bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
137+
val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
138+
val &= ~BIT(bit);
139+
bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
113140

114-
raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
141+
raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
142+
}
143+
144+
++bank->gpio_unlock_count[bit];
115145
}
116146

117147
static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio)
@@ -362,6 +392,7 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d)
362392

363393
kona_gpio = irq_data_get_irq_chip_data(d);
364394
reg_base = kona_gpio->reg_base;
395+
365396
raw_spin_lock_irqsave(&kona_gpio->lock, flags);
366397

367398
val = readl(reg_base + GPIO_INT_MASK(bank_id));
@@ -384,6 +415,7 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d)
384415

385416
kona_gpio = irq_data_get_irq_chip_data(d);
386417
reg_base = kona_gpio->reg_base;
418+
387419
raw_spin_lock_irqsave(&kona_gpio->lock, flags);
388420

389421
val = readl(reg_base + GPIO_INT_MSKCLR(bank_id));
@@ -479,15 +511,26 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc)
479511
static int bcm_kona_gpio_irq_reqres(struct irq_data *d)
480512
{
481513
struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);
514+
unsigned int gpio = d->hwirq;
515+
516+
/*
517+
* We need to unlock the GPIO before any other operations are performed
518+
* on the relevant GPIO configuration registers
519+
*/
520+
bcm_kona_gpio_unlock_gpio(kona_gpio, gpio);
482521

483-
return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq);
522+
return gpiochip_reqres_irq(&kona_gpio->gpio_chip, gpio);
484523
}
485524

486525
static void bcm_kona_gpio_irq_relres(struct irq_data *d)
487526
{
488527
struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d);
528+
unsigned int gpio = d->hwirq;
529+
530+
/* Once we no longer use it, lock the GPIO again */
531+
bcm_kona_gpio_lock_gpio(kona_gpio, gpio);
489532

490-
gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq);
533+
gpiochip_relres_irq(&kona_gpio->gpio_chip, gpio);
491534
}
492535

493536
static struct irq_chip bcm_gpio_irq_chip = {

0 commit comments

Comments
 (0)