summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/Kconfig2
-rw-r--r--drivers/spi/spi-altera.c14
-rw-r--r--drivers/spi/spi-ath79.c13
-rw-r--r--drivers/spi/spi-atmel.c15
-rw-r--r--drivers/spi/spi-au1550.c1
-rw-r--r--drivers/spi/spi-bfin-sport.c13
-rw-r--r--drivers/spi/spi-bfin5xx.c2
-rw-r--r--drivers/spi/spi-bitbang.c1
-rw-r--r--drivers/spi/spi-butterfly.c1
-rw-r--r--drivers/spi/spi-coldfire-qspi.c16
-rw-r--r--drivers/spi/spi-davinci.c20
-rw-r--r--drivers/spi/spi-dw-mid.c9
-rw-r--r--drivers/spi/spi-dw-mmio.c15
-rw-r--r--drivers/spi/spi-dw-pci.c1
-rw-r--r--drivers/spi/spi-dw.c63
-rw-r--r--drivers/spi/spi-dw.h97
-rw-r--r--drivers/spi/spi-ep93xx.c21
-rw-r--r--drivers/spi/spi-fsl-espi.c13
-rw-r--r--drivers/spi/spi-fsl-spi.c3
-rw-r--r--drivers/spi/spi-gpio.c22
-rw-r--r--drivers/spi/spi-imx.c18
-rw-r--r--drivers/spi/spi-mpc512x-psc.c13
-rw-r--r--drivers/spi/spi-mpc52xx-psc.c13
-rw-r--r--drivers/spi/spi-mpc52xx.c14
-rw-r--r--drivers/spi/spi-nuc900.c14
-rw-r--r--drivers/spi/spi-oc-tiny.c14
-rw-r--r--drivers/spi/spi-omap-uwire.c1
-rw-r--r--drivers/spi/spi-omap2-mcspi.c7
-rw-r--r--drivers/spi/spi-orion.c1
-rw-r--r--drivers/spi/spi-pl022.c238
-rw-r--r--drivers/spi/spi-ppc4xx.c15
-rw-r--r--drivers/spi/spi-pxa2xx-pci.c1
-rw-r--r--drivers/spi/spi-s3c24xx.c22
-rw-r--r--drivers/spi/spi-s3c64xx.c175
-rw-r--r--drivers/spi/spi-sh-msiof.c16
-rw-r--r--drivers/spi/spi-sh-sci.c14
-rw-r--r--drivers/spi/spi-sh.c15
-rw-r--r--drivers/spi/spi-stmp.c13
-rw-r--r--drivers/spi/spi-tegra.c17
-rw-r--r--drivers/spi/spi-ti-ssp.c14
-rw-r--r--drivers/spi/spi-tle62x0.c1
-rw-r--r--drivers/spi/spi-topcliff-pch.c93
-rw-r--r--drivers/spi/spi-txx9.c1
-rw-r--r--drivers/spi/spi-xilinx.c13
-rw-r--r--drivers/spi/spi.c1
45 files changed, 457 insertions, 629 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 52e2900d9d8..a1fd73df541 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -88,7 +88,7 @@ config SPI_BFIN_SPORT
config SPI_AU1550
tristate "Au1550/Au12x0 SPI Controller"
- depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL
+ depends on MIPS_ALCHEMY && EXPERIMENTAL
select SPI_BITBANG
help
If you say yes to this option, support will be included for the
diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c
index 4813a63ce6f..c00d00e96ee 100644
--- a/drivers/spi/spi-altera.c
+++ b/drivers/spi/spi-altera.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@@ -320,18 +321,7 @@ static struct platform_driver altera_spi_driver = {
.of_match_table = altera_spi_match,
},
};
-
-static int __init altera_spi_init(void)
-{
- return platform_driver_register(&altera_spi_driver);
-}
-module_init(altera_spi_init);
-
-static void __exit altera_spi_exit(void)
-{
- platform_driver_unregister(&altera_spi_driver);
-}
-module_exit(altera_spi_exit);
+module_platform_driver(altera_spi_driver);
MODULE_DESCRIPTION("Altera SPI driver");
MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
index 03019bf5a5e..024b48aed5c 100644
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -273,18 +273,7 @@ static struct platform_driver ath79_spi_driver = {
.owner = THIS_MODULE,
},
};
-
-static __init int ath79_spi_init(void)
-{
- return platform_driver_register(&ath79_spi_driver);
-}
-module_init(ath79_spi_init);
-
-static __exit void ath79_spi_exit(void)
-{
- platform_driver_unregister(&ath79_spi_driver);
-}
-module_exit(ath79_spi_exit);
+module_platform_driver(ath79_spi_driver);
MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR913X");
MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 82dee9a6c0d..79665e2e6ec 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -22,7 +22,7 @@
#include <asm/io.h>
#include <mach/board.h>
-#include <mach/gpio.h>
+#include <asm/gpio.h>
#include <mach/cpu.h>
/* SPI register offsets */
@@ -1074,18 +1074,7 @@ static struct platform_driver atmel_spi_driver = {
.resume = atmel_spi_resume,
.remove = __exit_p(atmel_spi_remove),
};
-
-static int __init atmel_spi_init(void)
-{
- return platform_driver_probe(&atmel_spi_driver, atmel_spi_probe);
-}
-module_init(atmel_spi_init);
-
-static void __exit atmel_spi_exit(void)
-{
- platform_driver_unregister(&atmel_spi_driver);
-}
-module_exit(atmel_spi_exit);
+module_platform_driver(atmel_spi_driver);
MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver");
MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c
index bddee5f516b..5784c879961 100644
--- a/drivers/spi/spi-au1550.c
+++ b/drivers/spi/spi-au1550.c
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/resource.h>
diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c
index e557ff617b1..248a2cc671a 100644
--- a/drivers/spi/spi-bfin-sport.c
+++ b/drivers/spi/spi-bfin-sport.c
@@ -938,15 +938,4 @@ static struct platform_driver bfin_sport_spi_driver = {
.suspend = bfin_sport_spi_suspend,
.resume = bfin_sport_spi_resume,
};
-
-static int __init bfin_sport_spi_init(void)
-{
- return platform_driver_register(&bfin_sport_spi_driver);
-}
-module_init(bfin_sport_spi_init);
-
-static void __exit bfin_sport_spi_exit(void)
-{
- platform_driver_unregister(&bfin_sport_spi_driver);
-}
-module_exit(bfin_sport_spi_exit);
+module_platform_driver(bfin_sport_spi_driver);
diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c
index b8d25f2b703..3b83ff8b1e2 100644
--- a/drivers/spi/spi-bfin5xx.c
+++ b/drivers/spi/spi-bfin5xx.c
@@ -1098,7 +1098,7 @@ static int bfin_spi_setup(struct spi_device *spi)
if (chip->pio_interrupt && !drv_data->irq_requested) {
ret = request_irq(drv_data->spi_irq, bfin_spi_pio_irq_handler,
- IRQF_DISABLED, "BFIN_SPI", drv_data);
+ 0, "BFIN_SPI", drv_data);
if (ret) {
dev_err(&spi->dev, "Unable to register spi IRQ\n");
goto error;
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 02d57fbba29..aef59b1a15f 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -20,6 +20,7 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c
index 9f907ec52de..5ed08e53743 100644
--- a/drivers/spi/spi-butterfly.c
+++ b/drivers/spi/spi-butterfly.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/module.h>
#include <linux/device.h>
#include <linux/parport.h>
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
index ae2cd1c1fda..6eee64a5d24 100644
--- a/drivers/spi/spi-coldfire-qspi.c
+++ b/drivers/spi/spi-coldfire-qspi.c
@@ -487,7 +487,7 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev)
goto fail2;
}
- status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, IRQF_DISABLED,
+ status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, 0,
pdev->name, mcfqspi);
if (status) {
dev_dbg(&pdev->dev, "request_irq failed\n");
@@ -621,20 +621,10 @@ static struct platform_driver mcfqspi_driver = {
.driver.name = DRIVER_NAME,
.driver.owner = THIS_MODULE,
.driver.pm = MCFQSPI_DEV_PM_OPS,
+ .probe = mcfqspi_probe,
.remove = __devexit_p(mcfqspi_remove),
};
-
-static int __init mcfqspi_init(void)
-{
- return platform_driver_probe(&mcfqspi_driver, mcfqspi_probe);
-}
-module_init(mcfqspi_init);
-
-static void __exit mcfqspi_exit(void)
-{
- platform_driver_unregister(&mcfqspi_driver);
-}
-module_exit(mcfqspi_exit);
+module_platform_driver(mcfqspi_driver);
MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 1f0ed8005c9..31bfba805cf 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -799,7 +799,7 @@ rx_dma_failed:
* It will invoke spi_bitbang_start to create work queue so that client driver
* can register transfer method to work queue.
*/
-static int davinci_spi_probe(struct platform_device *pdev)
+static int __devinit davinci_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct davinci_spi *dspi;
@@ -984,7 +984,7 @@ err:
* It will also call spi_bitbang_stop to destroy the work queue which was
* created by spi_bitbang_start.
*/
-static int __exit davinci_spi_remove(struct platform_device *pdev)
+static int __devexit davinci_spi_remove(struct platform_device *pdev)
{
struct davinci_spi *dspi;
struct spi_master *master;
@@ -1011,20 +1011,10 @@ static struct platform_driver davinci_spi_driver = {
.name = "spi_davinci",
.owner = THIS_MODULE,
},
- .remove = __exit_p(davinci_spi_remove),
+ .probe = davinci_spi_probe,
+ .remove = __devexit_p(davinci_spi_remove),
};
-
-static int __init davinci_spi_init(void)
-{
- return platform_driver_probe(&davinci_spi_driver, davinci_spi_probe);
-}
-module_init(davinci_spi_init);
-
-static void __exit davinci_spi_exit(void)
-{
- platform_driver_unregister(&davinci_spi_driver);
-}
-module_exit(davinci_spi_exit);
+module_platform_driver(davinci_spi_driver);
MODULE_DESCRIPTION("TI DaVinci SPI Master Controller Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c
index 130e55537db..e743a45ee92 100644
--- a/drivers/spi/spi-dw-mid.c
+++ b/drivers/spi/spi-dw-mid.c
@@ -116,13 +116,13 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
/* 1. setup DMA related registers */
if (cs_change) {
spi_enable_chip(dws, 0);
- dw_writew(dws, dmardlr, 0xf);
- dw_writew(dws, dmatdlr, 0x10);
+ dw_writew(dws, DW_SPI_DMARDLR, 0xf);
+ dw_writew(dws, DW_SPI_DMATDLR, 0x10);
if (dws->tx_dma)
dma_ctrl |= 0x2;
if (dws->rx_dma)
dma_ctrl |= 0x1;
- dw_writew(dws, dmacr, dma_ctrl);
+ dw_writew(dws, DW_SPI_DMACR, dma_ctrl);
spi_enable_chip(dws, 1);
}
@@ -200,7 +200,8 @@ static struct dw_spi_dma_ops mid_dma_ops = {
int dw_spi_mid_init(struct dw_spi *dws)
{
- u32 *clk_reg, clk_cdiv;
+ void __iomem *clk_reg;
+ u32 clk_cdiv;
clk_reg = ioremap_nocache(MRST_CLK_SPI0_REG, 16);
if (!clk_reg)
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
index 34eb66501db..db2f1ba06ea 100644
--- a/drivers/spi/spi-dw-mmio.c
+++ b/drivers/spi/spi-dw-mmio.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/scatterlist.h>
+#include <linux/module.h>
#include "spi-dw.h"
@@ -127,24 +128,14 @@ static int __devexit dw_spi_mmio_remove(struct platform_device *pdev)
}
static struct platform_driver dw_spi_mmio_driver = {
+ .probe = dw_spi_mmio_probe,
.remove = __devexit_p(dw_spi_mmio_remove),
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
};
-
-static int __init dw_spi_mmio_init(void)
-{
- return platform_driver_probe(&dw_spi_mmio_driver, dw_spi_mmio_probe);
-}
-module_init(dw_spi_mmio_init);
-
-static void __exit dw_spi_mmio_exit(void)
-{
- platform_driver_unregister(&dw_spi_mmio_driver);
-}
-module_exit(dw_spi_mmio_exit);
+module_platform_driver(dw_spi_mmio_driver);
MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>");
MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core");
diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c
index c5f37f03ac8..f64250ea161 100644
--- a/drivers/spi/spi-dw-pci.c
+++ b/drivers/spi/spi-dw-pci.c
@@ -21,6 +21,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
+#include <linux/module.h>
#include "spi-dw.h"
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 857cd30b44b..082458d73ce 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -19,6 +19,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/slab.h>
@@ -88,35 +89,35 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
"=================================\n");
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "CTRL0: \t\t0x%08x\n", dw_readl(dws, ctrl0));
+ "CTRL0: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL0));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "CTRL1: \t\t0x%08x\n", dw_readl(dws, ctrl1));
+ "CTRL1: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL1));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "SSIENR: \t0x%08x\n", dw_readl(dws, ssienr));
+ "SSIENR: \t0x%08x\n", dw_readl(dws, DW_SPI_SSIENR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "SER: \t\t0x%08x\n", dw_readl(dws, ser));
+ "SER: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SER));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "BAUDR: \t\t0x%08x\n", dw_readl(dws, baudr));
+ "BAUDR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_BAUDR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "TXFTLR: \t0x%08x\n", dw_readl(dws, txfltr));
+ "TXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_TXFLTR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "RXFTLR: \t0x%08x\n", dw_readl(dws, rxfltr));
+ "RXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_RXFLTR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "TXFLR: \t\t0x%08x\n", dw_readl(dws, txflr));
+ "TXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_TXFLR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "RXFLR: \t\t0x%08x\n", dw_readl(dws, rxflr));
+ "RXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_RXFLR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "SR: \t\t0x%08x\n", dw_readl(dws, sr));
+ "SR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "IMR: \t\t0x%08x\n", dw_readl(dws, imr));
+ "IMR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_IMR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "ISR: \t\t0x%08x\n", dw_readl(dws, isr));
+ "ISR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_ISR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "DMACR: \t\t0x%08x\n", dw_readl(dws, dmacr));
+ "DMACR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_DMACR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "DMATDLR: \t0x%08x\n", dw_readl(dws, dmatdlr));
+ "DMATDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMATDLR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "DMARDLR: \t0x%08x\n", dw_readl(dws, dmardlr));
+ "DMARDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMARDLR));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
"=================================\n");
@@ -166,7 +167,7 @@ static inline u32 tx_max(struct dw_spi *dws)
u32 tx_left, tx_room, rxtx_gap;
tx_left = (dws->tx_end - dws->tx) / dws->n_bytes;
- tx_room = dws->fifo_len - dw_readw(dws, txflr);
+ tx_room = dws->fifo_len - dw_readw(dws, DW_SPI_TXFLR);
/*
* Another concern is about the tx/rx mismatch, we
@@ -187,7 +188,7 @@ static inline u32 rx_max(struct dw_spi *dws)
{
u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes;
- return min(rx_left, (u32)dw_readw(dws, rxflr));
+ return min(rx_left, (u32)dw_readw(dws, DW_SPI_RXFLR));
}
static void dw_writer(struct dw_spi *dws)
@@ -203,7 +204,7 @@ static void dw_writer(struct dw_spi *dws)
else
txw = *(u16 *)(dws->tx);
}
- dw_writew(dws, dr, txw);
+ dw_writew(dws, DW_SPI_DR, txw);
dws->tx += dws->n_bytes;
}
}
@@ -214,7 +215,7 @@ static void dw_reader(struct dw_spi *dws)
u16 rxw;
while (max--) {
- rxw = dw_readw(dws, dr);
+ rxw = dw_readw(dws, DW_SPI_DR);
/* Care rx only if the transfer's original "rx" is not null */
if (dws->rx_end - dws->len) {
if (dws->n_bytes == 1)
@@ -322,13 +323,13 @@ EXPORT_SYMBOL_GPL(dw_spi_xfer_done);
static irqreturn_t interrupt_transfer(struct dw_spi *dws)
{
- u16 irq_status = dw_readw(dws, isr);
+ u16 irq_status = dw_readw(dws, DW_SPI_ISR);
/* Error handling */
if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) {
- dw_readw(dws, txoicr);
- dw_readw(dws, rxoicr);
- dw_readw(dws, rxuicr);
+ dw_readw(dws, DW_SPI_TXOICR);
+ dw_readw(dws, DW_SPI_RXOICR);
+ dw_readw(dws, DW_SPI_RXUICR);
int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun");
return IRQ_HANDLED;
}
@@ -352,7 +353,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
static irqreturn_t dw_spi_irq(int irq, void *dev_id)
{
struct dw_spi *dws = dev_id;
- u16 irq_status = dw_readw(dws, isr) & 0x3f;
+ u16 irq_status = dw_readw(dws, DW_SPI_ISR) & 0x3f;
if (!irq_status)
return IRQ_NONE;
@@ -520,11 +521,11 @@ static void pump_transfers(unsigned long data)
* 2. clk_div is changed
* 3. control value changes
*/
- if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div || imask) {
+ if (dw_readw(dws, DW_SPI_CTRL0) != cr0 || cs_change || clk_div || imask) {
spi_enable_chip(dws, 0);
- if (dw_readw(dws, ctrl0) != cr0)
- dw_writew(dws, ctrl0, cr0);
+ if (dw_readw(dws, DW_SPI_CTRL0) != cr0)
+ dw_writew(dws, DW_SPI_CTRL0, cr0);
spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
spi_chip_sel(dws, spi->chip_select);
@@ -534,7 +535,7 @@ static void pump_transfers(unsigned long data)
if (imask)
spi_umask_intr(dws, imask);
if (txint_level)
- dw_writew(dws, txfltr, txint_level);
+ dw_writew(dws, DW_SPI_TXFLTR, txint_level);
spi_enable_chip(dws, 1);
if (cs_change)
@@ -790,13 +791,13 @@ static void spi_hw_init(struct dw_spi *dws)
if (!dws->fifo_len) {
u32 fifo;
for (fifo = 2; fifo <= 257; fifo++) {
- dw_writew(dws, txfltr, fifo);
- if (fifo != dw_readw(dws, txfltr))
+ dw_writew(dws, DW_SPI_TXFLTR, fifo);
+ if (fifo != dw_readw(dws, DW_SPI_TXFLTR))
break;
}
dws->fifo_len = (fifo == 257) ? 0 : fifo;
- dw_writew(dws, txfltr, 0);
+ dw_writew(dws, DW_SPI_TXFLTR, 0);
}
}
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 8b7b07bf6c3..9c57c078031 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -4,6 +4,33 @@
#include <linux/io.h>
#include <linux/scatterlist.h>
+/* Register offsets */
+#define DW_SPI_CTRL0 0x00
+#define DW_SPI_CTRL1 0x04
+#define DW_SPI_SSIENR 0x08
+#define DW_SPI_MWCR 0x0c
+#define DW_SPI_SER 0x10
+#define DW_SPI_BAUDR 0x14
+#define DW_SPI_TXFLTR 0x18
+#define DW_SPI_RXFLTR 0x1c
+#define DW_SPI_TXFLR 0x20
+#define DW_SPI_RXFLR 0x24
+#define DW_SPI_SR 0x28
+#define DW_SPI_IMR 0x2c
+#define DW_SPI_ISR 0x30
+#define DW_SPI_RISR 0x34
+#define DW_SPI_TXOICR 0x38
+#define DW_SPI_RXOICR 0x3c
+#define DW_SPI_RXUICR 0x40
+#define DW_SPI_MSTICR 0x44
+#define DW_SPI_ICR 0x48
+#define DW_SPI_DMACR 0x4c
+#define DW_SPI_DMATDLR 0x50
+#define DW_SPI_DMARDLR 0x54
+#define DW_SPI_IDR 0x58
+#define DW_SPI_VERSION 0x5c
+#define DW_SPI_DR 0x60
+
/* Bit fields in CTRLR0 */
#define SPI_DFS_OFFSET 0
@@ -55,35 +82,6 @@ enum dw_ssi_type {
SSI_NS_MICROWIRE,
};
-struct dw_spi_reg {
- u32 ctrl0;
- u32 ctrl1;
- u32 ssienr;
- u32 mwcr;
- u32 ser;
- u32 baudr;
- u32 txfltr;
- u32 rxfltr;
- u32 txflr;
- u32 rxflr;
- u32 sr;
- u32 imr;
- u32 isr;
- u32 risr;
- u32 txoicr;
- u32 rxoicr;
- u32 rxuicr;
- u32 msticr;
- u32 icr;
- u32 dmacr;
- u32 dmatdlr;
- u32 dmardlr;
- u32 idr;
- u32 version;
- u32 dr; /* Currently oper as 32 bits,
- though only low 16 bits matters */
-} __packed;
-
struct dw_spi;
struct dw_spi_dma_ops {
int (*dma_init)(struct dw_spi *dws);
@@ -161,23 +159,34 @@ struct dw_spi {
#endif
};
-#define dw_readl(dw, name) \
- __raw_readl(&(((struct dw_spi_reg *)dw->regs)->name))
-#define dw_writel(dw, name, val) \
- __raw_writel((val), &(((struct dw_spi_reg *)dw->regs)->name))
-#define dw_readw(dw, name) \
- __raw_readw(&(((struct dw_spi_reg *)dw->regs)->name))
-#define dw_writew(dw, name, val) \
- __raw_writew((val), &(((struct dw_spi_reg *)dw->regs)->name))
+static inline u32 dw_readl(struct dw_spi *dws, u32 offset)
+{
+ return __raw_readl(dws->regs + offset);
+}
+
+static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val)
+{
+ __raw_writel(val, dws->regs + offset);
+}
+
+static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
+{
+ return __raw_readw(dws->regs + offset);
+}
+
+static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val)
+{
+ __raw_writew(val, dws->regs + offset);
+}
static inline void spi_enable_chip(struct dw_spi *dws, int enable)
{
- dw_writel(dws, ssienr, (enable ? 1 : 0));
+ dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));
}
static inline void spi_set_clk(struct dw_spi *dws, u16 div)
{
- dw_writel(dws, baudr, div);
+ dw_writel(dws, DW_SPI_BAUDR, div);
}
static inline void spi_chip_sel(struct dw_spi *dws, u16 cs)
@@ -188,7 +197,7 @@ static inline void spi_chip_sel(struct dw_spi *dws, u16 cs)
if (dws->cs_control)
dws->cs_control(1);
- dw_writel(dws, ser, 1 << cs);
+ dw_writel(dws, DW_SPI_SER, 1 << cs);
}
/* Disable IRQ bits */
@@ -196,8 +205,8 @@ static inline void spi_mask_intr(struct dw_spi *dws, u32 mask)
{
u32 new_mask;
- new_mask = dw_readl(dws, imr) & ~mask;
- dw_writel(dws, imr, new_mask);
+ new_mask = dw_readl(dws, DW_SPI_IMR) & ~mask;
+ dw_writel(dws, DW_SPI_IMR, new_mask);
}
/* Enable IRQ bits */
@@ -205,8 +214,8 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask)
{
u32 new_mask;
- new_mask = dw_readl(dws, imr) | mask;
- dw_writel(dws, imr, new_mask);
+ new_mask = dw_readl(dws, DW_SPI_IMR) | mask;
+ dw_writel(dws, DW_SPI_IMR, new_mask);
}
/*
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
index 1cf645479bf..0a282e5fcc9 100644
--- a/drivers/spi/spi-ep93xx.c
+++ b/drivers/spi/spi-ep93xx.c
@@ -24,6 +24,7 @@
#include <linux/dmaengine.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
@@ -1025,7 +1026,7 @@ static void ep93xx_spi_release_dma(struct ep93xx_spi *espi)
free_page((unsigned long)espi->zeropage);
}
-static int __init ep93xx_spi_probe(struct platform_device *pdev)
+static int __devinit ep93xx_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct ep93xx_spi_info *info;
@@ -1150,7 +1151,7 @@ fail_release_master:
return error;
}
-static int __exit ep93xx_spi_remove(struct platform_device *pdev)
+static int __devexit ep93xx_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct ep93xx_spi *espi = spi_master_get_devdata(master);
@@ -1196,20 +1197,10 @@ static struct platform_driver ep93xx_spi_driver = {
.name = "ep93xx-spi",
.owner = THIS_MODULE,
},
- .remove = __exit_p(ep93xx_spi_remove),
+ .probe = ep93xx_spi_probe,
+ .remove = __devexit_p(ep93xx_spi_remove),
};
-
-static int __init ep93xx_spi_init(void)
-{
- return platform_driver_probe(&ep93xx_spi_driver, ep93xx_spi_probe);
-}
-module_init(ep93xx_spi_init);
-
-static void __exit ep93xx_spi_exit(void)
-{
- platform_driver_unregister(&ep93xx_spi_driver);
-}
-module_exit(ep93xx_spi_exit);
+module_platform_driver(ep93xx_spi_driver);
MODULE_DESCRIPTION("EP93xx SPI Controller driver");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 54e499d5f92..d770f03705c 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -744,18 +744,7 @@ static struct platform_driver fsl_espi_driver = {
.probe = of_fsl_espi_probe,
.remove = __devexit_p(of_fsl_espi_remove),
};
-
-static int __init fsl_espi_init(void)
-{
- return platform_driver_register(&fsl_espi_driver);
-}
-module_init(fsl_espi_init);
-
-static void __exit fsl_espi_exit(void)
-{
- platform_driver_unregister(&fsl_espi_driver);
-}
-module_exit(fsl_espi_exit);
+module_platform_driver(fsl_espi_driver);
MODULE_AUTHOR("Mingkai Hu");
MODULE_DESCRIPTION("Enhanced Freescale SPI Driver");
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index d2407558773..24cacff5778 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -825,6 +825,9 @@ static void fsl_spi_cpm_free(struct mpc8xxx_spi *mspi)
{
struct device *dev = mspi->dev;
+ if (!(mspi->flags & SPI_CPM_MODE))
+ return;
+
dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE);
dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE);
cpm_muram_free(cpm_muram_offset(mspi->tx_bd));
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index 0e88ab74549..e093d3ec41b 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
@@ -311,7 +312,7 @@ done:
return value;
}
-static int __init spi_gpio_probe(struct platform_device *pdev)
+static int __devinit spi_gpio_probe(struct platform_device *pdev)
{
int status;
struct spi_master *master;
@@ -379,7 +380,7 @@ gpio_free:
return status;
}
-static int __exit spi_gpio_remove(struct platform_device *pdev)
+static int __devexit spi_gpio_remove(struct platform_device *pdev)
{
struct spi_gpio *spi_gpio;
struct spi_gpio_platform_data *pdata;
@@ -408,21 +409,10 @@ MODULE_ALIAS("platform:" DRIVER_NAME);
static struct platform_driver spi_gpio_driver = {
.driver.name = DRIVER_NAME,
.driver.owner = THIS_MODULE,
- .remove = __exit_p(spi_gpio_remove),
+ .probe = spi_gpio_probe,
+ .remove = __devexit_p(spi_gpio_remove),
};
-
-static int __init spi_gpio_init(void)
-{
- return platform_driver_probe(&spi_gpio_driver, spi_gpio_probe);
-}
-module_init(spi_gpio_init);
-
-static void __exit spi_gpio_exit(void)
-{
- platform_driver_unregister(&spi_gpio_driver);
-}
-module_exit(spi_gpio_exit);
-
+module_platform_driver(spi_gpio_driver);
MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO ");
MODULE_AUTHOR("David Brownell");
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 8ac6542aedc..c6e697f5e00 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -786,9 +786,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
if (cs_gpio < 0)
cs_gpio = mxc_platform_info->chipselect[i];
+
+ spi_imx->chipselect[i] = cs_gpio;
if (cs_gpio < 0)
continue;
- spi_imx->chipselect[i] = cs_gpio;
+
ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
if (ret) {
while (i > 0) {
@@ -927,19 +929,7 @@ static struct platform_driver spi_imx_driver = {
.probe = spi_imx_probe,
.remove = __devexit_p(spi_imx_remove),
};
-
-static int __init spi_imx_init(void)
-{
- return platform_driver_register(&spi_imx_driver);
-}
-
-static void __exit spi_imx_exit(void)
-{
- platform_driver_unregister(&spi_imx_driver);
-}
-
-module_init(spi_imx_init);
-module_exit(spi_imx_exit);
+module_platform_driver(spi_imx_driver);
MODULE_DESCRIPTION("SPI Master Controller driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index 6a5b4238fb6..4c63f772780 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -559,18 +559,7 @@ static struct platform_driver mpc512x_psc_spi_of_driver = {
.of_match_table = mpc512x_psc_spi_of_match,
},
};
-
-static int __init mpc512x_psc_spi_init(void)
-{
- return platform_driver_register(&mpc512x_psc_spi_of_driver);
-}
-module_init(mpc512x_psc_spi_init);
-
-static void __exit mpc512x_psc_spi_exit(void)
-{
- platform_driver_unregister(&mpc512x_psc_spi_of_driver);
-}
-module_exit(mpc512x_psc_spi_exit);
+module_platform_driver(mpc512x_psc_spi_of_driver);
MODULE_AUTHOR("John Rigby");
MODULE_DESCRIPTION("MPC512x PSC SPI Driver");
diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c
index e30baf0852a..66047156d90 100644
--- a/drivers/spi/spi-mpc52xx-psc.c
+++ b/drivers/spi/spi-mpc52xx-psc.c
@@ -511,18 +511,7 @@ static struct platform_driver mpc52xx_psc_spi_of_driver = {
.of_match_table = mpc52xx_psc_spi_of_match,
},
};
-
-static int __init mpc52xx_psc_spi_init(void)
-{
- return platform_driver_register(&mpc52xx_psc_spi_of_driver);
-}
-module_init(mpc52xx_psc_spi_init);
-
-static void __exit mpc52xx_psc_spi_exit(void)
-{
- platform_driver_unregister(&mpc52xx_psc_spi_of_driver);
-}
-module_exit(mpc52xx_psc_spi_exit);
+module_platform_driver(mpc52xx_psc_spi_of_driver);
MODULE_AUTHOR("Dragos Carp");
MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");
diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c
index 015a974bed7..57633d96345 100644
--- a/drivers/spi/spi-mpc52xx.c
+++ b/drivers/spi/spi-mpc52xx.c
@@ -564,16 +564,4 @@ static struct platform_driver mpc52xx_spi_of_driver = {
.probe = mpc52xx_spi_probe,
.remove = __devexit_p(mpc52xx_spi_remove),
};
-
-static int __init mpc52xx_spi_init(void)
-{
- return platform_driver_register(&mpc52xx_spi_of_driver);
-}
-module_init(mpc52xx_spi_init);
-
-static void __exit mpc52xx_spi_exit(void)
-{
- platform_driver_unregister(&mpc52xx_spi_of_driver);
-}
-module_exit(mpc52xx_spi_exit);
-
+module_platform_driver(mpc52xx_spi_of_driver);
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c
index c0a6ce81f9c..e763254741c 100644
--- a/drivers/spi/spi-nuc900.c
+++ b/drivers/spi/spi-nuc900.c
@@ -484,19 +484,7 @@ static struct platform_driver nuc900_spi_driver = {
.owner = THIS_MODULE,
},
};
-
-static int __init nuc900_spi_init(void)
-{
- return platform_driver_register(&nuc900_spi_driver);
-}
-
-static void __exit nuc900_spi_exit(void)
-{
- platform_driver_unregister(&nuc900_spi_driver);
-}
-
-module_init(nuc900_spi_init);
-module_exit(nuc900_spi_exit);
+module_platform_driver(nuc900_spi_driver);
MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("nuc900 spi driver!");
diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c
index f1bde66cea1..698018fd992 100644
--- a/drivers/spi/spi-oc-tiny.c
+++ b/drivers/spi/spi-oc-tiny.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@@ -406,18 +407,7 @@ static struct platform_driver tiny_spi_driver = {
.of_match_table = tiny_spi_match,
},
};
-
-static int __init tiny_spi_init(void)
-{
- return platform_driver_register(&tiny_spi_driver);
-}
-module_init(tiny_spi_init);
-
-static void __exit tiny_spi_exit(void)
-{
- platform_driver_unregister(&tiny_spi_driver);
-}
-module_exit(tiny_spi_exit);
+module_platform_driver(tiny_spi_driver);
MODULE_DESCRIPTION("OpenCores tiny SPI driver");
MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c
index 00a8e9d7dbe..610f7391456 100644
--- a/drivers/spi/spi-omap-uwire.c
+++ b/drivers/spi/spi-omap-uwire.c
@@ -45,6 +45,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/irq.h>
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index fde3a2d4f12..322be7aea8b 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -1116,15 +1116,16 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
status = -ENODEV;
goto err1;
}
+
+ r->start += pdata->regs_offset;
+ r->end += pdata->regs_offset;
+ mcspi->phys = r->start;
if (!request_mem_region(r->start, resource_size(r),
dev_name(&pdev->dev))) {
status = -EBUSY;
goto err1;
}
- r->start += pdata->regs_offset;
- r->end += pdata->regs_offset;
- mcspi->phys = r->start;
mcspi->base = ioremap(r->start, resource_size(r));
if (!mcspi->base) {
dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 9421a390a5e..13448c832c4 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
+#include <linux/module.h>
#include <asm/unaligned.h>
#define DRIVER_NAME "orion_spi"
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 730b4a37b82..f103e470cb6 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -113,7 +113,6 @@
#define SSP_CR0_MASK_CSS_ST (0x1FUL << 16)
#define SSP_CR0_MASK_FRF_ST (0x3UL << 21)
-
/*
* SSP Control Register 0 - SSP_CR1
*/
@@ -283,7 +282,6 @@
#define SPI_POLLING_TIMEOUT 1000
-
/*
* The type of reading going on on this chip
*/
@@ -515,9 +513,6 @@ static void giveback(struct pl022 *pl022)
if (msg->complete)
msg->complete(msg->context);
/* This message is completed, so let's turn off the clocks & power */
- clk_disable(pl022->clk);
- amba_pclk_disable(pl022->adev);
- amba_vcore_disable(pl022->adev);
pm_runtime_put(&pl022->adev->dev);
}
@@ -752,7 +747,6 @@ static void readwriter(struct pl022 *pl022)
*/
}
-
/**
* next_transfer - Move to the Next transfer in the current spi message
* @pl022: SSP driver private data structure
@@ -1019,14 +1013,14 @@ static int configure_dma(struct pl022 *pl022)
dmaengine_slave_config(txchan, &tx_conf);
/* Create sglists for the transfers */
- pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1;
+ pages = DIV_ROUND_UP(pl022->cur_transfer->len, PAGE_SIZE);
dev_dbg(&pl022->adev->dev, "using %d pages for transfer\n", pages);
- ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_KERNEL);
+ ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_ATOMIC);
if (ret)
goto err_alloc_rx_sg;
- ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_KERNEL);
+ ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_ATOMIC);
if (ret)
goto err_alloc_tx_sg;
@@ -1534,8 +1528,7 @@ static void pump_messages(struct work_struct *work)
/* Initial message state */
pl022->cur_msg->state = STATE_START;
pl022->cur_transfer = list_entry(pl022->cur_msg->transfers.next,
- struct spi_transfer,
- transfer_list);
+ struct spi_transfer, transfer_list);
/* Setup the SPI using the per chip configuration */
pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi);
@@ -1545,9 +1538,6 @@ static void pump_messages(struct work_struct *work)
* (poll/interrupt/DMA)
*/
pm_runtime_get_sync(&pl022->adev->dev);
- amba_vcore_enable(pl022->adev);
- amba_pclk_enable(pl022->adev);
- clk_enable(pl022->clk);
restore_state(pl022);
flush(pl022);
@@ -1557,7 +1547,6 @@ static void pump_messages(struct work_struct *work)
do_interrupt_dma_transfer(pl022);
}
-
static int __init init_queue(struct pl022 *pl022)
{
INIT_LIST_HEAD(&pl022->queue);
@@ -1566,8 +1555,8 @@ static int __init init_queue(struct pl022 *pl022)
pl022->running = false;
pl022->busy = false;
- tasklet_init(&pl022->pump_transfers,
- pump_transfers, (unsigned long)pl022);
+ tasklet_init(&pl022->pump_transfers, pump_transfers,
+ (unsigned long)pl022);
INIT_WORK(&pl022->pump_messages, pump_messages);
pl022->workqueue = create_singlethread_workqueue(
@@ -1578,7 +1567,6 @@ static int __init init_queue(struct pl022 *pl022)
return 0;
}
-
static int start_queue(struct pl022 *pl022)
{
unsigned long flags;
@@ -1601,7 +1589,6 @@ static int start_queue(struct pl022 *pl022)
return 0;
}
-
static int stop_queue(struct pl022 *pl022)
{
unsigned long flags;
@@ -1797,71 +1784,70 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg)
return 0;
}
-static int calculate_effective_freq(struct pl022 *pl022,
- int freq,
- struct ssp_clock_params *clk_freq)
+static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr)
+{
+ return rate / (cpsdvsr * (1 + scr));
+}
+
+static int calculate_effective_freq(struct pl022 *pl022, int freq, struct
+ ssp_clock_params * clk_freq)
{
/* Lets calculate the frequency parameters */
- u16 cpsdvsr = 2;
- u16 scr = 0;
- bool freq_found = false;
- u32 rate;
- u32 max_tclk;
- u32 min_tclk;
+ u16 cpsdvsr = CPSDVR_MIN, scr = SCR_MIN;
+ u32 rate, max_tclk, min_tclk, best_freq = 0, best_cpsdvsr = 0,
+ best_scr = 0, tmp, found = 0;
rate = clk_get_rate(pl022->clk);
/* cpsdvscr = 2 & scr 0 */
- max_tclk = (rate / (CPSDVR_MIN * (1 + SCR_MIN)));
+ max_tclk = spi_rate(rate, CPSDVR_MIN, SCR_MIN);
/* cpsdvsr = 254 & scr = 255 */
- min_tclk = (rate / (CPSDVR_MAX * (1 + SCR_MAX)));
-
- if ((freq <= max_tclk) && (freq >= min_tclk)) {
- while (cpsdvsr <= CPSDVR_MAX && !freq_found) {
- while (scr <= SCR_MAX && !freq_found) {
- if ((rate /
- (cpsdvsr * (1 + scr))) > freq)
- scr += 1;
- else {
- /*
- * This bool is made true when
- * effective frequency >=
- * target frequency is found
- */
- freq_found = true;
- if ((rate /
- (cpsdvsr * (1 + scr))) != freq) {
- if (scr == SCR_MIN) {
- cpsdvsr -= 2;
- scr = SCR_MAX;
- } else
- scr -= 1;
- }
- }
- }
- if (!freq_found) {
- cpsdvsr += 2;
- scr = SCR_MIN;
- }
- }
- if (cpsdvsr != 0) {
- dev_dbg(&pl022->adev->dev,
- "SSP Effective Frequency is %u\n",
- (rate / (cpsdvsr * (1 + scr))));
- clk_freq->cpsdvsr = (u8) (cpsdvsr & 0xFF);
- clk_freq->scr = (u8) (scr & 0xFF);
- dev_dbg(&pl022->adev->dev,
- "SSP cpsdvsr = %d, scr = %d\n",
- clk_freq->cpsdvsr, clk_freq->scr);
- }
- } else {
+ min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX);
+
+ if (!((freq <= max_tclk) && (freq >= min_tclk))) {
dev_err(&pl022->adev->dev,
"controller data is incorrect: out of range frequency");
return -EINVAL;
}
+
+ /*
+ * best_freq will give closest possible available rate (<= requested
+ * freq) for all values of scr & cpsdvsr.
+ */
+ while ((cpsdvsr <= CPSDVR_MAX) && !found) {
+ while (scr <= SCR_MAX) {
+ tmp = spi_rate(rate, cpsdvsr, scr);
+
+ if (tmp > freq)
+ scr++;
+ /*
+ * If found exact value, update and break.
+ * If found more closer value, update and continue.
+ */
+ else if ((tmp == freq) || (tmp > best_freq)) {
+ best_freq = tmp;
+ best_cpsdvsr = cpsdvsr;
+ best_scr = scr;
+
+ if (tmp == freq)
+ break;
+ }
+ scr++;
+ }
+ cpsdvsr += 2;
+ scr = SCR_MIN;
+ }
+
+ clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF);
+ clk_freq->scr = (u8) (best_scr & 0xFF);
+ dev_dbg(&pl022->adev->dev,
+ "SSP Target Frequency is: %u, Effective Frequency is %u\n",
+ freq, best_freq);
+ dev_dbg(&pl022->adev->dev, "SSP cpsdvsr = %d, scr = %d\n",
+ clk_freq->cpsdvsr, clk_freq->scr);
+
return 0;
}
-
/*
* A piece of default chip info unless the platform
* supplies it.
@@ -1879,7 +1865,6 @@ static const struct pl022_config_chip pl022_default_chip_info = {
.cs_control = null_cs_control,
};
-
/**
* pl022_setup - setup function registered to SPI master framework
* @spi: spi device which is requesting setup
@@ -1956,7 +1941,6 @@ static int pl022_setup(struct spi_device *spi)
goto err_config_params;
}
-
status = verify_controller_parameters(pl022, chip_info);
if (status) {
dev_err(&spi->dev, "controller data is incorrect");
@@ -2096,7 +2080,8 @@ static int pl022_setup(struct spi_device *spi)
}
SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1);
SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2);
- SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3);
+ SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD,
+ 3);
/* Save controller_state */
spi_set_ctldata(spi, chip);
@@ -2122,7 +2107,6 @@ static void pl022_cleanup(struct spi_device *spi)
kfree(chip);
}
-
static int __devinit
pl022_probe(struct amba_device *adev, const struct amba_id *id)
{
@@ -2186,8 +2170,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
}
printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n",
adev->res.start, pl022->virtbase);
- pm_runtime_enable(dev);
- pm_runtime_resume(dev);
pl022->clk = clk_get(&adev->dev, NULL);
if (IS_ERR(pl022->clk)) {
@@ -2196,6 +2178,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
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;
+ }
+
/* Disable SSP */
writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
SSP_CR1(pl022->virtbase));
@@ -2235,22 +2223,22 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
goto err_spi_register;
}
dev_dbg(dev, "probe succeeded\n");
- /*
- * Disable the silicon block pclk and any voltage domain and just
- * power it up and clock it when it's needed
- */
- amba_pclk_disable(adev);
- amba_vcore_disable(adev);
+
+ /* let runtime pm put suspend */
+ pm_runtime_put(dev);
return 0;
err_spi_register:
err_start_queue:
err_init_queue:
destroy_queue(pl022);
- pl022_dma_remove(pl022);
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+
free_irq(adev->irq[0], pl022);
- pm_runtime_disable(&adev->dev);
err_no_irq:
+ clk_unprepare(pl022->clk);
+ err_clk_prep:
clk_put(pl022->clk);
err_no_clk:
iounmap(pl022->virtbase);
@@ -2271,13 +2259,22 @@ pl022_remove(struct amba_device *adev)
if (!pl022)
return 0;
+ /*
+ * undo pm_runtime_put() in probe. I assume that we're not
+ * accessing the primecell here.
+ */
+ pm_runtime_get_noresume(&adev->dev);
+
/* Remove the queue */
if (destroy_queue(pl022) != 0)
dev_err(&adev->dev, "queue remove failed\n");
load_ssp_default_config(pl022);
- pl022_dma_remove(pl022);
+ 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);
amba_release_regions(adev);
@@ -2288,46 +2285,70 @@ pl022_remove(struct amba_device *adev)
return 0;
}
-#ifdef CONFIG_PM
-static int pl022_suspend(struct amba_device *adev, pm_message_t state)
+#ifdef CONFIG_SUSPEND
+static int pl022_suspend(struct device *dev)
{
- struct pl022 *pl022 = amba_get_drvdata(adev);
+ struct pl022 *pl022 = dev_get_drvdata(dev);
int status = 0;
status = stop_queue(pl022);
if (status) {
- dev_warn(&adev->dev, "suspend cannot stop queue\n");
+ dev_warn(dev, "suspend cannot stop queue\n");
return status;
}
- amba_vcore_enable(adev);
- amba_pclk_enable(adev);
+ amba_vcore_enable(pl022->adev);
+ amba_pclk_enable(pl022->adev);
load_ssp_default_config(pl022);
- amba_pclk_disable(adev);
- amba_vcore_disable(adev);
- dev_dbg(&adev->dev, "suspended\n");
+ amba_pclk_disable(pl022->adev);
+ amba_vcore_disable(pl022->adev);
+ dev_dbg(dev, "suspended\n");
return 0;
}
-static int pl022_resume(struct amba_device *adev)
+static int pl022_resume(struct device *dev)
{
- struct pl022 *pl022 = amba_get_drvdata(adev);
+ struct pl022 *pl022 = dev_get_drvdata(dev);
int status = 0;
/* Start the queue running */
status = start_queue(pl022);
if (status)
- dev_err(&adev->dev, "problem starting queue (%d)\n", status);
+ dev_err(dev, "problem starting queue (%d)\n", status);
else
- dev_dbg(&adev->dev, "resumed\n");
+ dev_dbg(dev, "resumed\n");
return status;
}
-#else
-#define pl022_suspend NULL
-#define pl022_resume NULL
#endif /* CONFIG_PM */
+#ifdef CONFIG_PM_RUNTIME
+static int pl022_runtime_suspend(struct device *dev)
+{
+ struct pl022 *pl022 = dev_get_drvdata(dev);
+
+ clk_disable(pl022->clk);
+ amba_vcore_disable(pl022->adev);
+
+ return 0;
+}
+
+static int pl022_runtime_resume(struct device *dev)
+{
+ struct pl022 *pl022 = dev_get_drvdata(dev);
+
+ amba_vcore_enable(pl022->adev);
+ clk_enable(pl022->clk);
+
+ return 0;
+}
+#endif
+
+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)
+};
+
static struct vendor_data vendor_arm = {
.fifodepth = 8,
.max_bpw = 16,
@@ -2337,7 +2358,6 @@ static struct vendor_data vendor_arm = {
.loopback = true,
};
-
static struct vendor_data vendor_st = {
.fifodepth = 32,
.max_bpw = 32,
@@ -2392,9 +2412,9 @@ static struct amba_id pl022_ids[] = {
* and 32 locations deep TX/RX FIFO but no extended
* CR0/CR1 register
*/
- .id = 0x00080023,
- .mask = 0xffffffff,
- .data = &vendor_st_pl023,
+ .id = 0x00080023,
+ .mask = 0xffffffff,
+ .data = &vendor_st_pl023,
},
{
.id = 0x10080023,
@@ -2407,27 +2427,23 @@ static struct amba_id pl022_ids[] = {
static struct amba_driver pl022_driver = {
.drv = {
.name = "ssp-pl022",
+ .pm = &pl022_dev_pm_ops,
},
.id_table = pl022_ids,
.probe = pl022_probe,
.remove = __devexit_p(pl022_remove),
- .suspend = pl022_suspend,
- .resume = pl022_resume,
};
-
static int __init pl022_init(void)
{
return amba_driver_register(&pl022_driver);
}
-
subsys_initcall(pl022_init);
static void __exit pl022_exit(void)
{
amba_driver_unregister(&pl022_driver);
}
-
module_exit(pl022_exit);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c
index b267fd901e5..98ec53285fc 100644
--- a/drivers/spi/spi-ppc4xx.c
+++ b/drivers/spi/spi-ppc4xx.c
@@ -514,7 +514,7 @@ static int __init spi_ppc4xx_of_probe(struct platform_device *op)
/* Request IRQ */
hw->irqnum = irq_of_parse_and_map(np, 0);
ret = request_irq(hw->irqnum, spi_ppc4xx_int,
- IRQF_DISABLED, "spi_ppc4xx_of", (void *)hw);
+ 0, "spi_ppc4xx_of", (void *)hw);
if (ret) {
dev_err(dev, "unable to allocate interrupt\n");
goto free_gpios;
@@ -594,18 +594,7 @@ static struct platform_driver spi_ppc4xx_of_driver = {
.of_match_table = spi_ppc4xx_of_match,
},
};
-
-static int __init spi_ppc4xx_init(void)
-{
- return platform_driver_register(&spi_ppc4xx_of_driver);
-}
-module_init(spi_ppc4xx_init);
-
-static void __exit spi_ppc4xx_exit(void)
-{
- platform_driver_unregister(&spi_ppc4xx_of_driver);
-}
-module_exit(spi_ppc4xx_exit);
+module_platform_driver(spi_ppc4xx_of_driver);
MODULE_AUTHOR("Gary Jennejohn & Stefan Roese");
MODULE_DESCRIPTION("Simple PPC4xx SPI Driver");
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c
index 378e504f89e..8caa07d58e6 100644
--- a/drivers/spi/spi-pxa2xx-pci.c
+++ b/drivers/spi/spi-pxa2xx-pci.c
@@ -5,6 +5,7 @@
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
+#include <linux/module.h>
#include <linux/spi/pxa2xx_spi.h>
struct ce4100_info {
diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c
index 1996ac57ef9..fc064535f4f 100644
--- a/drivers/spi/spi-s3c24xx.c
+++ b/drivers/spi/spi-s3c24xx.c
@@ -24,6 +24,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
+#include <linux/module.h>
#include <plat/regs-spi.h>
#include <mach/spi.h>
@@ -505,7 +506,7 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
}
}
-static int __init s3c24xx_spi_probe(struct platform_device *pdev)
+static int __devinit s3c24xx_spi_probe(struct platform_device *pdev)
{
struct s3c2410_spi_info *pdata;
struct s3c24xx_spi *hw;
@@ -661,7 +662,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev)
return err;
}
-static int __exit s3c24xx_spi_remove(struct platform_device *dev)
+static int __devexit s3c24xx_spi_remove(struct platform_device *dev)
{
struct s3c24xx_spi *hw = platform_get_drvdata(dev);
@@ -719,26 +720,15 @@ static const struct dev_pm_ops s3c24xx_spi_pmops = {
MODULE_ALIAS("platform:s3c2410-spi");
static struct platform_driver s3c24xx_spi_driver = {
- .remove = __exit_p(s3c24xx_spi_remove),
+ .probe = s3c24xx_spi_probe,
+ .remove = __devexit_p(s3c24xx_spi_remove),
.driver = {
.name = "s3c2410-spi",
.owner = THIS_MODULE,
.pm = S3C24XX_SPI_PMOPS,
},
};
-
-static int __init s3c24xx_spi_init(void)
-{
- return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);
-}
-
-static void __exit s3c24xx_spi_exit(void)
-{
- platform_driver_unregister(&s3c24xx_spi_driver);
-}
-
-module_init(s3c24xx_spi_init);
-module_exit(s3c24xx_spi_exit);
+module_platform_driver(s3c24xx_spi_driver);
MODULE_DESCRIPTION("S3C24XX SPI Driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 595dacc7645..019a7163572 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -131,6 +131,12 @@
#define RXBUSY (1<<2)
#define TXBUSY (1<<3)
+struct s3c64xx_spi_dma_data {
+ unsigned ch;
+ enum dma_data_direction direction;
+ enum dma_ch dmach;
+};
+
/**
* struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
* @clk: Pointer to the spi clock.
@@ -164,13 +170,14 @@ struct s3c64xx_spi_driver_data {
struct work_struct work;
struct list_head queue;
spinlock_t lock;
- enum dma_ch rx_dmach;
- enum dma_ch tx_dmach;
unsigned long sfr_start;
struct completion xfer_completion;
unsigned state;
unsigned cur_mode, cur_bpw;
unsigned cur_speed;
+ struct s3c64xx_spi_dma_data rx_dma;
+ struct s3c64xx_spi_dma_data tx_dma;
+ struct samsung_dma_ops *ops;
};
static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -226,6 +233,78 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
writel(val, regs + S3C64XX_SPI_CH_CFG);
}
+static void s3c64xx_spi_dmacb(void *data)
+{
+ struct s3c64xx_spi_driver_data *sdd;
+ struct s3c64xx_spi_dma_data *dma = data;
+ unsigned long flags;
+
+ if (dma->direction == DMA_FROM_DEVICE)
+ sdd = container_of(data,
+ struct s3c64xx_spi_driver_data, rx_dma);
+ else
+ sdd = container_of(data,
+ struct s3c64xx_spi_driver_data, tx_dma);
+
+ spin_lock_irqsave(&sdd->lock, flags);
+
+ if (dma->direction == DMA_FROM_DEVICE) {
+ sdd->state &= ~RXBUSY;
+ if (!(sdd->state & TXBUSY))
+ complete(&sdd->xfer_completion);
+ } else {
+ sdd->state &= ~TXBUSY;
+ if (!(sdd->state & RXBUSY))
+ complete(&sdd->xfer_completion);
+ }
+
+ spin_unlock_irqrestore(&sdd->lock, flags);
+}
+
+static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
+ unsigned len, dma_addr_t buf)
+{
+ struct s3c64xx_spi_driver_data *sdd;
+ struct samsung_dma_prep_info info;
+
+ if (dma->direction == DMA_FROM_DEVICE)
+ sdd = container_of((void *)dma,
+ struct s3c64xx_spi_driver_data, rx_dma);
+ else
+ sdd = container_of((void *)dma,
+ struct s3c64xx_spi_driver_data, tx_dma);
+
+ info.cap = DMA_SLAVE;
+ info.len = len;
+ info.fp = s3c64xx_spi_dmacb;
+ info.fp_param = dma;
+ info.direction = dma->direction;
+ info.buf = buf;
+
+ sdd->ops->prepare(dma->ch, &info);
+ sdd->ops->trigger(dma->ch);
+}
+
+static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
+{
+ struct samsung_dma_info info;
+
+ sdd->ops = samsung_dma_get_ops();
+
+ info.cap = DMA_SLAVE;
+ info.client = &s3c64xx_spi_dma_client;
+ info.width = sdd->cur_bpw / 8;
+
+ info.direction = sdd->rx_dma.direction;
+ info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
+ sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info);
+ info.direction = sdd->tx_dma.direction;
+ info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
+ sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info);
+
+ return 1;
+}
+
static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
struct spi_device *spi,
struct spi_transfer *xfer, int dma_mode)
@@ -258,10 +337,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
chcfg |= S3C64XX_SPI_CH_TXCH_ON;
if (dma_mode) {
modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
- s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
- s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
- xfer->tx_dma, xfer->len);
- s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
+ prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma);
} else {
switch (sdd->cur_bpw) {
case 32:
@@ -293,10 +369,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
| S3C64XX_SPI_PACKET_CNT_EN,
regs + S3C64XX_SPI_PACKET_CNT);
- s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
- s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
- xfer->rx_dma, xfer->len);
- s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
+ prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma);
}
}
@@ -482,46 +555,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
}
}
-static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
- int size, enum s3c2410_dma_buffresult res)
-{
- struct s3c64xx_spi_driver_data *sdd = buf_id;
- unsigned long flags;
-
- spin_lock_irqsave(&sdd->lock, flags);
-
- if (res == S3C2410_RES_OK)
- sdd->state &= ~RXBUSY;
- else
- dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
-
- /* If the other done */
- if (!(sdd->state & TXBUSY))
- complete(&sdd->xfer_completion);
-
- spin_unlock_irqrestore(&sdd->lock, flags);
-}
-
-static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
- int size, enum s3c2410_dma_buffresult res)
-{
- struct s3c64xx_spi_driver_data *sdd = buf_id;
- unsigned long flags;
-
- spin_lock_irqsave(&sdd->lock, flags);
-
- if (res == S3C2410_RES_OK)
- sdd->state &= ~TXBUSY;
- else
- dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
-
- /* If the other done */
- if (!(sdd->state & RXBUSY))
- complete(&sdd->xfer_completion);
-
- spin_unlock_irqrestore(&sdd->lock, flags);
-}
-
#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
@@ -696,12 +729,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd,
if (use_dma) {
if (xfer->tx_buf != NULL
&& (sdd->state & TXBUSY))
- s3c2410_dma_ctrl(sdd->tx_dmach,
- S3C2410_DMAOP_FLUSH);
+ sdd->ops->stop(sdd->tx_dma.ch);
if (xfer->rx_buf != NULL
&& (sdd->state & RXBUSY))
- s3c2410_dma_ctrl(sdd->rx_dmach,
- S3C2410_DMAOP_FLUSH);
+ sdd->ops->stop(sdd->rx_dma.ch);
}
goto out;
@@ -739,30 +770,6 @@ out:
msg->complete(msg->context);
}
-static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
-{
- if (s3c2410_dma_request(sdd->rx_dmach,
- &s3c64xx_spi_dma_client, NULL) < 0) {
- dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
- return 0;
- }
- s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb);
- s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW,
- sdd->sfr_start + S3C64XX_SPI_RX_DATA);
-
- if (s3c2410_dma_request(sdd->tx_dmach,
- &s3c64xx_spi_dma_client, NULL) < 0) {
- dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
- s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
- return 0;
- }
- s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
- s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
- sdd->sfr_start + S3C64XX_SPI_TX_DATA);
-
- return 1;
-}
-
static void s3c64xx_spi_work(struct work_struct *work)
{
struct s3c64xx_spi_driver_data *sdd = container_of(work,
@@ -799,8 +806,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
spin_unlock_irqrestore(&sdd->lock, flags);
/* Free DMA channels */
- s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
- s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
+ sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
+ sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
}
static int s3c64xx_spi_transfer(struct spi_device *spi,
@@ -1017,8 +1024,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
sdd->cntrlr_info = sci;
sdd->pdev = pdev;
sdd->sfr_start = mem_res->start;
- sdd->tx_dmach = dmatx_res->start;
- sdd->rx_dmach = dmarx_res->start;
+ sdd->tx_dma.dmach = dmatx_res->start;
+ sdd->tx_dma.direction = DMA_TO_DEVICE;
+ sdd->rx_dma.dmach = dmarx_res->start;
+ sdd->rx_dma.direction = DMA_FROM_DEVICE;
sdd->cur_bpw = 8;
@@ -1106,7 +1115,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
pdev->id, master->num_chipselect);
dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
mem_res->end, mem_res->start,
- sdd->rx_dmach, sdd->tx_dmach);
+ sdd->rx_dma.dmach, sdd->tx_dma.dmach);
return 0;
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index e00d94b2225..1f466bc66d9 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -635,7 +636,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
goto err2;
}
- ret = request_irq(i, sh_msiof_spi_irq, IRQF_DISABLED,
+ ret = request_irq(i, sh_msiof_spi_irq, 0,
dev_name(&pdev->dev), p);
if (ret) {
dev_err(&pdev->dev, "unable to request irq\n");
@@ -730,18 +731,7 @@ static struct platform_driver sh_msiof_spi_drv = {
.pm = &sh_msiof_spi_dev_pm_ops,
},
};
-
-static int __init sh_msiof_spi_init(void)
-{
- return platform_driver_register(&sh_msiof_spi_drv);
-}
-module_init(sh_msiof_spi_init);
-
-static void __exit sh_msiof_spi_exit(void)
-{
- platform_driver_unregister(&sh_msiof_spi_drv);
-}
-module_exit(sh_msiof_spi_exit);
+module_platform_driver(sh_msiof_spi_drv);
MODULE_DESCRIPTION("SuperH MSIOF SPI Master Interface Driver");
MODULE_AUTHOR("Magnus Damm");
diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c
index e7779c09f6e..097e506042b 100644
--- a/drivers/spi/spi-sh-sci.c
+++ b/drivers/spi/spi-sh-sci.c
@@ -22,6 +22,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
+#include <linux/module.h>
#include <asm/spi.h>
#include <asm/io.h>
@@ -186,18 +187,7 @@ static struct platform_driver sh_sci_spi_drv = {
.owner = THIS_MODULE,
},
};
-
-static int __init sh_sci_spi_init(void)
-{
- return platform_driver_register(&sh_sci_spi_drv);
-}
-module_init(sh_sci_spi_init);
-
-static void __exit sh_sci_spi_exit(void)
-{
- platform_driver_unregister(&sh_sci_spi_drv);
-}
-module_exit(sh_sci_spi_exit);
+module_platform_driver(sh_sci_spi_drv);
MODULE_DESCRIPTION("SH SCI SPI Driver");
MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c
index 9eedd71ad89..70c8af9f7cc 100644
--- a/drivers/spi/spi-sh.c
+++ b/drivers/spi/spi-sh.c
@@ -484,7 +484,7 @@ static int __devinit spi_sh_probe(struct platform_device *pdev)
goto error2;
}
- ret = request_irq(irq, spi_sh_irq, IRQF_DISABLED, "spi_sh", ss);
+ ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss);
if (ret < 0) {
dev_err(&pdev->dev, "request_irq error\n");
goto error3;
@@ -524,18 +524,7 @@ static struct platform_driver spi_sh_driver = {
.owner = THIS_MODULE,
},
};
-
-static int __init spi_sh_init(void)
-{
- return platform_driver_register(&spi_sh_driver);
-}
-module_init(spi_sh_init);
-
-static void __exit spi_sh_exit(void)
-{
- platform_driver_unregister(&spi_sh_driver);
-}
-module_exit(spi_sh_exit);
+module_platform_driver(spi_sh_driver);
MODULE_DESCRIPTION("SH SPI bus driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-stmp.c b/drivers/spi/spi-stmp.c
index fadff76eb7e..58e38528532 100644
--- a/drivers/spi/spi-stmp.c
+++ b/drivers/spi/spi-stmp.c
@@ -659,19 +659,8 @@ static struct platform_driver stmp_spi_driver = {
.suspend = stmp_spi_suspend,
.resume = stmp_spi_resume,
};
+module_platform_driver(stmp_spi_driver);
-static int __init stmp_spi_init(void)
-{
- return platform_driver_register(&stmp_spi_driver);
-}
-
-static void __exit stmp_spi_exit(void)
-{
- platform_driver_unregister(&stmp_spi_driver);
-}
-
-module_init(stmp_spi_init);
-module_exit(stmp_spi_exit);
module_param(pio, int, S_IRUGO);
module_param(clock, int, S_IRUGO);
MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com>");
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c
index a5a6302dc8e..ae6d78a3e91 100644
--- a/drivers/spi/spi-tegra.c
+++ b/drivers/spi/spi-tegra.c
@@ -18,6 +18,7 @@
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -464,7 +465,7 @@ static int spi_tegra_transfer(struct spi_device *spi, struct spi_message *m)
return 0;
}
-static int __init spi_tegra_probe(struct platform_device *pdev)
+static int __devinit spi_tegra_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct spi_tegra_data *tspi;
@@ -612,19 +613,9 @@ static struct platform_driver spi_tegra_driver = {
.owner = THIS_MODULE,
.of_match_table = spi_tegra_of_match_table,
},
+ .probe = spi_tegra_probe,
.remove = __devexit_p(spi_tegra_remove),
};
-
-static int __init spi_tegra_init(void)
-{
- return platform_driver_probe(&spi_tegra_driver, spi_tegra_probe);
-}
-module_init(spi_tegra_init);
-
-static void __exit spi_tegra_exit(void)
-{
- platform_driver_unregister(&spi_tegra_driver);
-}
-module_exit(spi_tegra_exit);
+module_platform_driver(spi_tegra_driver);
MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-ti-ssp.c b/drivers/spi/spi-ti-ssp.c
index ee22795c797..3f6f6e81c65 100644
--- a/drivers/spi/spi-ti-ssp.c
+++ b/drivers/spi/spi-ti-ssp.c
@@ -22,6 +22,7 @@
#include <linux/err.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/mfd/ti_ssp.h>
@@ -383,18 +384,7 @@ static struct platform_driver ti_ssp_spi_driver = {
.owner = THIS_MODULE,
},
};
-
-static int __init ti_ssp_spi_init(void)
-{
- return platform_driver_register(&ti_ssp_spi_driver);
-}
-module_init(ti_ssp_spi_init);
-
-static void __exit ti_ssp_spi_exit(void)
-{
- platform_driver_unregister(&ti_ssp_spi_driver);
-}
-module_exit(ti_ssp_spi_exit);
+module_platform_driver(ti_ssp_spi_driver);
MODULE_DESCRIPTION("SSP SPI Master");
MODULE_AUTHOR("Cyril Chemparathy");
diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c
index 940e73d1cf0..0ce5c12aab5 100644
--- a/drivers/spi/spi-tle62x0.c
+++ b/drivers/spi/spi-tle62x0.c
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 1d23f383186..6a80749391d 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -50,6 +50,8 @@
#define PCH_RX_THOLD 7
#define PCH_RX_THOLD_MAX 15
+#define PCH_TX_THOLD 2
+
#define PCH_MAX_BAUDRATE 5000000
#define PCH_MAX_FIFO_DEPTH 16
@@ -58,6 +60,7 @@
#define PCH_SLEEP_TIME 10
#define SSN_LOW 0x02U
+#define SSN_HIGH 0x03U
#define SSN_NO_CONTROL 0x00U
#define PCH_MAX_CS 0xFF
#define PCI_DEVICE_ID_GE_SPI 0x8816
@@ -316,16 +319,19 @@ static void pch_spi_handler_sub(struct pch_spi_data *data, u32 reg_spsr_val,
/* if transfer complete interrupt */
if (reg_spsr_val & SPSR_FI_BIT) {
- if (tx_index < bpw_len)
+ if ((tx_index == bpw_len) && (rx_index == tx_index)) {
+ /* disable interrupts */
+ pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL);
+
+ /* transfer is completed;
+ inform pch_spi_process_messages */
+ data->transfer_complete = true;
+ data->transfer_active = false;
+ wake_up(&data->wait);
+ } else {
dev_err(&data->master->dev,
"%s : Transfer is not completed", __func__);
- /* disable interrupts */
- pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL);
-
- /* transfer is completed;inform pch_spi_process_messages */
- data->transfer_complete = true;
- data->transfer_active = false;
- wake_up(&data->wait);
+ }
}
}
@@ -348,16 +354,26 @@ static irqreturn_t pch_spi_handler(int irq, void *dev_id)
"%s returning due to suspend\n", __func__);
return IRQ_NONE;
}
- if (data->use_dma)
- return IRQ_NONE;
io_remap_addr = data->io_remap_addr;
spsr = io_remap_addr + PCH_SPSR;
reg_spsr_val = ioread32(spsr);
- if (reg_spsr_val & SPSR_ORF_BIT)
- dev_err(&board_dat->pdev->dev, "%s Over run error", __func__);
+ if (reg_spsr_val & SPSR_ORF_BIT) {
+ dev_err(&board_dat->pdev->dev, "%s Over run error\n", __func__);
+ if (data->current_msg->complete != 0) {
+ data->transfer_complete = true;
+ data->current_msg->status = -EIO;
+ data->current_msg->complete(data->current_msg->context);
+ data->bcurrent_msg_processing = false;
+ data->current_msg = NULL;
+ data->cur_trans = NULL;
+ }
+ }
+
+ if (data->use_dma)
+ return IRQ_NONE;
/* Check if the interrupt is for SPI device */
if (reg_spsr_val & (SPSR_FI_BIT | SPSR_RFI_BIT)) {
@@ -756,10 +772,6 @@ static void pch_spi_set_ir(struct pch_spi_data *data)
wait_event_interruptible(data->wait, data->transfer_complete);
- pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL);
- dev_dbg(&data->master->dev,
- "%s:no more control over SSN-writing 0 to SSNXCR.", __func__);
-
/* clear all interrupts */
pch_spi_writereg(data->master, PCH_SPSR,
pch_spi_readreg(data->master, PCH_SPSR));
@@ -815,10 +827,11 @@ static void pch_spi_copy_rx_data_for_dma(struct pch_spi_data *data, int bpw)
}
}
-static void pch_spi_start_transfer(struct pch_spi_data *data)
+static int pch_spi_start_transfer(struct pch_spi_data *data)
{
struct pch_spi_dma_ctrl *dma;
unsigned long flags;
+ int rtn;
dma = &data->dma;
@@ -833,19 +846,23 @@ static void pch_spi_start_transfer(struct pch_spi_data *data)
initiating the transfer. */
dev_dbg(&data->master->dev,
"%s:waiting for transfer to get over\n", __func__);
- wait_event_interruptible(data->wait, data->transfer_complete);
+ rtn = wait_event_interruptible_timeout(data->wait,
+ data->transfer_complete,
+ msecs_to_jiffies(2 * HZ));
dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent,
DMA_FROM_DEVICE);
+
+ dma_sync_sg_for_cpu(&data->master->dev, dma->sg_tx_p, dma->nent,
+ DMA_FROM_DEVICE);
+ memset(data->dma.tx_buf_virt, 0, PAGE_SIZE);
+
async_tx_ack(dma->desc_rx);
async_tx_ack(dma->desc_tx);
kfree(dma->sg_tx_p);
kfree(dma->sg_rx_p);
spin_lock_irqsave(&data->lock, flags);
- pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL);
- dev_dbg(&data->master->dev,
- "%s:no more control over SSN-writing 0 to SSNXCR.", __func__);
/* clear fifo threshold, disable interrupts, disable SPI transfer */
pch_spi_setclr_reg(data->master, PCH_SPCR, 0,
@@ -858,6 +875,8 @@ static void pch_spi_start_transfer(struct pch_spi_data *data)
pch_spi_clear_fifo(data->master);
spin_unlock_irqrestore(&data->lock, flags);
+
+ return rtn;
}
static void pch_dma_rx_complete(void *arg)
@@ -1023,8 +1042,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
/* set receive fifo threshold and transmit fifo threshold */
pch_spi_setclr_reg(data->master, PCH_SPCR,
((size - 1) << SPCR_RFIC_FIELD) |
- ((PCH_MAX_FIFO_DEPTH - PCH_DMA_TRANS_SIZE) <<
- SPCR_TFIC_FIELD),
+ (PCH_TX_THOLD << SPCR_TFIC_FIELD),
MASK_RFIC_SPCR_BITS | MASK_TFIC_SPCR_BITS);
spin_unlock_irqrestore(&data->lock, flags);
@@ -1035,13 +1053,20 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
/* offset, length setting */
sg = dma->sg_rx_p;
for (i = 0; i < num; i++, sg++) {
- if (i == 0) {
- sg->offset = 0;
+ if (i == (num - 2)) {
+ sg->offset = size * i;
+ sg->offset = sg->offset * (*bpw / 8);
sg_set_page(sg, virt_to_page(dma->rx_buf_virt), rem,
sg->offset);
sg_dma_len(sg) = rem;
+ } else if (i == (num - 1)) {
+ sg->offset = size * (i - 1) + rem;
+ sg->offset = sg->offset * (*bpw / 8);
+ sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size,
+ sg->offset);
+ sg_dma_len(sg) = size;
} else {
- sg->offset = rem + size * (i - 1);
+ sg->offset = size * i;
sg->offset = sg->offset * (*bpw / 8);
sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size,
sg->offset);
@@ -1065,6 +1090,16 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
dma->desc_rx = desc_rx;
/* TX */
+ if (data->bpw_len > PCH_DMA_TRANS_SIZE) {
+ num = data->bpw_len / PCH_DMA_TRANS_SIZE;
+ size = PCH_DMA_TRANS_SIZE;
+ rem = 16;
+ } else {
+ num = 1;
+ size = data->bpw_len;
+ rem = data->bpw_len;
+ }
+
dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC);
sg_init_table(dma->sg_tx_p, num); /* Initialize SG table */
/* offset, length setting */
@@ -1162,6 +1197,7 @@ static void pch_spi_process_messages(struct work_struct *pwork)
if (data->use_dma)
pch_spi_request_dma(data,
data->current_msg->spi->bits_per_word);
+ pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL);
do {
/* If we are already processing a message get the next
transfer structure from the message otherwise retrieve
@@ -1184,7 +1220,8 @@ static void pch_spi_process_messages(struct work_struct *pwork)
if (data->use_dma) {
pch_spi_handle_dma(data, &bpw);
- pch_spi_start_transfer(data);
+ if (!pch_spi_start_transfer(data))
+ goto out;
pch_spi_copy_rx_data_for_dma(data, bpw);
} else {
pch_spi_set_tx(data, &bpw);
@@ -1222,6 +1259,8 @@ static void pch_spi_process_messages(struct work_struct *pwork)
} while (data->cur_trans != NULL);
+out:
+ pch_spi_writereg(data->master, PCH_SSNXCR, SSN_HIGH);
if (data->use_dma)
pch_spi_release_dma(data);
}
diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c
index f0a2ab0428a..d5a3cbb646c 100644
--- a/drivers/spi/spi-txx9.c
+++ b/drivers/spi/spi-txx9.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/module.h>
#include <asm/gpio.h>
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 4d2c75df886..4c5a663b9fa 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -538,18 +538,7 @@ static struct platform_driver xilinx_spi_driver = {
.of_match_table = xilinx_spi_of_match,
},
};
-
-static int __init xilinx_spi_pltfm_init(void)
-{
- return platform_driver_register(&xilinx_spi_driver);
-}
-module_init(xilinx_spi_pltfm_init);
-
-static void __exit xilinx_spi_pltfm_exit(void)
-{
- platform_driver_unregister(&xilinx_spi_driver);
-}
-module_exit(xilinx_spi_pltfm_exit);
+module_platform_driver(xilinx_spi_driver);
MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
MODULE_DESCRIPTION("Xilinx SPI driver");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 4d1b9f517ce..77eae99af11 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -29,6 +29,7 @@
#include <linux/spi/spi.h>
#include <linux/of_spi.h>
#include <linux/pm_runtime.h>
+#include <linux/export.h>
static void spidev_release(struct device *dev)
{