aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi/spi-bcm63xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-bcm63xx.c')
-rw-r--r--drivers/spi/spi-bcm63xx.c123
1 files changed, 27 insertions, 96 deletions
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index a4ec5f4ec81..8510400e786 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -20,7 +20,6 @@
*/
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
@@ -30,13 +29,10 @@
#include <linux/spi/spi.h>
#include <linux/completion.h>
#include <linux/err.h>
-#include <linux/workqueue.h>
#include <linux/pm_runtime.h>
#include <bcm63xx_dev_spi.h>
-#define PFX KBUILD_MODNAME
-
#define BCM63XX_SPI_MAX_PREPEND 15
struct bcm63xx_spi {
@@ -124,17 +120,6 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
/* the spi->mode bits understood by this driver: */
#define MODEBITS (SPI_CPOL | SPI_CPHA)
-static int bcm63xx_spi_setup(struct spi_device *spi)
-{
- if (spi->bits_per_word != 8) {
- dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
- __func__, spi->bits_per_word);
- return -EINVAL;
- }
-
- return 0;
-}
-
static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
unsigned int num_transfers)
{
@@ -180,9 +165,7 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
transfer_list);
}
- len -= prepend_len;
-
- init_completion(&bs->done);
+ reinit_completion(&bs->done);
/* Fill in the Message control register */
msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
@@ -216,13 +199,7 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
if (!timeout)
return -ETIMEDOUT;
- /* read out all data */
- rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
-
- if (do_rx && rx_tail != len)
- return -EIO;
-
- if (!rx_tail)
+ if (!do_rx)
return 0;
len = 0;
@@ -242,24 +219,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
return 0;
}
-static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
-{
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
-
- pm_runtime_get_sync(&bs->pdev->dev);
-
- return 0;
-}
-
-static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
-{
- struct bcm63xx_spi *bs = spi_master_get_devdata(master);
-
- pm_runtime_put(&bs->pdev->dev);
-
- return 0;
-}
-
static int bcm63xx_spi_transfer_one(struct spi_master *master,
struct spi_message *m)
{
@@ -277,13 +236,6 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master,
* full-duplex transfers.
*/
list_for_each_entry(t, &m->transfers, transfer_list) {
- if (t->bits_per_word != 8) {
- dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
- __func__, t->bits_per_word);
- status = -EINVAL;
- goto exit;
- }
-
if (!first)
first = t;
@@ -371,46 +323,38 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
{
struct resource *r;
struct device *dev = &pdev->dev;
- struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data;
+ struct bcm63xx_spi_pdata *pdata = dev_get_platdata(&pdev->dev);
int irq;
struct spi_master *master;
struct clk *clk;
struct bcm63xx_spi *bs;
int ret;
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r) {
- dev_err(dev, "no iomem\n");
- ret = -ENXIO;
- goto out;
- }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "no irq\n");
- ret = -ENXIO;
- goto out;
+ return -ENXIO;
}
- clk = clk_get(dev, "spi");
+ clk = devm_clk_get(dev, "spi");
if (IS_ERR(clk)) {
dev_err(dev, "no clock for device\n");
- ret = PTR_ERR(clk);
- goto out;
+ return PTR_ERR(clk);
}
master = spi_alloc_master(dev, sizeof(*bs));
if (!master) {
dev_err(dev, "out of memory\n");
- ret = -ENOMEM;
- goto out_clk;
+ return -ENOMEM;
}
bs = spi_master_get_devdata(master);
+ init_completion(&bs->done);
platform_set_drvdata(pdev, master);
bs->pdev = pdev;
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bs->regs = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(bs->regs)) {
ret = PTR_ERR(bs->regs);
@@ -430,11 +374,10 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->num_chipselect;
- master->setup = bcm63xx_spi_setup;
- master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
- master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
master->transfer_one_message = bcm63xx_spi_transfer_one;
master->mode_bits = MODEBITS;
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
+ master->auto_runtime_pm = true;
bs->msg_type_shift = pdata->msg_type_shift;
bs->msg_ctl_width = pdata->msg_ctl_width;
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
@@ -451,11 +394,14 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
}
/* Initialize hardware */
- clk_prepare_enable(bs->clk);
+ ret = clk_prepare_enable(bs->clk);
+ if (ret)
+ goto out_err;
+
bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
/* register and we are done */
- ret = spi_register_master(master);
+ ret = devm_spi_register_master(dev, master);
if (ret) {
dev_err(dev, "spi register failed\n");
goto out_clk_disable;
@@ -469,40 +415,28 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
out_clk_disable:
clk_disable_unprepare(clk);
out_err:
- platform_set_drvdata(pdev, NULL);
spi_master_put(master);
-out_clk:
- clk_put(clk);
-out:
return ret;
}
static int bcm63xx_spi_remove(struct platform_device *pdev)
{
- struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+ struct spi_master *master = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
- spi_unregister_master(master);
-
/* reset spi block */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
/* HW shutdown */
clk_disable_unprepare(bs->clk);
- clk_put(bs->clk);
-
- platform_set_drvdata(pdev, 0);
-
- spi_master_put(master);
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int bcm63xx_spi_suspend(struct device *dev)
{
- struct spi_master *master =
- platform_get_drvdata(to_platform_device(dev));
+ struct spi_master *master = dev_get_drvdata(dev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
spi_master_suspend(master);
@@ -514,32 +448,29 @@ static int bcm63xx_spi_suspend(struct device *dev)
static int bcm63xx_spi_resume(struct device *dev)
{
- struct spi_master *master =
- platform_get_drvdata(to_platform_device(dev));
+ struct spi_master *master = dev_get_drvdata(dev);
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
+ int ret;
- clk_prepare_enable(bs->clk);
+ ret = clk_prepare_enable(bs->clk);
+ if (ret)
+ return ret;
spi_master_resume(master);
return 0;
}
+#endif
static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
- .suspend = bcm63xx_spi_suspend,
- .resume = bcm63xx_spi_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_spi_suspend, bcm63xx_spi_resume)
};
-#define BCM63XX_SPI_PM_OPS (&bcm63xx_spi_pm_ops)
-#else
-#define BCM63XX_SPI_PM_OPS NULL
-#endif
-
static struct platform_driver bcm63xx_spi_driver = {
.driver = {
.name = "bcm63xx-spi",
.owner = THIS_MODULE,
- .pm = BCM63XX_SPI_PM_OPS,
+ .pm = &bcm63xx_spi_pm_ops,
},
.probe = bcm63xx_spi_probe,
.remove = bcm63xx_spi_remove,