Skip to content

Commit b6505a4

Browse files
Junjie650gregkh
authored andcommitted
gpio: ml-ioh: use raw_spinlock_t for the register lock
commit 600411e upstream. ioh_irq_type() is registered as the irq_chip .irq_set_type callback and takes chip->spinlock with spin_lock_irqsave(). This callback is reached from __setup_irq() -> __irq_set_trigger() -> chip->irq_set_type() while the caller holds desc->lock, a raw_spinlock_t, with hardirqs disabled. That context is not sleepable, but on PREEMPT_RT a regular spinlock_t is an rtmutex-backed sleeping lock, so acquiring it there is invalid. ioh_irq_enable() and ioh_irq_disable() take the same lock from the .irq_enable/.irq_disable callbacks, which are likewise invoked with desc->lock held. Convert the register lock to raw_spinlock_t. The same lock also serializes the GPIO direction/value callbacks and the suspend/resume register save/restore, and those critical sections only perform short sequences of MMIO register accesses (ioread32()/iowrite32()); the .irq_set_type callback additionally emits a dev_warn() on an unsupported type. None of these are sleepable operations, so keeping this register lock non-sleeping is appropriate for the irqchip callbacks and does not change the GPIO-side locking contract. This is the same fix as commit a02b895 ("gpio: pch: use raw_spinlock_t for the register lock"); this driver shares the same structure as gpio-pch. Fixes: 54be566 ("gpio-ml-ioh: Support interrupt function") Cc: stable@vger.kernel.org Reviewed-by: Linus Walleij <linusw@kernel.org> Link: https://patch.msgid.link/20260731032747.2987292-1-junjie.cao@intel.com Signed-off-by: Junjie Cao <junjie.cao@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e99120b commit b6505a4

1 file changed

Lines changed: 18 additions & 18 deletions

File tree

drivers/gpio/gpio-ml-ioh.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ struct ioh_gpio {
8484
u32 gpio_use_sel;
8585
int ch;
8686
int irq_base;
87-
spinlock_t spinlock;
87+
raw_spinlock_t spinlock;
8888
};
8989

9090
static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12};
@@ -95,15 +95,15 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
9595
struct ioh_gpio *chip = gpiochip_get_data(gpio);
9696
unsigned long flags;
9797

98-
spin_lock_irqsave(&chip->spinlock, flags);
98+
raw_spin_lock_irqsave(&chip->spinlock, flags);
9999
reg_val = ioread32(&chip->reg->regs[chip->ch].po);
100100
if (val)
101101
reg_val |= BIT(nr);
102102
else
103103
reg_val &= ~BIT(nr);
104104

105105
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
106-
spin_unlock_irqrestore(&chip->spinlock, flags);
106+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
107107
}
108108

109109
static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
@@ -121,7 +121,7 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
121121
u32 reg_val;
122122
unsigned long flags;
123123

124-
spin_lock_irqsave(&chip->spinlock, flags);
124+
raw_spin_lock_irqsave(&chip->spinlock, flags);
125125
pm = ioread32(&chip->reg->regs[chip->ch].pm);
126126
pm &= BIT(num_ports[chip->ch]) - 1;
127127
pm |= BIT(nr);
@@ -134,7 +134,7 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
134134
reg_val &= ~BIT(nr);
135135
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
136136

137-
spin_unlock_irqrestore(&chip->spinlock, flags);
137+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
138138

139139
return 0;
140140
}
@@ -145,12 +145,12 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
145145
u32 pm;
146146
unsigned long flags;
147147

148-
spin_lock_irqsave(&chip->spinlock, flags);
148+
raw_spin_lock_irqsave(&chip->spinlock, flags);
149149
pm = ioread32(&chip->reg->regs[chip->ch].pm);
150150
pm &= BIT(num_ports[chip->ch]) - 1;
151151
pm &= ~BIT(nr);
152152
iowrite32(pm, &chip->reg->regs[chip->ch].pm);
153-
spin_unlock_irqrestore(&chip->spinlock, flags);
153+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
154154

