Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 219010
b: refs/heads/master
c: 40bba0c
h: refs/heads/master
v: v3
  • Loading branch information
Ohad Ben-Cohen authored and Chris Ball committed Oct 23, 2010
1 parent 9aca56a commit 1176fae
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 81968561bd69536c82be7ee654b04c68cd3e1746
refs/heads/master: 40bba0c1ca83a370f749c8bc9afda71cf79ebd91
5 changes: 5 additions & 0 deletions trunk/drivers/mmc/core/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,11 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
err = sdio_init_func(host->card, i + 1);
if (err)
goto remove;

/*
* Enable Runtime PM for this func
*/
pm_runtime_enable(&card->sdio_func[i]->dev);
}

mmc_release_host(host);
Expand Down
38 changes: 35 additions & 3 deletions trunk/drivers/mmc/core/sdio_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,21 +126,46 @@ static int sdio_bus_probe(struct device *dev)
if (!id)
return -ENODEV;

/* Unbound SDIO functions are always suspended.
* During probe, the function is set active and the usage count
* is incremented. If the driver supports runtime PM,
* it should call pm_runtime_put_noidle() in its probe routine and
* pm_runtime_get_noresume() in its remove routine.
*/
ret = pm_runtime_get_sync(dev);
if (ret < 0)
goto out;

/* Set the default block size so the driver is sure it's something
* sensible. */
sdio_claim_host(func);
ret = sdio_set_block_size(func, 0);
sdio_release_host(func);
if (ret)
return ret;
goto disable_runtimepm;

ret = drv->probe(func, id);
if (ret)
goto disable_runtimepm;

return drv->probe(func, id);
return 0;

disable_runtimepm:
pm_runtime_put_noidle(dev);
out:
return ret;
}

static int sdio_bus_remove(struct device *dev)
{
struct sdio_driver *drv = to_sdio_driver(dev->driver);
struct sdio_func *func = dev_to_sdio_func(dev);
int ret;

/* Make sure card is powered before invoking ->remove() */
ret = pm_runtime_get_sync(dev);
if (ret < 0)
goto out;

drv->remove(func);

Expand All @@ -152,7 +177,14 @@ static int sdio_bus_remove(struct device *dev)
sdio_release_host(func);
}

return 0;
/* First, undo the increment made directly above */
pm_runtime_put_noidle(dev);

/* Then undo the runtime PM settings in sdio_bus_probe() */
pm_runtime_put_noidle(dev);

out:
return ret;
}

#ifdef CONFIG_PM_RUNTIME
Expand Down

0 comments on commit 1176fae

Please sign in to comment.