mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
usb: typec: fusb302: Revert incorrect threaded irq fix
The fusb302 irq handler has been carefully optimized by Hans de Goede in commit207338ec5a
("usb: typec: fusb302: Improve suspend/resume handling"). A recent 'fix' undid most of that work to avoid a virtio-gpio driver bug. This reverts the incorrect fix, since it is of very low quality. It reverts the quirks from Hans change (and thus reintroduces the problems fixed by Hans) while keeping the overhead from the original change. The proper fix to support using fusb302 with an interrupt line provided by virtio-gpio must be implemented in the virtio driver instead, which should support disabling the IRQ from the fusb302 interrupt routine. Cc: Hans de Goede <hansg@kernel.org> Cc: Yongbo Zhang <giraffesnn123@gmail.com> Fixes:1c2d81bded
("usb: typec: fusb302: fix scheduling while atomic when using virtio-gpio") Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Link: https://lore.kernel.org/r/20250818-fusb302-unthreaded-irq-v1-1-3a9a11a9f56f@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
70fb252a84
commit
309b6341d5
1 changed files with 8 additions and 4 deletions
|
@ -1485,6 +1485,9 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id)
|
|||
struct fusb302_chip *chip = dev_id;
|
||||
unsigned long flags;
|
||||
|
||||
/* Disable our level triggered IRQ until our irq_work has cleared it */
|
||||
disable_irq_nosync(chip->gpio_int_n_irq);
|
||||
|
||||
spin_lock_irqsave(&chip->irq_lock, flags);
|
||||
if (chip->irq_suspended)
|
||||
chip->irq_while_suspended = true;
|
||||
|
@ -1627,6 +1630,7 @@ static void fusb302_irq_work(struct work_struct *work)
|
|||
}
|
||||
done:
|
||||
mutex_unlock(&chip->lock);
|
||||
enable_irq(chip->gpio_int_n_irq);
|
||||
}
|
||||
|
||||
static int init_gpio(struct fusb302_chip *chip)
|
||||
|
@ -1751,10 +1755,9 @@ static int fusb302_probe(struct i2c_client *client)
|
|||
goto destroy_workqueue;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(dev, chip->gpio_int_n_irq,
|
||||
NULL, fusb302_irq_intn,
|
||||
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
|
||||
"fsc_interrupt_int_n", chip);
|
||||
ret = request_irq(chip->gpio_int_n_irq, fusb302_irq_intn,
|
||||
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
|
||||
"fsc_interrupt_int_n", chip);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "cannot request IRQ for GPIO Int_N, ret=%d", ret);
|
||||
goto tcpm_unregister_port;
|
||||
|
@ -1779,6 +1782,7 @@ static void fusb302_remove(struct i2c_client *client)
|
|||
struct fusb302_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
disable_irq_wake(chip->gpio_int_n_irq);
|
||||
free_irq(chip->gpio_int_n_irq, chip);
|
||||
cancel_work_sync(&chip->irq_work);
|
||||
cancel_delayed_work_sync(&chip->bc_lvl_handler);
|
||||
tcpm_unregister_port(chip->tcpm_port);
|
||||
|
|
Loading…
Add table
Reference in a new issue