diff options
author | Takashi Iwai <tiwai@suse.de> | 2024-03-11 18:18:47 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2024-03-11 18:18:47 +0300 |
commit | f5d9ddf1214bf878ca69c905c2f410c5b51de99c (patch) | |
tree | 3ea7bf6f519a490f72cf5f9023b5c0a6dff0fea0 /drivers/usb/chipidea/core.c | |
parent | 6719cd5e45111449f4021e08f2e488f17a9b292b (diff) | |
parent | 6c023ad32b192dea51a4f842cc6ecf89bb6238c9 (diff) | |
download | linux-f5d9ddf1214bf878ca69c905c2f410c5b51de99c.tar.xz |
Merge tag 'asoc-v6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v6.9
This has been quite a small release, there's a lot of driver specific
cleanups and minor enhancements but hardly anything on the core and only
one new driver. Highlights include:
- SoundWire support for AMD ACP 6.3 systems.
- Support for reporting version information for AVS firmware.
- Support DSPless mode for Intel Soundwire systems.
- Support for configuring CS35L56 amplifiers using EFI calibration
data.
- Log which component is being operated on as part of power management
trace events.
- Support for Microchip SAM9x7, NXP i.MX95 and Qualcomm WCD939x
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r-- | drivers/usb/chipidea/core.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 41014f93cfdf..835bf2428dc6 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -856,6 +856,27 @@ static int ci_extcon_register(struct ci_hdrc *ci) return 0; } +static void ci_power_lost_work(struct work_struct *work) +{ + struct ci_hdrc *ci = container_of(work, struct ci_hdrc, power_lost_work); + enum ci_role role; + + disable_irq_nosync(ci->irq); + pm_runtime_get_sync(ci->dev); + if (!ci_otg_is_fsm_mode(ci)) { + role = ci_get_role(ci); + + if (ci->role != role) { + ci_handle_id_switch(ci); + } else if (role == CI_ROLE_GADGET) { + if (ci->is_otg && hw_read_otgsc(ci, OTGSC_BSV)) + usb_gadget_vbus_connect(&ci->gadget); + } + } + pm_runtime_put_sync(ci->dev); + enable_irq(ci->irq); +} + static DEFINE_IDA(ci_ida); struct platform_device *ci_hdrc_add_device(struct device *dev, @@ -1045,6 +1066,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) spin_lock_init(&ci->lock); mutex_init(&ci->mutex); + INIT_WORK(&ci->power_lost_work, ci_power_lost_work); + ci->dev = dev; ci->platdata = dev_get_platdata(dev); ci->imx28_write_fix = !!(ci->platdata->flags & @@ -1396,25 +1419,6 @@ static int ci_suspend(struct device *dev) return 0; } -static void ci_handle_power_lost(struct ci_hdrc *ci) -{ - enum ci_role role; - - disable_irq_nosync(ci->irq); - if (!ci_otg_is_fsm_mode(ci)) { - role = ci_get_role(ci); - - if (ci->role != role) { - ci_handle_id_switch(ci); - } else if (role == CI_ROLE_GADGET) { - if (ci->is_otg && hw_read_otgsc(ci, OTGSC_BSV)) - usb_gadget_vbus_connect(&ci->gadget); - } - } - - enable_irq(ci->irq); -} - static int ci_resume(struct device *dev) { struct ci_hdrc *ci = dev_get_drvdata(dev); @@ -1446,7 +1450,7 @@ static int ci_resume(struct device *dev) ci_role(ci)->resume(ci, power_lost); if (power_lost) - ci_handle_power_lost(ci); + queue_work(system_freezable_wq, &ci->power_lost_work); if (ci->supports_runtime_pm) { pm_runtime_disable(dev); |