Commit 6e695472 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/mxs',...

Merge remote-tracking branches 'spi/topic/imx', 'spi/topic/mxs', 'spi/topic/orion', 'spi/topic/rspi' and 'spi/topic/s3c64xx' into spi-next
...@@ -5,11 +5,14 @@ Required properties: ...@@ -5,11 +5,14 @@ Required properties:
"renesas,rspi-<soctype>", "renesas,rspi" as fallback. "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
For Renesas Serial Peripheral Interface on RZ/A1H: For Renesas Serial Peripheral Interface on RZ/A1H:
"renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback. "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
For Quad Serial Peripheral Interface on R-Car Gen2: For Quad Serial Peripheral Interface on R-Car Gen2 and
RZ/G1 devices:
"renesas,qspi-<soctype>", "renesas,qspi" as fallback. "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
Examples with soctypes are: Examples with soctypes are:
- "renesas,rspi-sh7757" (SH) - "renesas,rspi-sh7757" (SH)
- "renesas,rspi-r7s72100" (RZ/A1H) - "renesas,rspi-r7s72100" (RZ/A1H)
- "renesas,qspi-r8a7743" (RZ/G1M)
- "renesas,qspi-r8a7745" (RZ/G1E)
- "renesas,qspi-r8a7790" (R-Car H2) - "renesas,qspi-r8a7790" (R-Car H2)
- "renesas,qspi-r8a7791" (R-Car M2-W) - "renesas,qspi-r8a7791" (R-Car M2-W)
- "renesas,qspi-r8a7792" (R-Car V2H) - "renesas,qspi-r8a7792" (R-Car V2H)
......
This diff is collapsed.
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/stmp_device.h> #include <linux/stmp_device.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -442,6 +443,85 @@ static int mxs_spi_transfer_one(struct spi_master *master, ...@@ -442,6 +443,85 @@ static int mxs_spi_transfer_one(struct spi_master *master,
return status; return status;
} }
static int mxs_spi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mxs_spi *spi = spi_master_get_devdata(master);
struct mxs_ssp *ssp = &spi->ssp;
int ret;
clk_disable_unprepare(ssp->clk);
ret = pinctrl_pm_select_idle_state(dev);
if (ret) {
int ret2 = clk_prepare_enable(ssp->clk);
if (ret2)
dev_warn(dev, "Failed to reenable clock after failing pinctrl request (pinctrl: %d, clk: %d)\n",
ret, ret2);
}
return ret;
}
static int mxs_spi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct mxs_spi *spi = spi_master_get_devdata(master);
struct mxs_ssp *ssp = &spi->ssp;
int ret;
ret = pinctrl_pm_select_default_state(dev);
if (ret)
return ret;
ret = clk_prepare_enable(ssp->clk);
if (ret)
pinctrl_pm_select_idle_state(dev);
return ret;
}
static int __maybe_unused mxs_spi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
int ret;
ret = spi_master_suspend(master);
if (ret)
return ret;
if (!pm_runtime_suspended(dev))
return mxs_spi_runtime_suspend(dev);
else
return 0;
}
static int __maybe_unused mxs_spi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
int ret;
if (!pm_runtime_suspended(dev))
ret = mxs_spi_runtime_resume(dev);
else
ret = 0;
if (ret)
return ret;
ret = spi_master_resume(master);
if (ret < 0 && !pm_runtime_suspended(dev))
mxs_spi_runtime_suspend(dev);
return ret;
}
static const struct dev_pm_ops mxs_spi_pm = {
SET_RUNTIME_PM_OPS(mxs_spi_runtime_suspend,
mxs_spi_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(mxs_spi_suspend, mxs_spi_resume)
};
static const struct of_device_id mxs_spi_dt_ids[] = { static const struct of_device_id mxs_spi_dt_ids[] = {
{ .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, }, { .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, },
{ .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, }, { .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, },
...@@ -493,12 +573,15 @@ static int mxs_spi_probe(struct platform_device *pdev) ...@@ -493,12 +573,15 @@ static int mxs_spi_probe(struct platform_device *pdev)
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, master);
master->transfer_one_message = mxs_spi_transfer_one; master->transfer_one_message = mxs_spi_transfer_one;
master->bits_per_word_mask = SPI_BPW_MASK(8); master->bits_per_word_mask = SPI_BPW_MASK(8);
master->mode_bits = SPI_CPOL | SPI_CPHA; master->mode_bits = SPI_CPOL | SPI_CPHA;
master->num_chipselect = 3; master->num_chipselect = 3;
master->dev.of_node = np; master->dev.of_node = np;
master->flags = SPI_MASTER_HALF_DUPLEX; master->flags = SPI_MASTER_HALF_DUPLEX;
master->auto_runtime_pm = true;
spi = spi_master_get_devdata(master); spi = spi_master_get_devdata(master);
ssp = &spi->ssp; ssp = &spi->ssp;
...@@ -521,28 +604,41 @@ static int mxs_spi_probe(struct platform_device *pdev) ...@@ -521,28 +604,41 @@ static int mxs_spi_probe(struct platform_device *pdev)
goto out_master_free; goto out_master_free;
} }
ret = clk_prepare_enable(ssp->clk); pm_runtime_enable(ssp->dev);
if (ret) if (!pm_runtime_enabled(ssp->dev)) {
goto out_dma_release; ret = mxs_spi_runtime_resume(ssp->dev);
if (ret < 0) {
dev_err(ssp->dev, "runtime resume failed\n");
goto out_dma_release;
}
}
ret = pm_runtime_get_sync(ssp->dev);
if (ret < 0) {
dev_err(ssp->dev, "runtime_get_sync failed\n");
goto out_pm_runtime_disable;
}
clk_set_rate(ssp->clk, clk_freq); clk_set_rate(ssp->clk, clk_freq);
ret = stmp_reset_block(ssp->base); ret = stmp_reset_block(ssp->base);
if (ret) if (ret)
goto out_disable_clk; goto out_pm_runtime_put;
platform_set_drvdata(pdev, master);
ret = devm_spi_register_master(&pdev->dev, master); ret = devm_spi_register_master(&pdev->dev, master);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret); dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);
goto out_disable_clk; goto out_pm_runtime_put;
} }
pm_runtime_put(ssp->dev);
return 0; return 0;
out_disable_clk: out_pm_runtime_put:
clk_disable_unprepare(ssp->clk); pm_runtime_put(ssp->dev);
out_pm_runtime_disable:
pm_runtime_disable(ssp->dev);
out_dma_release: out_dma_release:
dma_release_channel(ssp->dmach); dma_release_channel(ssp->dmach);
out_master_free: out_master_free:
...@@ -560,7 +656,10 @@ static int mxs_spi_remove(struct platform_device *pdev) ...@@ -560,7 +656,10 @@ static int mxs_spi_remove(struct platform_device *pdev)
spi = spi_master_get_devdata(master); spi = spi_master_get_devdata(master);
ssp = &spi->ssp; ssp = &spi->ssp;
clk_disable_unprepare(ssp->clk); pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mxs_spi_runtime_suspend(&pdev->dev);
dma_release_channel(ssp->dmach); dma_release_channel(ssp->dmach);
return 0; return 0;
...@@ -572,6 +671,7 @@ static struct platform_driver mxs_spi_driver = { ...@@ -572,6 +671,7 @@ static struct platform_driver mxs_spi_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.of_match_table = mxs_spi_dt_ids, .of_match_table = mxs_spi_dt_ids,
.pm = &mxs_spi_pm,
}, },
}; };
......
...@@ -671,7 +671,6 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -671,7 +671,6 @@ static int orion_spi_probe(struct platform_device *pdev)
dev_err(&pdev->dev, dev_err(&pdev->dev,
"%pOF has no valid 'reg' property (%d)\n", "%pOF has no valid 'reg' property (%d)\n",
np, status); np, status);
status = 0;
continue; continue;
} }
......
...@@ -1221,7 +1221,6 @@ static int rspi_probe(struct platform_device *pdev) ...@@ -1221,7 +1221,6 @@ static int rspi_probe(struct platform_device *pdev)
struct spi_master *master; struct spi_master *master;
struct rspi_data *rspi; struct rspi_data *rspi;
int ret; int ret;
const struct of_device_id *of_id;
const struct rspi_plat_data *rspi_pd; const struct rspi_plat_data *rspi_pd;
const struct spi_ops *ops; const struct spi_ops *ops;
...@@ -1229,9 +1228,8 @@ static int rspi_probe(struct platform_device *pdev) ...@@ -1229,9 +1228,8 @@ static int rspi_probe(struct platform_device *pdev)
if (master == NULL) if (master == NULL)
return -ENOMEM; return -ENOMEM;
of_id = of_match_device(rspi_of_match, &pdev->dev); ops = of_device_get_match_data(&pdev->dev);
if (of_id) { if (ops) {
ops = of_id->data;
ret = rspi_parse_dt(&pdev->dev, master); ret = rspi_parse_dt(&pdev->dev, master);
if (ret) if (ret)
goto error1; goto error1;
......
...@@ -752,7 +752,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) ...@@ -752,7 +752,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
{ {
struct s3c64xx_spi_csinfo *cs = spi->controller_data; struct s3c64xx_spi_csinfo *cs = spi->controller_data;
struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_driver_data *sdd;
struct s3c64xx_spi_info *sci;
int err; int err;
sdd = spi_master_get_devdata(spi->master); sdd = spi_master_get_devdata(spi->master);
...@@ -788,8 +787,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi) ...@@ -788,8 +787,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
spi_set_ctldata(spi, cs); spi_set_ctldata(spi, cs);
} }
sci = sdd->cntrlr_info;
pm_runtime_get_sync(&sdd->pdev->dev); pm_runtime_get_sync(&sdd->pdev->dev);
/* Check if we can provide the requested rate */ /* Check if we can provide the requested rate */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment