/*
 * SPI bus via the Blackfin SPORT peripheral
 *
 * Enter bugs at http://blackfin.uclinux.org/
 *
 * Copyright 2009-2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/workqueue.h>

#include <asm/portmux.h>
#include <asm/bfin5xx_spi.h>
#include <asm/blackfin.h>
#include <asm/bfin_sport.h>
#include <asm/cacheflush.h>

#define DRV_NAME	"bfin-sport-spi"
#define DRV_DESC	"SPI bus via the Blackfin SPORT"

MODULE_AUTHOR("Cliff Cai");
MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:bfin-sport-spi");

enum bfin_sport_spi_state {
	START_STATE,
	RUNNING_STATE,
	DONE_STATE,
	ERROR_STATE,
};

struct bfin_sport_spi_master_data;

struct bfin_sport_transfer_ops {
	void (*write) (struct bfin_sport_spi_master_data *);
	void (*read) (struct bfin_sport_spi_master_data *);
	void (*duplex) (struct bfin_sport_spi_master_data *);
};

struct bfin_sport_spi_master_data {
	/* Driver model hookup */
	struct device *dev;

	/* SPI framework hookup */
	struct spi_master *master;

	/* Regs base of SPI controller */
	struct sport_register __iomem *regs;
	int err_irq;

	/* Pin request list */
	u16 *pin_req;

	/* Driver message queue */
	struct workqueue_struct *workqueue;
	struct work_struct pump_messages;
	spinlock_t lock;
	struct list_head queue;
	int busy;
	bool run;

	/* Message Transfer pump */
	struct tasklet_struct pump_transfers;

	/* Current message transfer state info */
	enum bfin_sport_spi_state state;
	struct spi_message *cur_msg;
	struct spi_transfer *cur_transfer;
	struct bfin_sport_spi_slave_data *cur_chip;
	union {
		void *tx;
		u8 *tx8;
		u16 *tx16;
	};
	void *tx_end;
	union {
		void *rx;
		u8 *rx8;
		u16 *rx16;
	};
	void *rx_end;

	int cs_change;
	struct bfin_sport_transfer_ops *ops;
};

struct bfin_sport_spi_slave_data {
	u16 ctl_reg;
	u16 baud;
	u16 cs_chg_udelay;	/* Some devices require > 255usec delay */
	u32 cs_gpio;
	u16 idle_tx_val;
	struct bfin_sport_transfer_ops *ops;
};

static void
bfin_sport_spi_enable(struct bfin_sport_spi_master_data *drv_data)
{
	bfin_write_or(&drv_data->regs->tcr1, TSPEN);
	bfin_write_or(&drv_data->regs->rcr1, TSPEN);
	SSYNC();
}

static void
bfin_sport_spi_disable(struct bfin_sport_spi_master_data *drv_data)
{
	bfin_write_and(&drv_data->regs->tcr1, ~TSPEN);
	bfin_write_and(&drv_data->regs->rcr1, ~TSPEN);
	SSYNC();
}

/* Caculate the SPI_BAUD register value based on input HZ */
static u16
bfin_sport_hz_to_spi_baud(u32 speed_hz)
{
	u_long clk, sclk = get_sclk();
	int div = (sclk / (2 * speed_hz)) - 1;

	if (div < 0)
		div = 0;

	clk = sclk / (2 * (div + 1));

	if (clk > speed_hz)
		div++;

	return div;
}

/* Chip select operation functions for cs_change flag */
static void
bfin_sport_spi_cs_active(struct bfin_sport_spi_slave_data *chip)
{
	gpio_direction_output(chip->cs_gpio, 0);
}

static void
bfin_sport_spi_cs_deactive(struct bfin_sport_spi_slave_data *chip)
{
	gpio_direction_output(chip->cs_gpio, 1);
	/* Move delay here for consistency */
	if (chip->cs_chg_udelay)
		udelay(chip->cs_chg_udelay);
}

