Skip to content

Commit 309b634

Browse files
sregregkh
authored andcommitted
usb: typec: fusb302: Revert incorrect threaded irq fix
The fusb302 irq handler has been carefully optimized by Hans de Goede in commit 207338e ("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 <[email protected]> Cc: Yongbo Zhang <[email protected]> Fixes: 1c2d81b ("usb: typec: fusb302: fix scheduling while atomic when using virtio-gpio") Signed-off-by: Sebastian Reichel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 70fb252 commit 309b634

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

drivers/usb/typec/tcpm/fusb302.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,9 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id)
14851485
struct fusb302_chip *chip = dev_id;
14861486
unsigned long flags;
14871487

1488+
/* Disable our level triggered IRQ until our irq_work has cleared it */
1489+
disable_irq_nosync(chip->gpio_int_n_irq);
1490+
14881491
spin_lock_irqsave(&chip->irq_lock, flags);
14891492
if (chip->irq_suspended)
14901493
chip->irq_while_suspended = true;
@@ -1627,6 +1630,7 @@ static void fusb302_irq_work(struct work_struct *work)
16271630
}
16281631
done:
16291632
mutex_unlock(&chip->lock);
1633+
enable_irq(chip->gpio_int_n_irq);
16301634
}
16311635

16321636
static int init_gpio(struct fusb302_chip *chip)
@@ -1751,10 +1755,9 @@ static int fusb302_probe(struct i2c_client *client)
17511755
goto destroy_workqueue;
17521756
}
17531757

1754-
ret = devm_request_threaded_irq(dev, chip->gpio_int_n_irq,
1755-
NULL, fusb302_irq_intn,
1756-
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
1757-
"fsc_interrupt_int_n", chip);
1758+
ret = request_irq(chip->gpio_int_n_irq, fusb302_irq_intn,
1759+
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
1760+
"fsc_interrupt_int_n", chip);
17581761
if (ret < 0) {
17591762
dev_err(dev, "cannot request IRQ for GPIO Int_N, ret=%d", ret);
17601763
goto tcpm_unregister_port;
@@ -1779,6 +1782,7 @@ static void fusb302_remove(struct i2c_client *client)
17791782
struct fusb302_chip *chip = i2c_get_clientdata(client);
17801783

17811784
disable_irq_wake(chip->gpio_int_n_irq);
1785+
free_irq(chip->gpio_int_n_irq, chip);
17821786
cancel_work_sync(&chip->irq_work);
17831787
cancel_delayed_work_sync(&chip->bc_lvl_handler);
17841788
tcpm_unregister_port(chip->tcpm_port);

0 commit comments

Comments
 (0)