Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84c6a81b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull misc SPI device driver bug fixes from Grant Likely.

* tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6:
  spi/spi-bfin5xx: Fix flush of last bit after each spi transfer
  spi/spi-bfin5xx: fix reversed if condition in interrupt mode
  spi/spi_bfin_sport: drop bits_per_word from client data
  spi/bfin_spi: drop bits_per_word from client data
  spi/spi-bfin-sport: move word length setup to transfer handler
  spi/bfin5xx: rename config macro name for bfin5xx spi controller driver
  spi/pl022: Allow request for higher frequency than maximum possible
  spi/bcm63xx: set master driver mode_bits.
  spi/bcm63xx: don't use the stopping state
  spi/bcm63xx: convert to the pump message infrastructure
  spi/spi-ep93xx.c: use dma_transfer_direction instead of dma_data_direction
  spi: fix spi.h kernel-doc warning
  spi/pl022: Fix calculate_effective_freq()
  spi/pl022: Fix range checking for bits per word
parents 9f7e2f90 2431a815
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -74,7 +74,7 @@ config SPI_ATMEL
	  This selects a driver for the Atmel SPI Controller, present on
	  This selects a driver for the Atmel SPI Controller, present on
	  many AT32 (AVR32) and AT91 (ARM) chips.
	  many AT32 (AVR32) and AT91 (ARM) chips.


config SPI_BFIN
config SPI_BFIN5XX
	tristate "SPI controller driver for ADI Blackfin5xx"
	tristate "SPI controller driver for ADI Blackfin5xx"
	depends on BLACKFIN
	depends on BLACKFIN
	help
	help
+1 −1
Original line number Original line Diff line number Diff line
@@ -15,7 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o
obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o
obj-$(CONFIG_SPI_BFIN)			+= spi-bfin5xx.o
obj-$(CONFIG_SPI_BFIN5XX)		+= spi-bfin5xx.o
obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o
obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi-bfin-sport.o
obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o
obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o
obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o
+92 −71
Original line number Original line Diff line number Diff line
/*
/*
 * Broadcom BCM63xx SPI controller support
 * Broadcom BCM63xx SPI controller support
 *
 *
 * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org>
 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
@@ -30,6 +30,8 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>
#include <linux/completion.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/workqueue.h>
#include <linux/pm_runtime.h>


#include <bcm63xx_dev_spi.h>
#include <bcm63xx_dev_spi.h>


@@ -37,8 +39,6 @@
#define DRV_VER		"0.1.2"
#define DRV_VER		"0.1.2"


struct bcm63xx_spi {
struct bcm63xx_spi {
	spinlock_t		lock;
	int			stopping;
	struct completion	done;
	struct completion	done;


	void __iomem		*regs;
	void __iomem		*regs;
@@ -96,17 +96,12 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
	{   391000, SPI_CLK_0_391MHZ }
	{   391000, SPI_CLK_0_391MHZ }
};
};


static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
static int bcm63xx_spi_check_transfer(struct spi_device *spi,
					struct spi_transfer *t)
					struct spi_transfer *t)
{
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	u8 bits_per_word;
	u8 bits_per_word;
	u8 clk_cfg, reg;
	u32 hz;
	int i;


	bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
	bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
	hz = (t) ? t->speed_hz : spi->max_speed_hz;
	if (bits_per_word != 8) {
	if (bits_per_word != 8) {
		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
			__func__, bits_per_word);
			__func__, bits_per_word);
@@ -119,6 +114,19 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
		return -EINVAL;
		return -EINVAL;
	}
	}


	return 0;
}

static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
				      struct spi_transfer *t)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	u32 hz;
	u8 clk_cfg, reg;
	int i;

	hz = (t) ? t->speed_hz : spi->max_speed_hz;

	/* Find the closest clock configuration */
	/* Find the closest clock configuration */
	for (i = 0; i < SPI_CLK_MASK; i++) {
	for (i = 0; i < SPI_CLK_MASK; i++) {
		if (hz <= bcm63xx_spi_freq_table[i][0]) {
		if (hz <= bcm63xx_spi_freq_table[i][0]) {
@@ -139,8 +147,6 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
	bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
	bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
	dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
	dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
		clk_cfg, hz);
		clk_cfg, hz);

	return 0;
}
}


/* the spi->mode bits understood by this driver: */
/* the spi->mode bits understood by this driver: */
@@ -153,9 +159,6 @@ static int bcm63xx_spi_setup(struct spi_device *spi)


	bs = spi_master_get_devdata(spi->master);
	bs = spi_master_get_devdata(spi->master);


	if (bs->stopping)
		return -ESHUTDOWN;

	if (!spi->bits_per_word)
	if (!spi->bits_per_word)
		spi->bits_per_word = 8;
		spi->bits_per_word = 8;


@@ -165,7 +168,7 @@ static int bcm63xx_spi_setup(struct spi_device *spi)
		return -EINVAL;
		return -EINVAL;
	}
	}


	ret = bcm63xx_spi_setup_transfer(spi, NULL);
	ret = bcm63xx_spi_check_transfer(spi, NULL);
	if (ret < 0) {
	if (ret < 0) {
		dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
		dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
			spi->mode & ~MODEBITS);
			spi->mode & ~MODEBITS);
@@ -190,28 +193,29 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
	bs->remaining_bytes -= size;
	bs->remaining_bytes -= size;
}
}


static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
					struct spi_transfer *t)
{
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	u16 msg_ctl;
	u16 msg_ctl;
	u16 cmd;
	u16 cmd;


	/* Disable the CMD_DONE interrupt */
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);

	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
		t->tx_buf, t->rx_buf, t->len);
		t->tx_buf, t->rx_buf, t->len);


	/* Transmitter is inhibited */
	/* Transmitter is inhibited */
	bs->tx_ptr = t->tx_buf;
	bs->tx_ptr = t->tx_buf;
	bs->rx_ptr = t->rx_buf;
	bs->rx_ptr = t->rx_buf;
	init_completion(&bs->done);


	if (t->tx_buf) {
	if (t->tx_buf) {
		bs->remaining_bytes = t->len;
		bs->remaining_bytes = t->len;
		bcm63xx_spi_fill_tx_fifo(bs);
		bcm63xx_spi_fill_tx_fifo(bs);
	}
	}


	/* Enable the command done interrupt which
	init_completion(&bs->done);
	 * we use to determine completion of a command */
	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);


	/* Fill in the Message control register */
	/* Fill in the Message control register */
	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
@@ -230,33 +234,76 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
	cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
	cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
	cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
	cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
	bcm_spi_writew(bs, cmd, SPI_CMD);
	bcm_spi_writew(bs, cmd, SPI_CMD);
	wait_for_completion(&bs->done);


	/* Disable the CMD_DONE interrupt */
	/* Enable the CMD_DONE interrupt */
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);
	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);


	return t->len - bs->remaining_bytes;
	return t->len - bs->remaining_bytes;
}
}


static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m)
static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
{
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	struct spi_transfer *t;
	int ret = 0;


	if (unlikely(list_empty(&m->transfers)))
	pm_runtime_get_sync(&bs->pdev->dev);
		return -EINVAL;

	return 0;
}

static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);

	pm_runtime_put(&bs->pdev->dev);


	if (bs->stopping)
	return 0;
		return -ESHUTDOWN;
}

static int bcm63xx_spi_transfer_one(struct spi_master *master,
					struct spi_message *m)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	struct spi_transfer *t;
	struct spi_device *spi = m->spi;
	int status = 0;
	unsigned int timeout = 0;


	list_for_each_entry(t, &m->transfers, transfer_list) {
	list_for_each_entry(t, &m->transfers, transfer_list) {
		ret += bcm63xx_txrx_bufs(spi, t);
		unsigned int len = t->len;
		u8 rx_tail;

		status = bcm63xx_spi_check_transfer(spi, t);
		if (status < 0)
			goto exit;

		/* configure adapter for a new transfer */
		bcm63xx_spi_setup_transfer(spi, t);

		while (len) {
			/* send the data */
			len -= bcm63xx_txrx_bufs(spi, t);

			timeout = wait_for_completion_timeout(&bs->done, HZ);
			if (!timeout) {
				status = -ETIMEDOUT;
				goto exit;
			}
			}


	m->complete(m->context);
			/* read out all data */
			rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);


	return ret;
			/* Read out all the data */
			if (rx_tail)
				memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
		}

		m->actual_length += t->len;
	}
exit:
	m->status = status;
	spi_finalize_current_message(master);

	return 0;
}
}


/* This driver supports single master mode only. Hence
/* This driver supports single master mode only. Hence
@@ -267,39 +314,15 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
	struct spi_master *master = (struct spi_master *)dev_id;
	struct spi_master *master = (struct spi_master *)dev_id;
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	u8 intr;
	u8 intr;
	u16 cmd;


	/* Read interupts and clear them immediately */
	/* Read interupts and clear them immediately */
	intr = bcm_spi_readb(bs, SPI_INT_STATUS);
	intr = bcm_spi_readb(bs, SPI_INT_STATUS);
	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);


	/* A tansfer completed */
	/* A transfer completed */
	if (intr & SPI_INTR_CMD_DONE) {
	if (intr & SPI_INTR_CMD_DONE)
		u8 rx_tail;

		rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);

		/* Read out all the data */
		if (rx_tail)
			memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);

		/* See if there is more data to send */
		if (bs->remaining_bytes > 0) {
			bcm63xx_spi_fill_tx_fifo(bs);

			/* Start the transfer */
			bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT,
				       SPI_MSG_CTL);
			cmd = bcm_spi_readw(bs, SPI_CMD);
			cmd |= SPI_CMD_START_IMMEDIATE;
			cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
			bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
			bcm_spi_writew(bs, cmd, SPI_CMD);
		} else {
		complete(&bs->done);
		complete(&bs->done);
		}
	}


	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}
@@ -345,7 +368,6 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
	}
	}


	bs = spi_master_get_devdata(master);
	bs = spi_master_get_devdata(master);
	init_completion(&bs->done);


	platform_set_drvdata(pdev, master);
	platform_set_drvdata(pdev, master);
	bs->pdev = pdev;
	bs->pdev = pdev;
@@ -379,12 +401,13 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
	master->bus_num = pdata->bus_num;
	master->bus_num = pdata->bus_num;
	master->num_chipselect = pdata->num_chipselect;
	master->num_chipselect = pdata->num_chipselect;
	master->setup = bcm63xx_spi_setup;
	master->setup = bcm63xx_spi_setup;
	master->transfer = bcm63xx_transfer;
	master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
	master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
	master->transfer_one_message = bcm63xx_spi_transfer_one;
	master->mode_bits = MODEBITS;
	bs->speed_hz = pdata->speed_hz;
	bs->speed_hz = pdata->speed_hz;
	bs->stopping = 0;
	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
	spin_lock_init(&bs->lock);


	/* Initialize hardware */
	/* Initialize hardware */
	clk_enable(bs->clk);
	clk_enable(bs->clk);
@@ -418,18 +441,16 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev)
	struct spi_master *master = platform_get_drvdata(pdev);
	struct spi_master *master = platform_get_drvdata(pdev);
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);


	spi_unregister_master(master);

	/* reset spi block */
	/* reset spi block */
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);
	spin_lock(&bs->lock);
	bs->stopping = 1;


	/* HW shutdown */
	/* HW shutdown */
	clk_disable(bs->clk);
	clk_disable(bs->clk);
	clk_put(bs->clk);
	clk_put(bs->clk);


	spin_unlock(&bs->lock);
	platform_set_drvdata(pdev, 0);
	platform_set_drvdata(pdev, 0);
	spi_unregister_master(master);


	return 0;
	return 0;
}
}
+11 −10
Original line number Original line Diff line number Diff line
@@ -252,19 +252,15 @@ static void
bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)
bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)
{
{
	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
	unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15);


	bfin_sport_spi_disable(drv_data);
	bfin_sport_spi_disable(drv_data);
	dev_dbg(drv_data->dev, "restoring spi ctl state\n");
	dev_dbg(drv_data->dev, "restoring spi ctl state\n");


	bfin_write(&drv_data->regs->tcr1, chip->ctl_reg);
	bfin_write(&drv_data->regs->tcr1, chip->ctl_reg);
	bfin_write(&drv_data->regs->tcr2, bits);
	bfin_write(&drv_data->regs->tclkdiv, chip->baud);
	bfin_write(&drv_data->regs->tclkdiv, chip->baud);
	bfin_write(&drv_data->regs->tfsdiv, bits);
	SSYNC();
	SSYNC();


	bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS));
	bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS));
	bfin_write(&drv_data->regs->rcr2, bits);
	SSYNC();
	SSYNC();


	bfin_sport_spi_cs_active(chip);
	bfin_sport_spi_cs_active(chip);
@@ -420,11 +416,15 @@ bfin_sport_spi_pump_transfers(unsigned long data)
	drv_data->cs_change = transfer->cs_change;
	drv_data->cs_change = transfer->cs_change;


	/* Bits per word setup */
	/* Bits per word setup */
	bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word;
	bits_per_word = transfer->bits_per_word ? :
	if (bits_per_word == 8)
		message->spi->bits_per_word ? : 8;
		drv_data->ops = &bfin_sport_transfer_ops_u8;
	if (bits_per_word % 16 == 0)
	else
		drv_data->ops = &bfin_sport_transfer_ops_u16;
		drv_data->ops = &bfin_sport_transfer_ops_u16;
	else
		drv_data->ops = &bfin_sport_transfer_ops_u8;
	bfin_write(&drv_data->regs->tcr2, bits_per_word - 1);
	bfin_write(&drv_data->regs->tfsdiv, bits_per_word - 1);
	bfin_write(&drv_data->regs->rcr2, bits_per_word - 1);


	drv_data->state = RUNNING_STATE;
	drv_data->state = RUNNING_STATE;


@@ -598,11 +598,12 @@ bfin_sport_spi_setup(struct spi_device *spi)
			}
			}
			chip->cs_chg_udelay = chip_info->cs_chg_udelay;
			chip->cs_chg_udelay = chip_info->cs_chg_udelay;
			chip->idle_tx_val = chip_info->idle_tx_val;
			chip->idle_tx_val = chip_info->idle_tx_val;
			spi->bits_per_word = chip_info->bits_per_word;
		}
		}
	}
	}


	if (spi->bits_per_word != 8 && spi->bits_per_word != 16) {
	if (spi->bits_per_word % 8) {
		dev_err(&spi->dev, "%d bits_per_word is not supported\n",
				spi->bits_per_word);
		ret = -EINVAL;
		ret = -EINVAL;
		goto error;
		goto error;
	}
	}
+8 −6
Original line number Original line Diff line number Diff line
@@ -396,7 +396,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)
		/* last read */
		/* last read */
		if (drv_data->rx) {
		if (drv_data->rx) {
			dev_dbg(&drv_data->pdev->dev, "last read\n");
			dev_dbg(&drv_data->pdev->dev, "last read\n");
			if (n_bytes % 2) {
			if (!(n_bytes % 2)) {
				u16 *buf = (u16 *)drv_data->rx;
				u16 *buf = (u16 *)drv_data->rx;
				for (loop = 0; loop < n_bytes / 2; loop++)
				for (loop = 0; loop < n_bytes / 2; loop++)
					*buf++ = bfin_read(&drv_data->regs->rdbr);
					*buf++ = bfin_read(&drv_data->regs->rdbr);
@@ -424,7 +424,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)
	if (drv_data->rx && drv_data->tx) {
	if (drv_data->rx && drv_data->tx) {
		/* duplex */
		/* duplex */
		dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n");
		dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n");
		if (n_bytes % 2) {
		if (!(n_bytes % 2)) {
			u16 *buf = (u16 *)drv_data->rx;
			u16 *buf = (u16 *)drv_data->rx;
			u16 *buf2 = (u16 *)drv_data->tx;
			u16 *buf2 = (u16 *)drv_data->tx;
			for (loop = 0; loop < n_bytes / 2; loop++) {
			for (loop = 0; loop < n_bytes / 2; loop++) {
@@ -442,7 +442,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)
	} else if (drv_data->rx) {
	} else if (drv_data->rx) {
		/* read */
		/* read */
		dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n");
		dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n");
		if (n_bytes % 2) {
		if (!(n_bytes % 2)) {
			u16 *buf = (u16 *)drv_data->rx;
			u16 *buf = (u16 *)drv_data->rx;
			for (loop = 0; loop < n_bytes / 2; loop++) {
			for (loop = 0; loop < n_bytes / 2; loop++) {
				*buf++ = bfin_read(&drv_data->regs->rdbr);
				*buf++ = bfin_read(&drv_data->regs->rdbr);
@@ -458,7 +458,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id)
	} else if (drv_data->tx) {
	} else if (drv_data->tx) {
		/* write */
		/* write */
		dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n");
		dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n");
		if (n_bytes % 2) {
		if (!(n_bytes % 2)) {
			u16 *buf = (u16 *)drv_data->tx;
			u16 *buf = (u16 *)drv_data->tx;
			for (loop = 0; loop < n_bytes / 2; loop++) {
			for (loop = 0; loop < n_bytes / 2; loop++) {
				bfin_read(&drv_data->regs->rdbr);
				bfin_read(&drv_data->regs->rdbr);
@@ -587,6 +587,7 @@ static void bfin_spi_pump_transfers(unsigned long data)
	if (message->state == DONE_STATE) {
	if (message->state == DONE_STATE) {
		dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n");
		dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n");
		message->status = 0;
		message->status = 0;
		bfin_spi_flush(drv_data);
		bfin_spi_giveback(drv_data);
		bfin_spi_giveback(drv_data);
		return;
		return;
	}
	}
@@ -870,9 +871,11 @@ static void bfin_spi_pump_transfers(unsigned long data)
		message->actual_length += drv_data->len_in_bytes;
		message->actual_length += drv_data->len_in_bytes;
		/* Move to next transfer of this msg */
		/* Move to next transfer of this msg */
		message->state = bfin_spi_next_transfer(drv_data);
		message->state = bfin_spi_next_transfer(drv_data);
		if (drv_data->cs_change)
		if (drv_data->cs_change && message->state != DONE_STATE) {
			bfin_spi_flush(drv_data);
			bfin_spi_cs_deactive(drv_data, chip);
			bfin_spi_cs_deactive(drv_data, chip);
		}
		}
	}


	/* Schedule next transfer tasklet */
	/* Schedule next transfer tasklet */
	tasklet_schedule(&drv_data->pump_transfers);
	tasklet_schedule(&drv_data->pump_transfers);
@@ -1026,7 +1029,6 @@ static int bfin_spi_setup(struct spi_device *spi)
		chip->cs_chg_udelay = chip_info->cs_chg_udelay;
		chip->cs_chg_udelay = chip_info->cs_chg_udelay;
		chip->idle_tx_val = chip_info->idle_tx_val;
		chip->idle_tx_val = chip_info->idle_tx_val;
		chip->pio_interrupt = chip_info->pio_interrupt;
		chip->pio_interrupt = chip_info->pio_interrupt;
		spi->bits_per_word = chip_info->bits_per_word;
	} else {
	} else {
		/* force a default base state */
		/* force a default base state */
		chip->ctl_reg &= bfin_ctl_reg;
		chip->ctl_reg &= bfin_ctl_reg;
Loading