static void
bfin_sport_spi_stat_poll_complete(struct bfin_sport_spi_master_data *drv_data)
{
	unsigned long timeout = jiffies + HZ;
	while (!(bfin_read(&drv_data->regs->stat) & RXNE)) {
		if (!time_before(jiffies, timeout))
			break;
	}
}

static void
bfin_sport_spi_u8_writer(struct bfin_sport_spi_master_data *drv_data)
{
	u16 dummy;

	while (drv_data->tx < drv_data->tx_end) {
		bfin_write(&drv_data->regs->tx16, *drv_data->tx8++);
		bfin_sport_spi_stat_poll_complete(drv_data);
		dummy = bfin_read(&drv_data->regs->rx16);
	}
}

static void
bfin_sport_spi_u8_reader(struct bfin_sport_spi_master_data *drv_data)
{
	u16 tx_val = drv_data->cur_chip->idle_tx_val;

	while (drv_data->rx < drv_data->rx_end) {
		bfin_write(&drv_data->regs->tx16, tx_val);
		bfin_sport_spi_stat_poll_complete(drv_data);
		*drv_data->rx8++ = bfin_read(&drv_data->regs->rx16);
	}
}

static void
bfin_sport_spi_u8_duplex(struct bfin_sport_spi_master_data *drv_data)
{
	while (drv_data->rx < drv_data->rx_end) {
		bfin_write(&drv_data->regs->tx16, *drv_data->tx8++);
		bfin_sport_spi_stat_poll_complete(drv_data);
		*drv_data->rx8++ = bfin_read(&drv_data->regs->rx16);
	}
}

static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u8 = {
	.write  = bfin_sport_spi_u8_writer,
	.read   = bfin_sport_spi_u8_reader,
	.duplex = bfin_sport_spi_u8_duplex,
};

static void
bfin_sport_spi_u16_writer(struct bfin_sport_spi_master_data *drv_data)
{
	u16 dummy;

	while (drv_data->tx < drv_data->tx_end) {
		bfin_write(&drv_data->regs->tx16, *drv_data->tx16++);
		bfin_sport_spi_stat_poll_complete(drv_data);
		dummy = bfin_read(&drv_data->regs->rx16);
	}
}

static void
bfin_sport_spi_u16_reader(struct bfin_sport_spi_master_data *drv_data)
{
	u16 tx_val = drv_data->cur_chip->idle_tx_val;

	while (drv_data->rx < drv_data->rx_end) {
		bfin_write(&drv_data->regs->tx16, tx_val);
		bfin_sport_spi_stat_poll_complete(drv_data);
		*drv_data->rx16++ = bfin_read(&drv_data->regs->rx16);
	}
}

static void
bfin_sport_spi_u16_duplex(struct bfin_sport_spi_master_data *drv_data)
{
	while (drv_data->rx < drv_data->rx_end) {
		bfin_write(&drv_data->regs->tx16, *drv_data->tx16++);
		bfin_sport_spi_stat_poll_complete(drv_data);
		*drv_data->rx16++ = bfin_read(&drv_data->regs->rx16);
	}
}

static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u16 = {
	.write  = bfin_sport_spi_u16_writer,
	.read   = bfin_sport_spi_u16_reader,
	.duplex = bfin_sport_spi_u16_duplex,
};

/* stop controller and re-config current chip */
static void
bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)
{
	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;

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

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

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

	bfin_sport_spi_cs_active(chip);
}

/* test if there is more transfer to be done */
static enum bfin_sport_spi_state
bfin_sport_spi_next_transfer(struct bfin_sport_spi_master_data *drv_data)
{
	struct spi_message *msg = drv_data->cur_msg;
	struct spi_transfer *trans = drv_data->cur_transfer;

	/* Move to next transfer */
	if (trans->transfer_list.next != &msg->transfers) {
		drv_data->cur_transfer =
		    list_entry(trans->transfer_list.next,
			       struct spi_transfer, transfer_list);
		return RUNNING_STATE;
	}

	return DONE_STATE;
}

/*
 * caller already set message->status;
 * dma and pio irqs are blocked give finished message back
 */
static void
bfin_sport_spi_giveback(struct bfin_sport_spi_master_data *drv_data)
{
	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
	unsigned long flags;
	struct spi_message *msg;

	spin_lock_irqsave(&drv_data->lock, flags);
	msg = drv_data->cur_msg;
	drv_data->state = START_STATE;
	drv_data->cur_msg = NULL;
	drv_data->cur_transfer = NULL;
	drv_data->cur_chip = NULL;
	queue_work(drv_data->workqueue, &drv_data->pump_messages);
	spin_unlock_irqrestore(&drv_data->lock, flags);

	if (!drv_data->cs_change)
		bfin_sport_spi_cs_deactive(chip);

	if (msg->complete)
		msg->complete(msg->context);
}

static irqreturn_t
sport_err_handler(int irq, void *dev_id)
{
	struct bfin_sport_spi_master_data *drv_data = dev_id;
	u16 status;

	dev_dbg(drv_data->dev, "%s enter\n", __func__);
	status = bfin_read(&drv_data->regs->stat) & (TOVF | TUVF | ROVF | RUVF);

	if (status) {
		bfin_write(&drv_data->regs->stat, status);
		SSYNC();

		bfin_sport_spi_disable(drv_data);
		dev_err(drv_data->dev, "status error:%s%s%s%s\n",
			status & TOVF ? " TOVF" : "",
			status & TUVF ? " TUVF" : "",
			status & ROVF ? " ROVF" : "",
			status & RUVF ? " RUVF" : "");
	}

	return IRQ_HANDLED;
}

