Skip to content

Commit

Permalink
spi/pl022: get/put resources on suspend/resume
Browse files Browse the repository at this point in the history
This factors out the resource handling in runtime
suspend/resume and also calls it from the ordinary suspend
and resume hooks.

The semantics require that ordinary PM op suspend is called
with runtime PM in resumed mode, so that ordinary suspend
can assume that it will e.g. decrease the clock reference
counter to 0, runtime resume having previously increased it
to 1.

Cc: Vipul Kumar Samar <vipulkumar.samar@st.com>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Linus Walleij authored and Mark Brown committed Sep 28, 2012
1 parent aeef991 commit ada7aec
Showing 1 changed file with 44 additions and 22 deletions.
66 changes: 44 additions & 22 deletions drivers/spi/spi-pl022.c
Original file line number Diff line number Diff line change
Expand Up @@ -2300,6 +2300,45 @@ pl022_remove(struct amba_device *adev)
return 0;
}

#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME)
/*
* These two functions are used from both suspend/resume and
* the runtime counterparts to handle external resources like
* clocks, pins and regulators when going to sleep.
*/
static void pl022_suspend_resources(struct pl022 *pl022)
{
int ret;

clk_disable(pl022->clk);

/* Optionally let pins go into sleep states */
if (!IS_ERR(pl022->pins_sleep)) {
ret = pinctrl_select_state(pl022->pinctrl,
pl022->pins_sleep);
if (ret)
dev_err(&pl022->adev->dev,
"could not set pins to sleep state\n");
}
}

static void pl022_resume_resources(struct pl022 *pl022)
{
int ret;

/* Optionaly enable pins to be muxed in and configured */
if (!IS_ERR(pl022->pins_default)) {
ret = pinctrl_select_state(pl022->pinctrl,
pl022->pins_default);
if (ret)
dev_err(&pl022->adev->dev,
"could not set default pins\n");
}

clk_enable(pl022->clk);
}
#endif

#ifdef CONFIG_SUSPEND
static int pl022_suspend(struct device *dev)
{
Expand All @@ -2311,6 +2350,7 @@ static int pl022_suspend(struct device *dev)
dev_warn(dev, "cannot suspend master\n");
return ret;
}
pl022_suspend_resources(pl022);

dev_dbg(dev, "suspended\n");
return 0;
Expand All @@ -2321,6 +2361,8 @@ static int pl022_resume(struct device *dev)
struct pl022 *pl022 = dev_get_drvdata(dev);
int ret;

pl022_resume_resources(pl022);

/* Start the queue running */
ret = spi_master_resume(pl022->master);
if (ret)
Expand All @@ -2336,36 +2378,16 @@ static int pl022_resume(struct device *dev)
static int pl022_runtime_suspend(struct device *dev)
{
struct pl022 *pl022 = dev_get_drvdata(dev);
int status = 0;

clk_disable(pl022->clk);

/* Optionally let pins go into sleep states */
if (!IS_ERR(pl022->pins_sleep)) {
status = pinctrl_select_state(pl022->pinctrl,
pl022->pins_sleep);
if (status)
dev_err(dev, "could not set pins to sleep state\n");
}

pl022_suspend_resources(pl022);
return 0;
}

static int pl022_runtime_resume(struct device *dev)
{
struct pl022 *pl022 = dev_get_drvdata(dev);
int status = 0;

/* Optionaly enable pins to be muxed in and configured */
if (!IS_ERR(pl022->pins_default)) {
status = pinctrl_select_state(pl022->pinctrl,
pl022->pins_default);
if (status)
dev_err(dev, "could not set default pins\n");
}

clk_enable(pl022->clk);

pl022_resume_resources(pl022);
return 0;
}
#endif
Expand Down

0 comments on commit ada7aec

Please sign in to comment.