diff options
Diffstat (limited to 'drivers/spi')
39 files changed, 1331 insertions, 625 deletions
| diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4887f317ea58..8b9c2a38d1cc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -88,6 +88,17 @@ config SPI_BCM2835  	  is for the regular SPI controller. Slave mode operation is not also  	  not supported. +config SPI_BCM2835AUX +	tristate "BCM2835 SPI auxiliary controller" +	depends on ARCH_BCM2835 || COMPILE_TEST +	depends on GPIOLIB +	help +	  This selects a driver for the Broadcom BCM2835 SPI aux master. + +	  The BCM2835 contains two types of SPI master controller; the +	  "universal SPI master", and the regular SPI controller. +	  This driver is for the universal/auxiliary SPI controller. +  config SPI_BFIN5XX  	tristate "SPI controller driver for ADI Blackfin5xx"  	depends on BLACKFIN && !BF60x @@ -125,7 +136,7 @@ config SPI_BCM53XX  config SPI_BCM63XX  	tristate "Broadcom BCM63xx SPI controller" -	depends on BCM63XX +	depends on BCM63XX || COMPILE_TEST  	help            Enable support for the SPI controller on the Broadcom BCM63xx SoCs. @@ -304,7 +315,7 @@ config SPI_FSL_SPI  config SPI_FSL_DSPI  	tristate "Freescale DSPI controller"  	select REGMAP_MMIO -	depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST +	depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST  	help  	  This enables support for the Freescale DSPI controller in master  	  mode. VF610 platform uses the controller. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 6a7f6f9d0d1c..31fb7fb2a0b6 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o  obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o  obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o  obj-$(CONFIG_SPI_BCM2835)		+= spi-bcm2835.o +obj-$(CONFIG_SPI_BCM2835AUX)		+= spi-bcm2835aux.o  obj-$(CONFIG_SPI_BCM53XX)		+= spi-bcm53xx.o  obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o  obj-$(CONFIG_SPI_BCM63XX_HSSPI)		+= spi-bcm63xx-hsspi.o diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index bf1f9b32c597..6165bf21d427 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -240,14 +240,9 @@ static int ath79_spi_probe(struct platform_device *pdev)  	sp->bitbang.flags = SPI_CS_HIGH;  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (r == NULL) { -		ret = -ENOENT; -		goto err_put_master; -	} - -	sp->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); -	if (!sp->base) { -		ret = -ENXIO; +	sp->base = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(sp->base)) { +		ret = PTR_ERR(sp->base);  		goto err_put_master;  	} diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 63318e2afba1..aebad36391c9 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -773,7 +773,8 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,  	*plen = len; -	if (atmel_spi_dma_slave_config(as, &slave_config, 8)) +	if (atmel_spi_dma_slave_config(as, &slave_config, +				       xfer->bits_per_word))  		goto err_exit;  	/* Send both scatterlists */ @@ -871,14 +872,7 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,  	 * Calculate the lowest divider that satisfies the  	 * constraint, assuming div32/fdiv/mbz == 0.  	 */ -	if (xfer->speed_hz) -		scbr = DIV_ROUND_UP(bus_hz, xfer->speed_hz); -	else -		/* -		 * This can happend if max_speed is null. -		 * In this case, we set the lowest possible speed -		 */ -		scbr = 0xff; +	scbr = DIV_ROUND_UP(bus_hz, xfer->speed_hz);  	/*  	 * If the resulting divider doesn't fit into the @@ -1300,14 +1294,12 @@ static int atmel_spi_one_transfer(struct spi_master *master,  		return -EINVAL;  	} -	if (xfer->bits_per_word) { -		asd = spi->controller_state; -		bits = (asd->csr >> 4) & 0xf; -		if (bits != xfer->bits_per_word - 8) { -			dev_dbg(&spi->dev, +	asd = spi->controller_state; +	bits = (asd->csr >> 4) & 0xf; +	if (bits != xfer->bits_per_word - 8) { +		dev_dbg(&spi->dev,  			"you can't yet change bits_per_word in transfers\n"); -			return -ENOPROTOOPT; -		} +		return -ENOPROTOOPT;  	}  	/* diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index f45e085c01a6..afd239d6dec1 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -233,13 +233,12 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)  	unsigned bpw, hz;  	u32 cfg, stat; -	bpw = spi->bits_per_word; -	hz = spi->max_speed_hz;  	if (t) { -		if (t->bits_per_word) -			bpw = t->bits_per_word; -		if (t->speed_hz) -			hz = t->speed_hz; +		bpw = t->bits_per_word; +		hz = t->speed_hz; +	} else { +		bpw = spi->bits_per_word; +		hz = spi->max_speed_hz;  	}  	if (!hz) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 3e8eeb23d4e9..cf04960cc3e6 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -777,7 +777,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)  		goto out_master_put;  	} -	bs->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); +	bs->irq = platform_get_irq(pdev, 0);  	if (bs->irq <= 0) {  		dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);  		err = bs->irq ? bs->irq : -ENODEV; @@ -786,6 +786,12 @@ static int bcm2835_spi_probe(struct platform_device *pdev)  	clk_prepare_enable(bs->clk); +	bcm2835_dma_init(master, &pdev->dev); + +	/* initialise the hardware with the default polarities */ +	bcm2835_wr(bs, BCM2835_SPI_CS, +		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); +  	err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0,  			       dev_name(&pdev->dev), master);  	if (err) { @@ -793,12 +799,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev)  		goto out_clk_disable;  	} -	bcm2835_dma_init(master, &pdev->dev); - -	/* initialise the hardware with the default polarities */ -	bcm2835_wr(bs, BCM2835_SPI_CS, -		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); -  	err = devm_spi_register_master(&pdev->dev, master);  	if (err) {  		dev_err(&pdev->dev, "could not register SPI master: %d\n", err); diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c new file mode 100644 index 000000000000..7de6f8472a81 --- /dev/null +++ b/drivers/spi/spi-bcm2835aux.c @@ -0,0 +1,512 @@ +/* + * Driver for Broadcom BCM2835 auxiliary SPI Controllers + * + * the driver does not rely on the native chipselects at all + * but only uses the gpio type chipselects + * + * Based on: spi-bcm2835.c + * + * Copyright (C) 2015 Martin Sperl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <linux/of_irq.h> +#include <linux/regmap.h> +#include <linux/spi/spi.h> +#include <linux/spinlock.h> + +/* + * spi register defines + * + * note there is garbage in the "official" documentation, + * so some data is taken from the file: + *   brcm_usrlib/dag/vmcsx/vcinclude/bcm2708_chip/aux_io.h + * inside of: + *   http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz + */ + +/* SPI register offsets */ +#define BCM2835_AUX_SPI_CNTL0	0x00 +#define BCM2835_AUX_SPI_CNTL1	0x04 +#define BCM2835_AUX_SPI_STAT	0x08 +#define BCM2835_AUX_SPI_PEEK	0x0C +#define BCM2835_AUX_SPI_IO	0x20 +#define BCM2835_AUX_SPI_TXHOLD	0x30 + +/* Bitfields in CNTL0 */ +#define BCM2835_AUX_SPI_CNTL0_SPEED	0xFFF00000 +#define BCM2835_AUX_SPI_CNTL0_SPEED_MAX	0xFFF +#define BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT	20 +#define BCM2835_AUX_SPI_CNTL0_CS	0x000E0000 +#define BCM2835_AUX_SPI_CNTL0_POSTINPUT	0x00010000 +#define BCM2835_AUX_SPI_CNTL0_VAR_CS	0x00008000 +#define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH	0x00004000 +#define BCM2835_AUX_SPI_CNTL0_DOUTHOLD	0x00003000 +#define BCM2835_AUX_SPI_CNTL0_ENABLE	0x00000800 +#define BCM2835_AUX_SPI_CNTL0_CPHA_IN	0x00000400 +#define BCM2835_AUX_SPI_CNTL0_CLEARFIFO	0x00000200 +#define BCM2835_AUX_SPI_CNTL0_CPHA_OUT	0x00000100 +#define BCM2835_AUX_SPI_CNTL0_CPOL	0x00000080 +#define BCM2835_AUX_SPI_CNTL0_MSBF_OUT	0x00000040 +#define BCM2835_AUX_SPI_CNTL0_SHIFTLEN	0x0000003F + +/* Bitfields in CNTL1 */ +#define BCM2835_AUX_SPI_CNTL1_CSHIGH	0x00000700 +#define BCM2835_AUX_SPI_CNTL1_IDLE	0x00000080 +#define BCM2835_AUX_SPI_CNTL1_TXEMPTY	0x00000040 +#define BCM2835_AUX_SPI_CNTL1_MSBF_IN	0x00000002 +#define BCM2835_AUX_SPI_CNTL1_KEEP_IN	0x00000001 + +/* Bitfields in STAT */ +#define BCM2835_AUX_SPI_STAT_TX_LVL	0xFF000000 +#define BCM2835_AUX_SPI_STAT_RX_LVL	0x00FF0000 +#define BCM2835_AUX_SPI_STAT_TX_FULL	0x00000400 +#define BCM2835_AUX_SPI_STAT_TX_EMPTY	0x00000200 +#define BCM2835_AUX_SPI_STAT_RX_FULL	0x00000100 +#define BCM2835_AUX_SPI_STAT_RX_EMPTY	0x00000080 +#define BCM2835_AUX_SPI_STAT_BUSY	0x00000040 +#define BCM2835_AUX_SPI_STAT_BITCOUNT	0x0000003F + +/* timeout values */ +#define BCM2835_AUX_SPI_POLLING_LIMIT_US	30 +#define BCM2835_AUX_SPI_POLLING_JIFFIES		2 + +#define BCM2835_AUX_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ +				  | SPI_NO_CS) + +struct bcm2835aux_spi { +	void __iomem *regs; +	struct clk *clk; +	int irq; +	u32 cntl[2]; +	const u8 *tx_buf; +	u8 *rx_buf; +	int tx_len; +	int rx_len; +	int pending; +}; + +static inline u32 bcm2835aux_rd(struct bcm2835aux_spi *bs, unsigned reg) +{ +	return readl(bs->regs + reg); +} + +static inline void bcm2835aux_wr(struct bcm2835aux_spi *bs, unsigned reg, +				 u32 val) +{ +	writel(val, bs->regs + reg); +} + +static inline void bcm2835aux_rd_fifo(struct bcm2835aux_spi *bs) +{ +	u32 data; +	int count = min(bs->rx_len, 3); + +	data = bcm2835aux_rd(bs, BCM2835_AUX_SPI_IO); +	if (bs->rx_buf) { +		switch (count) { +		case 4: +			*bs->rx_buf++ = (data >> 24) & 0xff; +			/* fallthrough */ +		case 3: +			*bs->rx_buf++ = (data >> 16) & 0xff; +			/* fallthrough */ +		case 2: +			*bs->rx_buf++ = (data >> 8) & 0xff; +			/* fallthrough */ +		case 1: +			*bs->rx_buf++ = (data >> 0) & 0xff; +			/* fallthrough - no default */ +		} +	} +	bs->rx_len -= count; +	bs->pending -= count; +} + +static inline void bcm2835aux_wr_fifo(struct bcm2835aux_spi *bs) +{ +	u32 data; +	u8 byte; +	int count; +	int i; + +	/* gather up to 3 bytes to write to the FIFO */ +	count = min(bs->tx_len, 3); +	data = 0; +	for (i = 0; i < count; i++) { +		byte = bs->tx_buf ? *bs->tx_buf++ : 0; +		data |= byte << (8 * (2 - i)); +	} + +	/* and set the variable bit-length */ +	data |= (count * 8) << 24; + +	/* and decrement length */ +	bs->tx_len -= count; +	bs->pending += count; + +	/* write to the correct TX-register */ +	if (bs->tx_len) +		bcm2835aux_wr(bs, BCM2835_AUX_SPI_TXHOLD, data); +	else +		bcm2835aux_wr(bs, BCM2835_AUX_SPI_IO, data); +} + +static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs) +{ +	/* disable spi clearing fifo and interrupts */ +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, 0); +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, +		      BCM2835_AUX_SPI_CNTL0_CLEARFIFO); +} + +static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) +{ +	struct spi_master *master = dev_id; +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); +	irqreturn_t ret = IRQ_NONE; + +	/* check if we have data to read */ +	while (bs->rx_len && +	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & +		  BCM2835_AUX_SPI_STAT_RX_EMPTY))) { +		bcm2835aux_rd_fifo(bs); +		ret = IRQ_HANDLED; +	} + +	/* check if we have data to write */ +	while (bs->tx_len && +	       (bs->pending < 12) && +	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & +		  BCM2835_AUX_SPI_STAT_TX_FULL))) { +		bcm2835aux_wr_fifo(bs); +		ret = IRQ_HANDLED; +	} + +	/* and check if we have reached "done" */ +	while (bs->rx_len && +	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & +		  BCM2835_AUX_SPI_STAT_BUSY))) { +		bcm2835aux_rd_fifo(bs); +		ret = IRQ_HANDLED; +	} + +	/* and if rx_len is 0 then wake up completion and disable spi */ +	if (!bs->rx_len) { +		bcm2835aux_spi_reset_hw(bs); +		complete(&master->xfer_completion); +	} + +	/* and return */ +	return ret; +} + +static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master, +					     struct spi_device *spi, +					     struct spi_transfer *tfr) +{ +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + +	/* enable interrupts */ +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] | +		BCM2835_AUX_SPI_CNTL1_TXEMPTY | +		BCM2835_AUX_SPI_CNTL1_IDLE); + +	/* and wait for finish... */ +	return 1; +} + +static int bcm2835aux_spi_transfer_one_irq(struct spi_master *master, +					   struct spi_device *spi, +					   struct spi_transfer *tfr) +{ +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + +	/* fill in registers and fifos before enabling interrupts */ +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); + +	/* fill in tx fifo with data before enabling interrupts */ +	while ((bs->tx_len) && +	       (bs->pending < 12) && +	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & +		  BCM2835_AUX_SPI_STAT_TX_FULL))) { +		bcm2835aux_wr_fifo(bs); +	} + +	/* now run the interrupt mode */ +	return __bcm2835aux_spi_transfer_one_irq(master, spi, tfr); +} + +static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, +					    struct spi_device *spi, +					struct spi_transfer *tfr) +{ +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); +	unsigned long timeout; +	u32 stat; + +	/* configure spi */ +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); +	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); + +	/* set the timeout */ +	timeout = jiffies + BCM2835_AUX_SPI_POLLING_JIFFIES; + +	/* loop until finished the transfer */ +	while (bs->rx_len) { +		/* read status */ +		stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT); + +		/* fill in tx fifo with remaining data */ +		if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) { +			bcm2835aux_wr_fifo(bs); +			continue; +		} + +		/* read data from fifo for both cases */ +		if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) { +			bcm2835aux_rd_fifo(bs); +			continue; +		} +		if (!(stat & BCM2835_AUX_SPI_STAT_BUSY)) { +			bcm2835aux_rd_fifo(bs); +			continue; +		} + +		/* there is still data pending to read check the timeout */ +		if (bs->rx_len && time_after(jiffies, timeout)) { +			dev_dbg_ratelimited(&spi->dev, +					    "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n", +					    jiffies - timeout, +					    bs->tx_len, bs->rx_len); +			/* forward to interrupt handler */ +			return __bcm2835aux_spi_transfer_one_irq(master, +							       spi, tfr); +		} +	} + +	/* Transfer complete - reset SPI HW */ +	bcm2835aux_spi_reset_hw(bs); + +	/* and return without waiting for completion */ +	return 0; +} + +static int bcm2835aux_spi_transfer_one(struct spi_master *master, +				       struct spi_device *spi, +				       struct spi_transfer *tfr) +{ +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); +	unsigned long spi_hz, clk_hz, speed; +	unsigned long spi_used_hz; +	unsigned long long xfer_time_us; + +	/* calculate the registers to handle +	 * +	 * note that we use the variable data mode, which +	 * is not optimal for longer transfers as we waste registers +	 * resulting (potentially) in more interrupts when transferring +	 * more than 12 bytes +	 */ +	bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE | +		      BCM2835_AUX_SPI_CNTL0_VAR_WIDTH | +		      BCM2835_AUX_SPI_CNTL0_MSBF_OUT; +	bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; + +	/* set clock */ +	spi_hz = tfr->speed_hz; +	clk_hz = clk_get_rate(bs->clk); + +	if (spi_hz >= clk_hz / 2) { +		speed = 0; +	} else if (spi_hz) { +		speed = DIV_ROUND_UP(clk_hz, 2 * spi_hz) - 1; +		if (speed >  BCM2835_AUX_SPI_CNTL0_SPEED_MAX) +			speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; +	} else { /* the slowest we can go */ +		speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX; +	} +	bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT; + +	spi_used_hz = clk_hz / (2 * (speed + 1)); + +	/* handle all the modes */ +	if (spi->mode & SPI_CPOL) +		bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; +	if (spi->mode & SPI_CPHA) +		bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT | +			       BCM2835_AUX_SPI_CNTL0_CPHA_IN; + +	/* set transmit buffers and length */ +	bs->tx_buf = tfr->tx_buf; +	bs->rx_buf = tfr->rx_buf; +	bs->tx_len = tfr->len; +	bs->rx_len = tfr->len; +	bs->pending = 0; + +	/* calculate the estimated time in us the transfer runs +	 * note that there are are 2 idle clocks after each +	 * chunk getting transferred - in our case the chunk size +	 * is 3 bytes, so we approximate this by 9 bits/byte +	 */ +	xfer_time_us = tfr->len * 9 * 1000000; +	do_div(xfer_time_us, spi_used_hz); + +	/* run in polling mode for short transfers */ +	if (xfer_time_us < BCM2835_AUX_SPI_POLLING_LIMIT_US) +		return bcm2835aux_spi_transfer_one_poll(master, spi, tfr); + +	/* run in interrupt mode for all others */ +	return bcm2835aux_spi_transfer_one_irq(master, spi, tfr); +} + +static void bcm2835aux_spi_handle_err(struct spi_master *master, +				      struct spi_message *msg) +{ +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + +	bcm2835aux_spi_reset_hw(bs); +} + +static int bcm2835aux_spi_probe(struct platform_device *pdev) +{ +	struct spi_master *master; +	struct bcm2835aux_spi *bs; +	struct resource *res; +	unsigned long clk_hz; +	int err; + +	master = spi_alloc_master(&pdev->dev, sizeof(*bs)); +	if (!master) { +		dev_err(&pdev->dev, "spi_alloc_master() failed\n"); +		return -ENOMEM; +	} + +	platform_set_drvdata(pdev, master); +	master->mode_bits = BCM2835_AUX_SPI_MODE_BITS; +	master->bits_per_word_mask = SPI_BPW_MASK(8); +	master->num_chipselect = -1; +	master->transfer_one = bcm2835aux_spi_transfer_one; +	master->handle_err = bcm2835aux_spi_handle_err; +	master->dev.of_node = pdev->dev.of_node; + +	bs = spi_master_get_devdata(master); + +	/* the main area */ +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	bs->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(bs->regs)) { +		err = PTR_ERR(bs->regs); +		goto out_master_put; +	} + +	bs->clk = devm_clk_get(&pdev->dev, NULL); +	if ((!bs->clk) || (IS_ERR(bs->clk))) { +		err = PTR_ERR(bs->clk); +		dev_err(&pdev->dev, "could not get clk: %d\n", err); +		goto out_master_put; +	} + +	bs->irq = platform_get_irq(pdev, 0); +	if (bs->irq <= 0) { +		dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); +		err = bs->irq ? bs->irq : -ENODEV; +		goto out_master_put; +	} + +	/* this also enables the HW block */ +	err = clk_prepare_enable(bs->clk); +	if (err) { +		dev_err(&pdev->dev, "could not prepare clock: %d\n", err); +		goto out_master_put; +	} + +	/* just checking if the clock returns a sane value */ +	clk_hz = clk_get_rate(bs->clk); +	if (!clk_hz) { +		dev_err(&pdev->dev, "clock returns 0 Hz\n"); +		err = -ENODEV; +		goto out_clk_disable; +	} + +	/* reset SPI-HW block */ +	bcm2835aux_spi_reset_hw(bs); + +	err = devm_request_irq(&pdev->dev, bs->irq, +			       bcm2835aux_spi_interrupt, +			       IRQF_SHARED, +			       dev_name(&pdev->dev), master); +	if (err) { +		dev_err(&pdev->dev, "could not request IRQ: %d\n", err); +		goto out_clk_disable; +	} + +	err = devm_spi_register_master(&pdev->dev, master); +	if (err) { +		dev_err(&pdev->dev, "could not register SPI master: %d\n", err); +		goto out_clk_disable; +	} + +	return 0; + +out_clk_disable: +	clk_disable_unprepare(bs->clk); +out_master_put: +	spi_master_put(master); +	return err; +} + +static int bcm2835aux_spi_remove(struct platform_device *pdev) +{ +	struct spi_master *master = platform_get_drvdata(pdev); +	struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + +	bcm2835aux_spi_reset_hw(bs); + +	/* disable the HW block by releasing the clock */ +	clk_disable_unprepare(bs->clk); + +	return 0; +} + +static const struct of_device_id bcm2835aux_spi_match[] = { +	{ .compatible = "brcm,bcm2835-aux-spi", }, +	{} +}; +MODULE_DEVICE_TABLE(of, bcm2835aux_spi_match); + +static struct platform_driver bcm2835aux_spi_driver = { +	.driver		= { +		.name		= "spi-bcm2835aux", +		.of_match_table	= bcm2835aux_spi_match, +	}, +	.probe		= bcm2835aux_spi_probe, +	.remove		= bcm2835aux_spi_remove, +}; +module_platform_driver(bcm2835aux_spi_driver); + +MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2835 aux"); +MODULE_AUTHOR("Martin Sperl <[email protected]>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c index 1520554978a3..cc3f938f0a6b 100644 --- a/drivers/spi/spi-bcm53xx.c +++ b/drivers/spi/spi-bcm53xx.c @@ -247,28 +247,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core)  	if (err) {  		spi_master_put(master);  		bcma_set_drvdata(core, NULL); -		goto out; +		return err;  	}  	/* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */  	spi_new_device(master, &bcm53xx_info); -out: -	return err; -} - -static void bcm53xxspi_bcma_remove(struct bcma_device *core) -{ -	struct bcm53xxspi *b53spi = bcma_get_drvdata(core); - -	spi_unregister_master(b53spi->master); +	return 0;  }  static struct bcma_driver bcm53xxspi_bcma_driver = {  	.name		= KBUILD_MODNAME,  	.id_table	= bcm53xxspi_bcma_tbl,  	.probe		= bcm53xxspi_bcma_probe, -	.remove		= bcm53xxspi_bcma_remove,  };  /************************************************** diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index e73e2b052c9c..06858e04ec59 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -27,10 +27,117 @@  #include <linux/err.h>  #include <linux/pm_runtime.h> -#include <bcm63xx_dev_spi.h> +/* BCM 6338/6348 SPI core */ +#define SPI_6348_RSET_SIZE		64 +#define SPI_6348_CMD			0x00	/* 16-bits register */ +#define SPI_6348_INT_STATUS		0x02 +#define SPI_6348_INT_MASK_ST		0x03 +#define SPI_6348_INT_MASK		0x04 +#define SPI_6348_ST			0x05 +#define SPI_6348_CLK_CFG		0x06 +#define SPI_6348_FILL_BYTE		0x07 +#define SPI_6348_MSG_TAIL		0x09 +#define SPI_6348_RX_TAIL		0x0b +#define SPI_6348_MSG_CTL		0x40	/* 8-bits register */ +#define SPI_6348_MSG_CTL_WIDTH		8 +#define SPI_6348_MSG_DATA		0x41 +#define SPI_6348_MSG_DATA_SIZE		0x3f +#define SPI_6348_RX_DATA		0x80 +#define SPI_6348_RX_DATA_SIZE		0x3f + +/* BCM 3368/6358/6262/6368 SPI core */ +#define SPI_6358_RSET_SIZE		1804 +#define SPI_6358_MSG_CTL		0x00	/* 16-bits register */ +#define SPI_6358_MSG_CTL_WIDTH		16 +#define SPI_6358_MSG_DATA		0x02 +#define SPI_6358_MSG_DATA_SIZE		0x21e +#define SPI_6358_RX_DATA		0x400 +#define SPI_6358_RX_DATA_SIZE		0x220 +#define SPI_6358_CMD			0x700	/* 16-bits register */ +#define SPI_6358_INT_STATUS		0x702 +#define SPI_6358_INT_MASK_ST		0x703 +#define SPI_6358_INT_MASK		0x704 +#define SPI_6358_ST			0x705 +#define SPI_6358_CLK_CFG		0x706 +#define SPI_6358_FILL_BYTE		0x707 +#define SPI_6358_MSG_TAIL		0x709 +#define SPI_6358_RX_TAIL		0x70B + +/* Shared SPI definitions */ + +/* Message configuration */ +#define SPI_FD_RW			0x00 +#define SPI_HD_W			0x01 +#define SPI_HD_R			0x02 +#define SPI_BYTE_CNT_SHIFT		0 +#define SPI_6348_MSG_TYPE_SHIFT		6 +#define SPI_6358_MSG_TYPE_SHIFT		14 + +/* Command */ +#define SPI_CMD_NOOP			0x00 +#define SPI_CMD_SOFT_RESET		0x01 +#define SPI_CMD_HARD_RESET		0x02 +#define SPI_CMD_START_IMMEDIATE		0x03 +#define SPI_CMD_COMMAND_SHIFT		0 +#define SPI_CMD_COMMAND_MASK		0x000f +#define SPI_CMD_DEVICE_ID_SHIFT		4 +#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT	8 +#define SPI_CMD_ONE_BYTE_SHIFT		11 +#define SPI_CMD_ONE_WIRE_SHIFT		12 +#define SPI_DEV_ID_0			0 +#define SPI_DEV_ID_1			1 +#define SPI_DEV_ID_2			2 +#define SPI_DEV_ID_3			3 + +/* Interrupt mask */ +#define SPI_INTR_CMD_DONE		0x01 +#define SPI_INTR_RX_OVERFLOW		0x02 +#define SPI_INTR_TX_UNDERFLOW		0x04 +#define SPI_INTR_TX_OVERFLOW		0x08 +#define SPI_INTR_RX_UNDERFLOW		0x10 +#define SPI_INTR_CLEAR_ALL		0x1f + +/* Status */ +#define SPI_RX_EMPTY			0x02 +#define SPI_CMD_BUSY			0x04 +#define SPI_SERIAL_BUSY			0x08 + +/* Clock configuration */ +#define SPI_CLK_20MHZ			0x00 +#define SPI_CLK_0_391MHZ		0x01 +#define SPI_CLK_0_781MHZ		0x02	/* default */ +#define SPI_CLK_1_563MHZ		0x03 +#define SPI_CLK_3_125MHZ		0x04 +#define SPI_CLK_6_250MHZ		0x05 +#define SPI_CLK_12_50MHZ		0x06 +#define SPI_CLK_MASK			0x07 +#define SPI_SSOFFTIME_MASK		0x38 +#define SPI_SSOFFTIME_SHIFT		3 +#define SPI_BYTE_SWAP			0x80 + +enum bcm63xx_regs_spi { +	SPI_CMD, +	SPI_INT_STATUS, +	SPI_INT_MASK_ST, +	SPI_INT_MASK, +	SPI_ST, +	SPI_CLK_CFG, +	SPI_FILL_BYTE, +	SPI_MSG_TAIL, +	SPI_RX_TAIL, +	SPI_MSG_CTL, +	SPI_MSG_DATA, +	SPI_RX_DATA, +	SPI_MSG_TYPE_SHIFT, +	SPI_MSG_CTL_WIDTH, +	SPI_MSG_DATA_SIZE, +};  #define BCM63XX_SPI_MAX_PREPEND		15 +#define BCM63XX_SPI_MAX_CS		8 +#define BCM63XX_SPI_BUS_NUM		0 +  struct bcm63xx_spi {  	struct completion	done; @@ -38,6 +145,7 @@ struct bcm63xx_spi {  	int			irq;  	/* Platform data */ +	const unsigned long	*reg_offsets;  	unsigned		fifo_size;  	unsigned int		msg_type_shift;  	unsigned int		msg_ctl_width; @@ -51,27 +159,35 @@ struct bcm63xx_spi {  };  static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, -				unsigned int offset) +			       unsigned int offset)  { -	return bcm_readb(bs->regs + bcm63xx_spireg(offset)); +	return readb(bs->regs + bs->reg_offsets[offset]);  }  static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,  				unsigned int offset)  { -	return bcm_readw(bs->regs + bcm63xx_spireg(offset)); +#ifdef CONFIG_CPU_BIG_ENDIAN +	return ioread16be(bs->regs + bs->reg_offsets[offset]); +#else +	return readw(bs->regs + bs->reg_offsets[offset]); +#endif  }  static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,  				  u8 value, unsigned int offset)  { -	bcm_writeb(value, bs->regs + bcm63xx_spireg(offset)); +	writeb(value, bs->regs + bs->reg_offsets[offset]);  }  static inline void bcm_spi_writew(struct bcm63xx_spi *bs,  				  u16 value, unsigned int offset)  { -	bcm_writew(value, bs->regs + bcm63xx_spireg(offset)); +#ifdef CONFIG_CPU_BIG_ENDIAN +	iowrite16be(value, bs->regs + bs->reg_offsets[offset]); +#else +	writew(value, bs->regs + bs->reg_offsets[offset]); +#endif  }  static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { @@ -122,7 +238,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,  	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; @@ -314,18 +429,71 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)  	return IRQ_HANDLED;  } +static const unsigned long bcm6348_spi_reg_offsets[] = { +	[SPI_CMD]		= SPI_6348_CMD, +	[SPI_INT_STATUS]	= SPI_6348_INT_STATUS, +	[SPI_INT_MASK_ST]	= SPI_6348_INT_MASK_ST, +	[SPI_INT_MASK]		= SPI_6348_INT_MASK, +	[SPI_ST]		= SPI_6348_ST, +	[SPI_CLK_CFG]		= SPI_6348_CLK_CFG, +	[SPI_FILL_BYTE]		= SPI_6348_FILL_BYTE, +	[SPI_MSG_TAIL]		= SPI_6348_MSG_TAIL, +	[SPI_RX_TAIL]		= SPI_6348_RX_TAIL, +	[SPI_MSG_CTL]		= SPI_6348_MSG_CTL, +	[SPI_MSG_DATA]		= SPI_6348_MSG_DATA, +	[SPI_RX_DATA]		= SPI_6348_RX_DATA, +	[SPI_MSG_TYPE_SHIFT]	= SPI_6348_MSG_TYPE_SHIFT, +	[SPI_MSG_CTL_WIDTH]	= SPI_6348_MSG_CTL_WIDTH, +	[SPI_MSG_DATA_SIZE]	= SPI_6348_MSG_DATA_SIZE, +}; + +static const unsigned long bcm6358_spi_reg_offsets[] = { +	[SPI_CMD]		= SPI_6358_CMD, +	[SPI_INT_STATUS]	= SPI_6358_INT_STATUS, +	[SPI_INT_MASK_ST]	= SPI_6358_INT_MASK_ST, +	[SPI_INT_MASK]		= SPI_6358_INT_MASK, +	[SPI_ST]		= SPI_6358_ST, +	[SPI_CLK_CFG]		= SPI_6358_CLK_CFG, +	[SPI_FILL_BYTE]		= SPI_6358_FILL_BYTE, +	[SPI_MSG_TAIL]		= SPI_6358_MSG_TAIL, +	[SPI_RX_TAIL]		= SPI_6358_RX_TAIL, +	[SPI_MSG_CTL]		= SPI_6358_MSG_CTL, +	[SPI_MSG_DATA]		= SPI_6358_MSG_DATA, +	[SPI_RX_DATA]		= SPI_6358_RX_DATA, +	[SPI_MSG_TYPE_SHIFT]	= SPI_6358_MSG_TYPE_SHIFT, +	[SPI_MSG_CTL_WIDTH]	= SPI_6358_MSG_CTL_WIDTH, +	[SPI_MSG_DATA_SIZE]	= SPI_6358_MSG_DATA_SIZE, +}; + +static const struct platform_device_id bcm63xx_spi_dev_match[] = { +	{ +		.name = "bcm6348-spi", +		.driver_data = (unsigned long)bcm6348_spi_reg_offsets, +	}, +	{ +		.name = "bcm6358-spi", +		.driver_data = (unsigned long)bcm6358_spi_reg_offsets, +	}, +	{ +	}, +};  static int bcm63xx_spi_probe(struct platform_device *pdev)  {  	struct resource *r; +	const unsigned long *bcm63xx_spireg;  	struct device *dev = &pdev->dev; -	struct bcm63xx_spi_pdata *pdata = dev_get_platdata(&pdev->dev);  	int irq;  	struct spi_master *master;  	struct clk *clk;  	struct bcm63xx_spi *bs;  	int ret; +	if (!pdev->id_entry->driver_data) +		return -EINVAL; + +	bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data; +  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) {  		dev_err(dev, "no irq\n"); @@ -359,7 +527,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)  	bs->irq = irq;  	bs->clk = clk; -	bs->fifo_size = pdata->fifo_size; +	bs->reg_offsets = bcm63xx_spireg; +	bs->fifo_size = bs->reg_offsets[SPI_MSG_DATA_SIZE];  	ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,  							pdev->name, master); @@ -368,26 +537,16 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)  		goto out_err;  	} -	master->bus_num = pdata->bus_num; -	master->num_chipselect = pdata->num_chipselect; +	master->bus_num = BCM63XX_SPI_BUS_NUM; +	master->num_chipselect = BCM63XX_SPI_MAX_CS;  	master->transfer_one_message = bcm63xx_spi_transfer_one;  	master->mode_bits = MODEBITS;  	master->bits_per_word_mask = SPI_BPW_MASK(8);  	master->auto_runtime_pm = true; -	bs->msg_type_shift = pdata->msg_type_shift; -	bs->msg_ctl_width = pdata->msg_ctl_width; -	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); -	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); - -	switch (bs->msg_ctl_width) { -	case 8: -	case 16: -		break; -	default: -		dev_err(dev, "unsupported MSG_CTL width: %d\n", -			 bs->msg_ctl_width); -		goto out_err; -	} +	bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; +	bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; +	bs->tx_io = (u8 *)(bs->regs + bs->reg_offsets[SPI_MSG_DATA]); +	bs->rx_io = (const u8 *)(bs->regs + bs->reg_offsets[SPI_RX_DATA]);  	/* Initialize hardware */  	ret = clk_prepare_enable(bs->clk); @@ -467,6 +626,7 @@ static struct platform_driver bcm63xx_spi_driver = {  		.name	= "bcm63xx-spi",  		.pm	= &bcm63xx_spi_pm_ops,  	}, +	.id_table	= bcm63xx_spi_dev_match,  	.probe		= bcm63xx_spi_probe,  	.remove		= bcm63xx_spi_remove,  }; diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index a78693189f45..6c967555a56a 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c @@ -352,10 +352,7 @@ bfin_sport_spi_pump_transfers(unsigned long data)  	transfer = drv_data->cur_transfer;  	chip = drv_data->cur_chip; -	if (transfer->speed_hz) -		transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); -	else -		transfer_speed = chip->baud; +	transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz);  	bfin_write(&drv_data->regs->tclkdiv, transfer_speed);  	SSYNC(); diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index a3d65b4f4944..1e91325bf39c 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -661,11 +661,7 @@ static void bfin_spi_pump_transfers(unsigned long data)  	message->state = RUNNING_STATE;  	dma_config = 0; -	/* Speed setup (surely valid because already checked) */ -	if (transfer->speed_hz) -		bfin_write(&drv_data->regs->baud, hz_to_spi_baud(transfer->speed_hz)); -	else -		bfin_write(&drv_data->regs->baud, chip->baud); +	bfin_write(&drv_data->regs->baud, hz_to_spi_baud(transfer->speed_hz));  	bfin_write(&drv_data->regs->stat, BIT_STAT_CLR);  	bfin_spi_cs_active(drv_data, chip); diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 840a4984d365..3aa9e6e3dac8 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -24,6 +24,8 @@  #include <linux/spi/spi.h>  #include <linux/spi/spi_bitbang.h> +#define SPI_BITBANG_CS_DELAY	100 +  /*----------------------------------------------------------------------*/ @@ -180,7 +182,6 @@ int spi_bitbang_setup(struct spi_device *spi)  {  	struct spi_bitbang_cs	*cs = spi->controller_state;  	struct spi_bitbang	*bitbang; -	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi->master); @@ -210,12 +211,12 @@ int spi_bitbang_setup(struct spi_device *spi)  	 */  	/* deselect chip (low or high) */ -	spin_lock_irqsave(&bitbang->lock, flags); +	mutex_lock(&bitbang->lock);  	if (!bitbang->busy) {  		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);  		ndelay(cs->nsecs);  	} -	spin_unlock_irqrestore(&bitbang->lock, flags); +	mutex_unlock(&bitbang->lock);  	return 0;  } @@ -255,122 +256,39 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)  static int spi_bitbang_prepare_hardware(struct spi_master *spi)  {  	struct spi_bitbang	*bitbang; -	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi); -	spin_lock_irqsave(&bitbang->lock, flags); +	mutex_lock(&bitbang->lock);  	bitbang->busy = 1; -	spin_unlock_irqrestore(&bitbang->lock, flags); +	mutex_unlock(&bitbang->lock);  	return 0;  }  static int spi_bitbang_transfer_one(struct spi_master *master, -				    struct spi_message *m) +				    struct spi_device *spi, +				    struct spi_transfer *transfer)  { -	struct spi_bitbang	*bitbang; -	unsigned		nsecs; -	struct spi_transfer	*t = NULL; -	unsigned		cs_change; -	int			status; -	int			do_setup = -1; -	struct spi_device	*spi = m->spi; - -	bitbang = spi_master_get_devdata(master); - -	/* FIXME this is made-up ... the correct value is known to -	 * word-at-a-time bitbang code, and presumably chipselect() -	 * should enforce these requirements too? -	 */ -	nsecs = 100; - -	cs_change = 1; -	status = 0; - -	list_for_each_entry(t, &m->transfers, transfer_list) { - -		/* 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 (bitbang->setup_transfer) { -				status = bitbang->setup_transfer(spi, t); -				if (status < 0) -					break; -			} -			if (do_setup == -1) -				do_setup = 0; -		} - -		/* set up default clock polarity, and activate chip; -		 * this implicitly updates clock and spi modes as -		 * previously recorded for this device via setup(). -		 * (and also deselects any other chip that might be -		 * selected ...) -		 */ -		if (cs_change) { -			bitbang->chipselect(spi, BITBANG_CS_ACTIVE); -			ndelay(nsecs); -		} -		cs_change = t->cs_change; -		if (!t->tx_buf && !t->rx_buf && t->len) { -			status = -EINVAL; -			break; -		} - -		/* transfer data.  the lower level code handles any -		 * new dma mappings it needs. our caller always gave -		 * us dma-safe buffers. -		 */ -		if (t->len) { -			/* REVISIT dma API still needs a designated -			 * DMA_ADDR_INVALID; ~0 might be better. -			 */ -			if (!m->is_dma_mapped) -				t->rx_dma = t->tx_dma = 0; -			status = bitbang->txrx_bufs(spi, t); -		} -		if (status > 0) -			m->actual_length += status; -		if (status != t->len) { -			/* always report some kind of error */ -			if (status >= 0) -				status = -EREMOTEIO; -			break; -		} -		status = 0; +	struct spi_bitbang *bitbang = spi_master_get_devdata(master); +	int status = 0; -		/* protocol tweaks before next transfer */ -		if (t->delay_usecs) -			udelay(t->delay_usecs); - -		if (cs_change && -		    !list_is_last(&t->transfer_list, &m->transfers)) { -			/* sometimes a short mid-message deselect of the chip -			 * may be needed to terminate a mode or command -			 */ -			ndelay(nsecs); -			bitbang->chipselect(spi, BITBANG_CS_INACTIVE); -			ndelay(nsecs); -		} +	if (bitbang->setup_transfer) { +		status = bitbang->setup_transfer(spi, transfer); +		if (status < 0) +			goto out;  	} -	m->status = status; +	if (transfer->len) +		status = bitbang->txrx_bufs(spi, transfer); -	/* normally deactivate chipselect ... unless no error and -	 * cs_change has hinted that the next message will probably -	 * be for this chip too. -	 */ -	if (!(status == 0 && cs_change)) { -		ndelay(nsecs); -		bitbang->chipselect(spi, BITBANG_CS_INACTIVE); -		ndelay(nsecs); -	} +	if (status == transfer->len) +		status = 0; +	else if (status >= 0) +		status = -EREMOTEIO; -	spi_finalize_current_message(master); +out: +	spi_finalize_current_transfer(master);  	return status;  } @@ -378,17 +296,32 @@ static int spi_bitbang_transfer_one(struct spi_master *master,  static int spi_bitbang_unprepare_hardware(struct spi_master *spi)  {  	struct spi_bitbang	*bitbang; -	unsigned long		flags;  	bitbang = spi_master_get_devdata(spi); -	spin_lock_irqsave(&bitbang->lock, flags); +	mutex_lock(&bitbang->lock);  	bitbang->busy = 0; -	spin_unlock_irqrestore(&bitbang->lock, flags); +	mutex_unlock(&bitbang->lock);  	return 0;  } +static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) +{ +	struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master); + +	/* SPI core provides CS high / low, but bitbang driver +	 * expects CS active +	 * spi device driver takes care of handling SPI_CS_HIGH +	 */ +	enable = (!!(spi->mode & SPI_CS_HIGH) == enable); + +	ndelay(SPI_BITBANG_CS_DELAY); +	bitbang->chipselect(spi, enable ? BITBANG_CS_ACTIVE : +			    BITBANG_CS_INACTIVE); +	ndelay(SPI_BITBANG_CS_DELAY); +} +  /*----------------------------------------------------------------------*/  /** @@ -427,7 +360,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)  	if (!master || !bitbang->chipselect)  		return -EINVAL; -	spin_lock_init(&bitbang->lock); +	mutex_init(&bitbang->lock);  	if (!master->mode_bits)  		master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; @@ -437,7 +370,8 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)  	master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;  	master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; -	master->transfer_one_message = spi_bitbang_transfer_one; +	master->transfer_one = spi_bitbang_transfer_one; +	master->set_cs = spi_bitbang_set_cs;  	if (!bitbang->txrx_bufs) {  		bitbang->use_dma = 0; diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 688956ff5095..23f6fffd75e1 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -420,19 +420,20 @@ static int mcfqspi_probe(struct platform_device *pdev)  	master->auto_runtime_pm = true;  	platform_set_drvdata(pdev, master); +	pm_runtime_enable(&pdev->dev);  	status = devm_spi_register_master(&pdev->dev, master);  	if (status) {  		dev_dbg(&pdev->dev, "spi_register_master failed\n");  		goto fail2;  	} -	pm_runtime_enable(&pdev->dev);  	dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");  	return 0;  fail2: +	pm_runtime_disable(&pdev->dev);  	mcfqspi_cs_teardown(mcfqspi);  fail1:  	clk_disable(mcfqspi->clk); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index a85d863d4a44..7d3af3eacf57 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -215,18 +215,10 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)  	struct davinci_spi_config *spicfg = spi->controller_data;  	u8 chip_sel = spi->chip_select;  	u16 spidat1 = CS_DEFAULT; -	bool gpio_chipsel = false; -	int gpio;  	dspi = spi_master_get_devdata(spi->master);  	pdata = &dspi->pdata; -	if (spi->cs_gpio >= 0) { -		/* SPI core parse and update master->cs_gpio */ -		gpio_chipsel = true; -		gpio = spi->cs_gpio; -	} -  	/* program delay transfers if tx_delay is non zero */  	if (spicfg->wdelay)  		spidat1 |= SPIDAT1_WDEL; @@ -235,11 +227,12 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)  	 * Board specific chip select logic decides the polarity and cs  	 * line for the controller  	 */ -	if (gpio_chipsel) { +	if (spi->cs_gpio >= 0) {  		if (value == BITBANG_CS_ACTIVE) -			gpio_set_value(gpio, spi->mode & SPI_CS_HIGH); +			gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH);  		else -			gpio_set_value(gpio, !(spi->mode & SPI_CS_HIGH)); +			gpio_set_value(spi->cs_gpio, +				!(spi->mode & SPI_CS_HIGH));  	} else {  		if (value == BITBANG_CS_ACTIVE) {  			spidat1 |= SPIDAT1_CSHOLD_MASK; diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 7edede6e024b..a6d7029a85ac 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c @@ -19,6 +19,7 @@  #include <linux/of.h>  #include <linux/of_gpio.h>  #include <linux/of_platform.h> +#include <linux/property.h>  #include "spi-dw.h" @@ -74,13 +75,11 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)  	dws->max_freq = clk_get_rate(dwsmmio->clk); -	of_property_read_u32(pdev->dev.of_node, "reg-io-width", -			     &dws->reg_io_width); +	device_property_read_u32(&pdev->dev, "reg-io-width", &dws->reg_io_width);  	num_cs = 4; -	if (pdev->dev.of_node) -		of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); +	device_property_read_u32(&pdev->dev, "num-cs", &num_cs);  	dws->num_cs = num_cs; diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 6d331e0db331..332ccb0539a7 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -23,11 +23,6 @@  #define DRIVER_NAME "dw_spi_pci" -struct dw_spi_pci { -	struct pci_dev	*pdev; -	struct dw_spi	dws; -}; -  struct spi_pci_desc {  	int	(*setup)(struct dw_spi *);  	u16	num_cs; @@ -48,7 +43,6 @@ static struct spi_pci_desc spi_pci_mid_desc_2 = {  static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  { -	struct dw_spi_pci *dwpci;  	struct dw_spi *dws;  	struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data;  	int pci_bar = 0; @@ -58,14 +52,10 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (ret)  		return ret; -	dwpci = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_pci), -			GFP_KERNEL); -	if (!dwpci) +	dws = devm_kzalloc(&pdev->dev, sizeof(*dws), GFP_KERNEL); +	if (!dws)  		return -ENOMEM; -	dwpci->pdev = pdev; -	dws = &dwpci->dws; -  	/* Get basic io resource and map it */  	dws->paddr = pci_resource_start(pdev, pci_bar); @@ -74,7 +64,6 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		return ret;  	dws->regs = pcim_iomap_table(pdev)[pci_bar]; -  	dws->irq = pdev->irq;  	/* @@ -99,7 +88,7 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		return ret;  	/* PCI hook and SPI hook use the same drv data */ -	pci_set_drvdata(pdev, dwpci); +	pci_set_drvdata(pdev, dws);  	dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",  		pdev->vendor, pdev->device); @@ -109,26 +98,26 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  static void spi_pci_remove(struct pci_dev *pdev)  { -	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); +	struct dw_spi *dws = pci_get_drvdata(pdev); -	dw_spi_remove_host(&dwpci->dws); +	dw_spi_remove_host(dws);  }  #ifdef CONFIG_PM_SLEEP  static int spi_suspend(struct device *dev)  {  	struct pci_dev *pdev = to_pci_dev(dev); -	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); +	struct dw_spi *dws = pci_get_drvdata(pdev); -	return dw_spi_suspend_host(&dwpci->dws); +	return dw_spi_suspend_host(dws);  }  static int spi_resume(struct device *dev)  {  	struct pci_dev *pdev = to_pci_dev(dev); -	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); +	struct dw_spi *dws = pci_get_drvdata(pdev); -	return dw_spi_resume_host(&dwpci->dws); +	return dw_spi_resume_host(dws);  }  #endif diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 4fbfcdc5cb24..882cd6618cd5 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -30,19 +30,13 @@  /* Slave spi_dev related */  struct chip_data { -	u16 cr0;  	u8 cs;			/* chip select pin */ -	u8 n_bytes;		/* current is a 1/2/4 byte op */  	u8 tmode;		/* TR/TO/RO/EEPROM */  	u8 type;		/* SPI/SSP/MicroWire */  	u8 poll_mode;		/* 1 means use poll mode */ -	u32 dma_width; -	u32 rx_threshold; -	u32 tx_threshold;  	u8 enable_dma; -	u8 bits_per_word;  	u16 clk_div;		/* baud rate divider */  	u32 speed_hz;		/* baud rate */  	void (*cs_control)(u32 command); @@ -289,14 +283,11 @@ static int dw_spi_transfer_one(struct spi_master *master,  	struct chip_data *chip = spi_get_ctldata(spi);  	u8 imask = 0;  	u16 txlevel = 0; -	u16 clk_div = 0; -	u32 speed = 0; -	u32 cr0 = 0; +	u16 clk_div; +	u32 cr0;  	int ret;  	dws->dma_mapped = 0; -	dws->n_bytes = chip->n_bytes; -	dws->dma_width = chip->dma_width;  	dws->tx = (void *)transfer->tx_buf;  	dws->tx_end = dws->tx + transfer->len; @@ -306,37 +297,30 @@ static int dw_spi_transfer_one(struct spi_master *master,  	spi_enable_chip(dws, 0); -	cr0 = chip->cr0; -  	/* Handle per transfer options for bpw and speed */ -	if (transfer->speed_hz) { -		speed = chip->speed_hz; - -		if ((transfer->speed_hz != speed) || !chip->clk_div) { -			speed = transfer->speed_hz; - -			/* clk_div doesn't support odd number */ -			clk_div = (dws->max_freq / speed + 1) & 0xfffe; +	if (transfer->speed_hz != chip->speed_hz) { +		/* clk_div doesn't support odd number */ +		clk_div = (dws->max_freq / transfer->speed_hz + 1) & 0xfffe; -			chip->speed_hz = speed; -			chip->clk_div = clk_div; +		chip->speed_hz = transfer->speed_hz; +		chip->clk_div = clk_div; -			spi_set_clk(dws, chip->clk_div); -		} +		spi_set_clk(dws, chip->clk_div);  	} -	if (transfer->bits_per_word) { -		if (transfer->bits_per_word == 8) { -			dws->n_bytes = 1; -			dws->dma_width = 1; -		} else if (transfer->bits_per_word == 16) { -			dws->n_bytes = 2; -			dws->dma_width = 2; -		} -		cr0 = (transfer->bits_per_word - 1) -			| (chip->type << SPI_FRF_OFFSET) -			| (spi->mode << SPI_MODE_OFFSET) -			| (chip->tmode << SPI_TMOD_OFFSET); +	if (transfer->bits_per_word == 8) { +		dws->n_bytes = 1; +		dws->dma_width = 1; +	} else if (transfer->bits_per_word == 16) { +		dws->n_bytes = 2; +		dws->dma_width = 2; +	} else { +		return -EINVAL;  	} +	/* Default SPI mode is SCPOL = 0, SCPH = 0 */ +	cr0 = (transfer->bits_per_word - 1) +		| (chip->type << SPI_FRF_OFFSET) +		| (spi->mode << SPI_MODE_OFFSET) +		| (chip->tmode << SPI_TMOD_OFFSET);  	/*  	 * Adjust transfer mode if necessary. Requires platform dependent @@ -439,34 +423,9 @@ static int dw_spi_setup(struct spi_device *spi)  		chip->poll_mode = chip_info->poll_mode;  		chip->type = chip_info->type; - -		chip->rx_threshold = 0; -		chip->tx_threshold = 0; -	} - -	if (spi->bits_per_word == 8) { -		chip->n_bytes = 1; -		chip->dma_width = 1; -	} else if (spi->bits_per_word == 16) { -		chip->n_bytes = 2; -		chip->dma_width = 2; -	} -	chip->bits_per_word = spi->bits_per_word; - -	if (!spi->max_speed_hz) { -		dev_err(&spi->dev, "No max speed HZ parameter\n"); -		return -EINVAL;  	}  	chip->tmode = 0; /* Tx & Rx */ -	/* Default SPI mode is SCPOL = 0, SCPH = 0 */ -	chip->cr0 = (chip->bits_per_word - 1) -			| (chip->type << SPI_FRF_OFFSET) -			| (spi->mode  << SPI_MODE_OFFSET) -			| (chip->tmode << SPI_TMOD_OFFSET); - -	if (spi->mode & SPI_LOOP) -		chip->cr0 |= 1 << SPI_SRL_OFFSET;  	if (gpio_is_valid(spi->cs_gpio)) {  		ret = gpio_direction_output(spi->cs_gpio, @@ -524,13 +483,12 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)  	dws->master = master;  	dws->type = SSI_MOTO_SPI;  	dws->dma_inited = 0; -	dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); +	dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);  	snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); -	ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED, -			dws->name, master); +	ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master);  	if (ret < 0) { -		dev_err(&master->dev, "can not get IRQ\n"); +		dev_err(dev, "can not get IRQ\n");  		goto err_free_master;  	} @@ -573,6 +531,7 @@ err_dma_exit:  	if (dws->dma_ops && dws->dma_ops->dma_exit)  		dws->dma_ops->dma_exit(dws);  	spi_enable_chip(dws, 0); +	free_irq(dws->irq, master);  err_free_master:  	spi_master_put(master);  	return ret; @@ -581,28 +540,27 @@ EXPORT_SYMBOL_GPL(dw_spi_add_host);  void dw_spi_remove_host(struct dw_spi *dws)  { -	if (!dws) -		return;  	dw_spi_debugfs_remove(dws);  	if (dws->dma_ops && dws->dma_ops->dma_exit)  		dws->dma_ops->dma_exit(dws); -	spi_enable_chip(dws, 0); -	/* Disable clk */ -	spi_set_clk(dws, 0); + +	spi_shutdown_chip(dws); + +	free_irq(dws->irq, dws->master);  }  EXPORT_SYMBOL_GPL(dw_spi_remove_host);  int dw_spi_suspend_host(struct dw_spi *dws)  { -	int ret = 0; +	int ret;  	ret = spi_master_suspend(dws->master);  	if (ret)  		return ret; -	spi_enable_chip(dws, 0); -	spi_set_clk(dws, 0); -	return ret; + +	spi_shutdown_chip(dws); +	return 0;  }  EXPORT_SYMBOL_GPL(dw_spi_suspend_host); diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index b75ed327d5a2..35589a270468 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -225,6 +225,12 @@ static inline void spi_reset_chip(struct dw_spi *dws)  	spi_enable_chip(dws, 1);  } +static inline void spi_shutdown_chip(struct dw_spi *dws) +{ +	spi_enable_chip(dws, 0); +	spi_set_clk(dws, 0); +} +  /*   * Each SPI slave device to work with dw_api controller should   * has such a structure claiming its working mode (poll or PIO/DMA), diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 86bcdd68c1fe..59a11437db70 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -409,9 +409,6 @@ static int dspi_transfer_one_message(struct spi_master *master,  				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);  		regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),  				dspi->cur_chip->ctar_val); -		if (transfer->speed_hz) -			regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), -					dspi->cur_chip->ctar_val);  		trans_mode = dspi->devtype_data->trans_mode;  		switch (trans_mode) { diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index f9deb84e4e55..0e5723ab47f0 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -336,13 +336,20 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,  	if (config->mode & SPI_CPHA)  		cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); +	else +		cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(config->cs);  	if (config->mode & SPI_CPOL) {  		cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs);  		cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs); +	} else { +		cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(config->cs); +		cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(config->cs);  	}  	if (config->mode & SPI_CS_HIGH)  		cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); +	else +		cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs);  	writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);  	writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 1e75341689a6..c3ec46cd9f91 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -302,11 +302,9 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,  	cs_change = 1;  	status = 0;  	list_for_each_entry(t, &m->transfers, transfer_list) { -		if (t->bits_per_word || t->speed_hz) { -			status = mpc512x_psc_spi_transfer_setup(spi, t); -			if (status < 0) -				break; -		} +		status = mpc512x_psc_spi_transfer_setup(spi, t); +		if (status < 0) +			break;  		if (cs_change)  			mpc512x_psc_spi_activate_cs(spi); diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index ecb6c58238c4..563954a61424 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -20,6 +20,7 @@  #include <linux/ioport.h>  #include <linux/module.h>  #include <linux/of.h> +#include <linux/of_gpio.h>  #include <linux/platform_device.h>  #include <linux/platform_data/spi-mt65xx.h>  #include <linux/pm_runtime.h> @@ -84,7 +85,8 @@ struct mtk_spi_compatible {  struct mtk_spi {  	void __iomem *base;  	u32 state; -	u32 pad_sel; +	int pad_num; +	u32 *pad_sel;  	struct clk *parent_clk, *sel_clk, *spi_clk;  	struct spi_transfer *cur_transfer;  	u32 xfer_len; @@ -131,10 +133,28 @@ static void mtk_spi_reset(struct mtk_spi *mdata)  	writel(reg_val, mdata->base + SPI_CMD_REG);  } -static void mtk_spi_config(struct mtk_spi *mdata, -			   struct mtk_chip_config *chip_config) +static int mtk_spi_prepare_message(struct spi_master *master, +				   struct spi_message *msg)  { +	u16 cpha, cpol;  	u32 reg_val; +	struct spi_device *spi = msg->spi; +	struct mtk_chip_config *chip_config = spi->controller_data; +	struct mtk_spi *mdata = spi_master_get_devdata(master); + +	cpha = spi->mode & SPI_CPHA ? 1 : 0; +	cpol = spi->mode & SPI_CPOL ? 1 : 0; + +	reg_val = readl(mdata->base + SPI_CMD_REG); +	if (cpha) +		reg_val |= SPI_CMD_CPHA; +	else +		reg_val &= ~SPI_CMD_CPHA; +	if (cpol) +		reg_val |= SPI_CMD_CPOL; +	else +		reg_val &= ~SPI_CMD_CPOL; +	writel(reg_val, mdata->base + SPI_CMD_REG);  	reg_val = readl(mdata->base + SPI_CMD_REG); @@ -170,38 +190,8 @@ static void mtk_spi_config(struct mtk_spi *mdata,  	/* pad select */  	if (mdata->dev_comp->need_pad_sel) -		writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); -} - -static int mtk_spi_prepare_message(struct spi_master *master, -				   struct spi_message *msg) -{ -	u32 reg_val; -	u8 cpha, cpol; -	struct mtk_chip_config *chip_config; -	struct spi_device *spi = msg->spi; -	struct mtk_spi *mdata = spi_master_get_devdata(master); - -	cpha = spi->mode & SPI_CPHA ? 1 : 0; -	cpol = spi->mode & SPI_CPOL ? 1 : 0; - -	reg_val = readl(mdata->base + SPI_CMD_REG); -	if (cpha) -		reg_val |= SPI_CMD_CPHA; -	else -		reg_val &= ~SPI_CMD_CPHA; -	if (cpol) -		reg_val |= SPI_CMD_CPOL; -	else -		reg_val &= ~SPI_CMD_CPOL; -	writel(reg_val, mdata->base + SPI_CMD_REG); - -	chip_config = spi->controller_data; -	if (!chip_config) { -		chip_config = (void *)&mtk_default_chip_info; -		spi->controller_data = chip_config; -	} -	mtk_spi_config(mdata, chip_config); +		writel(mdata->pad_sel[spi->chip_select], +		       mdata->base + SPI_PAD_SEL_REG);  	return 0;  } @@ -413,6 +403,19 @@ static bool mtk_spi_can_dma(struct spi_master *master,  	return xfer->len > MTK_SPI_MAX_FIFO_SIZE;  } +static int mtk_spi_setup(struct spi_device *spi) +{ +	struct mtk_spi *mdata = spi_master_get_devdata(spi->master); + +	if (!spi->controller_data) +		spi->controller_data = (void *)&mtk_default_chip_info; + +	if (mdata->dev_comp->need_pad_sel) +		gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); + +	return 0; +} +  static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)  {  	u32 cmd, reg_val, cnt; @@ -484,7 +487,7 @@ static int mtk_spi_probe(struct platform_device *pdev)  	struct mtk_spi *mdata;  	const struct of_device_id *of_id;  	struct resource *res; -	int irq, ret; +	int i, irq, ret;  	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));  	if (!master) { @@ -500,6 +503,7 @@ static int mtk_spi_probe(struct platform_device *pdev)  	master->prepare_message = mtk_spi_prepare_message;  	master->transfer_one = mtk_spi_transfer_one;  	master->can_dma = mtk_spi_can_dma; +	master->setup = mtk_spi_setup;  	of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node);  	if (!of_id) { @@ -514,21 +518,34 @@ static int mtk_spi_probe(struct platform_device *pdev)  		master->flags = SPI_MASTER_MUST_TX;  	if (mdata->dev_comp->need_pad_sel) { -		ret = of_property_read_u32(pdev->dev.of_node, -					   "mediatek,pad-select", -					   &mdata->pad_sel); -		if (ret) { -			dev_err(&pdev->dev, "failed to read pad select: %d\n", -				ret); +		mdata->pad_num = of_property_count_u32_elems( +			pdev->dev.of_node, +			"mediatek,pad-select"); +		if (mdata->pad_num < 0) { +			dev_err(&pdev->dev, +				"No 'mediatek,pad-select' property\n"); +			ret = -EINVAL;  			goto err_put_master;  		} -		if (mdata->pad_sel > MT8173_SPI_MAX_PAD_SEL) { -			dev_err(&pdev->dev, "wrong pad-select: %u\n", -				mdata->pad_sel); -			ret = -EINVAL; +		mdata->pad_sel = devm_kmalloc_array(&pdev->dev, mdata->pad_num, +						    sizeof(u32), GFP_KERNEL); +		if (!mdata->pad_sel) { +			ret = -ENOMEM;  			goto err_put_master;  		} + +		for (i = 0; i < mdata->pad_num; i++) { +			of_property_read_u32_index(pdev->dev.of_node, +						   "mediatek,pad-select", +						   i, &mdata->pad_sel[i]); +			if (mdata->pad_sel[i] > MT8173_SPI_MAX_PAD_SEL) { +				dev_err(&pdev->dev, "wrong pad-sel[%d]: %u\n", +					i, mdata->pad_sel[i]); +				ret = -EINVAL; +				goto err_put_master; +			} +		}  	}  	platform_set_drvdata(pdev, master); @@ -606,6 +623,26 @@ static int mtk_spi_probe(struct platform_device *pdev)  		goto err_put_master;  	} +	if (mdata->dev_comp->need_pad_sel) { +		if (mdata->pad_num != master->num_chipselect) { +			dev_err(&pdev->dev, +				"pad_num does not match num_chipselect(%d != %d)\n", +				mdata->pad_num, master->num_chipselect); +			ret = -EINVAL; +			goto err_put_master; +		} + +		for (i = 0; i < master->num_chipselect; i++) { +			ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], +						dev_name(&pdev->dev)); +			if (ret) { +				dev_err(&pdev->dev, +					"can't get CS GPIO %i\n", i); +				goto err_put_master; +			} +		} +	} +  	return 0;  err_disable_clk: diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 76656a77ec12..b5911282a611 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -207,8 +207,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev)  	struct tiny_spi *hw = platform_get_drvdata(pdev);  	struct device_node *np = pdev->dev.of_node;  	unsigned int i; -	const __be32 *val; -	int len; +	u32 val;  	if (!np)  		return 0; @@ -226,13 +225,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev)  			return -ENODEV;  	}  	hw->bitbang.master->dev.of_node = pdev->dev.of_node; -	val = of_get_property(pdev->dev.of_node, -			      "clock-frequency", &len); -	if (val && len >= sizeof(__be32)) -		hw->freq = be32_to_cpup(val); -	val = of_get_property(pdev->dev.of_node, "baud-width", &len); -	if (val && len >= sizeof(__be32)) -		hw->baudwidth = be32_to_cpup(val); +	if (!of_property_read_u32(np, "clock-frequency", &val)) +		hw->freq = val; +	if (!of_property_read_u32(np, "baud-width", &val)) +		hw->baudwidth = val;  	return 0;  }  #else /* !CONFIG_OF */ diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index e99d6a93d394..07e4ce8273df 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -65,7 +65,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,  	cpha = mode & SPI_CPHA;  	cpol = mode & SPI_CPOL; -	speed_hz = xfer->speed_hz ? : spi->max_speed_hz; +	speed_hz = xfer->speed_hz;  	clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz); diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 35b332dacb13..76a8425be227 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -244,12 +244,12 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi,  {  	struct omap1_spi100k *spi100k = spi_master_get_devdata(spi->master);  	struct omap1_spi100k_cs *cs = spi->controller_state; -	u8 word_len = spi->bits_per_word; +	u8 word_len; -	if (t != NULL && t->bits_per_word) +	if (t != NULL)  		word_len = t->bits_per_word; -	if (!word_len) -		word_len = 8; +	else +		word_len = spi->bits_per_word;  	if (spi->bits_per_word > 32)  		return -EINVAL; @@ -302,7 +302,6 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,  	struct spi_device *spi = m->spi;  	struct spi_transfer *t = NULL;  	int cs_active = 0; -	int par_override = 0;  	int status = 0;  	list_for_each_entry(t, &m->transfers, transfer_list) { @@ -310,14 +309,9 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,  			status = -EINVAL;  			break;  		} -		if (par_override || t->speed_hz || t->bits_per_word) { -			par_override = 1; -			status = omap1_spi100k_setup_transfer(spi, t); -			if (status < 0) -				break; -			if (!t->speed_hz && !t->bits_per_word) -				par_override = 0; -		} +		status = omap1_spi100k_setup_transfer(spi, t); +		if (status < 0) +			break;  		if (!cs_active) {  			omap1_spi100k_force_cs(spi100k, 1); @@ -347,11 +341,7 @@ static int omap1_spi100k_transfer_one_message(struct spi_master *master,  		}  	} -	/* Restore defaults if they were overriden */ -	if (par_override) { -		par_override = 0; -		status = omap1_spi100k_setup_transfer(spi, NULL); -	} +	status = omap1_spi100k_setup_transfer(spi, NULL);  	if (cs_active)  		omap1_spi100k_force_cs(spi100k, 0); diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 55576db31549..ce8dbdbce312 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -205,7 +205,7 @@ static void uwire_chipselect(struct spi_device *spi, int value)  static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)  {  	unsigned	len = t->len; -	unsigned	bits = t->bits_per_word ? : spi->bits_per_word; +	unsigned	bits = t->bits_per_word;  	unsigned	bytes;  	u16		val, w;  	int		status = 0; @@ -344,9 +344,10 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)  	/* assume it's already enabled */  	rate = clk_get_rate(uwire->ck); -	hz = spi->max_speed_hz; -	if (t != NULL && t->speed_hz) +	if (t != NULL)  		hz = t->speed_hz; +	else +		hz = spi->max_speed_hz;  	if (!hz) {  		pr_debug("%s: zero speed?\n", dev_name(&spi->dev)); diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 3d09e0b69b73..1f8903d356e5 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1217,6 +1217,33 @@ out:  	return status;  } +static int omap2_mcspi_prepare_message(struct spi_master *master, +				       struct spi_message *msg) +{ +	struct omap2_mcspi	*mcspi = spi_master_get_devdata(master); +	struct omap2_mcspi_regs	*ctx = &mcspi->ctx; +	struct omap2_mcspi_cs	*cs; + +	/* Only a single channel can have the FORCE bit enabled +	 * in its chconf0 register. +	 * Scan all channels and disable them except the current one. +	 * A FORCE can remain from a last transfer having cs_change enabled +	 */ +	list_for_each_entry(cs, &ctx->cs, node) { +		if (msg->spi->controller_state == cs) +			continue; + +		if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE)) { +			cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE; +			writel_relaxed(cs->chconf0, +					cs->base + OMAP2_MCSPI_CHCONF0); +			readl_relaxed(cs->base + OMAP2_MCSPI_CHCONF0); +		} +	} + +	return 0; +} +  static int omap2_mcspi_transfer_one(struct spi_master *master,  		struct spi_device *spi, struct spi_transfer *t)  { @@ -1344,6 +1371,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)  	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);  	master->setup = omap2_mcspi_setup;  	master->auto_runtime_pm = true; +	master->prepare_message = omap2_mcspi_prepare_message;  	master->transfer_one = omap2_mcspi_transfer_one;  	master->set_cs = omap2_mcspi_set_cs;  	master->cleanup = omap2_mcspi_cleanup; diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 54fb984a3e17..dd3d0a218d8b 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -210,12 +210,12 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)  	if (in_8(&hw->regs->cdm) != cdm)  		out_8(&hw->regs->cdm, cdm); -	spin_lock(&hw->bitbang.lock); +	mutex_lock(&hw->bitbang.lock);  	if (!hw->bitbang.busy) {  		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);  		/* Need to ndelay here? */  	} -	spin_unlock(&hw->bitbang.lock); +	mutex_unlock(&hw->bitbang.lock);  	return 0;  } diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index 66a173939be8..bd8b369a343c 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c @@ -344,10 +344,6 @@ void pxa2xx_spi_dma_release(struct driver_data *drv_data)  	}  } -void pxa2xx_spi_dma_resume(struct driver_data *drv_data) -{ -} -  int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,  					   struct spi_device *spi,  					   u8 bits_per_word, u32 *burst_code, diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index a8ef38ebb9c9..b25dc71b0ea9 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -13,6 +13,7 @@   * GNU General Public License for more details.   */ +#include <linux/bitops.h>  #include <linux/init.h>  #include <linux/module.h>  #include <linux/device.h> @@ -61,9 +62,13 @@ MODULE_ALIAS("platform:pxa2xx-spi");  				| QUARK_X1000_SSCR1_TFT		\  				| SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) -#define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) -#define SPI_CS_CONTROL_SW_MODE	BIT(0) -#define SPI_CS_CONTROL_CS_HIGH	BIT(1) +#define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE	BIT(24) +#define LPSS_CS_CONTROL_SW_MODE			BIT(0) +#define LPSS_CS_CONTROL_CS_HIGH			BIT(1) +#define LPSS_CS_CONTROL_CS_SEL_SHIFT		8 +#define LPSS_CS_CONTROL_CS_SEL_MASK		(3 << LPSS_CS_CONTROL_CS_SEL_SHIFT) +#define LPSS_CAPS_CS_EN_SHIFT			9 +#define LPSS_CAPS_CS_EN_MASK			(0xf << LPSS_CAPS_CS_EN_SHIFT)  struct lpss_config {  	/* LPSS offset from drv_data->ioaddr */ @@ -72,6 +77,7 @@ struct lpss_config {  	int reg_general;  	int reg_ssp;  	int reg_cs_ctrl; +	int reg_capabilities;  	/* FIFO thresholds */  	u32 rx_threshold;  	u32 tx_threshold_lo; @@ -85,6 +91,7 @@ static const struct lpss_config lpss_platforms[] = {  		.reg_general = 0x08,  		.reg_ssp = 0x0c,  		.reg_cs_ctrl = 0x18, +		.reg_capabilities = -1,  		.rx_threshold = 64,  		.tx_threshold_lo = 160,  		.tx_threshold_hi = 224, @@ -94,6 +101,7 @@ static const struct lpss_config lpss_platforms[] = {  		.reg_general = 0x08,  		.reg_ssp = 0x0c,  		.reg_cs_ctrl = 0x18, +		.reg_capabilities = -1,  		.rx_threshold = 64,  		.tx_threshold_lo = 160,  		.tx_threshold_hi = 224, @@ -103,10 +111,21 @@ static const struct lpss_config lpss_platforms[] = {  		.reg_general = -1,  		.reg_ssp = 0x20,  		.reg_cs_ctrl = 0x24, +		.reg_capabilities = 0xfc,  		.rx_threshold = 1,  		.tx_threshold_lo = 32,  		.tx_threshold_hi = 56,  	}, +	{	/* LPSS_BXT_SSP */ +		.offset = 0x200, +		.reg_general = -1, +		.reg_ssp = 0x20, +		.reg_cs_ctrl = 0x24, +		.reg_capabilities = 0xfc, +		.rx_threshold = 1, +		.tx_threshold_lo = 16, +		.tx_threshold_hi = 48, +	},  };  static inline const struct lpss_config @@ -121,6 +140,7 @@ static bool is_lpss_ssp(const struct driver_data *drv_data)  	case LPSS_LPT_SSP:  	case LPSS_BYT_SSP:  	case LPSS_SPT_SSP: +	case LPSS_BXT_SSP:  		return true;  	default:  		return false; @@ -249,7 +269,9 @@ static void lpss_ssp_setup(struct driver_data *drv_data)  	drv_data->lpss_base = drv_data->ioaddr + config->offset;  	/* Enable software chip select control */ -	value = SPI_CS_CONTROL_SW_MODE | SPI_CS_CONTROL_CS_HIGH; +	value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); +	value &= ~(LPSS_CS_CONTROL_SW_MODE | LPSS_CS_CONTROL_CS_HIGH); +	value |= LPSS_CS_CONTROL_SW_MODE | LPSS_CS_CONTROL_CS_HIGH;  	__lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value);  	/* Enable multiblock DMA transfers */ @@ -259,7 +281,7 @@ static void lpss_ssp_setup(struct driver_data *drv_data)  		if (config->reg_general >= 0) {  			value = __lpss_ssp_read_priv(drv_data,  						     config->reg_general); -			value |= GENERAL_REG_RXTO_HOLDOFF_DISABLE; +			value |= LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE;  			__lpss_ssp_write_priv(drv_data,  					      config->reg_general, value);  		} @@ -269,15 +291,34 @@ static void lpss_ssp_setup(struct driver_data *drv_data)  static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)  {  	const struct lpss_config *config; -	u32 value; +	u32 value, cs;  	config = lpss_get_config(drv_data);  	value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); -	if (enable) -		value &= ~SPI_CS_CONTROL_CS_HIGH; -	else -		value |= SPI_CS_CONTROL_CS_HIGH; +	if (enable) { +		cs = drv_data->cur_msg->spi->chip_select; +		cs <<= LPSS_CS_CONTROL_CS_SEL_SHIFT; +		if (cs != (value & LPSS_CS_CONTROL_CS_SEL_MASK)) { +			/* +			 * When switching another chip select output active +			 * the output must be selected first and wait 2 ssp_clk +			 * cycles before changing state to active. Otherwise +			 * a short glitch will occur on the previous chip +			 * select since output select is latched but state +			 * control is not. +			 */ +			value &= ~LPSS_CS_CONTROL_CS_SEL_MASK; +			value |= cs; +			__lpss_ssp_write_priv(drv_data, +					      config->reg_cs_ctrl, value); +			ndelay(1000000000 / +			       (drv_data->master->max_speed_hz / 2)); +		} +		value &= ~LPSS_CS_CONTROL_CS_HIGH; +	} else { +		value |= LPSS_CS_CONTROL_CS_HIGH; +	}  	__lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value);  } @@ -734,7 +775,7 @@ static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)  	mul = (1 << 24) >> 1;  	/* Calculate initial quot */ -	q1 = DIV_ROUND_CLOSEST(fref1, rate); +	q1 = DIV_ROUND_UP(fref1, rate);  	/* Scale q1 if it's too big */  	if (q1 > 256) { @@ -759,7 +800,7 @@ static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)  	/* Case 2 */ -	q2 = DIV_ROUND_CLOSEST(fref2, rate); +	q2 = DIV_ROUND_UP(fref2, rate);  	r2 = abs(fref2 / q2 - rate);  	/* @@ -778,13 +819,13 @@ static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)  		mul = (1 << 24) * 2 / 5;  	} -	/* Check case 3 only If the divisor is big enough */ +	/* Check case 3 only if the divisor is big enough */  	if (fref / rate >= 80) {  		u64 fssp;  		u32 m;  		/* Calculate initial quot */ -		q1 = DIV_ROUND_CLOSEST(fref, rate); +		q1 = DIV_ROUND_UP(fref, rate);  		m = (1 << 24) / q1;  		/* Get the remainder */ @@ -806,7 +847,7 @@ static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)  static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)  { -	unsigned long ssp_clk = drv_data->max_clk_rate; +	unsigned long ssp_clk = drv_data->master->max_speed_hz;  	const struct ssp_device *ssp = drv_data->ssp;  	rate = min_t(int, ssp_clk, rate); @@ -818,8 +859,9 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)  }  static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, -					   struct chip_data *chip, int rate) +					   int rate)  { +	struct chip_data *chip = drv_data->cur_chip;  	unsigned int clk_div;  	switch (drv_data->ssp_type) { @@ -922,52 +964,55 @@ static void pump_transfers(unsigned long data)  	drv_data->read = drv_data->rx ? chip->read : null_reader;  	/* Change speed and bit per word on a per transfer */ -	cr0 = chip->cr0; -	if (transfer->speed_hz || transfer->bits_per_word) { - -		bits = chip->bits_per_word; -		speed = chip->speed_hz; - -		if (transfer->speed_hz) -			speed = transfer->speed_hz; - -		if (transfer->bits_per_word) -			bits = transfer->bits_per_word; - -		clk_div = pxa2xx_ssp_get_clk_div(drv_data, chip, speed); - -		if (bits <= 8) { -			drv_data->n_bytes = 1; -			drv_data->read = drv_data->read != null_reader ? -						u8_reader : null_reader; -			drv_data->write = drv_data->write != null_writer ? -						u8_writer : null_writer; -		} else if (bits <= 16) { -			drv_data->n_bytes = 2; -			drv_data->read = drv_data->read != null_reader ? -						u16_reader : null_reader; -			drv_data->write = drv_data->write != null_writer ? -						u16_writer : null_writer; -		} else if (bits <= 32) { -			drv_data->n_bytes = 4; -			drv_data->read = drv_data->read != null_reader ? -						u32_reader : null_reader; -			drv_data->write = drv_data->write != null_writer ? -						u32_writer : null_writer; -		} -		/* if bits/word is changed in dma mode, then must check the -		 * thresholds and burst also */ -		if (chip->enable_dma) { -			if (pxa2xx_spi_set_dma_burst_and_threshold(chip, -							message->spi, -							bits, &dma_burst, -							&dma_thresh)) -				dev_warn_ratelimited(&message->spi->dev, -						     "pump_transfers: DMA burst size reduced to match bits_per_word\n"); -		} - -		cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits); +	bits = transfer->bits_per_word; +	speed = transfer->speed_hz; + +	clk_div = pxa2xx_ssp_get_clk_div(drv_data, speed); + +	if (bits <= 8) { +		drv_data->n_bytes = 1; +		drv_data->read = drv_data->read != null_reader ? +					u8_reader : null_reader; +		drv_data->write = drv_data->write != null_writer ? +					u8_writer : null_writer; +	} else if (bits <= 16) { +		drv_data->n_bytes = 2; +		drv_data->read = drv_data->read != null_reader ? +					u16_reader : null_reader; +		drv_data->write = drv_data->write != null_writer ? +					u16_writer : null_writer; +	} else if (bits <= 32) { +		drv_data->n_bytes = 4; +		drv_data->read = drv_data->read != null_reader ? +					u32_reader : null_reader; +		drv_data->write = drv_data->write != null_writer ? +					u32_writer : null_writer;  	} +	/* +	 * if bits/word is changed in dma mode, then must check the +	 * thresholds and burst also +	 */ +	if (chip->enable_dma) { +		if (pxa2xx_spi_set_dma_burst_and_threshold(chip, +						message->spi, +						bits, &dma_burst, +						&dma_thresh)) +			dev_warn_ratelimited(&message->spi->dev, +					     "pump_transfers: DMA burst size reduced to match bits_per_word\n"); +	} + +	/* NOTE:  PXA25x_SSP _could_ use external clocking ... */ +	cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits); +	if (!pxa25x_ssp_comp(drv_data)) +		dev_dbg(&message->spi->dev, "%u Hz actual, %s\n", +			drv_data->master->max_speed_hz +				/ (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)), +			chip->enable_dma ? "DMA" : "PIO"); +	else +		dev_dbg(&message->spi->dev, "%u Hz actual, %s\n", +			drv_data->master->max_speed_hz / 2 +				/ (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)), +			chip->enable_dma ? "DMA" : "PIO");  	message->state = RUNNING_STATE; @@ -1111,7 +1156,6 @@ static int setup(struct spi_device *spi)  	struct chip_data *chip;  	const struct lpss_config *config;  	struct driver_data *drv_data = spi_master_get_devdata(spi->master); -	unsigned int clk_div;  	uint tx_thres, tx_hi_thres, rx_thres;  	switch (drv_data->ssp_type) { @@ -1123,6 +1167,7 @@ static int setup(struct spi_device *spi)  	case LPSS_LPT_SSP:  	case LPSS_BYT_SSP:  	case LPSS_SPT_SSP: +	case LPSS_BXT_SSP:  		config = lpss_get_config(drv_data);  		tx_thres = config->tx_threshold_lo;  		tx_hi_thres = config->tx_threshold_hi; @@ -1203,11 +1248,6 @@ static int setup(struct spi_device *spi)  		}  	} -	clk_div = pxa2xx_ssp_get_clk_div(drv_data, chip, spi->max_speed_hz); -	chip->speed_hz = spi->max_speed_hz; - -	chip->cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, -					   spi->bits_per_word);  	switch (drv_data->ssp_type) {  	case QUARK_X1000_SSP:  		chip->threshold = (QUARK_X1000_SSCR1_RxTresh(rx_thres) @@ -1228,18 +1268,6 @@ static int setup(struct spi_device *spi)  	if (spi->mode & SPI_LOOP)  		chip->cr1 |= SSCR1_LBM; -	/* NOTE:  PXA25x_SSP _could_ use external clocking ... */ -	if (!pxa25x_ssp_comp(drv_data)) -		dev_dbg(&spi->dev, "%ld Hz actual, %s\n", -			drv_data->max_clk_rate -				/ (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)), -			chip->enable_dma ? "DMA" : "PIO"); -	else -		dev_dbg(&spi->dev, "%ld Hz actual, %s\n", -			drv_data->max_clk_rate / 2 -				/ (1 + ((chip->cr0 & SSCR0_SCR(0x0ff)) >> 8)), -			chip->enable_dma ? "DMA" : "PIO"); -  	if (spi->bits_per_word <= 8) {  		chip->n_bytes = 1;  		chip->read = u8_reader; @@ -1249,13 +1277,10 @@ static int setup(struct spi_device *spi)  		chip->read = u16_reader;  		chip->write = u16_writer;  	} else if (spi->bits_per_word <= 32) { -		if (!is_quark_x1000_ssp(drv_data)) -			chip->cr0 |= SSCR0_EDSS;  		chip->n_bytes = 4;  		chip->read = u32_reader;  		chip->write = u32_writer;  	} -	chip->bits_per_word = spi->bits_per_word;  	spi_set_ctldata(spi, chip); @@ -1279,6 +1304,7 @@ static void cleanup(struct spi_device *spi)  	kfree(chip);  } +#ifdef CONFIG_PCI  #ifdef CONFIG_ACPI  static const struct acpi_device_id pxa2xx_spi_acpi_match[] = { @@ -1292,6 +1318,23 @@ static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {  };  MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); +static int pxa2xx_spi_get_port_id(struct acpi_device *adev) +{ +	unsigned int devid; +	int port_id = -1; + +	if (adev && adev->pnp.unique_id && +	    !kstrtouint(adev->pnp.unique_id, 0, &devid)) +		port_id = devid; +	return port_id; +} +#else /* !CONFIG_ACPI */ +static int pxa2xx_spi_get_port_id(struct acpi_device *adev) +{ +	return -1; +} +#endif +  /*   * PCI IDs of compound devices that integrate both host controller and private   * integrated DMA engine. Please note these are not used in module @@ -1304,6 +1347,14 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {  	/* SPT-H */  	{ PCI_VDEVICE(INTEL, 0xa129), LPSS_SPT_SSP },  	{ PCI_VDEVICE(INTEL, 0xa12a), LPSS_SPT_SSP }, +	/* BXT */ +	{ PCI_VDEVICE(INTEL, 0x0ac2), LPSS_BXT_SSP }, +	{ PCI_VDEVICE(INTEL, 0x0ac4), LPSS_BXT_SSP }, +	{ PCI_VDEVICE(INTEL, 0x0ac6), LPSS_BXT_SSP }, +	/* APL */ +	{ PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, +	{ PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, +	{ PCI_VDEVICE(INTEL, 0x5ac6), LPSS_BXT_SSP },  	{ },  }; @@ -1318,7 +1369,7 @@ static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)  }  static struct pxa2xx_spi_master * -pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) +pxa2xx_spi_init_pdata(struct platform_device *pdev)  {  	struct pxa2xx_spi_master *pdata;  	struct acpi_device *adev; @@ -1326,18 +1377,18 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)  	struct resource *res;  	const struct acpi_device_id *adev_id = NULL;  	const struct pci_device_id *pcidev_id = NULL; -	int devid, type; +	int type; -	if (!ACPI_HANDLE(&pdev->dev) || -	    acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) -		return NULL; +	adev = ACPI_COMPANION(&pdev->dev);  	if (dev_is_pci(pdev->dev.parent))  		pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match,  					 to_pci_dev(pdev->dev.parent)); -	else +	else if (adev)  		adev_id = acpi_match_device(pdev->dev.driver->acpi_match_table,  					    &pdev->dev); +	else +		return NULL;  	if (adev_id)  		type = (int)adev_id->driver_data; @@ -1371,10 +1422,7 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)  	ssp->irq = platform_get_irq(pdev, 0);  	ssp->type = type;  	ssp->pdev = pdev; - -	ssp->port_id = -1; -	if (adev->pnp.unique_id && !kstrtoint(adev->pnp.unique_id, 0, &devid)) -		ssp->port_id = devid; +	ssp->port_id = pxa2xx_spi_get_port_id(adev);  	pdata->num_chipselect = 1;  	pdata->enable_dma = true; @@ -1382,9 +1430,9 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)  	return pdata;  } -#else +#else /* !CONFIG_PCI */  static inline struct pxa2xx_spi_master * -pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) +pxa2xx_spi_init_pdata(struct platform_device *pdev)  {  	return NULL;  } @@ -1397,12 +1445,13 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)  	struct spi_master *master;  	struct driver_data *drv_data;  	struct ssp_device *ssp; +	const struct lpss_config *config;  	int status;  	u32 tmp;  	platform_info = dev_get_platdata(dev);  	if (!platform_info) { -		platform_info = pxa2xx_spi_acpi_get_pdata(pdev); +		platform_info = pxa2xx_spi_init_pdata(pdev);  		if (!platform_info) {  			dev_err(&pdev->dev, "missing platform data\n");  			return -ENODEV; @@ -1436,7 +1485,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;  	master->bus_num = ssp->port_id; -	master->num_chipselect = platform_info->num_chipselect;  	master->dma_alignment = DMA_ALIGNMENT;  	master->cleanup = cleanup;  	master->setup = setup; @@ -1489,7 +1537,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)  	/* Enable SOC clock */  	clk_prepare_enable(ssp->clk); -	drv_data->max_clk_rate = clk_get_rate(ssp->clk); +	master->max_speed_hz = clk_get_rate(ssp->clk);  	/* Load default SSP configuration */  	pxa2xx_spi_write(drv_data, SSCR0, 0); @@ -1522,6 +1570,19 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)  	if (is_lpss_ssp(drv_data))  		lpss_ssp_setup(drv_data); +	if (is_lpss_ssp(drv_data)) { +		lpss_ssp_setup(drv_data); +		config = lpss_get_config(drv_data); +		if (config->reg_capabilities >= 0) { +			tmp = __lpss_ssp_read_priv(drv_data, +						   config->reg_capabilities); +			tmp &= LPSS_CAPS_CS_EN_MASK; +			tmp >>= LPSS_CAPS_CS_EN_SHIFT; +			platform_info->num_chipselect = ffz(tmp); +		} +	} +	master->num_chipselect = platform_info->num_chipselect; +  	tasklet_init(&drv_data->pump_transfers, pump_transfers,  		     (unsigned long)drv_data); @@ -1614,8 +1675,6 @@ static int pxa2xx_spi_resume(struct device *dev)  	struct ssp_device *ssp = drv_data->ssp;  	int status = 0; -	pxa2xx_spi_dma_resume(drv_data); -  	/* Enable the SSP clock */  	if (!pm_runtime_suspended(dev))  		clk_prepare_enable(ssp->clk); diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h index 0a9b6390a817..58efa98313aa 100644 --- a/drivers/spi/spi-pxa2xx.h +++ b/drivers/spi/spi-pxa2xx.h @@ -46,9 +46,6 @@ struct driver_data {  	u32 clear_sr;  	u32 mask_sr; -	/* Maximun clock rate */ -	unsigned long max_clk_rate; -  	/* Message Transfer pump */  	struct tasklet_struct pump_transfers; @@ -86,10 +83,8 @@ struct driver_data {  };  struct chip_data { -	u32 cr0;  	u32 cr1;  	u32 dds_rate; -	u32 psp;  	u32 timeout;  	u8 n_bytes;  	u32 dma_burst_size; @@ -98,8 +93,6 @@ struct chip_data {  	u16 lpss_rx_threshold;  	u16 lpss_tx_threshold;  	u8 enable_dma; -	u8 bits_per_word; -	u32 speed_hz;  	union {  		int gpio_cs;  		unsigned int frm; @@ -175,7 +168,6 @@ extern int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst);  extern void pxa2xx_spi_dma_start(struct driver_data *drv_data);  extern int pxa2xx_spi_dma_setup(struct driver_data *drv_data);  extern void pxa2xx_spi_dma_release(struct driver_data *drv_data); -extern void pxa2xx_spi_dma_resume(struct driver_data *drv_data);  extern int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,  						  struct spi_device *spi,  						  u8 bits_per_word, @@ -196,7 +188,6 @@ static inline int pxa2xx_spi_dma_setup(struct driver_data *drv_data)  	return 0;  }  static inline void pxa2xx_spi_dma_release(struct driver_data *drv_data) {} -static inline void pxa2xx_spi_dma_resume(struct driver_data *drv_data) {}  static inline int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,  							 struct spi_device *spi,  							 u8 bits_per_word, diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index f36bc320a807..4e7d1bfed7e6 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -198,12 +198,12 @@ static int s3c24xx_spi_setup(struct spi_device *spi)  	if (ret)  		return ret; -	spin_lock(&hw->bitbang.lock); +	mutex_lock(&hw->bitbang.lock);  	if (!hw->bitbang.busy) {  		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);  		/* need to ndelay for 0.5 clocktick ? */  	} -	spin_unlock(&hw->bitbang.lock); +	mutex_unlock(&hw->bitbang.lock);  	return 0;  } diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index cd1cfac0447f..8e86e7f6663a 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -32,6 +32,7 @@  #define MAX_SPI_PORTS		6  #define S3C64XX_SPI_QUIRK_POLL		(1 << 0)  #define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1) +#define AUTOSUSPEND_TIMEOUT	2000  /* Registers and bit-fields */ @@ -682,7 +683,7 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,  	/* Only BPW and Speed may change across transfers */  	bpw = xfer->bits_per_word; -	speed = xfer->speed_hz ? : spi->max_speed_hz; +	speed = xfer->speed_hz;  	if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {  		sdd->cur_bpw = bpw; @@ -859,13 +860,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi)  		}  	} -	pm_runtime_put(&sdd->pdev->dev); +	pm_runtime_mark_last_busy(&sdd->pdev->dev); +	pm_runtime_put_autosuspend(&sdd->pdev->dev);  	if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))  		writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);  	return 0;  setup_exit: -	pm_runtime_put(&sdd->pdev->dev); +	pm_runtime_mark_last_busy(&sdd->pdev->dev); +	pm_runtime_put_autosuspend(&sdd->pdev->dev);  	/* setup() returns with device de-selected */  	if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))  		writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); @@ -1162,6 +1165,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  		goto err2;  	} +	pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); +	pm_runtime_use_autosuspend(&pdev->dev); +	pm_runtime_set_active(&pdev->dev); +	pm_runtime_enable(&pdev->dev); +	pm_runtime_get_sync(&pdev->dev); +  	/* Setup Deufult Mode */  	s3c64xx_spi_hwinit(sdd, sdd->port_id); @@ -1180,9 +1189,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  	       S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,  	       sdd->regs + S3C64XX_SPI_INT_EN); -	pm_runtime_set_active(&pdev->dev); -	pm_runtime_enable(&pdev->dev); -  	ret = devm_spi_register_master(&pdev->dev, master);  	if (ret != 0) {  		dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret); @@ -1195,9 +1201,16 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)  					mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1,  					sdd->rx_dma.dmach, sdd->tx_dma.dmach); +	pm_runtime_mark_last_busy(&pdev->dev); +	pm_runtime_put_autosuspend(&pdev->dev); +  	return 0;  err3: +	pm_runtime_put_noidle(&pdev->dev); +	pm_runtime_disable(&pdev->dev); +	pm_runtime_set_suspended(&pdev->dev); +  	clk_disable_unprepare(sdd->src_clk);  err2:  	clk_disable_unprepare(sdd->clk); @@ -1212,7 +1225,7 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)  	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); -	pm_runtime_disable(&pdev->dev); +	pm_runtime_get_sync(&pdev->dev);  	writel(0, sdd->regs + S3C64XX_SPI_INT_EN); @@ -1220,6 +1233,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)  	clk_disable_unprepare(sdd->clk); +	pm_runtime_put_noidle(&pdev->dev); +	pm_runtime_disable(&pdev->dev); +	pm_runtime_set_suspended(&pdev->dev); +  	return 0;  } @@ -1233,10 +1250,9 @@ static int s3c64xx_spi_suspend(struct device *dev)  	if (ret)  		return ret; -	if (!pm_runtime_suspended(dev)) { -		clk_disable_unprepare(sdd->clk); -		clk_disable_unprepare(sdd->src_clk); -	} +	ret = pm_runtime_force_suspend(dev); +	if (ret < 0) +		return ret;  	sdd->cur_speed = 0; /* Output Clock is stopped */ @@ -1248,14 +1264,14 @@ static int s3c64xx_spi_resume(struct device *dev)  	struct spi_master *master = dev_get_drvdata(dev);  	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);  	struct s3c64xx_spi_info *sci = sdd->cntrlr_info; +	int ret;  	if (sci->cfg_gpio)  		sci->cfg_gpio(); -	if (!pm_runtime_suspended(dev)) { -		clk_prepare_enable(sdd->src_clk); -		clk_prepare_enable(sdd->clk); -	} +	ret = pm_runtime_force_resume(dev); +	if (ret < 0) +		return ret;  	s3c64xx_spi_hwinit(sdd, sdd->port_id); diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index aa6d284131e0..64318fcfacf2 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -39,8 +39,6 @@ struct ti_qspi_regs {  };  struct ti_qspi { -	struct completion       transfer_complete; -  	/* list synchronization */  	struct mutex            list_lock; @@ -62,10 +60,6 @@ struct ti_qspi {  #define QSPI_PID			(0x0)  #define QSPI_SYSCONFIG			(0x10) -#define QSPI_INTR_STATUS_RAW_SET	(0x20) -#define QSPI_INTR_STATUS_ENABLED_CLEAR	(0x24) -#define QSPI_INTR_ENABLE_SET_REG	(0x28) -#define QSPI_INTR_ENABLE_CLEAR_REG	(0x2c)  #define QSPI_SPI_CLOCK_CNTRL_REG	(0x40)  #define QSPI_SPI_DC_REG			(0x44)  #define QSPI_SPI_CMD_REG		(0x48) @@ -97,7 +91,6 @@ struct ti_qspi {  #define QSPI_RD_DUAL			(3 << 16)  #define QSPI_RD_QUAD			(7 << 16)  #define QSPI_INVAL			(4 << 16) -#define QSPI_WC_CMD_INT_EN			(1 << 14)  #define QSPI_FLEN(n)			((n - 1) << 0)  #define QSPI_WLEN_MAX_BITS		128  #define QSPI_WLEN_MAX_BYTES		16 @@ -106,10 +99,6 @@ struct ti_qspi {  #define BUSY				0x01  #define WC				0x02 -/* INTERRUPT REGISTER */ -#define QSPI_WC_INT_EN				(1 << 1) -#define QSPI_WC_INT_DISABLE			(1 << 1) -  /* Device Control */  #define QSPI_DD(m, n)			(m << (3 + n * 8))  #define QSPI_CKPHA(n)			(1 << (2 + n * 8)) @@ -217,6 +206,24 @@ static inline u32 qspi_is_busy(struct ti_qspi *qspi)  	return stat & BUSY;  } +static inline int ti_qspi_poll_wc(struct ti_qspi *qspi) +{ +	u32 stat; +	unsigned long timeout = jiffies + QSPI_COMPLETION_TIMEOUT; + +	do { +		stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); +		if (stat & WC) +			return 0; +		cpu_relax(); +	} while (time_after(timeout, jiffies)); + +	stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); +	if (stat & WC) +		return 0; +	return  -ETIMEDOUT; +} +  static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)  {  	int wlen, count, xfer_len; @@ -275,8 +282,7 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)  		}  		ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); -		if (!wait_for_completion_timeout(&qspi->transfer_complete, -						 QSPI_COMPLETION_TIMEOUT)) { +		if (ti_qspi_poll_wc(qspi)) {  			dev_err(qspi->dev, "write timed out\n");  			return -ETIMEDOUT;  		} @@ -315,8 +321,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)  			return -EBUSY;  		ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); -		if (!wait_for_completion_timeout(&qspi->transfer_complete, -						 QSPI_COMPLETION_TIMEOUT)) { +		if (ti_qspi_poll_wc(qspi)) {  			dev_err(qspi->dev, "read timed out\n");  			return -ETIMEDOUT;  		} @@ -388,9 +393,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,  	qspi->cmd = 0;  	qspi->cmd |= QSPI_EN_CS(spi->chip_select);  	qspi->cmd |= QSPI_FLEN(frame_length); -	qspi->cmd |= QSPI_WC_CMD_INT_EN; -	ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG);  	ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG);  	mutex_lock(&qspi->list_lock); @@ -410,39 +413,13 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,  	mutex_unlock(&qspi->list_lock); +	ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);  	m->status = status;  	spi_finalize_current_message(master); -	ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG); -  	return status;  } -static irqreturn_t ti_qspi_isr(int irq, void *dev_id) -{ -	struct ti_qspi *qspi = dev_id; -	u16 int_stat; -	u32 stat; - -	irqreturn_t ret = IRQ_HANDLED; - -	int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); -	stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); - -	if (!int_stat) { -		dev_dbg(qspi->dev, "No IRQ triggered\n"); -		ret = IRQ_NONE; -		goto out; -	} - -	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, -				QSPI_INTR_STATUS_ENABLED_CLEAR); -	if (stat & WC) -		complete(&qspi->transfer_complete); -out: -	return ret; -} -  static int ti_qspi_runtime_resume(struct device *dev)  {  	struct ti_qspi      *qspi; @@ -551,22 +528,12 @@ static int ti_qspi_probe(struct platform_device *pdev)  		}  	} -	ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, -			dev_name(&pdev->dev), qspi); -	if (ret < 0) { -		dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", -				irq); -		goto free_master; -	} -  	qspi->fclk = devm_clk_get(&pdev->dev, "fck");  	if (IS_ERR(qspi->fclk)) {  		ret = PTR_ERR(qspi->fclk);  		dev_err(&pdev->dev, "could not get clk: %d\n", ret);  	} -	init_completion(&qspi->transfer_complete); -  	pm_runtime_use_autosuspend(&pdev->dev);  	pm_runtime_set_autosuspend_delay(&pdev->dev, QSPI_AUTOSUSPEND_TIMEOUT);  	pm_runtime_enable(&pdev->dev); @@ -587,18 +554,7 @@ free_master:  static int ti_qspi_remove(struct platform_device *pdev)  { -	struct ti_qspi *qspi = platform_get_drvdata(pdev); -	int ret; - -	ret = pm_runtime_get_sync(qspi->dev); -	if (ret < 0) { -		dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); -		return ret; -	} - -	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); - -	pm_runtime_put(qspi->dev); +	pm_runtime_put_sync(&pdev->dev);  	pm_runtime_disable(&pdev->dev);  	return 0; diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c index daf5aa1c24c3..c6ae775289e5 100644 --- a/drivers/spi/spi-tle62x0.c +++ b/drivers/spi/spi-tle62x0.c @@ -307,7 +307,6 @@ static int tle62x0_remove(struct spi_device *spi)  static struct spi_driver tle62x0_driver = {  	.driver = {  		.name	= "tle62x0", -		.owner	= THIS_MODULE,  	},  	.probe		= tle62x0_probe,  	.remove		= tle62x0_remove, diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index 9190124b6d90..d69f8f8f3fa6 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -181,7 +181,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)  		u32 data;  		unsigned int len = t->len;  		unsigned int wsize; -		u32 speed_hz = t->speed_hz ? : spi->max_speed_hz; +		u32 speed_hz = t->speed_hz;  		u8 bits_per_word = t->bits_per_word;  		wsize = bits_per_word >> 3; /* in bytes */ diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index a339c1e9997a..3009121173cd 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -270,6 +270,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  	while (remaining_words) {  		int n_words, tx_words, rx_words; +		u32 sr;  		n_words = min(remaining_words, xspi->buffer_size); @@ -284,24 +285,33 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)  		if (use_irq) {  			xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);  			wait_for_completion(&xspi->done); -		} else -			while (!(xspi->read_fn(xspi->regs + XSPI_SR_OFFSET) & -						XSPI_SR_TX_EMPTY_MASK)) -				; - -		/* A transmit has just completed. Process received data and -		 * check for more data to transmit. Always inhibit the -		 * transmitter while the Isr refills the transmit register/FIFO, -		 * or make sure it is stopped if we're done. -		 */ -		if (use_irq) +			/* A transmit has just completed. Process received data +			 * and check for more data to transmit. Always inhibit +			 * the transmitter while the Isr refills the transmit +			 * register/FIFO, or make sure it is stopped if we're +			 * done. +			 */  			xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, -			       xspi->regs + XSPI_CR_OFFSET); +				       xspi->regs + XSPI_CR_OFFSET); +			sr = XSPI_SR_TX_EMPTY_MASK; +		} else +			sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);  		/* Read out all the data from the Rx FIFO */  		rx_words = n_words; -		while (rx_words--) -			xilinx_spi_rx(xspi); +		while (rx_words) { +			if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) { +				xilinx_spi_rx(xspi); +				rx_words--; +				continue; +			} + +			sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); +			if (!(sr & XSPI_SR_RX_EMPTY_MASK)) { +				xilinx_spi_rx(xspi); +				rx_words--; +			} +		}  		remaining_words -= n_words;  	} diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a5f53de813d3..e2415be209d5 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -123,6 +123,28 @@ SPI_STATISTICS_SHOW(bytes, "%llu");  SPI_STATISTICS_SHOW(bytes_rx, "%llu");  SPI_STATISTICS_SHOW(bytes_tx, "%llu"); +#define SPI_STATISTICS_TRANSFER_BYTES_HISTO(index, number)		\ +	SPI_STATISTICS_SHOW_NAME(transfer_bytes_histo##index,		\ +				 "transfer_bytes_histo_" number,	\ +				 transfer_bytes_histo[index],  "%lu") +SPI_STATISTICS_TRANSFER_BYTES_HISTO(0,  "0-1"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(1,  "2-3"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(2,  "4-7"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(3,  "8-15"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(4,  "16-31"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(5,  "32-63"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(6,  "64-127"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(7,  "128-255"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(8,  "256-511"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(9,  "512-1023"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(10, "1024-2047"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(11, "2048-4095"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(12, "4096-8191"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(13, "8192-16383"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(14, "16384-32767"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(15, "32768-65535"); +SPI_STATISTICS_TRANSFER_BYTES_HISTO(16, "65536+"); +  static struct attribute *spi_dev_attrs[] = {  	&dev_attr_modalias.attr,  	NULL, @@ -143,6 +165,23 @@ static struct attribute *spi_device_statistics_attrs[] = {  	&dev_attr_spi_device_bytes.attr,  	&dev_attr_spi_device_bytes_rx.attr,  	&dev_attr_spi_device_bytes_tx.attr, +	&dev_attr_spi_device_transfer_bytes_histo0.attr, +	&dev_attr_spi_device_transfer_bytes_histo1.attr, +	&dev_attr_spi_device_transfer_bytes_histo2.attr, +	&dev_attr_spi_device_transfer_bytes_histo3.attr, +	&dev_attr_spi_device_transfer_bytes_histo4.attr, +	&dev_attr_spi_device_transfer_bytes_histo5.attr, +	&dev_attr_spi_device_transfer_bytes_histo6.attr, +	&dev_attr_spi_device_transfer_bytes_histo7.attr, +	&dev_attr_spi_device_transfer_bytes_histo8.attr, +	&dev_attr_spi_device_transfer_bytes_histo9.attr, +	&dev_attr_spi_device_transfer_bytes_histo10.attr, +	&dev_attr_spi_device_transfer_bytes_histo11.attr, +	&dev_attr_spi_device_transfer_bytes_histo12.attr, +	&dev_attr_spi_device_transfer_bytes_histo13.attr, +	&dev_attr_spi_device_transfer_bytes_histo14.attr, +	&dev_attr_spi_device_transfer_bytes_histo15.attr, +	&dev_attr_spi_device_transfer_bytes_histo16.attr,  	NULL,  }; @@ -168,6 +207,23 @@ static struct attribute *spi_master_statistics_attrs[] = {  	&dev_attr_spi_master_bytes.attr,  	&dev_attr_spi_master_bytes_rx.attr,  	&dev_attr_spi_master_bytes_tx.attr, +	&dev_attr_spi_master_transfer_bytes_histo0.attr, +	&dev_attr_spi_master_transfer_bytes_histo1.attr, +	&dev_attr_spi_master_transfer_bytes_histo2.attr, +	&dev_attr_spi_master_transfer_bytes_histo3.attr, +	&dev_attr_spi_master_transfer_bytes_histo4.attr, +	&dev_attr_spi_master_transfer_bytes_histo5.attr, +	&dev_attr_spi_master_transfer_bytes_histo6.attr, +	&dev_attr_spi_master_transfer_bytes_histo7.attr, +	&dev_attr_spi_master_transfer_bytes_histo8.attr, +	&dev_attr_spi_master_transfer_bytes_histo9.attr, +	&dev_attr_spi_master_transfer_bytes_histo10.attr, +	&dev_attr_spi_master_transfer_bytes_histo11.attr, +	&dev_attr_spi_master_transfer_bytes_histo12.attr, +	&dev_attr_spi_master_transfer_bytes_histo13.attr, +	&dev_attr_spi_master_transfer_bytes_histo14.attr, +	&dev_attr_spi_master_transfer_bytes_histo15.attr, +	&dev_attr_spi_master_transfer_bytes_histo16.attr,  	NULL,  }; @@ -186,10 +242,15 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats,  				       struct spi_master *master)  {  	unsigned long flags; +	int l2len = min(fls(xfer->len), SPI_STATISTICS_HISTO_SIZE) - 1; + +	if (l2len < 0) +		l2len = 0;  	spin_lock_irqsave(&stats->lock, flags);  	stats->transfers++; +	stats->transfer_bytes_histo[l2len]++;  	stats->bytes += xfer->len;  	if ((xfer->tx_buf) && @@ -270,15 +331,24 @@ EXPORT_SYMBOL_GPL(spi_bus_type);  static int spi_drv_probe(struct device *dev)  {  	const struct spi_driver		*sdrv = to_spi_driver(dev->driver); +	struct spi_device		*spi = to_spi_device(dev);  	int ret;  	ret = of_clk_set_defaults(dev->of_node, false);  	if (ret)  		return ret; +	if (dev->of_node) { +		spi->irq = of_irq_get(dev->of_node, 0); +		if (spi->irq == -EPROBE_DEFER) +			return -EPROBE_DEFER; +		if (spi->irq < 0) +			spi->irq = 0; +	} +  	ret = dev_pm_domain_attach(dev, true);  	if (ret != -EPROBE_DEFER) { -		ret = sdrv->probe(to_spi_device(dev)); +		ret = sdrv->probe(spi);  		if (ret)  			dev_pm_domain_detach(dev, true);  	} @@ -305,12 +375,15 @@ static void spi_drv_shutdown(struct device *dev)  }  /** - * spi_register_driver - register a SPI driver + * __spi_register_driver - register a SPI driver   * @sdrv: the driver to register   * Context: can sleep + * + * Return: zero on success, else a negative error code.   */ -int spi_register_driver(struct spi_driver *sdrv) +int __spi_register_driver(struct module *owner, struct spi_driver *sdrv)  { +	sdrv->driver.owner = owner;  	sdrv->driver.bus = &spi_bus_type;  	if (sdrv->probe)  		sdrv->driver.probe = spi_drv_probe; @@ -320,7 +393,7 @@ int spi_register_driver(struct spi_driver *sdrv)  		sdrv->driver.shutdown = spi_drv_shutdown;  	return driver_register(&sdrv->driver);  } -EXPORT_SYMBOL_GPL(spi_register_driver); +EXPORT_SYMBOL_GPL(__spi_register_driver);  /*-------------------------------------------------------------------------*/ @@ -359,7 +432,7 @@ static DEFINE_MUTEX(board_lock);   * needs to discard the spi_device without adding it, then it should   * call spi_dev_put() on it.   * - * Returns a pointer to the new device, or NULL. + * Return: a pointer to the new device, or NULL.   */  struct spi_device *spi_alloc_device(struct spi_master *master)  { @@ -418,7 +491,7 @@ static int spi_dev_check(struct device *dev, void *data)   * Companion function to spi_alloc_device.  Devices allocated with   * spi_alloc_device can be added onto the spi bus with this function.   * - * Returns 0 on success; negative errno on failure + * Return: 0 on success; negative errno on failure   */  int spi_add_device(struct spi_device *spi)  { @@ -491,7 +564,7 @@ EXPORT_SYMBOL_GPL(spi_add_device);   * this is exported so that for example a USB or parport based adapter   * driver could add devices (which it would learn about out-of-band).   * - * Returns the new device, or NULL. + * Return: the new device, or NULL.   */  struct spi_device *spi_new_device(struct spi_master *master,  				  struct spi_board_info *chip) @@ -563,6 +636,8 @@ static void spi_match_master_to_boardinfo(struct spi_master *master,   *   * The board info passed can safely be __initdata ... but be careful of   * any embedded pointers (platform_data, etc), they're copied as-is. + * + * Return: zero on success, else a negative error code.   */  int spi_register_board_info(struct spi_board_info const *info, unsigned n)  { @@ -597,7 +672,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable)  	if (spi->mode & SPI_CS_HIGH)  		enable = !enable; -	if (spi->cs_gpio >= 0) +	if (gpio_is_valid(spi->cs_gpio))  		gpio_set_value(spi->cs_gpio, !enable);  	else if (spi->master->set_cs)  		spi->master->set_cs(spi, !enable); @@ -1140,6 +1215,8 @@ static int spi_init_queue(struct spi_master *master)   *   * If there are more messages in the queue, the next message is returned from   * this call. + * + * Return: the next message in the queue, else NULL if the queue is empty.   */  struct spi_message *spi_get_next_queued_message(struct spi_master *master)  { @@ -1303,6 +1380,8 @@ static int __spi_queued_transfer(struct spi_device *spi,   * spi_queued_transfer - transfer function for queued transfers   * @spi: spi device which is requesting transfer   * @msg: spi message which is to handled is queued to driver queue + * + * Return: zero on success, else a negative error code.   */  static int spi_queued_transfer(struct spi_device *spi, struct spi_message *msg)  { @@ -1433,9 +1512,6 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc)  	}  	spi->max_speed_hz = value; -	/* IRQ */ -	spi->irq = irq_of_parse_and_map(nc, 0); -  	/* Store a pointer to the node in the device structure */  	of_node_get(nc);  	spi->dev.of_node = nc; @@ -1605,12 +1681,13 @@ static struct class spi_master_class = {   * only ones directly touching chip registers.  It's how they allocate   * an spi_master structure, prior to calling spi_register_master().   * - * This must be called from context that can sleep.  It returns the SPI - * master structure on success, else NULL. + * This must be called from context that can sleep.   *   * The caller is responsible for assigning the bus number and initializing   * the master's methods before calling spi_register_master(); and (after errors   * adding the device) calling spi_master_put() to prevent a memory leak. + * + * Return: the SPI master structure on success, else NULL.   */  struct spi_master *spi_alloc_master(struct device *dev, unsigned size)  { @@ -1694,6 +1771,8 @@ static int of_spi_register_master(struct spi_master *master)   * success, else a negative error code (dropping the master's refcount).   * After a successful return, the caller is responsible for calling   * spi_unregister_master(). + * + * Return: zero on success, else a negative error code.   */  int spi_register_master(struct spi_master *master)  { @@ -1787,6 +1866,8 @@ static void devm_spi_unregister(struct device *dev, void *res)   *   * Register a SPI device as with spi_register_master() which will   * automatically be unregister + * + * Return: zero on success, else a negative error code.   */  int devm_spi_register_master(struct device *dev, struct spi_master *master)  { @@ -1892,6 +1973,8 @@ static int __spi_master_match(struct device *dev, const void *data)   * arch init time.  It returns a refcounted pointer to the relevant   * spi_master (which the caller must release), or NULL if there is   * no such master registered. + * + * Return: the SPI master structure on success, else NULL.   */  struct spi_master *spi_busnum_to_master(u16 bus_num)  { @@ -1945,11 +2028,13 @@ static int __spi_validate_bits_per_word(struct spi_master *master, u8 bits_per_w   * 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. + * + * Return: zero on success, else a negative error code.   */  int spi_setup(struct spi_device *spi)  {  	unsigned	bad_bits, ugly_bits; -	int		status = 0; +	int		status;  	/* check mode to prevent that DUAL and QUAD set at the same time  	 */ @@ -1986,17 +2071,18 @@ int spi_setup(struct spi_device *spi)  	if (!spi->bits_per_word)  		spi->bits_per_word = 8; -	if (__spi_validate_bits_per_word(spi->master, spi->bits_per_word)) -		return -EINVAL; +	status = __spi_validate_bits_per_word(spi->master, spi->bits_per_word); +	if (status) +		return status;  	if (!spi->max_speed_hz)  		spi->max_speed_hz = spi->master->max_speed_hz; -	spi_set_cs(spi, false); -  	if (spi->master->setup)  		status = spi->master->setup(spi); +	spi_set_cs(spi, false); +  	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, " : "", @@ -2162,6 +2248,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)   * no other spi_message queued to that device will be processed.   * (This rule applies equally to all the synchronous transfer calls,   * which are wrappers around this core asynchronous primitive.) + * + * Return: zero on success, else a negative error code.   */  int spi_async(struct spi_device *spi, struct spi_message *message)  { @@ -2214,6 +2302,8 @@ EXPORT_SYMBOL_GPL(spi_async);   * no other spi_message queued to that device will be processed.   * (This rule applies equally to all the synchronous transfer calls,   * which are wrappers around this core asynchronous primitive.) + * + * Return: zero on success, else a negative error code.   */  int spi_async_locked(struct spi_device *spi, struct spi_message *message)  { @@ -2329,7 +2419,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,   * Also, the caller is guaranteeing that the memory associated with the   * message will not be freed before this call returns.   * - * It returns zero on success, else a negative error code. + * Return: zero on success, else a negative error code.   */  int spi_sync(struct spi_device *spi, struct spi_message *message)  { @@ -2351,7 +2441,7 @@ EXPORT_SYMBOL_GPL(spi_sync);   * SPI bus. It has to be preceded by a spi_bus_lock call. The SPI bus must   * be released by a spi_bus_unlock call when the exclusive access is over.   * - * It returns zero on success, else a negative error code. + * Return: zero on success, else a negative error code.   */  int spi_sync_locked(struct spi_device *spi, struct spi_message *message)  { @@ -2372,7 +2462,7 @@ EXPORT_SYMBOL_GPL(spi_sync_locked);   * exclusive access is over. Data transfer must be done by spi_sync_locked   * and spi_async_locked calls when the SPI bus lock is held.   * - * It returns zero on success, else a negative error code. + * Return: always zero.   */  int spi_bus_lock(struct spi_master *master)  { @@ -2401,7 +2491,7 @@ EXPORT_SYMBOL_GPL(spi_bus_lock);   * This call releases an SPI bus lock previously obtained by an spi_bus_lock   * call.   * - * It returns zero on success, else a negative error code. + * Return: always zero.   */  int spi_bus_unlock(struct spi_master *master)  { @@ -2436,6 +2526,8 @@ static u8	*buf;   * portable code should never use this for more than 32 bytes.   * Performance-sensitive or bulk transfer code should instead use   * spi_{async,sync}() calls with dma-safe buffers. + * + * Return: zero on success, else a negative error code.   */  int spi_write_then_read(struct spi_device *spi,  		const void *txbuf, unsigned n_tx, diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index ef008e52f953..91a0fcd72423 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -788,7 +788,6 @@ static int spidev_remove(struct spi_device *spi)  static struct spi_driver spidev_spi_driver = {  	.driver = {  		.name =		"spidev", -		.owner =	THIS_MODULE,  		.of_match_table = of_match_ptr(spidev_dt_ids),  	},  	.probe =	spidev_probe, |