static void
bfin_sport_spi_pump_transfers(unsigned long data)
{
	struct bfin_sport_spi_master_data *drv_data = (void *)data;
	struct spi_message *message = NULL;
	struct spi_transfer *transfer = NULL;
	struct spi_transfer *previous = NULL;
	struct bfin_sport_spi_slave_data *chip = NULL;
	unsigned int bits_per_word;
	u32 tranf_success = 1;
	u32 transfer_speed;
	u8 full_duplex = 0;

	/* Get current state information */
	message = drv_data->cur_msg;
	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;
	bfin_write(&drv_data->regs->tclkdiv, transfer_speed);
	SSYNC();

	/*
	 * if msg is error or done, report it back using complete() callback
	 */

	 /* Handle for abort */
	if (drv_data->state == ERROR_STATE) {
		dev_dbg(drv_data->dev, "transfer: we've hit an error\n");
		message->status = -EIO;
		bfin_sport_spi_giveback(drv_data);
		return;
	}

	/* Handle end of message */
	if (drv_data->state == DONE_STATE) {
		dev_dbg(drv_data->dev, "transfer: all done!\n");
		message->status = 0;
		bfin_sport_spi_giveback(drv_data);
		return;
	}

	/* Delay if requested at end of transfer */
	if (drv_data->state == RUNNING_STATE) {
		dev_dbg(drv_data->dev, "transfer: still running ...\n");
		previous = list_entry(transfer->transfer_list.prev,
				      struct spi_transfer, transfer_list);
		if (previous->delay_usecs)
			udelay(previous->delay_usecs);
	}

	if (transfer->len == 0) {
		/* Move to next transfer of this msg */
		drv_data->state = bfin_sport_spi_next_transfer(drv_data);
		/* Schedule next transfer tasklet */
		tasklet_schedule(&drv_data->pump_transfers);
	}

	if (transfer->tx_buf != NULL) {
		drv_data->tx = (void *)transfer->tx_buf;
		drv_data->tx_end = drv_data->tx + transfer->len;
		dev_dbg(drv_data->dev, "tx_buf is %p, tx_end is %p\n",
			transfer->tx_buf, drv_data->tx_end);
	} else
		drv_data->tx = NULL;

	if (transfer->rx_buf != NULL) {
		full_duplex = transfer->tx_buf != NULL;
		drv_data->rx = transfer->rx_buf;
		drv_data->rx_end = drv_data->rx + transfer->len;
		dev_dbg(drv_data->dev, "rx_buf is %p, rx_end is %p\n",
			transfer->rx_buf, drv_data->rx_end);
	} else
		drv_data->rx = NULL;

	drv_data->cs_change = transfer->cs_change;

	/* Bits per word setup */
	bits_per_word = transfer->bits_per_word ? :
		message->spi->bits_per_word ? : 8;
	if (bits_per_word % 16 == 0)
		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;

	if (drv_data->cs_change)
		bfin_sport_spi_cs_active(chip);

	dev_dbg(drv_data->dev,
		"now pumping a transfer: width is %d, len is %d\n",
		bits_per_word, transfer->len);

	/* PIO mode write then read */
	dev_dbg(drv_data->dev, "doing IO transfer\n");

	bfin_sport_spi_enable(drv_data);
	if (full_duplex) {
		/* full duplex mode */
		BUG_ON((drv_data->tx_end - drv_data->tx) !=
		       (drv_data->rx_end - drv_data->rx));
		drv_data->ops->duplex(drv_data);

		if (drv_data->tx != drv_data->tx_end)
			tranf_success = 0;
	} else if (drv_data->tx != NULL) {
		/* write only half duplex */

		drv_data->ops->write(drv_data);

		if (drv_data->tx != drv_data->tx_end)
			tranf_success = 0;
	} else if (drv_data->rx != NULL) {
		/* read only half duplex */

		drv_data->ops->read(drv_data);
		if (drv_data->rx != drv_data->rx_end)
			tranf_success = 0;
	}
	bfin_sport_spi_disable(drv_data);

	if (!tranf_success) {
		dev_dbg(drv_data->dev, "IO write error!\n");
		drv_data->state = ERROR_STATE;
	} else {
		/* Update total byte transferred */
		message->actual_length += transfer->len;
		/* Move to next transfer of this msg */
		drv_data->state = bfin_sport_spi_next_transfer(drv_data);
		if (drv_data->cs_change)
			bfin_sport_spi_cs_deactive(chip);
	}

	/* Schedule next transfer tasklet */
	tasklet_schedule(&drv_data->pump_transfers);
}

/* pop a msg from queue and kick off real transfer */
static void
bfin_sport_spi_pump_messages(struct work_struct *work)
{
	struct bfin_sport_spi_master_data *drv_data;
	unsigned long flags;
	struct spi_message *next_msg;

	drv_data = container_of(work, struct bfin_sport_spi_master_data, pump_messages);

	/* Lock queue and check for queue work */
	spin_lock_irqsave(&drv_data->lock, flags);
	if (list_empty(&drv_data->queue) || !drv_data->run) {
		/* pumper kicked off but no work to do */
		drv_data->busy = 0;
		spin_unlock_irqrestore(&drv_data->lock, flags);
		return;
	}

	/* Make sure we are not already running a message */
	if (drv_data->cur_msg) {
		spin_unlock_irqrestore(&drv_data->lock, flags);
		return;
	}

	/* Extract head of queue */
	next_msg = list_entry(drv_data->queue.next,
		struct spi_message, queue);

	drv_data->cur_msg = next_msg;

	/* Setup the SSP using the per chip configuration */
	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);

	list_del_init(&drv_data->cur_msg->queue);

	/* Initialize message state */
	drv_data->cur_msg->state = START_STATE;
	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
					    struct spi_transfer, transfer_list);
	bfin_sport_spi_restore_state(drv_data);
	dev_dbg(drv_data->dev, "got a message to pump, "
		"state is set to: baud %d, cs_gpio %i, ctl 0x%x\n",
		drv_data->cur_chip->baud, drv_data->cur_chip->cs_gpio,
		drv_data->cur_chip->ctl_reg);

	dev_dbg(drv_data->dev,
		"the first transfer len is %d\n",
		drv_data->cur_transfer->len);

	/* Mark as busy and launch transfers */
	tasklet_schedule(&drv_data->pump_transfers);

	drv_data->busy = 1;
	spin_unlock_irqrestore(&drv_data->lock, flags);
}

