From: Xu Yang <xu.yang_2@nxp.com>
To: Frank Li <Frank.li@nxp.com>
Cc: gregkh@linuxfoundation.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, shawnguo@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com, peter.chen@kernel.org,
linux-usb@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, jun.li@nxp.com
Subject: Re: [PATCH 3/6] usb: chipidea: imx: add wakeup interrupt handling
Date: Mon, 24 Feb 2025 19:07:51 +0800 [thread overview]
Message-ID: <20250224110751.7666zcafbyakvfb2@hippo> (raw)
In-Reply-To: <Z7iabsMl4ilQqrXN@lizhi-Precision-Tower-5810>
On Fri, Feb 21, 2025 at 10:23:26AM -0500, Frank Li wrote:
> On Fri, Feb 21, 2025 at 11:23:48AM +0800, Xu Yang wrote:
> > On Wed, Feb 19, 2025 at 03:26:42PM -0500, Frank Li wrote:
> > > On Wed, Feb 19, 2025 at 05:31:01PM +0800, Xu Yang wrote:
> > > > In previous imx platform, normal USB controller interrupt and wakeup
> > > > interrupt are bound to one irq line. However, it changes on latest
> > > > i.MX95 platform since it has a dedicated irq line for wakeup interrupt.
> > > > This will add wakup interrupt handling for i.MX95 to support various
> > > > wakeup events.
> > > >
> > > > Reviewed-by: Jun Li <jun.li@nxp.com>
> > > > Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> > > > ---
> > > > drivers/usb/chipidea/ci_hdrc_imx.c | 42 ++++++++++++++++++++++++++++++
> > > > 1 file changed, 42 insertions(+)
> > > >
> > > > diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
> > > > index 1a7fc638213e..5779568ebcf6 100644
> > > > --- a/drivers/usb/chipidea/ci_hdrc_imx.c
> > > > +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
> > > > @@ -98,9 +98,12 @@ struct ci_hdrc_imx_data {
> > > > struct clk *clk;
> > > > struct clk *clk_wakeup;
> > > > struct imx_usbmisc_data *usbmisc_data;
> > > > + /* wakeup interrupt*/
> > > > + int irq;
> > >
> > > use "wakeup_irq" to avoid confuse with normal controller irq?
> >
> > It doesn't matter. It can't be confused since the driver is different. The
> > controller driver is core.c. This glue driver is ci_hdrc_imx.c.
> >
> > >
> > > > bool supports_runtime_pm;
> > > > bool override_phy_control;
> > > > bool in_lpm;
> > > > + bool wakeup_pending;
> > > > struct pinctrl *pinctrl;
> > > > struct pinctrl_state *pinctrl_hsic_active;
> > > > struct regulator *hsic_pad_regulator;
> > > > @@ -336,6 +339,24 @@ 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 ci_hdrc_imx_data *imx_data = data;
> > > > +
> > > > + if (imx_data->in_lpm) {
> > > > + if (imx_data->wakeup_pending)
> > > > + return IRQ_HANDLED;
> > > > +
> > > > + disable_irq_nosync(irq);
> > > > + imx_data->wakeup_pending = true;
> > > > + pm_runtime_resume(&imx_data->ci_pdev->dev);
> > >
> > > Not sure why need pm_runtime_resume here? There are not access register
> > > here.
> >
> > It's needed for runtime resume case.
> > When wakeup event happens, wakeup irq will be triggered. To let controller
> > resume back, we need enable USB controller clock to trigger controller
> > irq. So we call pm_runtime_resume() to resume controller's parent back
> > and the parent device will enable clocks.
>
> Please add comment here. why need in_lpm if we can make sure irq only
> enable during suspend/resume pharse?
I have checked again, in_lpm checking is not needed. I will remove the
if condition later.
>
> >
> > >
> > > > +
> > > > + return IRQ_HANDLED;
> > > > + }
> > > > +
> > > > + return IRQ_NONE;
> > > > +}
> > > > +
> > > > static int ci_hdrc_imx_probe(struct platform_device *pdev)
> > > > {
> > > > struct ci_hdrc_imx_data *data;
> > > > @@ -476,6 +497,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
> > > > if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
> > > > data->supports_runtime_pm = true;
> > > >
> > > > + 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, pdata.name, data);
> > > > + if (ret)
> > > > + goto err_clk;
> > > > + }
> > > > +
> > > > ret = imx_usbmisc_init(data->usbmisc_data);
> > > > if (ret) {
> > > > dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
> > > > @@ -621,6 +651,11 @@ static int imx_controller_resume(struct device *dev,
> > > > goto clk_disable;
> > > > }
> > > >
> > > > + if (data->wakeup_pending) {
> > > > + data->wakeup_pending = false;
> > > > + enable_irq(data->irq);
> > > > + }
> > > > +
> > > > return 0;
> > > >
> > > > clk_disable:
> > > > @@ -643,6 +678,10 @@ static int 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;
> > > > }
> > > >
> > > > @@ -651,6 +690,9 @@ static int 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);
> > > > +
> > >
> > > Look like only want enable wakeup irq between suspend and resume. There are
> > > some questions to understand hehavor.
> > >
> > > 1 driver probe --> 2. hdrc suspend -->3 hdrc resume --> 4 controller resume
> > >
> > > 1--2, look like wakeup irq is enabled. maybe controller have some bit to
> > > disable issue wakeup irq, otherwise flood irq will happen because you check
> > > lpm in irq handler.
> >
> > It's not true.
> >
> > We has a bit WAKE_ENABLE to enable/disable wakeup irq. This bit will only be
> > enabled when do suspend() and disabled when do resume(). So before suspend()
> > called, the wakeup irq can't be triggered. No flood irq too.
> >
> > >
> > > after 2. wakeup irq enable, if wakeup irq happen, system resume.
> > > ci_hdrc_imx_resume() only clear a flags, not any sync problem.
> > >
> > > But sequence imx_controller_resume() and ci_wakeup_irq_handler() may not
> > > guaranteed.
> > >
> > > If ci_wakeup_irq_handler() call first, ci_wakeup_irq_handler() disable
> > > itself. imx_controller_resume() will enable wakeup irq, which will be same
> > > state 1--2. but if imx_controller_resume() run firstly,
> >
> > It's not true too. Because WAKE_ENABLE is disabled after resume().
> >
> > > ci_wakeup_irq_handler() will disable wakeup irq, which difference state
> > > with 1--2.
> > >
> > > If there are a bit(WAKEUP_EN) in controller can control wakeup irq
> > > enable/disable,
> >
> > Yes, WAKE_ENABLE bit. It's already used:
> >
> > ci_hdrc_imx_suspend()
> > imx_controller_suspend() -> enable WAKE_ENABLE
> >
> > ci_hdrc_imx_resume()
> > imx_controller_resume() -> disable WAKE_ENABLE
>
> Okay,
>
> I think wakeup_pending is not neccesary. ci_wakeup_irq_handler() can
> simple disable WAKE_ENABLE.
Right, wakeup_pending can be removed. However, it's not that simple to
control WAKE_ENABLE in ci_hdrc_imx.c due to imx_controller_susepnd/resume()
do more things expect enable/disable WAKE_ENABLE bit. And usbmisc.c doesn't
export a function to directly control WAKE_ENABLE. Therefore, I still need
to use enable/disable_irq() for simplicity.
Due to this wakeup irq is only used in suspend case, I would like to add
IRQF_NO_AUTOEN flag to request_threaded_irq(), then enable irq in
ci_hdrc_imx_suspend() and disable irq in ci_hdrc_imx_resume().
For example:
ci_wakeup_irq_handler()
{
disable_irq_nosync(data->irq);
...
}
ci_hdrc_imx_suspend()
{
...
enable_irq(data->irq);
}
ci_hdrc_imx_resume()
{
if (irq disabled)
disable_irq_nosync(data->irq);
...
}
Do you think if it's feasible and better than current patch?
Thanks,
Xu Yang
next prev parent reply other threads:[~2025-02-24 11:11 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-19 9:30 [PATCH 0/6] add USB2.0 support for i.MX95-19x19 EVK board Xu Yang
2025-02-19 9:30 ` [PATCH 1/6] dt-bindings: usb: chipidea: add compatible for i.MX95 platform Xu Yang
2025-02-19 17:58 ` Frank Li
2025-02-20 10:22 ` Xu Yang
2025-02-19 9:31 ` [PATCH 2/6] dt-bindings: usb: usbmisc-imx: " Xu Yang
2025-02-19 18:01 ` Frank Li
2025-02-20 10:32 ` Xu Yang
2025-02-21 21:49 ` Rob Herring
2025-02-19 9:31 ` [PATCH 3/6] usb: chipidea: imx: add wakeup interrupt handling Xu Yang
2025-02-19 20:26 ` Frank Li
2025-02-21 3:23 ` Xu Yang
2025-02-21 15:23 ` Frank Li
2025-02-24 11:07 ` Xu Yang [this message]
2025-02-24 15:58 ` Frank Li
2025-02-25 2:12 ` Xu Yang
2025-02-19 9:31 ` [PATCH 4/6] usb: chipidea: imx: add HSIO Block Control wakup setting Xu Yang
2025-02-19 20:35 ` Frank Li
2025-02-19 9:31 ` [PATCH 5/6] arm64: dts: imx95: add USB2.0 nodes Xu Yang
2025-02-19 20:37 ` Frank Li
2025-02-19 9:31 ` [PATCH 6/6] arm64: dts: imx95-19x19-evk: enable USB2.0 node Xu Yang
2025-02-19 20:39 ` Frank Li
2025-02-20 10:38 ` Xu Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250224110751.7666zcafbyakvfb2@hippo \
--to=xu.yang_2@nxp.com \
--cc=Frank.li@nxp.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=festevam@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=imx@lists.linux.dev \
--cc=jun.li@nxp.com \
--cc=kernel@pengutronix.de \
--cc=krzk+dt@kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=peter.chen@kernel.org \
--cc=robh@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=shawnguo@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox