Skip to content

Commit

Permalink
spi/omap100k: Convert to runtime PM
Browse files Browse the repository at this point in the history
Currently the omap100k driver uses prepare and unprepare transfer hardware
to enable and disable clocks for the IP block. Since these functions are
called along with runtime PM and end up duplicating its functionality in a
less flexible fashion we are trying to phase them out so convert this
driver to do runtime PM instead.

While doing so add missing error handling and remove a redundant NULL
assignment.

Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Mark Brown committed Mar 17, 2015
1 parent c517d83 commit db91841
Showing 1 changed file with 77 additions and 24 deletions.
101 changes: 77 additions & 24 deletions drivers/spi/spi-omap-100k.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
Expand Down Expand Up @@ -294,16 +295,6 @@ static int omap1_spi100k_setup(struct spi_device *spi)
return ret;
}

static int omap1_spi100k_prepare_hardware(struct spi_master *master)
{
struct omap1_spi100k *spi100k = spi_master_get_devdata(master);

clk_prepare_enable(spi100k->ick);
clk_prepare_enable(spi100k->fck);

return 0;
}

static int omap1_spi100k_transfer_one_message(struct spi_master *master,
struct spi_message *m)
{
Expand Down Expand Up @@ -372,16 +363,6 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,
return status;
}

static int omap1_spi100k_unprepare_hardware(struct spi_master *master)
{
struct omap1_spi100k *spi100k = spi_master_get_devdata(master);

clk_disable_unprepare(spi100k->ick);
clk_disable_unprepare(spi100k->fck);

return 0;
}

static int omap1_spi100k_probe(struct platform_device *pdev)
{
struct spi_master *master;
Expand All @@ -402,14 +383,12 @@ static int omap1_spi100k_probe(struct platform_device *pdev)

master->setup = omap1_spi100k_setup;
master->transfer_one_message = omap1_spi100k_transfer_one_message;
master->prepare_transfer_hardware = omap1_spi100k_prepare_hardware;
master->unprepare_transfer_hardware = omap1_spi100k_unprepare_hardware;
master->cleanup = NULL;
master->num_chipselect = 2;
master->mode_bits = MODEBITS;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
master->min_speed_hz = OMAP1_SPI100K_MAX_FREQ/(1<<16);
master->max_speed_hz = OMAP1_SPI100K_MAX_FREQ;
master->auto_runtime_pm = true;

spi100k = spi_master_get_devdata(master);

Expand All @@ -434,22 +413,96 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
goto err;
}

status = clk_prepare_enable(spi100k->ick);
if (status != 0) {
dev_err(&pdev->dev, "failed to enable ick: %d\n", status);
goto err;
}

status = clk_prepare_enable(spi100k->fck);
if (status != 0) {
dev_err(&pdev->dev, "failed to enable fck: %d\n", status);
goto err_ick;
}

pm_runtime_enable(&pdev->dev);
pm_runtime_set_active(&pdev->dev);

status = devm_spi_register_master(&pdev->dev, master);
if (status < 0)
goto err;
goto err_fck;

return status;

err_fck:
clk_disable_unprepare(spi100k->fck);
err_ick:
clk_disable_unprepare(spi100k->ick);
err:
spi_master_put(master);
return status;
}

static int omap1_spi100k_remove(struct platform_device *pdev)
{
struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
struct omap1_spi100k *spi100k = spi_master_get_devdata(master);

pm_runtime_disable(&pdev->dev);

clk_disable_unprepare(spi100k->fck);
clk_disable_unprepare(spi100k->ick);

return 0;
}

#ifdef CONFIG_PM
static int omap1_spi100k_runtime_suspend(struct device *dev)
{
struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
struct omap1_spi100k *spi100k = spi_master_get_devdata(master);

clk_disable_unprepare(spi100k->ick);
clk_disable_unprepare(spi100k->fck);

return 0;
}

static int omap1_spi100k_runtime_resume(struct device *dev)
{
struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
int ret;

ret = clk_prepare_enable(spi100k->ick);
if (ret != 0) {
dev_err(dev, "Failed to enable ick: %d\n", ret);
return ret;
}

ret = clk_prepare_enable(spi100k->fck);
if (ret != 0) {
dev_err(dev, "Failed to enable fck: %d\n", ret);
clk_disable_unprepare(spi100k->ick);
return ret;
}

return 0;
}
#endif

static const struct dev_pm_ops omap1_spi100k_pm = {
SET_RUNTIME_PM_OPS(omap1_spi100k_runtime_suspend,
omap1_spi100k_runtime_resume, NULL)
};

static struct platform_driver omap1_spi100k_driver = {
.driver = {
.name = "omap1_spi100k",
.pm = &omap1_spi100k_pm,
},
.probe = omap1_spi100k_probe,
.remove = omap1_spi100k_remove,
};

module_platform_driver(omap1_spi100k_driver);
Expand Down

0 comments on commit db91841

Please sign in to comment.