/*
 * got a msg to transfer, queue it in drv_data->queue.
 * And kick off message pumper
 */
static int
bfin_sport_spi_transfer(struct spi_device *spi, struct spi_message *msg)
{
	struct bfin_sport_spi_master_data *drv_data = spi_master_get_devdata(spi->master);
	unsigned long flags;

	spin_lock_irqsave(&drv_data->lock, flags);

	if (!drv_data->run) {
		spin_unlock_irqrestore(&drv_data->lock, flags);
		return -ESHUTDOWN;
	}

	msg->actual_length = 0;
	msg->status = -EINPROGRESS;
	msg->state = START_STATE;

	dev_dbg(&spi->dev, "adding an msg in transfer()\n");
	list_add_tail(&msg->queue, &drv_data->queue);

	if (drv_data->run && !drv_data->busy)
		queue_work(drv_data->workqueue, &drv_data->pump_messages);

	spin_unlock_irqrestore(&drv_data->lock, flags);

	return 0;
}

/* Called every time common spi devices change state */
static int
bfin_sport_spi_setup(struct spi_device *spi)
{
	struct bfin_sport_spi_slave_data *chip, *first = NULL;
	int ret;

	/* Only alloc (or use chip_info) on first setup */
	chip = spi_get_ctldata(spi);
	if (chip == NULL) {
		struct bfin5xx_spi_chip *chip_info;

		chip = first = kzalloc(sizeof(*chip), GFP_KERNEL);
		if (!chip)
			return -ENOMEM;

		/* platform chip_info isn't required */
		chip_info = spi->controller_data;
		if (chip_info) {
			/*
			 * DITFS and TDTYPE are only thing we don't set, but
			 * they probably shouldn't be changed by people.
			 */
			if (chip_info->ctl_reg || chip_info->enable_dma) {
				ret = -EINVAL;
				dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields");
				goto error;
			}
			chip->cs_chg_udelay = chip_info->cs_chg_udelay;
			chip->idle_tx_val = chip_info->idle_tx_val;
		}
	}

	if (spi->bits_per_word % 8) {
		dev_err(&spi->dev, "%d bits_per_word is not supported\n",
				spi->bits_per_word);
		ret = -EINVAL;
		goto error;
	}

	/* translate common spi framework into our register
	 * following configure contents are same for tx and rx.
	 */

	if (spi->mode & SPI_CPHA)
		chip->ctl_reg &= ~TCKFE;
	else
		chip->ctl_reg |= TCKFE;

	if (spi->mode & SPI_LSB_FIRST)
		chip->ctl_reg |= TLSBIT;
	else
		chip->ctl_reg &= ~TLSBIT;

	/* Sport in master mode */
	chip->ctl_reg |= ITCLK | ITFS | TFSR | LATFS | LTFS;

	chip->baud = bfin_sport_hz_to_spi_baud(spi->max_speed_hz);

	chip->cs_gpio = spi->chip_select;
	ret = gpio_request(chip->cs_gpio, spi->modalias);
	if (ret)
		goto error;

	dev_dbg(&spi->dev, "setup spi chip %s, width is %d\n",
			spi->modalias, spi->bits_per_word);
	dev_dbg(&spi->dev, "ctl_reg is 0x%x, GPIO is %i\n",
			chip->ctl_reg, spi->chip_select);

	spi_set_ctldata(spi, chip);

	bfin_sport_spi_cs_deactive(chip);

	return ret;

 error:
	kfree(first);
	return ret;
}

