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

Commit b29bc3df authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'spi/topic/bitbang' into spi-next

parents c3dbe2b7 2e29db40
Loading
Loading
Loading
Loading
+0 −12
Original line number Original line Diff line number Diff line
@@ -103,16 +103,6 @@ static void altera_spi_chipsel(struct spi_device *spi, int value)
	}
	}
}
}


static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
{
	return 0;
}

static int altera_spi_setup(struct spi_device *spi)
{
	return 0;
}

static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
{
{
	if (hw->tx) {
	if (hw->tx) {
@@ -224,7 +214,6 @@ static int altera_spi_probe(struct platform_device *pdev)
	master->bus_num = pdev->id;
	master->bus_num = pdev->id;
	master->num_chipselect = 16;
	master->num_chipselect = 16;
	master->mode_bits = SPI_CS_HIGH;
	master->mode_bits = SPI_CS_HIGH;
	master->setup = altera_spi_setup;


	hw = spi_master_get_devdata(master);
	hw = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, hw);
	platform_set_drvdata(pdev, hw);
@@ -233,7 +222,6 @@ static int altera_spi_probe(struct platform_device *pdev)
	hw->bitbang.master = spi_master_get(master);
	hw->bitbang.master = spi_master_get(master);
	if (!hw->bitbang.master)
	if (!hw->bitbang.master)
		return err;
		return err;
	hw->bitbang.setup_transfer = altera_spi_setupxfer;
	hw->bitbang.chipselect = altera_spi_chipsel;
	hw->bitbang.chipselect = altera_spi_chipsel;
	hw->bitbang.txrx_bufs = altera_spi_txrx;
	hw->bitbang.txrx_bufs = altera_spi_txrx;


+113 −147
Original line number Original line Diff line number Diff line
@@ -255,26 +255,33 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
 * Drivers can provide word-at-a-time i/o primitives, or provide
 * Drivers can provide word-at-a-time i/o primitives, or provide
 * transfer-at-a-time ones to leverage dma or fifo hardware.
 * transfer-at-a-time ones to leverage dma or fifo hardware.
 */
 */
static void bitbang_work(struct work_struct *work)

static int spi_bitbang_prepare_hardware(struct spi_master *spi)
{
{
	struct spi_bitbang	*bitbang =
	struct spi_bitbang 	*bitbang;
		container_of(work, struct spi_bitbang, work);
	unsigned long		flags;
	unsigned long		flags;
	struct spi_message	*m, *_m;

	bitbang = spi_master_get_devdata(spi);


	spin_lock_irqsave(&bitbang->lock, flags);
	spin_lock_irqsave(&bitbang->lock, flags);
	bitbang->busy = 1;
	bitbang->busy = 1;
	list_for_each_entry_safe(m, _m, &bitbang->queue, queue) {
	spin_unlock_irqrestore(&bitbang->lock, flags);
		struct spi_device	*spi;

	return 0;
}

static int spi_bitbang_transfer_one(struct spi_master *master,
				    struct spi_message *m)
{
	struct spi_bitbang 	*bitbang;
	unsigned		nsecs;
	unsigned		nsecs;
	struct spi_transfer	*t = NULL;
	struct spi_transfer	*t = NULL;
		unsigned		tmp;
	unsigned		cs_change;
	unsigned		cs_change;
	int			status;
	int			status;
	int			do_setup = -1;
	int			do_setup = -1;
	struct spi_device	*spi = m->spi;


		list_del(&m->queue);
	bitbang = spi_master_get_devdata(master);
		spin_unlock_irqrestore(&bitbang->lock, flags);


	/* FIXME this is made-up ... the correct value is known to
	/* FIXME this is made-up ... the correct value is known to
	 * word-at-a-time bitbang code, and presumably chipselect()
	 * word-at-a-time bitbang code, and presumably chipselect()
@@ -282,8 +289,6 @@ static void bitbang_work(struct work_struct *work)
	 */
	 */
	nsecs = 100;
	nsecs = 100;


		spi = m->spi;
		tmp = 0;
	cs_change = 1;
	cs_change = 1;
	status = 0;
	status = 0;


@@ -355,7 +360,6 @@ static void bitbang_work(struct work_struct *work)
	}
	}


	m->status = status;
	m->status = status;
		m->complete(m->context);


	/* normally deactivate chipselect ... unless no error and
	/* normally deactivate chipselect ... unless no error and
	 * cs_change has hinted that the next message will probably
	 * cs_change has hinted that the next message will probably
@@ -367,38 +371,24 @@ static void bitbang_work(struct work_struct *work)
		ndelay(nsecs);
		ndelay(nsecs);
	}
	}


		spin_lock_irqsave(&bitbang->lock, flags);
	spi_finalize_current_message(master);
	}

	bitbang->busy = 0;
	return status;
	spin_unlock_irqrestore(&bitbang->lock, flags);
}
}


/**
static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
 * spi_bitbang_transfer - default submit to transfer queue
 */
int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
{
{
	struct spi_bitbang 	*bitbang;
	struct spi_bitbang 	*bitbang;
	unsigned long		flags;
	unsigned long		flags;
	int			status = 0;

	m->actual_length = 0;
	m->status = -EINPROGRESS;


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


	spin_lock_irqsave(&bitbang->lock, flags);
	spin_lock_irqsave(&bitbang->lock, flags);
	if (!spi->max_speed_hz)
	bitbang->busy = 0;
		status = -ENETDOWN;
	else {
		list_add_tail(&m->queue, &bitbang->queue);
		queue_work(bitbang->workqueue, &bitbang->work);
	}
	spin_unlock_irqrestore(&bitbang->lock, flags);
	spin_unlock_irqrestore(&bitbang->lock, flags);


	return status;
	return 0;
}
}
EXPORT_SYMBOL_GPL(spi_bitbang_transfer);


/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/


@@ -428,20 +418,22 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
int spi_bitbang_start(struct spi_bitbang *bitbang)
int spi_bitbang_start(struct spi_bitbang *bitbang)
{
{
	struct spi_master *master = bitbang->master;
	struct spi_master *master = bitbang->master;
	int status;


	if (!master || !bitbang->chipselect)
	if (!master || !bitbang->chipselect)
		return -EINVAL;
		return -EINVAL;


	INIT_WORK(&bitbang->work, bitbang_work);
	spin_lock_init(&bitbang->lock);
	spin_lock_init(&bitbang->lock);
	INIT_LIST_HEAD(&bitbang->queue);


	if (!master->mode_bits)
	if (!master->mode_bits)
		master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
		master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;


	if (!master->transfer)
	if (master->transfer || master->transfer_one_message)
		master->transfer = spi_bitbang_transfer;
		return -EINVAL;

	master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
	master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
	master->transfer_one_message = spi_bitbang_transfer_one;

	if (!bitbang->txrx_bufs) {
	if (!bitbang->txrx_bufs) {
		bitbang->use_dma = 0;
		bitbang->use_dma = 0;
		bitbang->txrx_bufs = spi_bitbang_bufs;
		bitbang->txrx_bufs = spi_bitbang_bufs;
@@ -452,34 +444,12 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
			master->setup = spi_bitbang_setup;
			master->setup = spi_bitbang_setup;
			master->cleanup = spi_bitbang_cleanup;
			master->cleanup = spi_bitbang_cleanup;
		}
		}
	} else if (!master->setup)
		return -EINVAL;
	if (master->transfer == spi_bitbang_transfer &&
			!bitbang->setup_transfer)
		return -EINVAL;

	/* this task is the only thing to touch the SPI bits */
	bitbang->busy = 0;
	bitbang->workqueue = create_singlethread_workqueue(
			dev_name(master->dev.parent));
	if (bitbang->workqueue == NULL) {
		status = -EBUSY;
		goto err1;
	}
	}


	/* driver may get busy before register() returns, especially
	/* driver may get busy before register() returns, especially
	 * if someone registered boardinfo for devices
	 * if someone registered boardinfo for devices
	 */
	 */
	status = spi_register_master(master);
	return spi_register_master(master);
	if (status < 0)
		goto err2;

	return status;

err2:
	destroy_workqueue(bitbang->workqueue);
err1:
	return status;
}
}
EXPORT_SYMBOL_GPL(spi_bitbang_start);
EXPORT_SYMBOL_GPL(spi_bitbang_start);


@@ -490,10 +460,6 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
{
{
	spi_unregister_master(bitbang->master);
	spi_unregister_master(bitbang->master);


	WARN_ON(!list_empty(&bitbang->queue));

	destroy_workqueue(bitbang->workqueue);

	return 0;
	return 0;
}
}
EXPORT_SYMBOL_GPL(spi_bitbang_stop);
EXPORT_SYMBOL_GPL(spi_bitbang_stop);
+0 −13
Original line number Original line Diff line number Diff line
@@ -174,17 +174,6 @@ static void nuc900_spi_gobusy(struct nuc900_spi *hw)
	spin_unlock_irqrestore(&hw->lock, flags);
	spin_unlock_irqrestore(&hw->lock, flags);
}
}


