aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi/spi-pl022.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r--drivers/spi/spi-pl022.c340
1 files changed, 221 insertions, 119 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 400ae2121a2..66d2ae21e78 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1,7 +1,7 @@
/*
* A driver for the ARM PL022 PrimeCell SSP/SPI bus master.
*
- * Copyright (C) 2008-2009 ST-Ericsson AB
+ * Copyright (C) 2008-2012 ST-Ericsson AB
* Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
*
* Author: Linus Walleij <linus.walleij@stericsson.com>
@@ -40,6 +40,9 @@
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/pinctrl/consumer.h>
/*
* This macro is used to define some register default values.
@@ -356,6 +359,8 @@ struct vendor_data {
* @sgt_rx: scattertable for the RX transfer
* @sgt_tx: scattertable for the TX transfer
* @dummypage: a dummy page used for driving data on the bus with DMA
+ * @cur_cs: current chip select (gpio)
+ * @chipselects: list of chipselects (gpios)
*/
struct pl022 {
struct amba_device *adev;
@@ -389,6 +394,8 @@ struct pl022 {
char *dummypage;
bool dma_running;
#endif
+ int cur_cs;
+ int *chipselects;
};
/**
@@ -433,6 +440,14 @@ static void null_cs_control(u32 command)
pr_debug("pl022: dummy chip select control, CS=0x%x\n", command);
}
+static void pl022_cs_control(struct pl022 *pl022, u32 command)
+{
+ if (gpio_is_valid(pl022->cur_cs))
+ gpio_set_value(pl022->cur_cs, command);
+ else
+ pl022->cur_chip->cs_control(command);
+}
+
/**
* giveback - current spi_message is over, schedule next message and call
* callback of this message. Assumes that caller already
@@ -444,9 +459,8 @@ static void giveback(struct pl022 *pl022)
struct spi_transfer *last_transfer;
pl022->next_msg_cs_active = false;
- last_transfer = list_entry(pl022->cur_msg->transfers.prev,
- struct spi_transfer,
- transfer_list);
+ last_transfer = list_last_entry(&pl022->cur_msg->transfers,
+ struct spi_transfer, transfer_list);
/* Delay if requested before any change in chip select */
if (last_transfer->delay_usecs)
@@ -479,7 +493,7 @@ static void giveback(struct pl022 *pl022)
if (next_msg && next_msg->spi != pl022->cur_msg->spi)
next_msg = NULL;
if (!next_msg || pl022->cur_msg->state == STATE_ERROR)
- pl022->cur_chip->cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
else
pl022->next_msg_cs_active = true;
@@ -489,6 +503,11 @@ static void giveback(struct pl022 *pl022)
pl022->cur_transfer = NULL;
pl022->cur_chip = NULL;
spi_finalize_current_message(pl022->master);
+
+ /* disable the SPI/SSP operation */
+ writew((readw(SSP_CR1(pl022->virtbase)) &
+ (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase));
+
}
/**
@@ -813,8 +832,7 @@ static void dma_callback(void *data)
/* Update total bytes transferred */
msg->actual_length += pl022->cur_transfer->len;
if (pl022->cur_transfer->cs_change)
- pl022->cur_chip->
- cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
/* Move to next transfer */
msg->state = next_transfer(pl022);
@@ -1065,7 +1083,7 @@ err_alloc_rx_sg:
return -ENOMEM;
}
-static int __devinit pl022_dma_probe(struct pl022 *pl022)
+static int pl022_dma_probe(struct pl022 *pl022)
{
dma_cap_mask_t mask;
@@ -1093,10 +1111,8 @@ static int __devinit pl022_dma_probe(struct pl022 *pl022)
}
pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!pl022->dummypage) {
- dev_dbg(&pl022->adev->dev, "no DMA dummypage!\n");
+ if (!pl022->dummypage)
goto err_no_dummypage;
- }
dev_info(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n",
dma_chan_name(pl022->dma_rx_channel),
@@ -1115,6 +1131,35 @@ err_no_rxchan:
return -ENODEV;
}
+static int pl022_dma_autoprobe(struct pl022 *pl022)
+{
+ struct device *dev = &pl022->adev->dev;
+
+ /* automatically configure DMA channels from platform, normally using DT */
+ pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx");
+ if (!pl022->dma_rx_channel)
+ goto err_no_rxchan;
+
+ pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx");
+ if (!pl022->dma_tx_channel)
+ goto err_no_txchan;
+
+ pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!pl022->dummypage)
+ goto err_no_dummypage;
+
+ return 0;
+
+err_no_dummypage:
+ dma_release_channel(pl022->dma_tx_channel);
+ pl022->dma_tx_channel = NULL;
+err_no_txchan:
+ dma_release_channel(pl022->dma_rx_channel);
+ pl022->dma_rx_channel = NULL;
+err_no_rxchan:
+ return -ENODEV;
+}
+
static void terminate_dma(struct pl022 *pl022)
{
struct dma_chan *rxchan = pl022->dma_rx_channel;
@@ -1143,6 +1188,11 @@ static inline int configure_dma(struct pl022 *pl022)
return -ENODEV;
}
+static inline int pl022_dma_autoprobe(struct pl022 *pl022)
+{
+ return 0;
+}
+
static inline int pl022_dma_probe(struct pl022 *pl022)
{
return 0;
@@ -1247,8 +1297,7 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
/* Update total bytes transferred */
msg->actual_length += pl022->cur_transfer->len;
if (pl022->cur_transfer->cs_change)
- pl022->cur_chip->
- cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
/* Move to next transfer */
msg->state = next_transfer(pl022);
tasklet_schedule(&pl022->pump_transfers);
@@ -1333,7 +1382,7 @@ static void pump_transfers(unsigned long data)
/* Reselect chip select only if cs_change was requested */
if (previous->cs_change)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
} else {
/* STATE_START */
message->state = STATE_RUNNING;
@@ -1372,7 +1421,7 @@ static void do_interrupt_dma_transfer(struct pl022 *pl022)
/* Enable target chip, if not already active */
if (!pl022->next_msg_cs_active)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
if (set_up_next_transfer(pl022, pl022->cur_transfer)) {
/* Error path */
@@ -1424,12 +1473,12 @@ static void do_polling_transfer(struct pl022 *pl022)
if (previous->delay_usecs)
udelay(previous->delay_usecs);
if (previous->cs_change)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
} else {
/* STATE_START */
message->state = STATE_RUNNING;
if (!pl022->next_msg_cs_active)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
}
/* Configuration Changing Per Transfer */
@@ -1461,7 +1510,7 @@ static void do_polling_transfer(struct pl022 *pl022)
/* Update total byte transferred */
message->actual_length += pl022->cur_transfer->len;
if (pl022->cur_transfer->cs_change)
- pl022->cur_chip->cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
/* Move to next transfer */
message->state = next_transfer(pl022);
}
@@ -1490,6 +1539,7 @@ static int pl022_transfer_one_message(struct spi_master *master,
/* Setup the SPI using the per chip configuration */
pl022->cur_chip = spi_get_ctldata(msg->spi);
+ pl022->cur_cs = pl022->chipselects[msg->spi->chip_select];
restore_state(pl022);
flush(pl022);
@@ -1502,18 +1552,6 @@ 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);
@@ -1522,13 +1560,6 @@ 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;
}
@@ -1585,7 +1616,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
dev_err(&pl022->adev->dev,
"RX FIFO Trigger Level is configured incorrectly\n");
return -EINVAL;
- break;
}
switch (chip_info->tx_lev_trig) {
case SSP_TX_1_OR_MORE_EMPTY_LOC:
@@ -1611,7 +1641,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
dev_err(&pl022->adev->dev,
"TX FIFO Trigger Level is configured incorrectly\n");
return -EINVAL;
- break;
}
if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) {
if ((chip_info->ctrl_len < SSP_BITS_4)
@@ -1761,12 +1790,14 @@ static const struct pl022_config_chip pl022_default_chip_info = {
static int pl022_setup(struct spi_device *spi)
{
struct pl022_config_chip const *chip_info;
+ struct pl022_config_chip chip_info_dt;
struct chip_data *chip;
struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0};
int status = 0;
struct pl022 *pl022 = spi_master_get_devdata(spi->master);
unsigned int bits = spi->bits_per_word;
u32 tmp;
+ struct device_node *np = spi->dev.of_node;
if (!spi->max_speed_hz)
return -EINVAL;
@@ -1776,11 +1807,8 @@ static int pl022_setup(struct spi_device *spi)
if (chip == NULL) {
chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
- if (!chip) {
- dev_err(&spi->dev,
- "cannot allocate controller state\n");
+ if (!chip)
return -ENOMEM;
- }
dev_dbg(&spi->dev,
"allocated memory for controller's runtime state\n");
}
@@ -1789,10 +1817,32 @@ static int pl022_setup(struct spi_device *spi)
chip_info = spi->controller_data;
if (chip_info == NULL) {
- chip_info = &pl022_default_chip_info;
- /* spi_board_info.controller_data not is supplied */
- dev_dbg(&spi->dev,
- "using default controller_data settings\n");
+ if (np) {
+ chip_info_dt = pl022_default_chip_info;
+
+ chip_info_dt.hierarchy = SSP_MASTER;
+ of_property_read_u32(np, "pl022,interface",
+ &chip_info_dt.iface);
+ of_property_read_u32(np, "pl022,com-mode",
+ &chip_info_dt.com_mode);
+ of_property_read_u32(np, "pl022,rx-level-trig",
+ &chip_info_dt.rx_lev_trig);
+ of_property_read_u32(np, "pl022,tx-level-trig",
+ &chip_info_dt.tx_lev_trig);
+ of_property_read_u32(np, "pl022,ctrl-len",
+ &chip_info_dt.ctrl_len);
+ of_property_read_u32(np, "pl022,wait-state",
+ &chip_info_dt.wait_state);
+ of_property_read_u32(np, "pl022,duplex",
+ &chip_info_dt.duplex);
+
+ chip_info = &chip_info_dt;
+ } else {
+ chip_info = &pl022_default_chip_info;
+ /* spi_board_info.controller_data not is supplied */
+ dev_dbg(&spi->dev,
+ "using default controller_data settings\n");
+ }
} else
dev_dbg(&spi->dev,
"using user supplied controller_data settings\n");
@@ -1835,8 +1885,9 @@ static int pl022_setup(struct spi_device *spi)
chip->xfer_type = chip_info->com_mode;
if (!chip_info->cs_control) {
chip->cs_control = null_cs_control;
- dev_warn(&spi->dev,
- "chip select function is NULL for this chip\n");
+ if (!gpio_is_valid(pl022->chipselects[spi->chip_select]))
+ dev_warn(&spi->dev,
+ "invalid chip select\n");
} else
chip->cs_control = chip_info->cs_control;
@@ -1981,29 +2032,65 @@ static void pl022_cleanup(struct spi_device *spi)
kfree(chip);
}
-static int __devinit
-pl022_probe(struct amba_device *adev, const struct amba_id *id)
+static struct pl022_ssp_controller *
+pl022_platform_data_dt_get(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct pl022_ssp_controller *pd;
+ u32 tmp;
+
+ if (!np) {
+ dev_err(dev, "no dt node defined\n");
+ return NULL;
+ }
+
+ pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ if (!pd)
+ return NULL;
+
+ 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",
+ &pd->autosuspend_delay);
+ pd->rt = of_property_read_bool(np, "pl022,rt");
+
+ return pd;
+}
+
+static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
- struct pl022_ssp_controller *platform_info = adev->dev.platform_data;
+ struct pl022_ssp_controller *platform_info =
+ dev_get_platdata(&adev->dev);
struct spi_master *master;
struct pl022 *pl022 = NULL; /*Data for this driver */
- int status = 0;
+ struct device_node *np = adev->dev.of_node;
+ int status = 0, i, num_cs;
dev_info(&adev->dev,
"ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
- if (platform_info == NULL) {
- dev_err(&adev->dev, "probe - no platform data supplied\n");
- status = -ENODEV;
- goto err_no_pdata;
+ if (!platform_info && IS_ENABLED(CONFIG_OF))
+ platform_info = pl022_platform_data_dt_get(dev);
+
+ if (!platform_info) {
+ dev_err(dev, "probe: no platform data defined\n");
+ return -ENODEV;
+ }
+
+ if (platform_info->num_chipselect) {
+ num_cs = platform_info->num_chipselect;
+ } else {
+ dev_err(dev, "probe: no chip select defined\n");
+ return -ENODEV;
}
/* Allocate master with space for data */
master = spi_alloc_master(dev, sizeof(struct pl022));
if (master == NULL) {
dev_err(&adev->dev, "probe - cannot alloc SPI master\n");
- status = -ENOMEM;
- goto err_no_master;
+ return -ENOMEM;
}
pl022 = spi_master_get_devdata(master);
@@ -2011,19 +2098,49 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
pl022->master_info = platform_info;
pl022->adev = adev;
pl022->vendor = id->data;
+ pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
+ GFP_KERNEL);
/*
* Bus Number Which has been Assigned to this SSP controller
* on this board
*/
master->bus_num = platform_info->bus_id;
- master->num_chipselect = platform_info->num_chipselect;
+ master->num_chipselect = num_cs;
master->cleanup = pl022_cleanup;
master->setup = pl022_setup;
- master->prepare_transfer_hardware = pl022_prepare_transfer_hardware;
+ master->auto_runtime_pm = true;
master->transfer_one_message = pl022_transfer_one_message;
master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
master->rt = platform_info->rt;
+ master->dev.of_node = dev->of_node;
+
+ if (platform_info->num_chipselect && platform_info->chipselects) {
+ for (i = 0; i < num_cs; i++)
+ pl022->chipselects[i] = platform_info->chipselects[i];
+ } else if (IS_ENABLED(CONFIG_OF)) {
+ for (i = 0; i < num_cs; i++) {
+ int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
+
+ if (cs_gpio == -EPROBE_DEFER) {
+ status = -EPROBE_DEFER;
+ goto err_no_gpio;
+ }
+
+ pl022->chipselects[i] = cs_gpio;
+
+ if (gpio_is_valid(cs_gpio)) {
+ if (devm_gpio_request(dev, cs_gpio, "ssp-pl022"))
+ dev_err(&adev->dev,
+ "could not request %d gpio\n",
+ cs_gpio);
+ else if (gpio_direction_output(cs_gpio, 1))
+ dev_err(&adev->dev,
+ "could set gpio %d as output\n",
+ cs_gpio);
+ }
+ }
+ }
/*
* Supports mode 0-3, loopback, and active low CS. Transfers are
@@ -2040,28 +2157,23 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
goto err_no_ioregion;
pl022->phybase = adev->res.start;
- pl022->virtbase = ioremap(adev->res.start, resource_size(&adev->res));
+ pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
if (pl022->virtbase == NULL) {
status = -ENOMEM;
goto err_no_ioremap;
}
- printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
- adev->res.start, pl022->virtbase);
+ dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+ &adev->res.start, pl022->virtbase);
- pl022->clk = clk_get(&adev->dev, NULL);
+ pl022->clk = devm_clk_get(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
status = PTR_ERR(pl022->clk);
dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
goto err_no_clk;
}
- status = clk_prepare(pl022->clk);
- if (status) {
- dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
- goto err_clk_prep;
- }
-
- status = clk_enable(pl022->clk);
+ status = clk_prepare_enable(pl022->clk);
if (status) {
dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
goto err_no_clk_en;
@@ -2076,15 +2188,20 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
SSP_CR1(pl022->virtbase));
load_ssp_default_config(pl022);
- status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022",
- pl022);
+ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
if (status < 0) {
dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
goto err_no_irq;
}
- /* Get DMA channels */
- if (platform_info->enable_dma) {
+ /* Get DMA channels, try autoconfiguration first */
+ status = pl022_dma_autoprobe(pl022);
+
+ /* If that failed, use channels from platform_info */
+ if (status == 0)
+ platform_info->enable_dma = 1;
+ else if (platform_info->enable_dma) {
status = pl022_dma_probe(pl022);
if (status != 0)
platform_info->enable_dma = 0;
@@ -2092,7 +2209,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
/* Register with the SPI framework */
amba_set_drvdata(adev, pl022);
- status = spi_register_master(master);
+ status = devm_spi_register_master(&adev->dev, master);
if (status != 0) {
dev_err(&adev->dev,
"probe - problem registering spi master\n");
@@ -2108,35 +2225,27 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
pm_runtime_set_autosuspend_delay(dev,
platform_info->autosuspend_delay);
pm_runtime_use_autosuspend(dev);
- pm_runtime_put_autosuspend(dev);
- } else {
- pm_runtime_put(dev);
}
+ pm_runtime_put(dev);
+
return 0;
err_spi_register:
if (platform_info->enable_dma)
pl022_dma_remove(pl022);
-
- free_irq(adev->irq[0], pl022);
err_no_irq:
- clk_disable(pl022->clk);
+ clk_disable_unprepare(pl022->clk);
err_no_clk_en:
- clk_unprepare(pl022->clk);
- err_clk_prep:
- clk_put(pl022->clk);
err_no_clk:
- iounmap(pl022->virtbase);
err_no_ioremap:
amba_release_regions(adev);
err_no_ioregion:
+ err_no_gpio:
spi_master_put(master);
- err_no_master:
- err_no_pdata:
return status;
}
-static int __devexit
+static int
pl022_remove(struct amba_device *adev)
{
struct pl022 *pl022 = amba_get_drvdata(adev);
@@ -2154,20 +2263,13 @@ pl022_remove(struct amba_device *adev)
if (pl022->master_info->enable_dma)
pl022_dma_remove(pl022);
- free_irq(adev->irq[0], pl022);
- clk_disable(pl022->clk);
- clk_unprepare(pl022->clk);
- clk_put(pl022->clk);
- iounmap(pl022->virtbase);
+ clk_disable_unprepare(pl022->clk);
amba_release_regions(adev);
tasklet_disable(&pl022->pump_transfers);
- spi_unregister_master(pl022->master);
- spi_master_put(pl022->master);
- amba_set_drvdata(adev, NULL);
return 0;
}
-#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_PM_SLEEP
static int pl022_suspend(struct device *dev)
{
struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2179,6 +2281,14 @@ static int pl022_suspend(struct device *dev)
return ret;
}
+ ret = pm_runtime_force_suspend(dev);
+ if (ret) {
+ spi_master_resume(pl022->master);
+ return ret;
+ }
+
+ pinctrl_pm_select_sleep_state(dev);
+
dev_dbg(dev, "suspended\n");
return 0;
}
@@ -2188,6 +2298,10 @@ static int pl022_resume(struct device *dev)
struct pl022 *pl022 = dev_get_drvdata(dev);
int ret;
+ ret = pm_runtime_force_resume(dev);
+ if (ret)
+ dev_err(dev, "problem resuming\n");
+
/* Start the queue running */
ret = spi_master_resume(pl022->master);
if (ret)
@@ -2197,14 +2311,15 @@ static int pl022_resume(struct device *dev)
return ret;
}
-#endif /* CONFIG_PM */
+#endif
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
static int pl022_runtime_suspend(struct device *dev)
{
struct pl022 *pl022 = dev_get_drvdata(dev);
- clk_disable(pl022->clk);
+ clk_disable_unprepare(pl022->clk);
+ pinctrl_pm_select_idle_state(dev);
return 0;
}
@@ -2213,7 +2328,8 @@ static int pl022_runtime_resume(struct device *dev)
{
struct pl022 *pl022 = dev_get_drvdata(dev);
- clk_enable(pl022->clk);
+ pinctrl_pm_select_default_state(dev);
+ clk_prepare_enable(pl022->clk);
return 0;
}
@@ -2221,7 +2337,7 @@ static int pl022_runtime_resume(struct device *dev)
static const struct dev_pm_ops pl022_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
- SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
+ SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
};
static struct vendor_data vendor_arm = {
@@ -2251,15 +2367,6 @@ static struct vendor_data vendor_st_pl023 = {
.loopback = false,
};
-static struct vendor_data vendor_db5500_pl023 = {
- .fifodepth = 32,
- .max_bpw = 32,
- .unidir = false,
- .extended_cr = true,
- .pl023 = true,
- .loopback = true,
-};
-
static struct amba_id pl022_ids[] = {
{
/*
@@ -2291,11 +2398,6 @@ static struct amba_id pl022_ids[] = {
.mask = 0xffffffff,
.data = &vendor_st_pl023,
},
- {
- .id = 0x10080023,
- .mask = 0xffffffff,
- .data = &vendor_db5500_pl023,
- },
{ 0, 0 },
};
@@ -2308,7 +2410,7 @@ static struct amba_driver pl022_driver = {
},
.id_table = pl022_ids,
.probe = pl022_probe,
- .remove = __devexit_p(pl022_remove),
+ .remove = pl022_remove,
};
static int __init pl022_init(void)