/*
 * callback for spi framework.
 * clean driver specific data
 */
static void
bfin_sport_spi_cleanup(struct spi_device *spi)
{
	struct bfin_sport_spi_slave_data *chip = spi_get_ctldata(spi);

	if (!chip)
		return;

	gpio_free(chip->cs_gpio);

	kfree(chip);
}

static int
bfin_sport_spi_init_queue(struct bfin_sport_spi_master_data *drv_data)
{
	INIT_LIST_HEAD(&drv_data->queue);
	spin_lock_init(&drv_data->lock);

	drv_data->run = false;
	drv_data->busy = 0;

	/* init transfer tasklet */
	tasklet_init(&drv_data->pump_transfers,
		     bfin_sport_spi_pump_transfers, (unsigned long)drv_data);

	/* init messages workqueue */
	INIT_WORK(&drv_data->pump_messages, bfin_sport_spi_pump_messages);
	drv_data->workqueue =
	    create_singlethread_workqueue(dev_name(drv_data->master->dev.parent));
	if (drv_data->workqueue == NULL)
		return -EBUSY;

	return 0;
}

static int
bfin_sport_spi_start_queue(struct bfin_sport_spi_master_data *drv_data)
{
	unsigned long flags;

	spin_lock_irqsave(&drv_data->lock, flags);

	if (drv_data->run || drv_data->busy) {
		spin_unlock_irqrestore(&drv_data->lock, flags);
		return -EBUSY;
	}

	drv_data->run = true;
	drv_data->cur_msg = NULL;
	drv_data->cur_transfer = NULL;
	drv_data->cur_chip = NULL;
	spin_unlock_irqrestore(&drv_data->lock, flags);

	queue_work(drv_data->workqueue, &drv_data->pump_messages);

	return 0;
}

static inline int
bfin_sport_spi_stop_queue(struct bfin_sport_spi_master_data *drv_data)
{
	unsigned long flags;
	unsigned limit = 500;
	int status = 0;

	spin_lock_irqsave(&drv_data->lock, flags);

	/*
	 * This is a bit lame, but is optimized for the common execution path.
	 * A wait_queue on the drv_data->busy could be used, but then the common
	 * execution path (pump_messages) would be required to call wake_up or
	 * friends on every SPI message. Do this instead
	 */
	drv_data->run = false;
	while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
		spin_unlock_irqrestore(&drv_data->lock, flags);
		msleep(10);
		spin_lock_irqsave(&drv_data->lock, flags);
	}

	if (!list_empty(&drv_data->queue) || drv_data->busy)
		status = -EBUSY;

	spin_unlock_irqrestore(&drv_data->lock, flags);

	return status;
}

static inline int
bfin_sport_spi_destroy_queue(struct bfin_sport_spi_master_data *drv_data)
{
	int status;

	status = bfin_sport_spi_stop_queue(drv_data);
	if (status)
		return status;

	destroy_workqueue(drv_data->workqueue);

	return 0;
}