155155
return 0;
156156
}
@@ -254,7 +254,7 @@ static int ioh_irq_type(struct irq_data *d, unsigned int type)
254254
dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n",
255255
__func__, irq, type, ch, im_pos, type);
256256

257-
spin_lock_irqsave(&chip->spinlock, flags);
257+
raw_spin_lock_irqsave(&chip->spinlock, flags);
258258

259259
switch (type) {
260260
case IRQ_TYPE_EDGE_RISING:
@@ -294,7 +294,7 @@ static int ioh_irq_type(struct irq_data *d, unsigned int type)
294294
ien = ioread32(&chip->reg->regs[chip->ch].ien);
295295
iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien);
296296
end:
297-
spin_unlock_irqrestore(&chip->spinlock, flags);
297+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
298298

299299
return 0;
300300
}
@@ -324,11 +324,11 @@ static void ioh_irq_disable(struct irq_data *d)
324324
unsigned long flags;
325325
u32 ien;
326326

327-
spin_lock_irqsave(&chip->spinlock, flags);
327+
raw_spin_lock_irqsave(&chip->spinlock, flags);
328328
ien = ioread32(&chip->reg->regs[chip->ch].ien);
329329
ien &= ~BIT(d->irq - chip->irq_base);
330330
iowrite32(ien, &chip->reg->regs[chip->ch].ien);
331-
spin_unlock_irqrestore(&chip->spinlock, flags);
331+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
332332
}
333333

334334
static void ioh_irq_enable(struct irq_data *d)
@@ -338,11 +338,11 @@ static void ioh_irq_enable(struct irq_data *d)
338338
unsigned long flags;
339339
u32 ien;
340340

341-
spin_lock_irqsave(&chip->spinlock, flags);
341+
raw_spin_lock_irqsave(&chip->spinlock, flags);
342342
ien = ioread32(&chip->reg->regs[chip->ch].ien);
343343
ien |= BIT(d->irq - chip->irq_base);
344344
iowrite32(ien, &chip->reg->regs[chip->ch].ien);
345-
spin_unlock_irqrestore(&chip->spinlock, flags);
345+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
346346
}
347347

348348
static irqreturn_t ioh_gpio_handler(int irq, void *dev_id)
@@ -438,7 +438,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
438438
chip->base = base;
439439
chip->reg = chip->base;
440440
chip->ch = i;
441-
spin_lock_init(&chip->spinlock);
441+
raw_spin_lock_init(&chip->spinlock);
442442
ioh_gpio_setup(chip, num_ports[i]);
443443
ret = devm_gpiochip_add_data(dev, &chip->gpio, chip);
444444
if (ret) {
@@ -482,9 +482,9 @@ static int __maybe_unused ioh_gpio_suspend(struct device *dev)
482482
struct ioh_gpio *chip = dev_get_drvdata(dev);
483483
unsigned long flags;
484484

485-
spin_lock_irqsave(&chip->spinlock, flags);
485+
raw_spin_lock_irqsave(&chip->spinlock, flags);
486486
ioh_gpio_save_reg_conf(chip);
487-
spin_unlock_irqrestore(&chip->spinlock, flags);
487+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
488488

489489
return 0;
490490
}
@@ -494,11 +494,11 @@ static int __maybe_unused ioh_gpio_resume(struct device *dev)
494494
struct ioh_gpio *chip = dev_get_drvdata(dev);
495495
unsigned long flags;
496496

497-
spin_lock_irqsave(&chip->spinlock, flags);
497+
raw_spin_lock_irqsave(&chip->spinlock, flags);
498498
iowrite32(0x01, &chip->reg->srst);
499499
iowrite32(0x00, &chip->reg->srst);
500500
ioh_gpio_restore_reg_conf(chip);
501-
spin_unlock_irqrestore(&chip->spinlock, flags);
501+
raw_spin_unlock_irqrestore(&chip->spinlock, flags);
502502

503503
return 0;
504504
}

0 commit comments

Comments
 (0)