[lkml]   [2012]   [Jul]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectRe: [PATCH v4 2/4] block: add runtime pm helpers
On Thu, 2012-07-05 at 15:11 +0200, Rafael J. Wysocki wrote:
> On Thursday, July 05, 2012, Lin Ming wrote:
> > Add runtime pm helper functions:
> >
> > blk_pm_runtime_init()
> > blk_pre_runtime_suspend()
> > blk_post_runtime_suspend()
> > blk_pre_runtime_resume()
> > blk_post_runtime_suspend()
> What exactly do you need these things for? Please be specific.

Alan described these functions nicely, copied here.

I'll add these function descriptions to the patch log.

This is not the way to do it. The block subsystem should not use
suspend/resume callbacks.

Instead, there should be block functions that can be called by client
drivers: block_pre_runtime_suspend, block_post_runtime_suspend,
bock_pre_runtime_resume, and block_post_runtime_resume.

They should do something like this:

If any requests are in the queue, return -EBUSY.
Otherwise set q->rpm_status to RPM_SUSPENDING and
return 0.

If the suspend succeeded then set q->rpm_status to
RPM_SUSPENDED. Otherwise set it to RPM_ACTIVE and
call pm_runtime_mark_last_busy().

Set q->rpm_status to RPM_RESUMING.

If the resume succeeded then set q->rpm_status to
RPM_ACTIVE and call pm_runtime_mark_last_busy() and
Otherwise set q->rpm_status to RPM_SUSPENDED.

There should also be an initialization function for client drivers to
call. block_runtime_pm_init() should call pm_runtime_mark_last_busy(),
pm_runtime_use_autosuspend(), and pm_runtime_autosuspend().

Next, you have to modify the parts of the block layer that run when a
new request is added to the queue or a request is removed.

When a request is added:
If q->rpm_status is RPM_SUSPENDED, or if q->rpm_status
is RPM_SUSPENDING and the REQ_PM flag isn't set, call

When a request finishes:
Call pm_runtime_mark_last_busy().

Next, you have to change the parts of the block layer responsible for
taking a request from the queue and handing it to the lower-level
driver (both peek and get). If q->rpm_status is RPM_SUSPENDED, they
shouldn't do anything -- act as though the queue is empty. If
q->rpm_status is RPM_SUSPENDING or RPM_RESUMING, they should hand over
the request only if it has the REQ_PM flag set.

For this to work, the block layer has to know what struct device
pointer to pass to the pm_runtime_* routines. You'll have to add that
information to the request_queue structure; I guess q->dev can get set
by block_pm_runtime_init(). In fact, when that's done you won't need
q->rpm_status any more. You'll be able to use q->dev->power.rpm_status
directly, and you won't have to update it because the PM core does that
for you.

(Or maybe it would be easier to make q->rpm_status be a pointer to
q->dev->power.rpm_status. That way, if CONFIG_PM_RUNTIME isn't enabled
or block_runtime_pm_init() hasn't been called, you can have
q->rpm_status simply point to a static value that is permanently set to

I may have left some parts out from this brief description. Hopefully
you'll be able to figure out the general idea and get it to work.

Lin Ming

 \ /
  Last update: 2012-07-06 03:41    [W:0.039 / U:8.180 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site