static int bfin_sport_spi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct bfin5xx_spi_master *platform_info;
	struct spi_master *master;
	struct resource *res, *ires;
	struct bfin_sport_spi_master_data *drv_data;
	int status;

	platform_info = dev->platform_data;

	/* Allocate master with space for drv_data */
	master = spi_alloc_master(dev, sizeof(*master) + 16);
	if (!master) {
		dev_err(dev, "cannot alloc spi_master\n");
		return -ENOMEM;
	}

	drv_data = spi_master_get_devdata(master);
	drv_data->master = master;
	drv_data->dev = dev;
	drv_data->pin_req = platform_info->pin_req;

	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
	master->bus_num = pdev->id;
	master->num_chipselect = platform_info->num_chipselect;
	master->cleanup = bfin_sport_spi_cleanup;
	master->setup = bfin_sport_spi_setup;
	master->transfer = bfin_sport_spi_transfer;

	/* Find and map our resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "cannot get IORESOURCE_MEM\n");
		status = -ENOENT;
		goto out_error_get_res;
	}

	drv_data->regs = ioremap(res->start, resource_size(res));
	if (drv_data->regs == NULL) {
		dev_err(dev, "cannot map registers\n");
		status = -ENXIO;
		goto out_error_ioremap;
	}

	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!ires) {
		dev_err(dev, "cannot get IORESOURCE_IRQ\n");
		status = -ENODEV;
		goto out_error_get_ires;
	}
	drv_data->err_irq = ires->start;

	/* Initial and start queue */
	status = bfin_sport_spi_init_queue(drv_data);
	if (status) {
		dev_err(dev, "problem initializing queue\n");
		goto out_error_queue_alloc;
	}

	status = bfin_sport_spi_start_queue(drv_data);
	if (status) {
		dev_err(dev, "problem starting queue\n");
		goto out_error_queue_alloc;
	}

	status = request_irq(drv_data->err_irq, sport_err_handler,
		0, "sport_spi_err", drv_data);
	if (status) {
		dev_err(dev, "unable to request sport err irq\n");
		goto out_error_irq;
	}

	status = peripheral_request_list(drv_data->pin_req, DRV_NAME);
	if (status) {
		dev_err(dev, "requesting peripherals failed\n");
		goto out_error_peripheral;
	}

	/* Register with the SPI framework */
	platform_set_drvdata(pdev, drv_data);
	status = spi_register_master(master);
	if (status) {
		dev_err(dev, "problem registering spi master\n");
		goto out_error_master;
	}

	dev_info(dev, "%s, regs_base@%p\n", DRV_DESC, drv_data->regs);
	return 0;

 out_error_master:
	peripheral_free_list(drv_data->pin_req);
 out_error_peripheral:
	free_irq(drv_data->err_irq, drv_data);
 out_error_irq:
 out_error_queue_alloc:
	bfin_sport_spi_destroy_queue(drv_data);
 out_error_get_ires:
	iounmap(drv_data->regs);
 out_error_ioremap:
 out_error_get_res:
	spi_master_put(master);

	return status;
}

/* stop hardware and remove the driver */
static int bfin_sport_spi_remove(struct platform_device *pdev)
{
	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
	int status = 0;

	if (!drv_data)
		return 0;

	/* Remove the queue */
	status = bfin_sport_spi_destroy_queue(drv_data);
	if (status)
		return status;

	/* Disable the SSP at the peripheral and SOC level */
	bfin_sport_spi_disable(drv_data);

	/* Disconnect from the SPI framework */
	spi_unregister_master(drv_data->master);

	peripheral_free_list(drv_data->pin_req);

	/* Prevent double remove */
	platform_set_drvdata(pdev, NULL);

	return 0;
}

#ifdef CONFIG_PM
static int
bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
	int status;

	status = bfin_sport_spi_stop_queue(drv_data);
	if (status)
		return status;

	/* stop hardware */
	bfin_sport_spi_disable(drv_data);

	return status;
}

static int
bfin_sport_spi_resume(struct platform_device *pdev)
{
	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
	int status;

	/* Enable the SPI interface */
	bfin_sport_spi_enable(drv_data);

	/* Start the queue running */
	status = bfin_sport_spi_start_queue(drv_data);
	if (status)
		dev_err(drv_data->dev, "problem resuming queue\n");

	return status;
}
#else
# define bfin_sport_spi_suspend NULL
# define bfin_sport_spi_resume  NULL
#endif

static struct platform_driver bfin_sport_spi_driver = {
	.driver	= {
		.name = DRV_NAME,
		.owner = THIS_MODULE,
	},
	.probe   = bfin_sport_spi_probe,
	.remove  = bfin_sport_spi_remove,
	.suspend = bfin_sport_spi_suspend,
	.resume  = bfin_sport_spi_resume,
};
module_platform_driver(bfin_sport_spi_driver);
