All of lore.kernel.org
 help / color / mirror / Atom feed
From: boris.brezillon@free-electrons.com (Boris Brezillon)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 3/3] rtc: at91sam9: properly act when IRQ handler is called in suspended state
Date: Thu, 26 Feb 2015 09:12:46 +0100	[thread overview]
Message-ID: <20150226091246.6bdae8db@bbrezillon> (raw)
In-Reply-To: <1611142.77NqGpG2im@vostro.rjw.lan>

On Wed, 25 Feb 2015 23:05:36 +0100
"Rafael J. Wysocki" <rjw@rjwysocki.net> wrote:

> On Tuesday, February 24, 2015 10:56:02 AM Boris Brezillon wrote:
> > The IRQ line used by the RTC device is often shared with the system timer
> > (PIT) on at91 platforms.
> > Since timers are registering their handlers with IRQF_NO_SUSPEND, we should
> > expect being called in suspended state, and properly wake the system up
> > when this is the case.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > ---
> >  drivers/rtc/rtc-at91sam9.c | 62 ++++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 51 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
> > index 2183fd2..8cf9c1b 100644
> > --- a/drivers/rtc/rtc-at91sam9.c
> > +++ b/drivers/rtc/rtc-at91sam9.c
> > @@ -77,6 +77,8 @@ struct sam9_rtc {
> >  	unsigned int		gpbr_offset;
> >  	int 			irq;
> >  	struct clk		*sclk;
> > +	unsigned long		events;
> > +	spinlock_t		lock;
> >  };
> >  
> >  #define rtt_readl(rtc, field) \
> > @@ -271,14 +273,9 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
> >  	return 0;
> >  }
> >  
> > -/*
> > - * IRQ handler for the RTC
> > - */
> > -static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
> > +static irqreturn_t at91_rtc_cache_events(struct sam9_rtc *rtc)
> >  {
> > -	struct sam9_rtc *rtc = _rtc;
> >  	u32 sr, mr;
> > -	unsigned long events = 0;
> >  
> >  	/* Shared interrupt may be for another device.  Note: reading
> >  	 * SR clears it, so we must only read it in this irq handler!
> > @@ -290,18 +287,54 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
> >  
> >  	/* alarm status */
> >  	if (sr & AT91_RTT_ALMS)
> > -		events |= (RTC_AF | RTC_IRQF);
> > +		rtc->events |= (RTC_AF | RTC_IRQF);
> >  
> >  	/* timer update/increment */
> >  	if (sr & AT91_RTT_RTTINC)
> > -		events |= (RTC_UF | RTC_IRQF);
> > +		rtc->events |= (RTC_UF | RTC_IRQF);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static void at91_rtc_flush_events(struct sam9_rtc *rtc)
> > +{
> > +	if (!rtc->events)
> > +		return;
> >  
> > -	rtc_update_irq(rtc->rtcdev, 1, events);
> > +	rtc_update_irq(rtc->rtcdev, 1, rtc->events);
> > +	rtc->events = 0;
> >  
> >  	pr_debug("%s: num=%ld, events=0x%02lx\n", __func__,
> > -		events >> 8, events & 0x000000FF);
> > +		rtc->events >> 8, rtc->events & 0x000000FF);
> > +}
> >  
> > -	return IRQ_HANDLED;
> > +/*
> > + * IRQ handler for the RTC
> > + */
> > +static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
> > +{
> > +	struct sam9_rtc *rtc = _rtc;
> > +	int ret;
> > +
> > +	spin_lock(&rtc->lock);
> > +
> > +	ret = at91_rtc_cache_events(rtc);
> > +
> > +	/* We're called in suspended state */
> > +	if (irq_is_wakeup_armed(irq)) {
> 
> Instead of doing this, I would set a flag in the driver's ->suspend
> callback (or in ->suspend_late, whichever is more convenient) and check
> that flag here.

Sure, if I can start acting as a suspended handler (in other words, if
I can safely call pm_system_wakeup) as soon as my suspend callback has
been called, then I'm fine adding a boolean to store the device state.

Thanks for your review.

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

WARNING: multiple messages have this Message-ID (diff)
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Jason Cooper <jason@lakedaemon.net>,
	Peter Zijlstra <peterz@infradead.org>,
	Mark Rutland <mark.rutland@arm.com>,
	linux-kernel@vger.kernel.org,
	Nicolas Ferre <nicolas.ferre@atmel.com>,
	Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>,
	Alexandre Belloni <alexandre.belloni@free-electrons.com>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [RFC PATCH 3/3] rtc: at91sam9: properly act when IRQ handler is called in suspended state
Date: Thu, 26 Feb 2015 09:12:46 +0100	[thread overview]
Message-ID: <20150226091246.6bdae8db@bbrezillon> (raw)
In-Reply-To: <1611142.77NqGpG2im@vostro.rjw.lan>

On Wed, 25 Feb 2015 23:05:36 +0100
"Rafael J. Wysocki" <rjw@rjwysocki.net> wrote:

> On Tuesday, February 24, 2015 10:56:02 AM Boris Brezillon wrote:
> > The IRQ line used by the RTC device is often shared with the system timer
> > (PIT) on at91 platforms.
> > Since timers are registering their handlers with IRQF_NO_SUSPEND, we should
> > expect being called in suspended state, and properly wake the system up
> > when this is the case.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > ---
> >  drivers/rtc/rtc-at91sam9.c | 62 ++++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 51 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
> > index 2183fd2..8cf9c1b 100644
> > --- a/drivers/rtc/rtc-at91sam9.c
> > +++ b/drivers/rtc/rtc-at91sam9.c
> > @@ -77,6 +77,8 @@ struct sam9_rtc {
> >  	unsigned int		gpbr_offset;
> >  	int 			irq;
> >  	struct clk		*sclk;
> > +	unsigned long		events;
> > +	spinlock_t		lock;
> >  };
> >  
> >  #define rtt_readl(rtc, field) \
> > @@ -271,14 +273,9 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
> >  	return 0;
> >  }
> >  
> > -/*
> > - * IRQ handler for the RTC
> > - */
> > -static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
> > +static irqreturn_t at91_rtc_cache_events(struct sam9_rtc *rtc)
> >  {
> > -	struct sam9_rtc *rtc = _rtc;
> >  	u32 sr, mr;
> > -	unsigned long events = 0;
> >  
> >  	/* Shared interrupt may be for another device.  Note: reading
> >  	 * SR clears it, so we must only read it in this irq handler!
> > @@ -290,18 +287,54 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
> >  
> >  	/* alarm status */
> >  	if (sr & AT91_RTT_ALMS)
> > -		events |= (RTC_AF | RTC_IRQF);
> > +		rtc->events |= (RTC_AF | RTC_IRQF);
> >  
> >  	/* timer update/increment */
> >  	if (sr & AT91_RTT_RTTINC)
> > -		events |= (RTC_UF | RTC_IRQF);
> > +		rtc->events |= (RTC_UF | RTC_IRQF);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static void at91_rtc_flush_events(struct sam9_rtc *rtc)
> > +{
> > +	if (!rtc->events)
> > +		return;
> >  
> > -	rtc_update_irq(rtc->rtcdev, 1, events);
> > +	rtc_update_irq(rtc->rtcdev, 1, rtc->events);
> > +	rtc->events = 0;
> >  
> >  	pr_debug("%s: num=%ld, events=0x%02lx\n", __func__,
> > -		events >> 8, events & 0x000000FF);
> > +		rtc->events >> 8, rtc->events & 0x000000FF);
> > +}
> >  
> > -	return IRQ_HANDLED;
> > +/*
> > + * IRQ handler for the RTC
> > + */
> > +static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
> > +{
> > +	struct sam9_rtc *rtc = _rtc;
> > +	int ret;
> > +
> > +	spin_lock(&rtc->lock);
> > +
> > +	ret = at91_rtc_cache_events(rtc);
> > +
> > +	/* We're called in suspended state */
> > +	if (irq_is_wakeup_armed(irq)) {
> 
> Instead of doing this, I would set a flag in the driver's ->suspend
> callback (or in ->suspend_late, whichever is more convenient) and check
> that flag here.

Sure, if I can start acting as a suspended handler (in other words, if
I can safely call pm_system_wakeup) as soon as my suspend callback has
been called, then I'm fine adding a boolean to store the device state.

Thanks for your review.

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

  reply	other threads:[~2015-02-26  8:12 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-24  9:55 [RFC PATCH 0/3] genirq: mixing IRQF_NO_SUSPEND and wakeup sources on shared IRQs Boris Brezillon
2015-02-24  9:55 ` Boris Brezillon
2015-02-24  9:56 ` [RFC PATCH 1/3] genirq: prevent system wakeup when dealing with IRQF_NO_SUSPEND IRQs Boris Brezillon
2015-02-24  9:56   ` Boris Brezillon
2015-02-25 22:01   ` Rafael J. Wysocki
2015-02-25 22:01     ` Rafael J. Wysocki
2015-02-26  8:06     ` Boris Brezillon
2015-02-26  8:06       ` Boris Brezillon
2015-02-24  9:56 ` [RFC PATCH 2/3] genirq: add helper functions to deal with wakeup on shared " Boris Brezillon
2015-02-24  9:56   ` Boris Brezillon
2015-02-25 22:03   ` Rafael J. Wysocki
2015-02-25 22:03     ` Rafael J. Wysocki
2015-02-26  8:09     ` Boris Brezillon
2015-02-26  8:09       ` Boris Brezillon
2015-02-24  9:56 ` [RFC PATCH 3/3] rtc: at91sam9: properly act when IRQ handler is called in suspended state Boris Brezillon
2015-02-24  9:56   ` Boris Brezillon
2015-02-25 22:05   ` Rafael J. Wysocki
2015-02-25 22:05     ` Rafael J. Wysocki
2015-02-26  8:12     ` Boris Brezillon [this message]
2015-02-26  8:12       ` Boris Brezillon
2015-02-25 21:59 ` [RFC PATCH 0/3] genirq: mixing IRQF_NO_SUSPEND and wakeup sources on shared IRQs Rafael J. Wysocki
2015-02-25 21:59   ` Rafael J. Wysocki
2015-02-26  8:03   ` Boris Brezillon
2015-02-26  8:03     ` Boris Brezillon
2015-02-26 15:44     ` Rafael J. Wysocki
2015-02-26 15:44       ` Rafael J. Wysocki
2015-02-26 15:47       ` Boris Brezillon
2015-02-26 15:47         ` Boris Brezillon
2015-02-26 18:17         ` Rafael J. Wysocki
2015-02-26 18:17           ` Rafael J. Wysocki
2015-02-26 18:17           ` Boris Brezillon
2015-02-26 18:17             ` Boris Brezillon
2015-02-26 21:55             ` Rafael J. Wysocki
2015-02-26 21:55               ` Rafael J. Wysocki
2015-02-26 23:07             ` [PATCH] genirq / PM: Add flag for shared NO_SUSPEND interrupt lines Rafael J. Wysocki
2015-02-26 23:07               ` Rafael J. Wysocki
2015-02-27  8:38               ` Peter Zijlstra
2015-02-27  8:38                 ` Peter Zijlstra
2015-02-27 22:13                 ` Rafael J. Wysocki
2015-02-27 22:13                   ` Rafael J. Wysocki
2015-02-27 22:11                   ` Peter Zijlstra
2015-02-27 22:11                     ` Peter Zijlstra
2015-03-04 19:42               ` Mark Rutland
2015-03-04 19:42                 ` Mark Rutland
2015-03-04 20:00                 ` [PATCH] genirq: describe IRQF_COND_SUSPEND Mark Rutland
2015-03-04 20:00                   ` Mark Rutland
2015-03-04 21:55                   ` Rafael J. Wysocki
2015-03-04 21:55                     ` Rafael J. Wysocki
2015-03-04 22:17                   ` Alexandre Belloni
2015-03-04 22:17                     ` Alexandre Belloni
2015-03-04 22:27                     ` Arnd Bergmann
2015-03-04 22:27                       ` Arnd Bergmann
2015-03-05 11:04                     ` Mark Rutland
2015-03-05 11:04                       ` Mark Rutland
2015-03-05 11:33                       ` Alexandre Belloni
2015-03-05 11:33                         ` Alexandre Belloni
2015-03-05 12:07                         ` Mark Rutland
2015-03-05 12:07                           ` Mark Rutland
2015-03-06  0:54                       ` Rafael J. Wysocki
2015-03-06  0:54                         ` Rafael J. Wysocki
2015-03-04 21:30                 ` [PATCH] genirq / PM: Add flag for shared NO_SUSPEND interrupt lines Rafael J. Wysocki
2015-03-04 21:30                   ` Rafael J. Wysocki

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=20150226091246.6bdae8db@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=linux-arm-kernel@lists.infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.