public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Maxim Levitsky <maximlevitsky@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>, Pavel Machek <pavel@ucw.cz>
Subject: [QUESTION] I need advice for writing .suspend/.resume functions
Date: Thu, 11 Oct 2007 05:13:10 +0200	[thread overview]
Message-ID: <200710110513.10753.maximlevitsky@gmail.com> (raw)

Hi,

I have few questions about .suspend()/.resume() driver functions and how best to write them.

I have written a support for suspend/resume for saa7134 v4l driver.
Now looking at code again and again, I found few problems, and I am seeking your advice how to fix them.

First of all the .suspend() function:

Looking at various drivers (including v4l ones) it seems that in general the function:

1) tells upper layers that it is suspended
2) saves the state of device
(generally there is nothing to save, since the driver maintains a copy of device state in memory)

3) disables the device (including DMA)
4) does usual pci_save_state+pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))
(I am talking about pci devices of course)

But there is one problem that my .suspend() function have together with quite a lot of drivers:
It can race with IRQ handler. Suppose the handler is called just before .suspend(), and thus .suspend() literally 
pulls the hadware from that handler.

I was told that I should use synchronize_irq(), and it looks exactly like the solution.
But I was surprised to see that very few drivers use it in their .suspend() routines.

Another issue, even bigger happens during the resume:
Suppose the IRQ line is shared with some other device and it gets resumed first.
And my IRQ handler is called because of the other device.
Now my IRQ handler can't determine whenever the IRQ for the device, since the hardware is still powered off.

Probably I can fix the following issues doing this:

1) do free_irq() in .suspend(), and request_irq() in .resume
this solves both problems since free_irq()  calls synchronize_irq()
Few drivers do that this way. I would like to know if this is the right way.


2) Disable the card's IRQ register , then call synchronize_irq(), at that point I can be sure that no IRQ handler is running and will run
then set some per device flag say dev->insuspend

let IRQ handler check this flag, and bail out if set, so false interrupts are caught on resume
Probably not a good idea, since I didn't find such implementation in kernel


Best regards,
	Maxim levitsky


             reply	other threads:[~2007-10-11  2:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-11  3:13 Maxim Levitsky [this message]
2007-10-11 22:15 ` [QUESTION] I need advice for writing .suspend/.resume functions Rafael J. Wysocki
2007-10-11 22:23   ` [linux-pm] " Alan Stern
2007-10-12 10:47     ` Maxim Levitsky

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=200710110513.10753.maximlevitsky@gmail.com \
    --to=maximlevitsky@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=rjw@sisk.pl \
    /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