diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 16 | ||||
-rw-r--r-- | drivers/spi/Makefile | 2 | ||||
-rw-r--r-- | drivers/spi/atmel_spi.c | 14 | ||||
-rw-r--r-- | drivers/spi/au1550_spi.c | 14 | ||||
-rw-r--r-- | drivers/spi/mpc52xx_psc_spi.c | 34 | ||||
-rw-r--r-- | drivers/spi/omap2_mcspi.c | 48 | ||||
-rw-r--r-- | drivers/spi/omap_uwire.c | 16 | ||||
-rw-r--r-- | drivers/spi/orion_spi.c | 12 | ||||
-rw-r--r-- | drivers/spi/pxa2xx_spi.c | 23 | ||||
-rw-r--r-- | drivers/spi/spi.c | 70 | ||||
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 15 | ||||
-rw-r--r-- | drivers/spi/spi_bitbang.c | 40 | ||||
-rw-r--r-- | drivers/spi/spi_imx.c | 17 | ||||
-rw-r--r-- | drivers/spi/spi_mpc8xxx.c (renamed from drivers/spi/spi_mpc83xx.c) | 529 | ||||
-rw-r--r-- | drivers/spi/spi_s3c24xx.c | 42 | ||||
-rw-r--r-- | drivers/spi/spi_txx9.c | 11 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 17 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi.c | 18 |
18 files changed, 453 insertions, 485 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e8aae227b5e0..2c733c27db2f 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -139,17 +139,15 @@ config SPI_MPC52xx_PSC This enables using the Freescale MPC52xx Programmable Serial Controller in master SPI mode. -config SPI_MPC83xx - tristate "Freescale MPC83xx/QUICC Engine SPI controller" - depends on (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL +config SPI_MPC8xxx + tristate "Freescale MPC8xxx SPI controller" + depends on FSL_SOC help - This enables using the Freescale MPC83xx and QUICC Engine SPI - controllers in master mode. + This enables using the Freescale MPC8xxx SPI controllers in master + mode. - Note, this driver uniquely supports the SPI controller on the MPC83xx - family of PowerPC processors, plus processors with QUICC Engine - technology. This driver uses a simple set of shift registers for data - (opposed to the CPM based descriptor model). + This driver uses a simple set of shift registers for data (opposed + to the CPM based descriptor model). config SPI_OMAP_UWIRE tristate "OMAP1 MicroWire" diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ecfadb180482..3de408d294ba 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -25,7 +25,7 @@ obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o obj-$(CONFIG_SPI_ORION) += orion_spi.o obj-$(CONFIG_SPI_PL022) += amba-pl022.o obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o -obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o +obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 12e443cc4ac9..f5b3fdbb1e27 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -530,9 +530,6 @@ atmel_spi_interrupt(int irq, void *dev_id) return ret; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) - static int atmel_spi_setup(struct spi_device *spi) { struct atmel_spi *as; @@ -555,8 +552,6 @@ static int atmel_spi_setup(struct spi_device *spi) return -EINVAL; } - if (bits == 0) - bits = 8; if (bits < 8 || bits > 16) { dev_dbg(&spi->dev, "setup: invalid bits_per_word %u (8 to 16)\n", @@ -564,12 +559,6 @@ static int atmel_spi_setup(struct spi_device *spi) return -EINVAL; } - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - /* see notes above re chipselect */ if (!atmel_spi_is_v2() && spi->chip_select == 0 @@ -775,6 +764,9 @@ static int __init atmel_spi_probe(struct platform_device *pdev) if (!master) goto out_free; + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + master->bus_num = pdev->id; master->num_chipselect = 4; master->setup = atmel_spi_setup; diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index b02f25c702fd..76cbc1a66598 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -284,27 +284,16 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) return 0; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST) - static int au1550_spi_setup(struct spi_device *spi) { struct au1550_spi *hw = spi_master_get_devdata(spi->master); - if (spi->bits_per_word == 0) - spi->bits_per_word = 8; if (spi->bits_per_word < 4 || spi->bits_per_word > 24) { dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n", spi->bits_per_word); return -EINVAL; } - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - if (spi->max_speed_hz == 0) spi->max_speed_hz = hw->freq_max; if (spi->max_speed_hz > hw->freq_max @@ -781,6 +770,9 @@ static int __init au1550_spi_probe(struct platform_device *pdev) goto err_nomem; } + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; + hw = spi_master_get_devdata(master); hw->master = spi_master_get(master); diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 68c77a911595..1b74d5ca03f3 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <linux/types.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/of_platform.h> @@ -30,8 +31,7 @@ struct mpc52xx_psc_spi { /* fsl_spi_platform data */ - void (*activate_cs)(u8, u8); - void (*deactivate_cs)(u8, u8); + void (*cs_control)(struct spi_device *spi, bool on); u32 sysclk; /* driver internal data */ @@ -111,18 +111,16 @@ static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi) out_be16((u16 __iomem *)&psc->ccr, ccr); mps->bits_per_word = cs->bits_per_word; - if (mps->activate_cs) - mps->activate_cs(spi->chip_select, - (spi->mode & SPI_CS_HIGH) ? 1 : 0); + if (mps->cs_control) + mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0); } static void mpc52xx_psc_spi_deactivate_cs(struct spi_device *spi) { struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master); - if (mps->deactivate_cs) - mps->deactivate_cs(spi->chip_select, - (spi->mode & SPI_CS_HIGH) ? 1 : 0); + if (mps->cs_control) + mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1); } #define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1) @@ -261,9 +259,6 @@ static void mpc52xx_psc_spi_work(struct work_struct *work) spin_unlock_irq(&mps->lock); } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST) - static int mpc52xx_psc_spi_setup(struct spi_device *spi) { struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master); @@ -273,12 +268,6 @@ static int mpc52xx_psc_spi_setup(struct spi_device *spi) if (spi->bits_per_word%8) return -EINVAL; - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - if (!cs) { cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) @@ -385,18 +374,19 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, dev_set_drvdata(dev, master); mps = spi_master_get_devdata(master); + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; + mps->irq = irq; if (pdata == NULL) { dev_warn(dev, "probe called without platform data, no " - "(de)activate_cs function will be called\n"); - mps->activate_cs = NULL; - mps->deactivate_cs = NULL; + "cs_control function will be called\n"); + mps->cs_control = NULL; mps->sysclk = 0; master->bus_num = bus_num; master->num_chipselect = 255; } else { - mps->activate_cs = pdata->activate_cs; - mps->deactivate_cs = pdata->deactivate_cs; + mps->cs_control = pdata->cs_control; mps->sysclk = pdata->sysclk; master->bus_num = pdata->bus_num; master->num_chipselect = pdata->max_chipselect; diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index d6d0c5d241ce..9b80ad36dbba 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -59,6 +59,8 @@ /* per-register bitmasks: */ +#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3) +#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP (1 << 2) #define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE (1 << 0) #define OMAP2_MCSPI_SYSCONFIG_SOFTRESET (1 << 1) @@ -90,6 +92,7 @@ #define OMAP2_MCSPI_CHCTRL_EN (1 << 0) +#define OMAP2_MCSPI_WAKEUPENABLE_WKEN (1 << 0) /* We have 2 DMA channels per CS, one for RX and one for TX */ struct omap2_mcspi_dma { @@ -269,7 +272,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) if (rx != NULL) { omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel, - data_type, element_count, 1, + data_type, element_count - 1, 1, OMAP_DMA_SYNC_ELEMENT, mcspi_dma->dma_rx_sync_dev, 1); @@ -300,6 +303,25 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) if (rx != NULL) { wait_for_completion(&mcspi_dma->dma_rx_completion); dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE); + omap2_mcspi_set_enable(spi, 0); + if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) + & OMAP2_MCSPI_CHSTAT_RXS)) { + u32 w; + + w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); + if (word_len <= 8) + ((u8 *)xfer->rx_buf)[element_count - 1] = w; + else if (word_len <= 16) + ((u16 *)xfer->rx_buf)[element_count - 1] = w; + else /* word_len <= 32 */ + ((u32 *)xfer->rx_buf)[element_count - 1] = w; + } else { + dev_err(&spi->dev, "DMA RX last word empty"); + count -= (word_len <= 8) ? 1 : + (word_len <= 16) ? 2 : + /* word_len <= 32 */ 4; + } + omap2_mcspi_set_enable(spi, 1); } return count; } @@ -603,9 +625,6 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) return 0; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) - static int omap2_mcspi_setup(struct spi_device *spi) { int ret; @@ -613,15 +632,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) struct omap2_mcspi_dma *mcspi_dma; struct omap2_mcspi_cs *cs = spi->controller_state; - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - - if (spi->bits_per_word == 0) - spi->bits_per_word = 8; - else if (spi->bits_per_word < 4 || spi->bits_per_word > 32) { + if (spi->bits_per_word < 4 || spi->bits_per_word > 32) { dev_dbg(&spi->dev, "setup: unsupported %d bit words\n", spi->bits_per_word); return -EINVAL; @@ -884,8 +895,12 @@ static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, - /* (3 << 8) | (2 << 3) | */ - OMAP2_MCSPI_SYSCONFIG_AUTOIDLE); + OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | + OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | + OMAP2_MCSPI_SYSCONFIG_SMARTIDLE); + + mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, + OMAP2_MCSPI_WAKEUPENABLE_WKEN); omap2_mcspi_set_master_mode(master); @@ -984,6 +999,9 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) return -ENOMEM; } + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + if (pdev->id != -1) master->bus_num = pdev->id; diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c index fe8b9ac0ccef..8980a5640bd9 100644 --- a/drivers/spi/omap_uwire.c +++ b/drivers/spi/omap_uwire.c @@ -339,8 +339,6 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) bits = spi->bits_per_word; if (t != NULL && t->bits_per_word) bits = t->bits_per_word; - if (!bits) - bits = 8; if (bits > 16) { pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits); @@ -449,19 +447,10 @@ done: return status; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) - static int uwire_setup(struct spi_device *spi) { struct uwire_state *ust = spi->controller_state; - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - if (ust == NULL) { ust = kzalloc(sizeof(*ust), GFP_KERNEL); if (ust == NULL) @@ -522,6 +511,11 @@ static int __init uwire_probe(struct platform_device *pdev) uwire_write_reg(UWIRE_SR3, 1); + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + + master->flags = SPI_MASTER_HALF_DUPLEX; + master->bus_num = 2; /* "official" */ master->num_chipselect = 4; master->setup = uwire_setup; diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c index c8b0babdc2a6..3aea50da7b29 100644 --- a/drivers/spi/orion_spi.c +++ b/drivers/spi/orion_spi.c @@ -358,20 +358,11 @@ static int orion_spi_setup(struct spi_device *spi) orion_spi = spi_master_get_devdata(spi->master); - if (spi->mode) { - dev_err(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode); - return -EINVAL; - } - /* Fix ac timing if required. */ if (orion_spi->spi_info->enable_clock_fix) orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, (1 << 14)); - if (spi->bits_per_word == 0) - spi->bits_per_word = 8; - if ((spi->max_speed_hz == 0) || (spi->max_speed_hz > orion_spi->max_speed)) spi->max_speed_hz = orion_spi->max_speed; @@ -476,6 +467,9 @@ static int __init orion_spi_probe(struct platform_device *pdev) if (pdev->id != -1) master->bus_num = pdev->id; + /* we support only mode 0, and no options */ + master->mode_bits = 0; + master->setup = orion_spi_setup; master->transfer = orion_spi_transfer; master->num_chipselect = ORION_NUM_CHIPSELECTS; diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 3f3c08c6ba4e..d949dbf1141f 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1185,9 +1185,6 @@ static int transfer(struct spi_device *spi, struct spi_message *msg) return 0; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA) - static int setup_cs(struct spi_device *spi, struct chip_data *chip, struct pxa2xx_spi_chip *chip_info) { @@ -1236,9 +1233,6 @@ static int setup(struct spi_device *spi) uint tx_thres = TX_THRESH_DFLT; uint rx_thres = RX_THRESH_DFLT; - if (!spi->bits_per_word) - spi->bits_per_word = 8; - if (drv_data->ssp_type != PXA25x_SSP && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " @@ -1255,12 +1249,6 @@ static int setup(struct spi_device *spi) return -EINVAL; } - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - /* Only alloc on first setup */ chip = spi_get_ctldata(spi); if (!chip) { @@ -1328,18 +1316,14 @@ static int setup(struct spi_device *spi) /* NOTE: PXA25x_SSP _could_ use external clocking ... */ if (drv_data->ssp_type != PXA25x_SSP) - dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n", - spi->bits_per_word, + dev_dbg(&spi->dev, "%ld Hz actual, %s\n", clk_get_rate(ssp->clk) / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3, chip->enable_dma ? "DMA" : "PIO"); else - dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n", - spi->bits_per_word, + dev_dbg(&spi->dev, "%ld Hz actual, %s\n", clk_get_rate(ssp->clk) / 2 / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), - spi->mode & 0x3, chip->enable_dma ? "DMA" : "PIO"); if (spi->bits_per_word <= 8) { @@ -1500,6 +1484,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) drv_data->pdev = pdev; drv_data->ssp = ssp; + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + master->bus_num = pdev->id; master->num_chipselect = platform_info->num_chipselect; master->dma_alignment = DMA_ALIGNMENT; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 8eba98c8ed1e..70845ccd85c3 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -265,7 +265,7 @@ int spi_add_device(struct spi_device *spi) * normally rely on the device being setup. Devices * using SPI_CS_HIGH can't coexist well otherwise... */ - status = spi->master->setup(spi); + status = spi_setup(spi); if (status < 0) { dev_err(dev, "can't %s %s, status %d\n", "setup", dev_name(&spi->dev), status); @@ -583,6 +583,70 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master); /*-------------------------------------------------------------------------*/ +/* Core methods for SPI master protocol drivers. Some of the + * other core methods are currently defined as inline functions. + */ + +/** + * spi_setup - setup SPI mode and clock rate + * @spi: the device whose settings are being modified + * Context: can sleep, and no requests are queued to the device + * + * SPI protocol drivers may need to update the transfer mode if the + * device doesn't work with its default. They may likewise need + * to update clock rates or word sizes from initial values. This function + * changes those settings, and must be called from a context that can sleep. + * Except for SPI_CS_HIGH, which takes effect immediately, the changes take + * effect the next time the device is selected and data is transferred to + * or from it. When this function returns, the spi device is deselected. + * + * Note that this call will fail if the protocol driver specifies an option + * that the underlying controller or its driver does not support. For + * example, not all hardware supports wire transfers using nine bit words, + * LSB-first wire encoding, or active-high chipselects. + */ +int spi_setup(struct spi_device *spi) +{ + unsigned bad_bits; + int status; + + /* help drivers fail *cleanly* when they need options + * that aren't supported with their current master + */ + bad_bits = spi->mode & ~spi->master->mode_bits; + if (bad_bits) { + dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", + bad_bits); + return -EINVAL; + } + + if (!spi->bits_per_word) + spi->bits_per_word = 8; + + status = spi->master->setup(spi); + + dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s" + "%u bits/w, %u Hz max --> %d\n", + (int) (spi->mode & (SPI_CPOL | SPI_CPHA)), + (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "", + (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "", + (spi->mode & SPI_3WIRE) ? "3wire, " : "", + (spi->mode & SPI_LOOP) ? "loopback, " : "", + spi->bits_per_word, spi->max_speed_hz, + status); + + return status; +} +EXPORT_SYMBOL_GPL(spi_setup); + + +/*-------------------------------------------------------------------------*/ + +/* Utility methods for SPI master protocol drivers, layered on + * top of the core. Some other utility methods are defined as + * inline functions. + */ + static void spi_complete(void *arg) { complete(arg); @@ -636,8 +700,8 @@ static u8 *buf; * @spi: device with which data will be exchanged * @txbuf: data to be written (need not be dma-safe) * @n_tx: size of txbuf, in bytes - * @rxbuf: buffer into which data will be read - * @n_rx: size of rxbuf, in bytes (need not be dma-safe) + * @rxbuf: buffer into which data will be read (need not be dma-safe) + * @n_rx: size of rxbuf, in bytes * Context: can sleep * * This performs a half duplex MicroWire style transaction with the diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 011c5bddba6a..73e24ef5a2f9 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -169,7 +169,7 @@ static int bfin_spi_flush(struct driver_data *drv_data) unsigned long limit = loops_per_jiffy << 1; /* wait for stop and clear stat */ - while (!(read_STAT(drv_data) & BIT_STAT_SPIF) && limit--) + while (!(read_STAT(drv_data) & BIT_STAT_SPIF) && --limit) cpu_relax(); write_STAT(drv_data, BIT_STAT_CLR); @@ -1010,16 +1010,6 @@ static int bfin_spi_setup(struct spi_device *spi) struct driver_data *drv_data = spi_master_get_devdata(spi->master); int ret; - /* Abort device setup if requested features are not supported */ - if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) { - dev_err(&spi->dev, "requested mode not fully supported\n"); - return -EINVAL; - } - - /* Zero (the default) here means 8 bits */ - if (!spi->bits_per_word) - spi->bits_per_word = 8; - if (spi->bits_per_word != 8 && spi->bits_per_word != 16) return -EINVAL; @@ -1287,6 +1277,9 @@ static int __init bfin_spi_probe(struct platform_device *pdev) drv_data->pdev = pdev; drv_data->pin_req = platform_info->pin_req; + /* the spi->mode bits supported by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; + master->bus_num = pdev->id; master->num_chipselect = platform_info->num_chipselect; master->cleanup = bfin_spi_cleanup; diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 85e61f451218..f1db395dd889 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -188,12 +188,6 @@ int spi_bitbang_setup(struct spi_device *spi) bitbang = spi_master_get_devdata(spi->master); - /* Bitbangers can support SPI_CS_HIGH, SPI_3WIRE, and so on; - * add those to master->flags, and provide the other support. - */ - if ((spi->mode & ~(SPI_CPOL|SPI_CPHA|bitbang->flags)) != 0) - return -EINVAL; - if (!cs) { cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) @@ -201,9 +195,6 @@ int spi_bitbang_setup(struct spi_device *spi) spi->controller_state = cs; } - if (!spi->bits_per_word) - spi->bits_per_word = 8; - /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; if (!cs->txrx_word) @@ -213,9 +204,7 @@ int spi_bitbang_setup(struct spi_device *spi) if (retval < 0) return retval; - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", - __func__, spi->mode & (SPI_CPOL | SPI_CPHA), - spi->bits_per_word, 2 * cs->nsecs); + dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); /* NOTE we _need_ to call chipselect() early, ideally with adapter * setup, unless the hardware defaults cooperate to avoid confusion @@ -269,6 +258,11 @@ static void bitbang_work(struct work_struct *work) struct spi_bitbang *bitbang = container_of(work, struct spi_bitbang, work); unsigned long flags; + int do_setup = -1; + int (*setup_transfer)(struct spi_device *, + struct spi_transfer *); + + setup_transfer = bitbang->setup_transfer; spin_lock_irqsave(&bitbang->lock, flags); bitbang->busy = 1; @@ -280,8 +274,6 @@ static void bitbang_work(struct work_struct *work) unsigned tmp; unsigned cs_change; int status; - int (*setup_transfer)(struct spi_device *, - struct spi_transfer *); m = container_of(bitbang->queue.next, struct spi_message, queue); @@ -298,19 +290,19 @@ static void bitbang_work(struct work_struct *work) tmp = 0; cs_change = 1; status = 0; - setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { - /* override or restore speed and wordsize */ - if (t->speed_hz || t->bits_per_word) { - setup_transfer = bitbang->setup_transfer; + /* override speed or wordsize? */ + if (t->speed_hz || t->bits_per_word) + do_setup = 1; + + /* init (-1) or override (1) transfer params */ + if (do_setup != 0) { if (!setup_transfer) { status = -ENOPROTOOPT; break; } - } - if (setup_transfer) { status = setup_transfer(spi, t); if (status < 0) break; @@ -374,9 +366,10 @@ static void bitbang_work(struct work_struct *work) m->status = status; m->complete(m->context); - /* restore speed and wordsize */ - if (setup_transfer) + /* restore speed and wordsize if it was overridden */ + if (do_setup == 1) setup_transfer(spi, NULL); + do_setup = 0; /* normally deactivate chipselect ... unless no error and * cs_change has hinted that the next message will probably @@ -457,6 +450,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) 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 (!bitbang->master->transfer) bitbang->master->transfer = spi_bitbang_transfer; if (!bitbang->txrx_bufs) { diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 0671aeef5792..c195e45f7f35 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -1171,9 +1171,6 @@ msg_rejected: return -EINVAL; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) - /* On first setup bad values must free chip_data memory since will cause spi_new_device to fail. Bad value setup from protocol driver are simply not applied and notified to the calling driver. */ @@ -1186,12 +1183,6 @@ static int setup(struct spi_device *spi) u32 tmp; int status = 0; - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - /* Get controller data */ chip_info = spi->controller_data; @@ -1286,10 +1277,7 @@ static int setup(struct spi_device *spi) /* SPI word width */ tmp = spi->bits_per_word; - if (tmp == 0) { - tmp = 8; - spi->bits_per_word = 8; - } else if (tmp > 16) { + if (tmp > 16) { status = -EINVAL; dev_err(&spi->dev, "setup - " @@ -1481,6 +1469,9 @@ static int __init spi_imx_probe(struct platform_device *pdev) drv_data->master_info = platform_info; drv_data->pdev = pdev; + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + master->bus_num = pdev->id; master->num_chipselect = platform_info->num_chipselect; master->dma_alignment = DMA_ALIGNMENT; diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc8xxx.c index a32ccb44065e..0fd0ec4d3a7d 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -1,5 +1,5 @@ /* - * MPC83xx SPI controller driver. + * MPC8xxx SPI controller driver. * * Maintainer: Kumar Gala * @@ -14,8 +14,10 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/kernel.h> +#include <linux/bug.h> #include <linux/errno.h> #include <linux/err.h> +#include <linux/io.h> #include <linux/completion.h> #include <linux/interrupt.h> #include <linux/delay.h> @@ -33,10 +35,9 @@ #include <sysdev/fsl_soc.h> #include <asm/irq.h> -#include <asm/io.h> /* SPI Controller registers */ -struct mpc83xx_spi_reg { +struct mpc8xxx_spi_reg { u8 res1[0x20]; __be32 mode; __be32 event; @@ -75,16 +76,16 @@ struct mpc83xx_spi_reg { #define SPIM_NF 0x00000100 /* Not full */ /* SPI Controller driver's private data. */ -struct mpc83xx_spi { - struct mpc83xx_spi_reg __iomem *base; +struct mpc8xxx_spi { + struct mpc8xxx_spi_reg __iomem *base; /* rx & tx bufs from the spi_transfer */ const void *tx; void *rx; /* functions to deal with different sized buffers */ - void (*get_rx) (u32 rx_data, struct mpc83xx_spi *); - u32(*get_tx) (struct mpc83xx_spi *); + void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *); + u32(*get_tx) (struct mpc8xxx_spi *); unsigned int count; unsigned int irq; @@ -97,8 +98,6 @@ struct mpc83xx_spi { bool qe_mode; - u8 busy; - struct workqueue_struct *workqueue; struct work_struct work; @@ -108,44 +107,44 @@ struct mpc83xx_spi { struct completion done; }; -struct spi_mpc83xx_cs { +struct spi_mpc8xxx_cs { /* functions to deal with different sized buffers */ - void (*get_rx) (u32 rx_data, struct mpc83xx_spi *); - u32 (*get_tx) (struct mpc83xx_spi *); + void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *); + u32 (*get_tx) (struct mpc8xxx_spi *); u32 rx_shift; /* RX data reg shift when in qe mode */ u32 tx_shift; /* TX data reg shift when in qe mode */ u32 hw_mode; /* Holds HW mode register settings */ }; -static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val) +static inline void mpc8xxx_spi_write_reg(__be32 __iomem *reg, u32 val) { out_be32(reg, val); } -static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg) +static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg) { return in_be32(reg); } #define MPC83XX_SPI_RX_BUF(type) \ static \ -void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ +void mpc8xxx_spi_rx_buf_##type(u32 data, struct mpc8xxx_spi *mpc8xxx_spi) \ { \ - type * rx = mpc83xx_spi->rx; \ - *rx++ = (type)(data >> mpc83xx_spi->rx_shift); \ - mpc83xx_spi->rx = rx; \ + type *rx = mpc8xxx_spi->rx; \ + *rx++ = (type)(data >> mpc8xxx_spi->rx_shift); \ + mpc8xxx_spi->rx = rx; \ } #define MPC83XX_SPI_TX_BUF(type) \ static \ -u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \ +u32 mpc8xxx_spi_tx_buf_##type(struct mpc8xxx_spi *mpc8xxx_spi) \ { \ u32 data; \ - const type * tx = mpc83xx_spi->tx; \ + const type *tx = mpc8xxx_spi->tx; \ if (!tx) \ return 0; \ - data = *tx++ << mpc83xx_spi->tx_shift; \ - mpc83xx_spi->tx = tx; \ + data = *tx++ << mpc8xxx_spi->tx_shift; \ + mpc8xxx_spi->tx = tx; \ return data; \ } @@ -156,12 +155,12 @@ MPC83XX_SPI_TX_BUF(u8) MPC83XX_SPI_TX_BUF(u16) MPC83XX_SPI_TX_BUF(u32) -static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) +static void mpc8xxx_spi_chipselect(struct spi_device *spi, int value) { - struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); + struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; bool pol = spi->mode & SPI_CS_HIGH; - struct spi_mpc83xx_cs *cs = spi->controller_state; + struct spi_mpc8xxx_cs *cs = spi->controller_state; if (value == BITBANG_CS_INACTIVE) { if (pdata->cs_control) @@ -169,16 +168,16 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) } if (value == BITBANG_CS_ACTIVE) { - u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + u32 regval = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode); - mpc83xx_spi->rx_shift = cs->rx_shift; - mpc83xx_spi->tx_shift = cs->tx_shift; - mpc83xx_spi->get_rx = cs->get_rx; - mpc83xx_spi->get_tx = cs->get_tx; + mpc8xxx_spi->rx_shift = cs->rx_shift; + mpc8xxx_spi->tx_shift = cs->tx_shift; + mpc8xxx_spi->get_rx = cs->get_rx; + mpc8xxx_spi->get_tx = cs->get_tx; if (cs->hw_mode != regval) { unsigned long flags; - __be32 __iomem *mode = &mpc83xx_spi->base->mode; + __be32 __iomem *mode = &mpc8xxx_spi->base->mode; regval = cs->hw_mode; /* Turn off IRQs locally to minimize time that @@ -186,8 +185,8 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) */ local_irq_save(flags); /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); - mpc83xx_spi_write_reg(mode, regval); + mpc8xxx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); + mpc8xxx_spi_write_reg(mode, regval); local_irq_restore(flags); } if (pdata->cs_control) @@ -196,15 +195,15 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value) } static -int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) +int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { - struct mpc83xx_spi *mpc83xx_spi; + struct mpc8xxx_spi *mpc8xxx_spi; u32 regval; u8 bits_per_word, pm; u32 hz; - struct spi_mpc83xx_cs *cs = spi->controller_state; + struct spi_mpc8xxx_cs *cs = spi->controller_state; - mpc83xx_spi = spi_master_get_devdata(spi->master); + mpc8xxx_spi = spi_master_get_devdata(spi->master); if (t) { bits_per_word = t->bits_per_word; @@ -229,26 +228,26 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) cs->rx_shift = 0; cs->tx_shift = 0; if (bits_per_word <= 8) { - cs->get_rx = mpc83xx_spi_rx_buf_u8; - cs->get_tx = mpc83xx_spi_tx_buf_u8; - if (mpc83xx_spi->qe_mode) { + cs->get_rx = mpc8xxx_spi_rx_buf_u8; + cs->get_tx = mpc8xxx_spi_tx_buf_u8; + if (mpc8xxx_spi->qe_mode) { cs->rx_shift = 16; cs->tx_shift = 24; } } else if (bits_per_word <= 16) { - cs->get_rx = mpc83xx_spi_rx_buf_u16; - cs->get_tx = mpc83xx_spi_tx_buf_u16; - if (mpc83xx_spi->qe_mode) { + cs->get_rx = mpc8xxx_spi_rx_buf_u16; + cs->get_tx = mpc8xxx_spi_tx_buf_u16; + if (mpc8xxx_spi->qe_mode) { cs->rx_shift = 16; cs->tx_shift = 16; } } else if (bits_per_word <= 32) { - cs->get_rx = mpc83xx_spi_rx_buf_u32; - cs->get_tx = mpc83xx_spi_tx_buf_u32; + cs->get_rx = mpc8xxx_spi_rx_buf_u32; + cs->get_tx = mpc8xxx_spi_tx_buf_u32; } else return -EINVAL; - if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) { + if (mpc8xxx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) { cs->tx_shift = 0; if (bits_per_word <= 8) cs->rx_shift = 8; @@ -256,10 +255,10 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) cs->rx_shift = 0; } - mpc83xx_spi->rx_shift = cs->rx_shift; - mpc83xx_spi->tx_shift = cs->tx_shift; - mpc83xx_spi->get_rx = cs->get_rx; - mpc83xx_spi->get_tx = cs->get_tx; + mpc8xxx_spi->rx_shift = cs->rx_shift; + mpc8xxx_spi->tx_shift = cs->tx_shift; + mpc8xxx_spi->get_rx = cs->get_rx; + mpc8xxx_spi->get_tx = cs->get_tx; if (bits_per_word == 32) bits_per_word = 0; @@ -272,25 +271,25 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) cs->hw_mode |= SPMODE_LEN(bits_per_word); - if ((mpc83xx_spi->spibrg / hz) > 64) { + if ((mpc8xxx_spi->spibrg / hz) > 64) { cs->hw_mode |= SPMODE_DIV16; - pm = mpc83xx_spi->spibrg / (hz * 64); - if (pm > 16) { - dev_err(&spi->dev, "Requested speed is too " - "low: %d Hz. Will use %d Hz instead.\n", - hz, mpc83xx_spi->spibrg / 1024); + pm = mpc8xxx_spi->spibrg / (hz * 64); + + WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. " + "Will use %d Hz instead.\n", dev_name(&spi->dev), + hz, mpc8xxx_spi->spibrg / 1024); + if (pm > 16) pm = 16; - } } else - pm = mpc83xx_spi->spibrg / (hz * 4); + pm = mpc8xxx_spi->spibrg / (hz * 4); if (pm) pm--; cs->hw_mode |= SPMODE_PM(pm); - regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + regval = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode); if (cs->hw_mode != regval) { unsigned long flags; - __be32 __iomem *mode = &mpc83xx_spi->base->mode; + __be32 __iomem *mode = &mpc8xxx_spi->base->mode; regval = cs->hw_mode; /* Turn off IRQs locally to minimize time @@ -298,22 +297,22 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) */ local_irq_save(flags); /* Turn off SPI unit prior changing mode */ - mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); - mpc83xx_spi_write_reg(mode, regval); + mpc8xxx_spi_write_reg(mode, regval & ~SPMODE_ENABLE); + mpc8xxx_spi_write_reg(mode, regval); local_irq_restore(flags); } return 0; } -static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) +static int mpc8xxx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) { - struct mpc83xx_spi *mpc83xx_spi; + struct mpc8xxx_spi *mpc8xxx_spi; u32 word, len, bits_per_word; - mpc83xx_spi = spi_master_get_devdata(spi->master); + mpc8xxx_spi = spi_master_get_devdata(spi->master); - mpc83xx_spi->tx = t->tx_buf; - mpc83xx_spi->rx = t->rx_buf; + mpc8xxx_spi->tx = t->tx_buf; + mpc8xxx_spi->rx = t->rx_buf; bits_per_word = spi->bits_per_word; if (t->bits_per_word) bits_per_word = t->bits_per_word; @@ -330,111 +329,106 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) return -EINVAL; len /= 2; } - mpc83xx_spi->count = len; + mpc8xxx_spi->count = len; - INIT_COMPLETION(mpc83xx_spi->done); + INIT_COMPLETION(mpc8xxx_spi->done); /* enable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, SPIM_NE); /* transmit word */ - word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); + word = mpc8xxx_spi->get_tx(mpc8xxx_spi); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->transmit, word); - wait_for_completion(&mpc83xx_spi->done); + wait_for_completion(&mpc8xxx_spi->done); /* disable rx ints */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0); - return mpc83xx_spi->count; + return mpc8xxx_spi->count; } -static void mpc83xx_spi_work(struct work_struct *work) +static void mpc8xxx_spi_do_one_msg(struct spi_message *m) { - struct mpc83xx_spi *mpc83xx_spi = - container_of(work, struct mpc83xx_spi, work); - - spin_lock_irq(&mpc83xx_spi->lock); - mpc83xx_spi->busy = 1; - while (!list_empty(&mpc83xx_spi->queue)) { - struct spi_message *m; - struct spi_device *spi; - struct spi_transfer *t = NULL; - unsigned cs_change; - int status, nsecs = 50; - - m = container_of(mpc83xx_spi->queue.next, - struct spi_message, queue); - list_del_init(&m->queue); - spin_unlock_irq(&mpc83xx_spi->lock); - - spi = m->spi; - cs_change = 1; - status = 0; - list_for_each_entry(t, &m->transfers, transfer_list) { - if (t->bits_per_word || t->speed_hz) { - /* Don't allow changes if CS is active */ - status = -EINVAL; - - if (cs_change) - status = mpc83xx_spi_setup_transfer(spi, t); - if (status < 0) - break; - } + struct spi_device *spi = m->spi; + struct spi_transfer *t; + unsigned int cs_change; + const int nsecs = 50; + int status; + + cs_change = 1; + status = 0; + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->bits_per_word || t->speed_hz) { + /* Don't allow changes if CS is active */ + status = -EINVAL; if (cs_change) - mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE); - cs_change = t->cs_change; - if (t->len) - status = mpc83xx_spi_bufs(spi, t); - if (status) { - status = -EMSGSIZE; + status = mpc8xxx_spi_setup_transfer(spi, t); + if (status < 0) break; - } - m->actual_length += t->len; - - if (t->delay_usecs) - udelay(t->delay_usecs); + } - if (cs_change) { - ndelay(nsecs); - mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); - } + if (cs_change) { + mpc8xxx_spi_chipselect(spi, BITBANG_CS_ACTIVE); + ndelay(nsecs); + } + cs_change = t->cs_change; + if (t->len) + status = mpc8xxx_spi_bufs(spi, t); + if (status) { + status = -EMSGSIZE; + break; } + m->actual_length += t->len; - m->status = status; - m->complete(m->context); + if (t->delay_usecs) + udelay(t->delay_usecs); - if (status || !cs_change) { + if (cs_change) { + ndelay(nsecs); + mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE); ndelay(nsecs); - mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); } + } - mpc83xx_spi_setup_transfer(spi, NULL); + m->status = status; + m->complete(m->context); - spin_lock_irq(&mpc83xx_spi->lock); + if (status || !cs_change) { + ndelay(nsecs); + mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE); } - mpc83xx_spi->busy = 0; - spin_unlock_irq(&mpc83xx_spi->lock); + + mpc8xxx_spi_setup_transfer(spi, NULL); } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_LSB_FIRST | SPI_LOOP) +static void mpc8xxx_spi_work(struct work_struct *work) +{ + struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi, + work); + + spin_lock_irq(&mpc8xxx_spi->lock); + while (!list_empty(&mpc8xxx_spi->queue)) { + struct spi_message *m = container_of(mpc8xxx_spi->queue.next, + struct spi_message, queue); + + list_del_init(&m->queue); + spin_unlock_irq(&mpc8xxx_spi->lock); + + mpc8xxx_spi_do_one_msg(m); + + spin_lock_irq(&mpc8xxx_spi->lock); + } + spin_unlock_irq(&mpc8xxx_spi->lock); +} -static int mpc83xx_spi_setup(struct spi_device *spi) +static int mpc8xxx_spi_setup(struct spi_device *spi) { - struct mpc83xx_spi *mpc83xx_spi; + struct mpc8xxx_spi *mpc8xxx_spi; int retval; u32 hw_mode; - struct spi_mpc83xx_cs *cs = spi->controller_state; - - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } + struct spi_mpc8xxx_cs *cs = spi->controller_state; if (!spi->max_speed_hz) return -EINVAL; @@ -445,13 +439,10 @@ static int mpc83xx_spi_setup(struct spi_device *spi) return -ENOMEM; spi->controller_state = cs; } - mpc83xx_spi = spi_master_get_devdata(spi->master); - - if (!spi->bits_per_word) - spi->bits_per_word = 8; + mpc8xxx_spi = spi_master_get_devdata(spi->master); hw_mode = cs->hw_mode; /* Save orginal settings */ - cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + cs->hw_mode = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode); /* mask out bits we are going to set */ cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH | SPMODE_REV | SPMODE_LOOP); @@ -465,45 +456,29 @@ static int mpc83xx_spi_setup(struct spi_device *spi) if (spi->mode & SPI_LOOP) cs->hw_mode |= SPMODE_LOOP; - retval = mpc83xx_spi_setup_transfer(spi, NULL); + retval = mpc8xxx_spi_setup_transfer(spi, NULL); if (retval < 0) { cs->hw_mode = hw_mode; /* Restore settings */ return retval; } - - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n", - __func__, spi->mode & (SPI_CPOL | SPI_CPHA), - spi->bits_per_word, spi->max_speed_hz); -#if 0 /* Don't think this is needed */ - /* NOTE we _need_ to call chipselect() early, ideally with adapter - * setup, unless the hardware defaults cooperate to avoid confusion - * between normal (active low) and inverted chipselects. - */ - - /* deselect chip (low or high) */ - spin_lock(&mpc83xx_spi->lock); - if (!mpc83xx_spi->busy) - mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); - spin_unlock(&mpc83xx_spi->lock); -#endif return 0; } -static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) +static irqreturn_t mpc8xxx_spi_irq(s32 irq, void *context_data) { - struct mpc83xx_spi *mpc83xx_spi = context_data; + struct mpc8xxx_spi *mpc8xxx_spi = context_data; u32 event; irqreturn_t ret = IRQ_NONE; /* Get interrupt events(tx/rx) */ - event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event); + event = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->event); /* We need handle RX first */ if (event & SPIE_NE) { - u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive); + u32 rx_data = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->receive); - if (mpc83xx_spi->rx) - mpc83xx_spi->get_rx(rx_data, mpc83xx_spi); + if (mpc8xxx_spi->rx) + mpc8xxx_spi->get_rx(rx_data, mpc8xxx_spi); ret = IRQ_HANDLED; } @@ -511,56 +486,56 @@ static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data) if ((event & SPIE_NF) == 0) /* spin until TX is done */ while (((event = - mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) & + mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->event)) & SPIE_NF) == 0) - cpu_relax(); + cpu_relax(); - mpc83xx_spi->count -= 1; - if (mpc83xx_spi->count) { - u32 word = mpc83xx_spi->get_tx(mpc83xx_spi); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); + mpc8xxx_spi->count -= 1; + if (mpc8xxx_spi->count) { + u32 word = mpc8xxx_spi->get_tx(mpc8xxx_spi); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->transmit, word); } else { - complete(&mpc83xx_spi->done); + complete(&mpc8xxx_spi->done); } /* Clear the events */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->event, event); return ret; } -static int mpc83xx_spi_transfer(struct spi_device *spi, +static int mpc8xxx_spi_transfer(struct spi_device *spi, struct spi_message *m) { - struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); + struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); unsigned long flags; m->actual_length = 0; m->status = -EINPROGRESS; - spin_lock_irqsave(&mpc83xx_spi->lock, flags); - list_add_tail(&m->queue, &mpc83xx_spi->queue); - queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work); - spin_unlock_irqrestore(&mpc83xx_spi->lock, flags); + spin_lock_irqsave(&mpc8xxx_spi->lock, flags); + list_add_tail(&m->queue, &mpc8xxx_spi->queue); + queue_work(mpc8xxx_spi->workqueue, &mpc8xxx_spi->work); + spin_unlock_irqrestore(&mpc8xxx_spi->lock, flags); return 0; } -static void mpc83xx_spi_cleanup(struct spi_device *spi) +static void mpc8xxx_spi_cleanup(struct spi_device *spi) { kfree(spi->controller_state); } static struct spi_master * __devinit -mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) +mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) { struct fsl_spi_platform_data *pdata = dev->platform_data; struct spi_master *master; - struct mpc83xx_spi *mpc83xx_spi; + struct mpc8xxx_spi *mpc8xxx_spi; u32 regval; int ret = 0; - master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi)); + master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); if (master == NULL) { ret = -ENOMEM; goto err; @@ -568,36 +543,40 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) dev_set_drvdata(dev, master); - master->setup = mpc83xx_spi_setup; - master->transfer = mpc83xx_spi_transfer; - master->cleanup = mpc83xx_spi_cleanup; - - mpc83xx_spi = spi_master_get_devdata(master); - mpc83xx_spi->qe_mode = pdata->qe_mode; - mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; - mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; - mpc83xx_spi->spibrg = pdata->sysclk; - - mpc83xx_spi->rx_shift = 0; - mpc83xx_spi->tx_shift = 0; - if (mpc83xx_spi->qe_mode) { - mpc83xx_spi->rx_shift = 16; - mpc83xx_spi->tx_shift = 24; + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH + | SPI_LSB_FIRST | SPI_LOOP; + + master->setup = mpc8xxx_spi_setup; + master->transfer = mpc8xxx_spi_transfer; + master->cleanup = mpc8xxx_spi_cleanup; + + mpc8xxx_spi = spi_master_get_devdata(master); + mpc8xxx_spi->qe_mode = pdata->qe_mode; + mpc8xxx_spi->get_rx = mpc8xxx_spi_rx_buf_u8; + mpc8xxx_spi->get_tx = mpc8xxx_spi_tx_buf_u8; + mpc8xxx_spi->spibrg = pdata->sysclk; + + mpc8xxx_spi->rx_shift = 0; + mpc8xxx_spi->tx_shift = 0; + if (mpc8xxx_spi->qe_mode) { + mpc8xxx_spi->rx_shift = 16; + mpc8xxx_spi->tx_shift = 24; } - init_completion(&mpc83xx_spi->done); + init_completion(&mpc8xxx_spi->done); - mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); - if (mpc83xx_spi->base == NULL) { + mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); + if (mpc8xxx_spi->base == NULL) { ret = -ENOMEM; goto put_master; } - mpc83xx_spi->irq = irq; + mpc8xxx_spi->irq = irq; /* Register for SPI Interrupt */ - ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, - 0, "mpc83xx_spi", mpc83xx_spi); + ret = request_irq(mpc8xxx_spi->irq, mpc8xxx_spi_irq, + 0, "mpc8xxx_spi", mpc8xxx_spi); if (ret != 0) goto unmap_io; @@ -606,25 +585,25 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) master->num_chipselect = pdata->max_chipselect; /* SPI controller initializations */ - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0); - mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, 0); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->command, 0); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->event, 0xffffffff); /* Enable SPI interface */ regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; if (pdata->qe_mode) regval |= SPMODE_OP; - mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); - spin_lock_init(&mpc83xx_spi->lock); - init_completion(&mpc83xx_spi->done); - INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work); - INIT_LIST_HEAD(&mpc83xx_spi->queue); + mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, regval); + spin_lock_init(&mpc8xxx_spi->lock); + init_completion(&mpc8xxx_spi->done); + INIT_WORK(&mpc8xxx_spi->work, mpc8xxx_spi_work); + INIT_LIST_HEAD(&mpc8xxx_spi->queue); - mpc83xx_spi->workqueue = create_singlethread_workqueue( + mpc8xxx_spi->workqueue = create_singlethread_workqueue( dev_name(master->dev.parent)); - if (mpc83xx_spi->workqueue == NULL) { + if (mpc8xxx_spi->workqueue == NULL) { ret = -EBUSY; goto free_irq; } @@ -634,57 +613,57 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) goto unreg_master; printk(KERN_INFO - "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n", - dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq); + "%s: MPC8xxx SPI Controller driver at 0x%p (irq = %d)\n", + dev_name(dev), mpc8xxx_spi->base, mpc8xxx_spi->irq); return master; unreg_master: - destroy_workqueue(mpc83xx_spi->workqueue); + destroy_workqueue(mpc8xxx_spi->workqueue); free_irq: - free_irq(mpc83xx_spi->irq, mpc83xx_spi); + free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); unmap_io: - iounmap(mpc83xx_spi->base); + iounmap(mpc8xxx_spi->base); put_master: spi_master_put(master); err: return ERR_PTR(ret); } -static int __devexit mpc83xx_spi_remove(struct device *dev) +static int __devexit mpc8xxx_spi_remove(struct device *dev) { - struct mpc83xx_spi *mpc83xx_spi; + struct mpc8xxx_spi *mpc8xxx_spi; struct spi_master *master; master = dev_get_drvdata(dev); - mpc83xx_spi = spi_master_get_devdata(master); + mpc8xxx_spi = spi_master_get_devdata(master); - flush_workqueue(mpc83xx_spi->workqueue); - destroy_workqueue(mpc83xx_spi->workqueue); + flush_workqueue(mpc8xxx_spi->workqueue); + destroy_workqueue(mpc8xxx_spi->workqueue); spi_unregister_master(master); - free_irq(mpc83xx_spi->irq, mpc83xx_spi); - iounmap(mpc83xx_spi->base); + free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); + iounmap(mpc8xxx_spi->base); return 0; } -struct mpc83xx_spi_probe_info { +struct mpc8xxx_spi_probe_info { struct fsl_spi_platform_data pdata; int *gpios; bool *alow_flags; }; -static struct mpc83xx_spi_probe_info * +static struct mpc8xxx_spi_probe_info * to_of_pinfo(struct fsl_spi_platform_data *pdata) { - return container_of(pdata, struct mpc83xx_spi_probe_info, pdata); + return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata); } -static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) +static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on) { struct device *dev = spi->dev.parent; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); + struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); u16 cs = spi->chip_select; int gpio = pinfo->gpios[cs]; bool alow = pinfo->alow_flags[cs]; @@ -692,11 +671,11 @@ static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) gpio_set_value(gpio, on ^ alow); } -static int of_mpc83xx_spi_get_chipselects(struct device *dev) +static int of_mpc8xxx_spi_get_chipselects(struct device *dev) { struct device_node *np = dev_archdata_get_node(&dev->archdata); struct fsl_spi_platform_data *pdata = dev->platform_data; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata); + struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); unsigned int ngpios; int i = 0; int ret; @@ -752,7 +731,7 @@ static int of_mpc83xx_spi_get_chipselects(struct device *dev) } pdata->max_chipselect = ngpios; - pdata->cs_control = mpc83xx_spi_cs_control; + pdata->cs_control = mpc8xxx_spi_cs_control; return 0; @@ -771,10 +750,10 @@ err_alloc_flags: return ret; } -static int of_mpc83xx_spi_free_chipselects(struct device *dev) +static int of_mpc8xxx_spi_free_chipselects(struct device *dev) { struct fsl_spi_platform_data *pdata = dev->platform_data; - struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata); + struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); int i; if (!pinfo->gpios) @@ -790,12 +769,12 @@ static int of_mpc83xx_spi_free_chipselects(struct device *dev) return 0; } -static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev, +static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->node; - struct mpc83xx_spi_probe_info *pinfo; + struct mpc8xxx_spi_probe_info *pinfo; struct fsl_spi_platform_data *pdata; struct spi_master *master; struct resource mem; @@ -827,7 +806,7 @@ static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev, if (prop && !strcmp(prop, "cpu-qe")) pdata->qe_mode = 1; - ret = of_mpc83xx_spi_get_chipselects(dev); + ret = of_mpc8xxx_spi_get_chipselects(dev); if (ret) goto err; @@ -841,7 +820,7 @@ static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev, goto err; } - master = mpc83xx_spi_probe(dev, &mem, irq.start); + master = mpc8xxx_spi_probe(dev, &mem, irq.start); if (IS_ERR(master)) { ret = PTR_ERR(master); goto err; @@ -852,34 +831,34 @@ static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev, return 0; err: - of_mpc83xx_spi_free_chipselects(dev); + of_mpc8xxx_spi_free_chipselects(dev); err_clk: kfree(pinfo); return ret; } -static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev) +static int __devexit of_mpc8xxx_spi_remove(struct of_device *ofdev) { int ret; - ret = mpc83xx_spi_remove(&ofdev->dev); + ret = mpc8xxx_spi_remove(&ofdev->dev); if (ret) return ret; - of_mpc83xx_spi_free_chipselects(&ofdev->dev); + of_mpc8xxx_spi_free_chipselects(&ofdev->dev); return 0; } -static const struct of_device_id of_mpc83xx_spi_match[] = { +static const struct of_device_id of_mpc8xxx_spi_match[] = { { .compatible = "fsl,spi" }, {}, }; -MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match); +MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match); -static struct of_platform_driver of_mpc83xx_spi_driver = { - .name = "mpc83xx_spi", - .match_table = of_mpc83xx_spi_match, - .probe = of_mpc83xx_spi_probe, - .remove = __devexit_p(of_mpc83xx_spi_remove), +static struct of_platform_driver of_mpc8xxx_spi_driver = { + .name = "mpc8xxx_spi", + .match_table = of_mpc8xxx_spi_match, + .probe = of_mpc8xxx_spi_probe, + .remove = __devexit_p(of_mpc8xxx_spi_remove), }; #ifdef CONFIG_MPC832x_RDB @@ -890,7 +869,7 @@ static struct of_platform_driver of_mpc83xx_spi_driver = { * tree can work with OpenFirmware driver. But for now we support old trees * as well. */ -static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev) +static int __devinit plat_mpc8xxx_spi_probe(struct platform_device *pdev) { struct resource *mem; unsigned int irq; @@ -907,23 +886,23 @@ static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev) if (!irq) return -EINVAL; - master = mpc83xx_spi_probe(&pdev->dev, mem, irq); + master = mpc8xxx_spi_probe(&pdev->dev, mem, irq); if (IS_ERR(master)) return PTR_ERR(master); return 0; } -static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev) +static int __devexit plat_mpc8xxx_spi_remove(struct platform_device *pdev) { - return mpc83xx_spi_remove(&pdev->dev); + return mpc8xxx_spi_remove(&pdev->dev); } -MODULE_ALIAS("platform:mpc83xx_spi"); -static struct platform_driver mpc83xx_spi_driver = { - .probe = plat_mpc83xx_spi_probe, - .remove = __exit_p(plat_mpc83xx_spi_remove), +MODULE_ALIAS("platform:mpc8xxx_spi"); +static struct platform_driver mpc8xxx_spi_driver = { + .probe = plat_mpc8xxx_spi_probe, + .remove = __exit_p(plat_mpc8xxx_spi_remove), .driver = { - .name = "mpc83xx_spi", + .name = "mpc8xxx_spi", .owner = THIS_MODULE, }, }; @@ -932,35 +911,35 @@ static bool legacy_driver_failed; static void __init legacy_driver_register(void) { - legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver); + legacy_driver_failed = platform_driver_register(&mpc8xxx_spi_driver); } static void __exit legacy_driver_unregister(void) { if (legacy_driver_failed) return; - platform_driver_unregister(&mpc83xx_spi_driver); + platform_driver_unregister(&mpc8xxx_spi_driver); } #else static void __init legacy_driver_register(void) {} static void __exit legacy_driver_unregister(void) {} #endif /* CONFIG_MPC832x_RDB */ -static int __init mpc83xx_spi_init(void) +static int __init mpc8xxx_spi_init(void) { legacy_driver_register(); - return of_register_platform_driver(&of_mpc83xx_spi_driver); + return of_register_platform_driver(&of_mpc8xxx_spi_driver); } -static void __exit mpc83xx_spi_exit(void) +static void __exit mpc8xxx_spi_exit(void) { - of_unregister_platform_driver(&of_mpc83xx_spi_driver); + of_unregister_platform_driver(&of_mpc8xxx_spi_driver); legacy_driver_unregister(); } -module_init(mpc83xx_spi_init); -module_exit(mpc83xx_spi_exit); +module_init(mpc8xxx_spi_init); +module_exit(mpc8xxx_spi_exit); MODULE_AUTHOR("Kumar Gala"); -MODULE_DESCRIPTION("Simple MPC83xx SPI Driver"); +MODULE_DESCRIPTION("Simple MPC8xxx SPI Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index b3ebc1d0f85f..3f3119d760db 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -111,29 +111,32 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi, unsigned int bpw; unsigned int hz; unsigned int div; + unsigned long clk; bpw = t ? t->bits_per_word : spi->bits_per_word; hz = t ? t->speed_hz : spi->max_speed_hz; + if (!bpw) + bpw = 8; + + if (!hz) + hz = spi->max_speed_hz; + if (bpw != 8) { dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); return -EINVAL; } - div = clk_get_rate(hw->clk) / hz; - - /* is clk = pclk / (2 * (pre+1)), or is it - * clk = (pclk * 2) / ( pre + 1) */ - - div /= 2; - - if (div > 0) - div -= 1; + clk = clk_get_rate(hw->clk); + div = DIV_ROUND_UP(clk, hz * 2) - 1; if (div > 255) div = 255; - dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz); + dev_dbg(&spi->dev, "setting pre-scaler to %d (wanted %d, got %ld)\n", + div, hz, clk / (2 * (div + 1))); + + writeb(div, hw->regs + S3C2410_SPPRE); spin_lock(&hw->bitbang.lock); @@ -146,32 +149,16 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi, return 0; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) - static int s3c24xx_spi_setup(struct spi_device *spi) { int ret; - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - ret = s3c24xx_spi_setupxfer(spi, NULL); if (ret < 0) { dev_err(&spi->dev, "setupxfer returned %d\n", ret); return ret; } - dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", - __func__, spi->mode, spi->bits_per_word, - spi->max_speed_hz); - return 0; } @@ -290,6 +277,9 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) /* setup the master state. */ + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + master->num_chipselect = hw->pdata->num_cs; master->bus_num = pdata->bus_num; diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c index 29cbb065618a..96057de133ad 100644 --- a/drivers/spi/spi_txx9.c +++ b/drivers/spi/spi_txx9.c @@ -110,23 +110,17 @@ static void txx9spi_cs_func(struct spi_device *spi, struct txx9spi *c, ndelay(cs_delay); /* CS Setup Time / CS Recovery Time */ } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CS_HIGH|SPI_CPOL|SPI_CPHA) - static int txx9spi_setup(struct spi_device *spi) { struct txx9spi *c = spi_master_get_devdata(spi->master); u8 bits_per_word; - if (spi->mode & ~MODEBITS) - return -EINVAL; - if (!spi->max_speed_hz || spi->max_speed_hz > c->max_speed_hz || spi->max_speed_hz < c->min_speed_hz) return -EINVAL; - bits_per_word = spi->bits_per_word ? : 8; + bits_per_word = spi->bits_per_word; if (bits_per_word != 8 && bits_per_word != 16) return -EINVAL; @@ -414,6 +408,9 @@ static int __init txx9spi_probe(struct platform_device *dev) (unsigned long long)res->start, irq, (c->baseclk + 500000) / 1000000); + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; + master->bus_num = dev->id; master->setup = txx9spi_setup; master->transfer = txx9spi_transfer; diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 5d869c4d3eb2..606e7a40a8da 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -58,15 +58,20 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; /* Bit masks for spi_device.mode management. Note that incorrect - * settings for CS_HIGH and 3WIRE can cause *lots* of trouble for other - * devices on a shared bus: CS_HIGH, because this device will be - * active when it shouldn't be; 3WIRE, because when active it won't - * behave as it should. + * settings for some settings can cause *lots* of trouble for other + * devices on a shared bus: * - * REVISIT should changing those two modes be privileged? + * - CS_HIGH ... this device will be active when it shouldn't be + * - 3WIRE ... when active, it won't behave as it should + * - NO_CS ... there will be no explicit message boundaries; this + * is completely incompatible with the shared bus model + * - READY ... transfers may proceed when they shouldn't. + * + * REVISIT should changing those flags be privileged? */ #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ - | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) + | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ + | SPI_NO_CS | SPI_READY) struct spidev_data { dev_t devt; diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 494d3f756e29..46b8c5c2f45e 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -158,9 +158,6 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi, return 0; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA) - static int xilinx_spi_setup(struct spi_device *spi) { struct spi_bitbang *bitbang; @@ -170,22 +167,10 @@ static int xilinx_spi_setup(struct spi_device *spi) xspi = spi_master_get_devdata(spi->master); bitbang = &xspi->bitbang; - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if (spi->mode & ~MODEBITS) { - dev_err(&spi->dev, "%s, unsupported mode bits %x\n", - __func__, spi->mode & ~MODEBITS); - return -EINVAL; - } - retval = xilinx_spi_setup_transfer(spi, NULL); if (retval < 0) return retval; - dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", - __func__, spi->mode & MODEBITS, spi->bits_per_word, 0); - return 0; } @@ -333,6 +318,9 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev, goto put_master; } + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA; + xspi = spi_master_get_devdata(master); xspi->bitbang.master = spi_master_get(master); xspi->bitbang.chipselect = xilinx_spi_chipselect; |