Merge tag 'spi-for-linus' of git://git.secretlab.ca/git/linux

Pull SPI changes from Grant Likely:
 "Changes to both core spi code and spi device drivers.  The driver
  changes are the usual set of bug fixes and platform enablement.

  Core code changes include:

   - More intelligent assignment of SPI bus numbers when using DT

   - Common mechanism for using gpios as CS lines

   - Pull checks for bits_per_word and transfer speed out of drivers and
     into core code

   - Ensure temporary DMA buffers are DMA safe"

* tag 'spi-for-linus' of git://git.secretlab.ca/git/linux: (50 commits)
  spi: Document cs_gpios and cs_gpio in kernel-doc
  spi/of: Fix initialization of cs_gpios array
  spi/pxa2xx: add support for Lynxpoint SPI controllers
  spi/pxa2xx: add support for Intel Low Power Subsystem SPI
  spi/pxa2xx: add support for SPI_LOOP
  spi/pxa2xx: add support for runtime PM
  spi/pxa2xx: add support for DMA engine
  spi/pxa2xx: break out the private DMA API usage into a separate file
  spi/ath79: add shutdown handler
  spi/mips-lantiq: set SPI_MASTER_HALF_DUPLEX flag
  spi/mips-lantiq: make use of spi_finalize_current_message
  spi/bcm63xx: work around inability to keep CS up
  spi/davinci: use request_threaded_irq() to fix deadlock
  spi/orion: Use module_platform_driver()
  spi/bcm63xx: reject transfers unable to transfer
  spi: Ensure memory used for spi_write_then_read() is DMA safe
  spi/spi-mpc512x-psc: init mode bits supported by the driver
  spi/mpc512x-psc: don't use obsolet cell-index property
  spi: Remove erroneous __init, __exit and __exit_p() references in drivers
  spi/s3c64xx: fix checkpatch warnings and error
  ...
