[linux-yocto] [PATCH 21/42] LSIAXXIA/spi: ported from 3.10 to 3.14
Cristian Bercaru
cristian.bercaru at windriver.com
Thu Jun 11 01:32:06 PDT 2015
From: Charlie Paul <cpaul.windriver at gmail.com>
Poerted the LSI spi driver from 3.10 to 3.14 because
the driver was failing.
Signed-off-by: Charlie Paul <cpaul.windriver at gmail.com>
---
drivers/spi/spi-pl022.c | 115 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 94 insertions(+), 21 deletions(-)
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index fe091a8..e004b7b 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -50,7 +50,7 @@
* val shifted sb steps to the left.
*/
#define SSP_WRITE_BITS(reg, val, mask, sb) \
- ((reg) = (((reg) & ~(mask)) | (((val)<<(sb)) & (mask))))
+ ((reg) = (((reg) & ~(mask)) | (((val)<<(sb)) & (mask))))
/*
* This macro is also used to define some default values.
@@ -58,7 +58,7 @@
* the result with mask.
*/
#define GEN_MASK_BITS(val, mask, sb) \
- (((val)<<(sb)) & (mask))
+ (((val)<<(sb)) & (mask))
#define DRIVE_TX 0
#define DO_NOT_DRIVE_TX 1
@@ -368,6 +368,11 @@ struct pl022 {
resource_size_t phybase;
void __iomem *virtbase;
struct clk *clk;
+ /* Two optional pin states - default & sleep */
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_default;
+ struct pinctrl_state *pins_idle;
+ struct pinctrl_state *pins_sleep;
struct spi_master *master;
struct pl022_ssp_controller *master_info;
/* Message per-transfer pump */
@@ -424,7 +429,7 @@ struct chip_data {
bool enable_dma;
enum ssp_reading read;
enum ssp_writing write;
- void (*cs_control) (u32 command);
+ void (*cs_control)(u32 command);
int xfer_type;
};
@@ -1075,7 +1080,7 @@ err_rxdesc:
pl022->sgt_tx.nents, DMA_TO_DEVICE);
err_tx_sgmap:
dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl,
- pl022->sgt_rx.nents, DMA_FROM_DEVICE);
+ pl022->sgt_tx.nents, DMA_FROM_DEVICE);
err_rx_sgmap:
sg_free_table(&pl022->sgt_tx);
err_alloc_tx_sg:
@@ -1162,7 +1167,7 @@ err_no_txchan:
err_no_rxchan:
return -ENODEV;
}
-
+
static void terminate_dma(struct pl022 *pl022)
{
struct dma_chan *rxchan = pl022->dma_rx_channel;
@@ -1555,6 +1560,18 @@ static int pl022_transfer_one_message(struct spi_master *master,
return 0;
}
+static int pl022_prepare_transfer_hardware(struct spi_master *master)
+{
+ struct pl022 *pl022 = spi_master_get_devdata(master);
+
+ /*
+ * Just make sure we have all we need to run the transfer by syncing
+ * with the runtime PM framework.
+ */
+ pm_runtime_get_sync(&pl022->adev->dev);
+ return 0;
+}
+
static int pl022_unprepare_transfer_hardware(struct spi_master *master)
{
struct pl022 *pl022 = spi_master_get_devdata(master);
@@ -1563,6 +1580,13 @@ static int pl022_unprepare_transfer_hardware(struct spi_master *master)
writew((readw(SSP_CR1(pl022->virtbase)) &
(~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
+ if (pl022->master_info->autosuspend_delay > 0) {
+ pm_runtime_mark_last_busy(&pl022->adev->dev);
+ pm_runtime_put_autosuspend(&pl022->adev->dev);
+ } else {
+ pm_runtime_put(&pl022->adev->dev);
+ }
+
return 0;
}
@@ -1747,7 +1771,7 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct
scr = SCR_MIN;
}
- WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n",
+ WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate\n",
freq);
clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF);
@@ -2057,7 +2081,6 @@ pl022_platform_data_dt_get(struct device *dev)
}
pd->bus_id = -1;
- pd->enable_dma = 1;
of_property_read_u32(np, "num-cs", &tmp);
pd->num_chipselect = tmp;
of_property_read_u32(np, "pl022,autosuspend-delay",
@@ -2070,8 +2093,7 @@ pl022_platform_data_dt_get(struct device *dev)
static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
- struct pl022_ssp_controller *platform_info =
- dev_get_platdata(&adev->dev);
+ struct pl022_ssp_controller *platform_info = adev->dev.platform_data;
struct spi_master *master;
struct pl022 *pl022 = NULL; /*Data for this driver */
struct device_node *np = adev->dev.of_node;
@@ -2109,7 +2131,32 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
GFP_KERNEL);
- pinctrl_pm_select_default_state(dev);
+ pl022->pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(pl022->pinctrl)) {
+ status = PTR_ERR(pl022->pinctrl);
+ goto err_no_pinctrl;
+ }
+
+ pl022->pins_default = pinctrl_lookup_state(pl022->pinctrl,
+ PINCTRL_STATE_DEFAULT);
+ /* 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");
+ } else
+ dev_err(dev, "could not get default pinstate\n");
+
+ pl022->pins_idle = pinctrl_lookup_state(pl022->pinctrl,
+ PINCTRL_STATE_IDLE);
+ if (IS_ERR(pl022->pins_idle))
+ dev_dbg(dev, "could not get idle pinstate\n");
+
+ pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl,
+ PINCTRL_STATE_SLEEP);
+ if (IS_ERR(pl022->pins_sleep))
+ dev_dbg(dev, "could not get sleep pinstate\n");
/*
* Bus Number Which has been Assigned to this SSP controller
@@ -2119,7 +2166,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
master->num_chipselect = num_cs;
master->cleanup = pl022_cleanup;
master->setup = pl022_setup;
- master->auto_runtime_pm = true;
+ master->prepare_transfer_hardware = pl022_prepare_transfer_hardware;
master->transfer_one_message = pl022_transfer_one_message;
master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
master->rt = platform_info->rt;
@@ -2173,8 +2220,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
status = -ENOMEM;
goto err_no_ioremap;
}
- dev_info(&adev->dev, "mapped registers from %pa to %p\n",
- &adev->res.start, pl022->virtbase);
+ pr_info("pl022: mapped registers from 0x%08lx to %p\n",
+ (unsigned long)adev->res.start, pl022->virtbase);
pl022->clk = devm_clk_get(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
@@ -2225,7 +2272,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
/* Register with the SPI framework */
amba_set_drvdata(adev, pl022);
- status = devm_spi_register_master(&adev->dev, master);
+ status = spi_register_master(master);
if (status != 0) {
dev_err(&adev->dev,
"probe - problem registering spi master\n");
@@ -2259,6 +2306,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
amba_release_regions(adev);
err_no_ioregion:
err_no_gpio:
+ err_no_pinctrl:
spi_master_put(master);
return status;
}
@@ -2285,6 +2333,8 @@ pl022_remove(struct amba_device *adev)
clk_unprepare(pl022->clk);
amba_release_regions(adev);
tasklet_disable(&pl022->pump_transfers);
+ spi_unregister_master(pl022->master);
+ amba_set_drvdata(adev, NULL);
return 0;
}
@@ -2296,21 +2346,44 @@ pl022_remove(struct amba_device *adev)
*/
static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
{
+ int ret;
+ struct pinctrl_state *pins_state;
+
clk_disable(pl022->clk);
- if (runtime)
- pinctrl_pm_select_idle_state(&pl022->adev->dev);
- else
- pinctrl_pm_select_sleep_state(&pl022->adev->dev);
+ pins_state = runtime ? pl022->pins_idle : pl022->pins_sleep;
+ /* Optionally let pins go into sleep states */
+ if (!IS_ERR(pins_state)) {
+ ret = pinctrl_select_state(pl022->pinctrl, pins_state);
+ if (ret)
+ dev_err(&pl022->adev->dev, "could not set %s pins\n",
+ runtime ? "idle" : "sleep");
+ }
}
static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
{
+ int ret;
+
+ /* Optionaly enable pins to be muxed in and configured */
/* First go to the default state */
- pinctrl_pm_select_default_state(&pl022->adev->dev);
- if (!runtime)
+ 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");
+ }
+
+ if (!runtime) {
/* Then let's idle the pins until the next transfer happens */
- pinctrl_pm_select_idle_state(&pl022->adev->dev);
+ if (!IS_ERR(pl022->pins_idle)) {
+ ret = pinctrl_select_state(pl022->pinctrl,
+ pl022->pins_idle);
+ if (ret)
+ dev_err(&pl022->adev->dev,
+ "could not set idle pins\n");
+ }
+ }
clk_enable(pl022->clk);
}
--
1.7.9.5
More information about the linux-yocto
mailing list