mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2026-01-27 12:35:36 +01:00
LF-10575-2 usb: chipidea: ci_hdrc_imx: add wakeup irq handling
Besides normal USB interrupt generated by Chipidea controller, another USB wakeup can also be generated. In previous cases, these two interrupts are bound to one irq line. However, the wakeup interrupt has a dedicated irq line in latest i.MX95 platform. This will add wakup irq handling for this case to support various wakeup cases. Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Reviewed-by: Jun Li <jun.li@nxp.com>
This commit is contained in:
parent
ebc89a771c
commit
2be33a6a8e
|
|
@ -99,9 +99,12 @@ struct ci_hdrc_imx_data {
|
|||
struct clk *clk;
|
||||
struct clk *clk_wakeup;
|
||||
struct imx_usbmisc_data *usbmisc_data;
|
||||
/* wakeup interrupt*/
|
||||
int irq;
|
||||
bool supports_runtime_pm;
|
||||
bool override_phy_control;
|
||||
bool in_lpm;
|
||||
bool wakeup_int;
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *pinctrl_hsic_active;
|
||||
struct regulator *hsic_pad_regulator;
|
||||
|
|
@ -342,6 +345,25 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t ci_wakeup_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct platform_device *pdev = data;
|
||||
struct ci_hdrc_imx_data *imx_data = platform_get_drvdata(pdev);
|
||||
|
||||
if (imx_data->in_lpm) {
|
||||
if (imx_data->wakeup_int)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
imx_data->wakeup_int = true;
|
||||
pm_runtime_resume(&imx_data->ci_pdev->dev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ci_hdrc_imx_data *data;
|
||||
|
|
@ -481,6 +503,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
|
|||
pdata.flags &= ~CI_HDRC_SUPPORTS_RUNTIME_PM;
|
||||
}
|
||||
|
||||
data->irq = platform_get_irq_optional(pdev, 1);
|
||||
if (data->irq > 0) {
|
||||
ret = devm_request_threaded_irq(dev, data->irq,
|
||||
NULL, ci_wakeup_irq_handler,
|
||||
IRQF_ONESHOT, "ci_imx_wakeup", pdev);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
ret = imx_usbmisc_init(data->usbmisc_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
|
||||
|
|
@ -625,6 +656,11 @@ static int __maybe_unused imx_controller_resume(struct device *dev,
|
|||
goto clk_disable;
|
||||
}
|
||||
|
||||
if (data->wakeup_int) {
|
||||
data->wakeup_int = false;
|
||||
enable_irq(data->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
clk_disable:
|
||||
|
|
@ -647,6 +683,10 @@ static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
|
|||
return ret;
|
||||
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(data->irq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -655,6 +695,9 @@ static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
|
|||
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(data->irq);
|
||||
|
||||
pinctrl_pm_select_default_state(dev);
|
||||
ret = imx_controller_resume(dev, PMSG_RESUME);
|
||||
if (!ret && data->supports_runtime_pm) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user