This commit is contained in:
Linus Torvalds
2013-02-20 11:03:22 -08:00
43 changed files with 2077 additions and 1236 deletions
@@ -0,0 +1,12 @@
Renesas MSIOF spi controller
Required properties:
- compatible : "renesas,sh-msiof" for SuperH or
"renesas,sh-mobile-msiof" for SH Mobile series
- reg : Offset and length of the register set for the device
- interrupts : interrupt line used by MSIOF
Optional properties:
- num-cs : total number of chip-selects
- renesas,tx-fifo-size : Overrides the default tx fifo size given in words
- renesas,rx-fifo-size : Overrides the default rx fifo size given in words
+1
View File
@@ -7168,6 +7168,7 @@ F: drivers/clk/spear/
SPI SUBSYSTEM
M: Grant Likely <grant.likely@secretlab.ca>
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
L: spi-devel-general@lists.sourceforge.net
Q: http://patchwork.kernel.org/project/spi-devel-general/list/
T: git git://git.secretlab.ca/git/linux-2.6.git
+13 -2
View File
@@ -297,9 +297,20 @@ config SPI_PPC4xx
help
This selects a driver for the PPC4xx SPI Controller.
config SPI_PXA2XX_PXADMA
bool "PXA2xx SSP legacy PXA DMA API support"
depends on SPI_PXA2XX && ARCH_PXA
help
Enable PXA private legacy DMA API support. Note that this is
deprecated in favor of generic DMA engine API.
config SPI_PXA2XX_DMA
def_bool y
depends on SPI_PXA2XX && !SPI_PXA2XX_PXADMA
config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL
depends on ARCH_PXA || PCI || ACPI
select PXA_SSP if ARCH_PXA
help
This enables using a PXA2xx or Sodaville SSP port as a SPI master
@@ -307,7 +318,7 @@ config SPI_PXA2XX
additional documentation can be found a Documentation/spi/pxa2xx.
config SPI_PXA2XX_PCI
def_bool SPI_PXA2XX && X86_32 && PCI
def_tristate SPI_PXA2XX && PCI
config SPI_RSPI
tristate "Renesas RSPI controller"
+4 -1
View File
@@ -47,7 +47,10 @@ obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o
obj-$(CONFIG_SPI_ORION) += spi-orion.o
obj-$(CONFIG_SPI_PL022) += spi-pl022.o
obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx.o
spi-pxa2xx-platform-objs := spi-pxa2xx.o
spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_PXADMA) += spi-pxa2xx-pxadma.o
spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
+1 -1
View File
@@ -134,7 +134,7 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
hw->tx = t->tx_buf;
hw->rx = t->rx_buf;
hw->count = 0;
hw->bytes_per_word = (t->bits_per_word ? : spi->bits_per_word) / 8;
hw->bytes_per_word = t->bits_per_word / 8;
hw->len = t->len / hw->bytes_per_word;
if (hw->irq >= 0) {
+91 -40
View File
@@ -24,17 +24,24 @@
#include <linux/spi/spi_bitbang.h>
#include <linux/bitops.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include <asm/mach-ath79/ath79_spi_platform.h>
#define DRV_NAME "ath79-spi"
#define ATH79_SPI_RRW_DELAY_FACTOR 12000
#define MHZ (1000 * 1000)
struct ath79_spi {
struct spi_bitbang bitbang;
u32 ioc_base;
u32 reg_ctrl;
void __iomem *base;
struct clk *clk;
unsigned rrw_delay;
};
static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
@@ -52,6 +59,12 @@ static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi)
return spi_master_get_devdata(spi->master);
}
static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned nsecs)
{
if (nsecs > sp->rrw_delay)
ndelay(nsecs - sp->rrw_delay);
}
static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
@@ -83,15 +96,8 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
}
static int ath79_spi_setup_cs(struct spi_device *spi)
static void ath79_spi_enable(struct ath79_spi *sp)
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
struct ath79_spi_controller_data *cdata;
cdata = spi->controller_data;
if (spi->chip_select && !cdata)
return -EINVAL;
/* enable GPIO mode */
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
@@ -101,46 +107,50 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
/* TODO: setup speed? */
ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
if (spi->chip_select) {
int status = 0;
status = gpio_request(cdata->gpio, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cdata->gpio,
spi->mode & SPI_CS_HIGH);
if (status) {
gpio_free(cdata->gpio);
return status;
}
} else {
if (spi->mode & SPI_CS_HIGH)
sp->ioc_base |= AR71XX_SPI_IOC_CS0;
else
sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
}
return 0;
}
static void ath79_spi_cleanup_cs(struct spi_device *spi)
static void ath79_spi_disable(struct ath79_spi *sp)
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
if (spi->chip_select) {
struct ath79_spi_controller_data *cdata = spi->controller_data;
gpio_free(cdata->gpio);
}
/* restore CTRL register */
ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
/* disable GPIO mode */
ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
}
static int ath79_spi_setup_cs(struct spi_device *spi)
{
struct ath79_spi_controller_data *cdata;
int status;
cdata = spi->controller_data;
if (spi->chip_select && !cdata)
return -EINVAL;
status = 0;
if (spi->chip_select) {
unsigned long flags;
flags = GPIOF_DIR_OUT;
if (spi->mode & SPI_CS_HIGH)
flags |= GPIOF_INIT_HIGH;
else
flags |= GPIOF_INIT_LOW;
status = gpio_request_one(cdata->gpio, flags,
dev_name(&spi->dev));
}
return status;
}
static void ath79_spi_cleanup_cs(struct spi_device *spi)
{
if (spi->chip_select) {
struct ath79_spi_controller_data *cdata = spi->controller_data;
gpio_free(cdata->gpio);
}
}
static int ath79_spi_setup(struct spi_device *spi)
{
int status = 0;
@@ -184,7 +194,11 @@ static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
/* setup MSB (to slave) on trailing edge */
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
ath79_spi_delay(sp, nsecs);
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
ath79_spi_delay(sp, nsecs);
if (bits == 1)
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
word <<= 1;
}
@@ -198,6 +212,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
struct ath79_spi *sp;
struct ath79_spi_platform_data *pdata;
struct resource *r;
unsigned long rate;
int ret;
master = spi_alloc_master(&pdev->dev, sizeof(*sp));
@@ -236,12 +251,39 @@ static int ath79_spi_probe(struct platform_device *pdev)
goto err_put_master;
}
sp->clk = clk_get(&pdev->dev, "ahb");
if (IS_ERR(sp->clk)) {
ret = PTR_ERR(sp->clk);
goto err_unmap;
}
ret = clk_enable(sp->clk);
if (ret)
goto err_clk_put;
rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
if (!rate) {
ret = -EINVAL;
goto err_clk_disable;
}
sp->rrw_delay = ATH79_SPI_RRW_DELAY_FACTOR / rate;
dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
sp->rrw_delay);
ath79_spi_enable(sp);
ret = spi_bitbang_start(&sp->bitbang);
if (ret)
goto err_unmap;
goto err_disable;
return 0;
err_disable:
ath79_spi_disable(sp);
err_clk_disable:
clk_disable(sp->clk);
err_clk_put:
clk_put(sp->clk);
err_unmap:
iounmap(sp->base);
err_put_master:
@@ -256,6 +298,9 @@ static int ath79_spi_remove(struct platform_device *pdev)
struct ath79_spi *sp = platform_get_drvdata(pdev);
spi_bitbang_stop(&sp->bitbang);
ath79_spi_disable(sp);
clk_disable(sp->clk);
clk_put(sp->clk);
iounmap(sp->base);
platform_set_drvdata(pdev, NULL);
spi_master_put(sp->bitbang.master);
@@ -263,9 +308,15 @@ static int ath79_spi_remove(struct platform_device *pdev)
return 0;
}
static void ath79_spi_shutdown(struct platform_device *pdev)
{
ath79_spi_remove(pdev);
}
static struct platform_driver ath79_spi_driver = {
.probe = ath79_spi_probe,
.remove = ath79_spi_remove,
.shutdown = ath79_spi_shutdown,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+1 -1
View File
@@ -1088,7 +1088,7 @@ static struct platform_driver atmel_spi_driver = {
.suspend = atmel_spi_suspend,
.resume = atmel_spi_resume,
.probe = atmel_spi_probe,
.remove = __exit_p(atmel_spi_remove),
.remove = atmel_spi_remove,
};
module_platform_driver(atmel_spi_driver);
+4 -4
View File
@@ -717,7 +717,7 @@ static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw)
}
}
static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
{
u32 stat, cfg;
@@ -766,7 +766,7 @@ static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
}
static int __init au1550_spi_probe(struct platform_device *pdev)
static int au1550_spi_probe(struct platform_device *pdev)
{
struct au1550_spi *hw;
struct spi_master *master;
@@ -968,7 +968,7 @@ err_nomem:
return err;
}
static int __exit au1550_spi_remove(struct platform_device *pdev)
static int au1550_spi_remove(struct platform_device *pdev)
{
struct au1550_spi *hw = platform_get_drvdata(pdev);
@@ -997,7 +997,7 @@ static int __exit au1550_spi_remove(struct platform_device *pdev)
MODULE_ALIAS("platform:au1550-spi");
static struct platform_driver au1550_spi_drv = {
.remove = __exit_p(au1550_spi_remove),
.remove = au1550_spi_remove,
.driver = {
.name = "au1550-spi",
.owner = THIS_MODULE,
+125 -54
View File
@@ -37,6 +37,8 @@
#define PFX KBUILD_MODNAME
#define BCM63XX_SPI_MAX_PREPEND 15
struct bcm63xx_spi {
struct completion done;
@@ -49,16 +51,10 @@ struct bcm63xx_spi {
unsigned int msg_type_shift;
unsigned int msg_ctl_width;
/* Data buffers */
const unsigned char *tx_ptr;
unsigned char *rx_ptr;
/* data iomem */
u8 __iomem *tx_io;
const u8 __iomem *rx_io;
int remaining_bytes;
struct clk *clk;
struct platform_device *pdev;
};
@@ -175,24 +171,17 @@ static int bcm63xx_spi_setup(struct spi_device *spi)
return 0;
}
/* Fill the TX FIFO with as many bytes as possible */
static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
{
u8 size;
/* Fill the Tx FIFO with as many bytes as possible */
size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes :
bs->fifo_size;
memcpy_toio(bs->tx_io, bs->tx_ptr, size);
bs->remaining_bytes -= size;
}
static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
struct spi_transfer *t)
static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
unsigned int num_transfers)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
u16 msg_ctl;
u16 cmd;
u8 rx_tail;
unsigned int i, timeout = 0, prepend_len = 0, len = 0;
struct spi_transfer *t = first;
bool do_rx = false;
bool do_tx = false;
/* Disable the CMD_DONE interrupt */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
@@ -200,25 +189,45 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
t->tx_buf, t->rx_buf, t->len);
/* Transmitter is inhibited */
bs->tx_ptr = t->tx_buf;
bs->rx_ptr = t->rx_buf;
if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
prepend_len = t->len;
if (t->tx_buf) {
bs->remaining_bytes = t->len;
bcm63xx_spi_fill_tx_fifo(bs);
/* prepare the buffer */
for (i = 0; i < num_transfers; i++) {
if (t->tx_buf) {
do_tx = true;
memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);
/* don't prepend more than one tx */
if (t != first)
prepend_len = 0;
}
if (t->rx_buf) {
do_rx = true;
/* prepend is half-duplex write only */
if (t == first)
prepend_len = 0;
}
len += t->len;
t = list_entry(t->transfer_list.next, struct spi_transfer,
transfer_list);
}
len -= prepend_len;
init_completion(&bs->done);
/* Fill in the Message control register */
msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
if (t->rx_buf && t->tx_buf)
if (do_rx && do_tx && prepend_len == 0)
msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
else if (t->rx_buf)
else if (do_rx)
msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
else if (t->tx_buf)
else if (do_tx)
msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
switch (bs->msg_ctl_width) {
@@ -232,14 +241,41 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
/* Issue the transfer */
cmd = SPI_CMD_START_IMMEDIATE;
cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
bcm_spi_writew(bs, cmd, SPI_CMD);
/* Enable the CMD_DONE interrupt */
bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
return t->len - bs->remaining_bytes;
timeout = wait_for_completion_timeout(&bs->done, HZ);
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)
return 0;
len = 0;
t = first;
/* Read out all the data */
for (i = 0; i < num_transfers; i++) {
if (t->rx_buf)
memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
if (t != first || prepend_len == 0)
len += t->len;
t = list_entry(t->transfer_list.next, struct spi_transfer,
transfer_list);
}
return 0;
}
static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
@@ -264,41 +300,76 @@ static int bcm63xx_spi_transfer_one(struct spi_master *master,
struct spi_message *m)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
struct spi_transfer *t;
struct spi_transfer *t, *first = NULL;
struct spi_device *spi = m->spi;
int status = 0;
unsigned int timeout = 0;
unsigned int n_transfers = 0, total_len = 0;
bool can_use_prepend = false;
/*
* This SPI controller does not support keeping CS active after a
* transfer.
* Work around this by merging as many transfers we can into one big
* full-duplex transfers.
*/
list_for_each_entry(t, &m->transfers, transfer_list) {
unsigned int len = t->len;
u8 rx_tail;
status = bcm63xx_spi_check_transfer(spi, t);
if (status < 0)
goto exit;
/* configure adapter for a new transfer */
bcm63xx_spi_setup_transfer(spi, t);
if (!first)
first = t;
while (len) {
/* send the data */
len -= bcm63xx_txrx_bufs(spi, t);
n_transfers++;
total_len += t->len;
timeout = wait_for_completion_timeout(&bs->done, HZ);
if (!timeout) {
status = -ETIMEDOUT;
goto exit;
}
if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
first->len <= BCM63XX_SPI_MAX_PREPEND)
can_use_prepend = true;
else if (can_use_prepend && t->tx_buf)
can_use_prepend = false;
/* read out all data */
rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
/* Read out all the data */
if (rx_tail)
memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
/* we can only transfer one fifo worth of data */
if ((can_use_prepend &&
total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
(!can_use_prepend && total_len > bs->fifo_size)) {
dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
total_len, bs->fifo_size);
status = -EINVAL;
goto exit;
}
m->actual_length += t->len;
/* all combined transfers have to have the same speed */
if (t->speed_hz != first->speed_hz) {
dev_err(&spi->dev, "unable to change speed between transfers\n");
status = -EINVAL;
goto exit;
}
/* CS will be deasserted directly after transfer */
if (t->delay_usecs) {
dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
status = -EINVAL;
goto exit;
}
if (t->cs_change ||
list_is_last(&t->transfer_list, &m->transfers)) {
/* configure adapter for a new transfer */
bcm63xx_spi_setup_transfer(spi, first);
/* send the data */
status = bcm63xx_txrx_bufs(spi, first, n_transfers);
if (status)
goto exit;
m->actual_length += total_len;
first = NULL;
n_transfers = 0;
total_len = 0;
can_use_prepend = false;
}
}
exit:
m->status = status;
+1 -2
View File
@@ -416,8 +416,7 @@ bfin_sport_spi_pump_transfers(unsigned long data)
drv_data->cs_change = transfer->cs_change;
/* Bits per word setup */
bits_per_word = transfer->bits_per_word ? :
message->spi->bits_per_word ? : 8;
bits_per_word = transfer->bits_per_word;
if (bits_per_word % 16 == 0)
drv_data->ops = &bfin_sport_transfer_ops_u16;
else
+2 -3
View File
@@ -642,8 +642,7 @@ static void bfin_spi_pump_transfers(unsigned long data)
drv_data->cs_change = transfer->cs_change;
/* Bits per word setup */
bits_per_word = transfer->bits_per_word ? :
message->spi->bits_per_word ? : 8;
bits_per_word = transfer->bits_per_word;
if (bits_per_word % 16 == 0) {
drv_data->n_bytes = bits_per_word/8;
drv_data->len = (transfer->len) >> 1;
@@ -1274,7 +1273,7 @@ static int bfin_spi_destroy_queue(struct bfin_spi_master_data *drv_data)
return 0;
}
static int __init bfin_spi_probe(struct platform_device *pdev)
static int bfin_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bfin5xx_spi_master *platform_info;
+17 -16
View File
@@ -69,7 +69,7 @@ static unsigned bitbang_txrx_8(
unsigned ns,
struct spi_transfer *t
) {
unsigned bits = t->bits_per_word ? : spi->bits_per_word;
unsigned bits = t->bits_per_word;
unsigned count = t->len;
const u8 *tx = t->tx_buf;
u8 *rx = t->rx_buf;
@@ -95,7 +95,7 @@ static unsigned bitbang_txrx_16(
unsigned ns,
struct spi_transfer *t
) {
unsigned bits = t->bits_per_word ? : spi->bits_per_word;
unsigned bits = t->bits_per_word;
unsigned count = t->len;
const u16 *tx = t->tx_buf;
u16 *rx = t->rx_buf;
@@ -121,7 +121,7 @@ static unsigned bitbang_txrx_32(
unsigned ns,
struct spi_transfer *t
) {
unsigned bits = t->bits_per_word ? : spi->bits_per_word;
unsigned bits = t->bits_per_word;
unsigned count = t->len;
const u32 *tx = t->tx_buf;
u32 *rx = t->rx_buf;
@@ -427,40 +427,41 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
*/
int spi_bitbang_start(struct spi_bitbang *bitbang)
{
int status;
struct spi_master *master = bitbang->master;
int status;
if (!bitbang->master || !bitbang->chipselect)
if (!master || !bitbang->chipselect)
return -EINVAL;
INIT_WORK(&bitbang->work, bitbang_work);
spin_lock_init(&bitbang->lock);
INIT_LIST_HEAD(&bitbang->queue);
if (!bitbang->master->mode_bits)
bitbang->master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
if (!master->mode_bits)
master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
if (!bitbang->master->transfer)
bitbang->master->transfer = spi_bitbang_transfer;
if (!master->transfer)
master->transfer = spi_bitbang_transfer;
if (!bitbang->txrx_bufs) {
bitbang->use_dma = 0;
bitbang->txrx_bufs = spi_bitbang_bufs;
if (!bitbang->master->setup) {
if (!master->setup) {
if (!bitbang->setup_transfer)
bitbang->setup_transfer =
spi_bitbang_setup_transfer;
bitbang->master->setup = spi_bitbang_setup;
bitbang->master->cleanup = spi_bitbang_cleanup;
master->setup = spi_bitbang_setup;
master->cleanup = spi_bitbang_cleanup;
}
} else if (!bitbang->master->setup)
} else if (!master->setup)
return -EINVAL;
if (bitbang->master->transfer == spi_bitbang_transfer &&
if (master->transfer == spi_bitbang_transfer &&
!bitbang->setup_transfer)
return -EINVAL;
/* this task is the only thing to touch the SPI bits */
bitbang->busy = 0;
bitbang->workqueue = create_singlethread_workqueue(
dev_name(bitbang->master->dev.parent));
dev_name(master->dev.parent));
if (bitbang->workqueue == NULL) {
status = -EBUSY;
goto err1;
@@ -469,7 +470,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
/* driver may get busy before register() returns, especially
* if someone registered boardinfo for devices
*/
status = spi_register_master(bitbang->master);
status = spi_register_master(master);
if (status < 0)
goto err2;
+1 -1
View File
@@ -68,7 +68,7 @@ static int spi_clps711x_setup_xfer(struct spi_device *spi,
struct spi_transfer *xfer)
{
u32 speed = xfer->speed_hz ? : spi->max_speed_hz;
u8 bpw = xfer->bits_per_word ? : spi->bits_per_word;
u8 bpw = xfer->bits_per_word;
struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master);
if (bpw != 8) {
+1 -2
View File
@@ -329,8 +329,7 @@ static int mcfqspi_transfer_one_message(struct spi_master *master,
mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
if ((t->bits_per_word ? t->bits_per_word :
spi->bits_per_word) == 8)
if (t->bits_per_word == 8)
mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf,
t->rx_buf);
else
+103 -16
View File
@@ -28,6 +28,8 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/edma.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/slab.h>
@@ -135,7 +137,7 @@ struct davinci_spi {
int dma_rx_chnum;
int dma_tx_chnum;
struct davinci_spi_platform_data *pdata;
struct davinci_spi_platform_data pdata;
void (*get_rx)(u32 rx_data, struct davinci_spi *);
u32 (*get_tx)(struct davinci_spi *);
@@ -213,7 +215,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
bool gpio_chipsel = false;
dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
pdata = &dspi->pdata;
if (pdata->chip_sel && chip_sel < pdata->num_chipselect &&
pdata->chip_sel[chip_sel] != SPI_INTERN_CS)
@@ -392,7 +394,7 @@ static int davinci_spi_setup(struct spi_device *spi)
struct davinci_spi_platform_data *pdata;
dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
pdata = &dspi->pdata;
/* if bits per word length is zero then set it default 8 */
if (!spi->bits_per_word)
@@ -534,7 +536,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
struct scatterlist sg_rx, sg_tx;
dspi = spi_master_get_devdata(spi->master);
pdata = dspi->pdata;
pdata = &dspi->pdata;
spicfg = (struct davinci_spi_config *)spi->controller_data;
if (!spicfg)
spicfg = &davinci_spi_default_cfg;
@@ -699,6 +701,19 @@ err_alloc_dummy_buf:
return ret;
}
/**
* dummy_thread_fn - dummy thread function
* @irq: IRQ number for this SPI Master
* @context_data: structure for SPI Master controller davinci_spi
*
* This is to satisfy the request_threaded_irq() API so that the irq
* handler is called in interrupt context.
*/
static irqreturn_t dummy_thread_fn(s32 irq, void *data)
{
return IRQ_HANDLED;
}
/**
* davinci_spi_irq - Interrupt handler for SPI Master Controller
* @irq: IRQ number for this SPI Master
@@ -758,6 +773,70 @@ rx_dma_failed:
return r;
}
#if defined(CONFIG_OF)
static const struct of_device_id davinci_spi_of_match[] = {
{
.compatible = "ti,dm644x-spi",
},
{
.compatible = "ti,da8xx-spi",
.data = (void *)SPI_VERSION_2,
},
{ },
};
MODULE_DEVICE_TABLE(of, davini_spi_of_match);
/**
* spi_davinci_get_pdata - Get platform data from DTS binding
* @pdev: ptr to platform data
* @dspi: ptr to driver data
*
* Parses and populates pdata in dspi from device tree bindings.
*
* NOTE: Not all platform data params are supported currently.
*/
static int spi_davinci_get_pdata(struct platform_device *pdev,
struct davinci_spi *dspi)
{
struct device_node *node = pdev->dev.of_node;
struct davinci_spi_platform_data *pdata;
unsigned int num_cs, intr_line = 0;
const struct of_device_id *match;
pdata = &dspi->pdata;
pdata->version = SPI_VERSION_1;
match = of_match_device(of_match_ptr(davinci_spi_of_match),
&pdev->dev);
if (!match)
return -ENODEV;
/* match data has the SPI version number for SPI_VERSION_2 */
if (match->data == (void *)SPI_VERSION_2)
pdata->version = SPI_VERSION_2;
/*
* default num_cs is 1 and all chipsel are internal to the chip
* indicated by chip_sel being NULL. GPIO based CS is not
* supported yet in DT bindings.
*/
num_cs = 1;
of_property_read_u32(node, "num-cs", &num_cs);
pdata->num_chipselect = num_cs;
of_property_read_u32(node, "ti,davinci-spi-intr-line", &intr_line);
pdata->intr_line = intr_line;
return 0;
}
#else
#define davinci_spi_of_match NULL
static struct davinci_spi_platform_data
*spi_davinci_get_pdata(struct platform_device *pdev,
struct davinci_spi *dspi)
{
return -ENODEV;
}
#endif
/**
* davinci_spi_probe - probe function for SPI Master Controller
* @pdev: platform_device structure which contains plateform specific data
@@ -780,12 +859,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
int i = 0, ret = 0;
u32 spipc0;
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
ret = -ENODEV;
goto err;
}
master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi));
if (master == NULL) {
ret = -ENOMEM;
@@ -800,6 +873,19 @@ static int davinci_spi_probe(struct platform_device *pdev)
goto free_master;
}
if (pdev->dev.platform_data) {
pdata = pdev->dev.platform_data;
dspi->pdata = *pdata;
} else {
/* update dspi pdata with that from the DT */
ret = spi_davinci_get_pdata(pdev, dspi);
if (ret < 0)
goto free_master;
}
/* pdata in dspi is now updated and point pdata to that */
pdata = &dspi->pdata;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
ret = -ENOENT;
@@ -807,7 +893,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
}
dspi->pbase = r->start;
dspi->pdata = pdata;
mem = request_mem_region(r->start, resource_size(r), pdev->name);
if (mem == NULL) {
@@ -827,8 +912,8 @@ static int davinci_spi_probe(struct platform_device *pdev)
goto unmap_io;
}
ret = request_irq(dspi->irq, davinci_spi_irq, 0, dev_name(&pdev->dev),
dspi);
ret = request_threaded_irq(dspi->irq, davinci_spi_irq, dummy_thread_fn,
0, dev_name(&pdev->dev), dspi);
if (ret)
goto unmap_io;
@@ -843,8 +928,9 @@ static int davinci_spi_probe(struct platform_device *pdev)
ret = -ENODEV;
goto put_master;
}
clk_enable(dspi->clk);
clk_prepare_enable(dspi->clk);
master->dev.of_node = pdev->dev.of_node;
master->bus_num = pdev->id;
master->num_chipselect = pdata->num_chipselect;
master->setup = davinci_spi_setup;
@@ -927,7 +1013,7 @@ free_dma:
dma_release_channel(dspi->dma_rx);
dma_release_channel(dspi->dma_tx);
free_clk:
clk_disable(dspi->clk);
clk_disable_unprepare(dspi->clk);
clk_put(dspi->clk);
put_master:
spi_master_put(master);
@@ -963,7 +1049,7 @@ static int davinci_spi_remove(struct platform_device *pdev)
spi_bitbang_stop(&dspi->bitbang);
clk_disable(dspi->clk);
clk_disable_unprepare(dspi->clk);
clk_put(dspi->clk);
spi_master_put(master);
free_irq(dspi->irq, dspi);
@@ -978,6 +1064,7 @@ static struct platform_driver davinci_spi_driver = {
.driver = {
.name = "spi_davinci",
.owner = THIS_MODULE,
.of_match_table = davinci_spi_of_match,
},
.probe = davinci_spi_probe,
.remove = davinci_spi_remove,
+1 -1
View File
@@ -446,7 +446,7 @@ static inline int bits_per_word(const struct ep93xx_spi *espi)
struct spi_message *msg = espi->current_msg;
struct spi_transfer *t = msg->state;
return t->bits_per_word ? t->bits_per_word : msg->spi->bits_per_word;
return t->bits_per_word;
}
static void ep93xx_do_write(struct ep93xx_spi *espi, struct spi_transfer *t)
+2 -1
View File
@@ -398,7 +398,7 @@ static int falcon_sflash_xfer_one(struct spi_master *master,
}
m->status = ret;
m->complete(m->context);
spi_finalize_current_message(master);
return 0;
}
@@ -423,6 +423,7 @@ static int falcon_sflash_probe(struct platform_device *pdev)
master->mode_bits = SPI_MODE_3;
master->num_chipselect = 1;
master->flags = SPI_MASTER_HALF_DUPLEX;
master->bus_num = -1;
master->setup = falcon_sflash_setup;
master->prepare_transfer_hardware = falcon_sflash_prepare_xfer;
+20 -3
View File
@@ -365,9 +365,26 @@ static int spi_gpio_probe_dt(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
pdata->sck = of_get_named_gpio(np, "gpio-sck", 0);
pdata->miso = of_get_named_gpio(np, "gpio-miso", 0);
pdata->mosi = of_get_named_gpio(np, "gpio-mosi", 0);
ret = of_get_named_gpio(np, "gpio-sck", 0);
if (ret < 0) {
dev_err(&pdev->dev, "gpio-sck property not found\n");
goto error_free;
}
pdata->sck = ret;
ret = of_get_named_gpio(np, "gpio-miso", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-miso property not found, switching to no-rx mode\n");
pdata->miso = SPI_GPIO_NO_MISO;
} else
pdata->miso = ret;
ret = of_get_named_gpio(np, "gpio-mosi", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-mosi property not found, switching to no-tx mode\n");
pdata->mosi = SPI_GPIO_NO_MOSI;
} else
pdata->mosi = ret;
ret = of_property_read_u32(np, "num-chipselects", &tmp);
if (ret < 0) {
+1
View File
@@ -949,3 +949,4 @@ module_platform_driver(spi_imx_driver);
MODULE_DESCRIPTION("SPI Master Controller driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
+6 -11
View File
@@ -438,6 +438,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
master->num_chipselect = pdata->max_chipselect;
}
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
master->setup = mpc512x_psc_spi_setup;
master->transfer = mpc512x_psc_spi_transfer;
master->cleanup = mpc512x_psc_spi_cleanup;
@@ -522,17 +523,11 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op)
regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);
/* get PSC id (0..11, used by port_config) */
if (op->dev.platform_data == NULL) {
const u32 *psc_nump;
psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL);
if (!psc_nump || *psc_nump > 11) {
dev_err(&op->dev, "mpc512x_psc_spi: Device node %s "
"has invalid cell-index property\n",
op->dev.of_node->full_name);
return -EINVAL;
}
id = *psc_nump;
id = of_alias_get_id(op->dev.of_node, "spi");
if (id < 0) {
dev_err(&op->dev, "no alias id for %s\n",
op->dev.of_node->full_name);
return id;
}
return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,

Some files were not shown because too many files have changed in this diff Show More