static int nuc900_spi_setupxfer(struct spi_device *spi,
				 struct spi_transfer *t)
{
	return 0;
}

static int nuc900_spi_setup(struct spi_device *spi)
{
	return 0;
}

static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
{
{
	return hw->tx ? hw->tx[count] : 0;
	return hw->tx ? hw->tx[count] : 0;
@@ -377,10 +366,8 @@ static int nuc900_spi_probe(struct platform_device *pdev)
	master->num_chipselect     = hw->pdata->num_cs;
	master->num_chipselect     = hw->pdata->num_cs;
	master->bus_num            = hw->pdata->bus_num;
	master->bus_num            = hw->pdata->bus_num;
	hw->bitbang.master         = hw->master;
	hw->bitbang.master         = hw->master;
	hw->bitbang.setup_transfer = nuc900_spi_setupxfer;
	hw->bitbang.chipselect     = nuc900_spi_chipsel;
	hw->bitbang.chipselect     = nuc900_spi_chipsel;
	hw->bitbang.txrx_bufs      = nuc900_spi_txrx;
	hw->bitbang.txrx_bufs      = nuc900_spi_txrx;
	hw->bitbang.master->setup  = nuc900_spi_setup;


	hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (hw->res == NULL) {
	if (hw->res == NULL) {
+0 −16
Original line number Original line Diff line number Diff line
@@ -233,21 +233,6 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi,
	return 0;
	return 0;
}
}


static int xilinx_spi_setup(struct spi_device *spi)
{
	/* always return 0, we can not check the number of bits.
	 * There are cases when SPI setup is called before any driver is
	 * there, in that case the SPI core defaults to 8 bits, which we
	 * do not support in some cases. But if we return an error, the
	 * SPI device would not be registered and no driver can get hold of it
	 * When the driver is there, it will call SPI setup again with the
	 * correct number of bits per transfer.
	 * If a driver setups with the wrong bit number, it will fail when
	 * it tries to do a transfer
	 */
	return 0;
}

static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi)
static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi)
{
{
	u8 sr;
	u8 sr;
@@ -375,7 +360,6 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
	xspi->bitbang.chipselect = xilinx_spi_chipselect;
	xspi->bitbang.chipselect = xilinx_spi_chipselect;
	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
	xspi->bitbang.master->setup = xilinx_spi_setup;
	init_completion(&xspi->done);
	init_completion(&xspi->done);


	if (!request_mem_region(mem->start, resource_size(mem),
	if (!request_mem_region(mem->start, resource_size(mem),
+0 −5
Original line number Original line Diff line number Diff line
@@ -4,11 +4,7 @@
#include <linux/workqueue.h>
#include <linux/workqueue.h>


struct spi_bitbang {
struct spi_bitbang {
	struct workqueue_struct	*workqueue;
	struct work_struct	work;

	spinlock_t		lock;
	spinlock_t		lock;
	struct list_head	queue;
	u8			busy;
	u8			busy;
	u8			use_dma;
	u8			use_dma;
	u8			flags;		/* extra spi->mode support */
	u8			flags;		/* extra spi->mode support */
@@ -41,7 +37,6 @@ struct spi_bitbang {
 */
 */
extern int spi_bitbang_setup(struct spi_device *spi);
extern int spi_bitbang_setup(struct spi_device *spi);
extern void spi_bitbang_cleanup(struct spi_device *spi);
extern void spi_bitbang_cleanup(struct spi_device *spi);
extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m);
extern int spi_bitbang_setup_transfer(struct spi_device *spi,
extern int spi_bitbang_setup_transfer(struct spi_device *spi,
				      struct spi_transfer *t);
				      struct spi_transfer *t);