All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform
@ 2013-07-08  8:37 Chao Fu
  2013-07-08  8:37 ` [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes Chao Fu
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Chao Fu @ 2013-07-08  8:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chao Fu <B44548@freescale.com>

The serial peripheral interface (SPI) module implemented on Freescale Vybrid 
platform provides a synchronous serial bus for communication between Vybrid 
and the external peripheral device. The SPI supports full-duplex, 
three-wire synchronous transfer, has TX/RX FIFO with depth of four entries.

This driver is the SPI master mode driver and has been tested on Vybrid VF610TWR board.

Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Chao Fu  <b44548@freescale.com>
---
 drivers/spi/Kconfig        |   6 +
 drivers/spi/Makefile       |   1 +
 drivers/spi/spi-fsl-dspi.c | 675 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 682 insertions(+)
 create mode 100644 drivers/spi/spi-fsl-dspi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 89cbbab..068715d 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -248,6 +248,12 @@ config SPI_FSL_SPI
 	  This also enables using the Aeroflex Gaisler GRLIB SPI controller in
 	  master mode.
 
+config SPI_FSL_DSPI
+         tristate "Freescale DSPI controller"
+         help
+         This enables support for the Freescale DSPI controller in master
+         mode.
+
 config SPI_FSL_ESPI
 	bool "Freescale eSPI controller"
 	depends on FSL_SOC
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 33f9c09..78416fd 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SPI_EP93XX)		+= spi-ep93xx.o
 obj-$(CONFIG_SPI_FALCON)		+= spi-falcon.o
 obj-$(CONFIG_SPI_FSL_CPM)		+= spi-fsl-cpm.o
 obj-$(CONFIG_SPI_FSL_LIB)		+= spi-fsl-lib.o
+obj-$(CONFIG_SPI_FSL_DSPI)		+= spi-fsl-dspi.o
 obj-$(CONFIG_SPI_FSL_ESPI)		+= spi-fsl-espi.o
 obj-$(CONFIG_SPI_FSL_SPI)		+= spi-fsl-spi.o
 obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
new file mode 100644
index 0000000..67e6c4b
--- /dev/null
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -0,0 +1,675 @@
+/*
+ * drivers/spi/spi-fsl-dspi.c
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Freescale DSPI driver
+ * This file contains a driver for the Freescale DSPI
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#define DRIVER_NAME "fsl-dspi"
+
+#define TRAN_STATE_RX_VOID		0x01
+#define TRAN_STATE_TX_VOID		0x02
+#define TRAN_STATE_WORD_ODD_NUM		0x04
+
+#define DSPI_FIFO_SIZE			4
+
+#define SPI_MCR			0x00
+#define SPI_TCR			0x08
+
+#define SPI_CTAR(x)		(0x0c + (x * 4))
+#define SPI_CTAR_FMSZ(x)	(((x) & 0x0000000f) << 27)
+#define SPI_CTAR_CPOL(x)	((x) << 26)
+#define SPI_CTAR_CPHA(x)	((x) << 25)
+#define SPI_CTAR_PCSSCR(x)	(((x) & 0x00000003) << 22)
+#define SPI_CTAR_PASC(x)	(((x) & 0x00000003) << 20)
+#define SPI_CTAR_PDT(x)		(((x) & 0x00000003) << 18)
+#define SPI_CTAR_PBR(x)		(((x) & 0x00000003) << 16)
+#define SPI_CTAR_CSSCK(x)	(((x) & 0x0000000f) << 12)
+#define SPI_CTAR_ASC(x)		(((x) & 0x0000000f) << 8)
+#define SPI_CTAR_DT(x)		(((x) & 0x0000000f) << 4)
+#define SPI_CTAR_BR(x)		((x) & 0x0000000f)
+
+#define SPI_CTAR0_SLAVE		0x0c
+
+#define SPI_SR			0x2c
+#define SPI_SR_EOQF		0x10000000
+
+#define SPI_RSER		0x30
+#define SPI_RSER_EOQFE		0x10000000
+
+#define SPI_PUSHR		0x34
+#define SPI_PUSHR_CONT		(1 << 31)
+#define SPI_PUSHR_CTAS(x)	(((x) & 0x00000007) << 28)
+#define SPI_PUSHR_EOQ		(1 << 27)
+#define SPI_PUSHR_CTCNT		(1 << 26)
+#define SPI_PUSHR_PCS(x)	(((1 << x) & 0x0000003f) << 16)
+#define SPI_PUSHR_TXDATA(x)	((x) & 0x0000ffff)
+
+#define SPI_PUSHR_SLAVE		0x34
+
+#define SPI_POPR		0x38
+#define SPI_POPR_RXDATA(x)	((x) & 0x0000ffff)
+
+#define SPI_TXFR0		0x3c
+#define SPI_TXFR1		0x40
+#define SPI_TXFR2		0x44
+#define SPI_TXFR3		0x48
+#define SPI_RXFR0		0x7c
+#define SPI_RXFR1		0x80
+#define SPI_RXFR2		0x84
+#define SPI_RXFR3		0x88
+
+#define SPI_FRAME_BITS		SPI_CTAR_FMSZ(0xf)
+#define SPI_FRAME_BITS_16	SPI_CTAR_FMSZ(0xf)
+#define SPI_FRAME_BITS_8	SPI_CTAR_FMSZ(0x7)
+
+#define SPI_CS_INIT		0x01
+#define SPI_CS_ASSERT		0x02
+#define SPI_CS_DROP		0x04
+
+struct DSPI_MCR {
+	unsigned halt:1;
+	unsigned reserved71:7;
+	unsigned smpl_pt:2;
+	unsigned clr_rxf:1;
+	unsigned clr_tx:1;
+	unsigned dis_rxf:1;
+	unsigned dis_tx:1;
+	unsigned mdis:1;
+	unsigned reserved15:1;
+	unsigned pcsis:8;
+	unsigned rooe:1;
+	unsigned pcsse:1;
+	unsigned mtfe:1;
+	unsigned frz:1;
+	unsigned dconf:2;
+	unsigned cont_scke:1;
+	unsigned master:1;
+};
+
+struct DSPI_CTAR {
+	unsigned br:4;
+	unsigned dt:4;
+	unsigned asc:4;
+	unsigned cssck:4;
+	unsigned pbr:2;
+	unsigned pdt:2;
+	unsigned pasc:2;
+	unsigned pcssck:2;
+	unsigned lsbfe:1;
+	unsigned cpha:1;
+	unsigned cpol:1;
+	unsigned fmsz:4;
+	unsigned dbr:1;
+};
+
+struct chip_data {
+	/* dspi data */
+	union {
+		u32 mcr_val;
+		struct DSPI_MCR mcr;
+	};
+	union {
+		u32 ctar_val;
+		struct DSPI_CTAR ctar;
+	};
+	u16 void_write_data;
+};
+
+struct fsl_dspi {
+	struct platform_device *pdev;
+	struct spi_master *master;
+
+	void *base;
+	int irq;
+	struct clk *clk;
+
+	struct spi_message *cur_msg;
+	struct spi_transfer *cur_transfer;
+	struct chip_data *cur_chip;
+	size_t len;
+	void *tx;
+	void *tx_end;
+	void *rx;
+	void *rx_end;
+	char dataflags;
+	u8 cs;
+	u16 void_write_data;
+	unsigned	cs_change:1;
+
+	wait_queue_head_t waitq;
+	u32 waitflags;
+};
+
+/* SPI local functions */
+static inline int is_word_transfer(struct fsl_dspi *dspi)
+{
+	return ((readl(dspi->base + SPI_CTAR(dspi->cs)) & SPI_FRAME_BITS)
+			== SPI_FRAME_BITS_8) ? 0 : 1;
+}
+
+static void set_8bit_transfer_mode(struct fsl_dspi *dspi)
+{
+	u32 temp;
+
+	temp = readl(dspi->base + SPI_CTAR(dspi->cs));
+	temp &= ~SPI_FRAME_BITS;
+	temp |= SPI_FRAME_BITS_8;
+	writel(temp, dspi->base + SPI_CTAR(dspi->cs));
+}
+
+static void set_16bit_transfer_mode(struct fsl_dspi *dspi)
+{
+	u32 temp;
+
+	temp = readl(dspi->base + SPI_CTAR(dspi->cs));
+	temp &= ~SPI_FRAME_BITS;
+	temp |= SPI_FRAME_BITS_16;
+	writel(temp, dspi->base + SPI_CTAR(dspi->cs));
+}
+
+static unsigned char hz_to_spi_baud(int pbr, int dbr, int speed_hz,
+		unsigned long clkrate)
+{
+	/* Valid baud rate pre-scaler values */
+	int pbr_tbl[4] = {2, 3, 5, 7};
+	int brs[16] = {	2,	4,	6,	8,
+		16,	32,	64,	128,
+		256,	512,	1024,	2048,
+		4096,	8192,	16384,	32768 };
+	int temp, index = 0;
+
+	/* table indexes out of range, go slow */
+	if ((pbr < 0) || (pbr > 3) || (dbr < 0) || (dbr > 1))
+		return 15;
+
+	/* cpu core clk need to check */
+	temp = ((((clkrate / 2) / pbr_tbl[pbr]) * (1 + dbr)) / speed_hz);
+
+	while (temp > brs[index])
+		if (index++ >= 15)
+			break;
+
+	return index;
+}
+
+static void dspi_setup_chip(struct fsl_dspi *dspi)
+{
+	struct chip_data *chip = dspi->cur_chip;
+
+	writel(chip->mcr_val, dspi->base + SPI_MCR);
+	writel(chip->ctar_val, dspi->base + SPI_CTAR(dspi->cs));
+	writel(SPI_RSER_EOQFE, dspi->base + SPI_RSER);
+}
+
+static int dspi_transfer_write(struct fsl_dspi *dspi)
+{
+	int tx_count = 0;
+	int tx_word;
+	u16 d16;
+	u8  d8;
+	u32 dspi_pushr = 0;
+	int first = 1;
+
+	tx_word = is_word_transfer(dspi);
+	/* If we are in word mode, but only have a single byte to transfer
+	 * then switch to byte mode temporarily.  Will switch back at the
+	 * end of the transfer. */
+	if (tx_word && (dspi->len == 1)) {
+		dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
+		set_8bit_transfer_mode(dspi);
+		tx_word = 0;
+	}
+	while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) {
+		if (tx_word) {
+			if (dspi->len == 1)
+				break;
+
+			if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) {
+				d16 = *(u16 *)dspi->tx;
+				dspi->tx += 2;
+			} else {
+				d16 = dspi->void_write_data;
+			}
+
+			dspi_pushr = SPI_PUSHR_TXDATA(d16) |
+				SPI_PUSHR_PCS(dspi->cs) |
+				SPI_PUSHR_CTAS(dspi->cs) |
+				SPI_PUSHR_CONT;
+
+			dspi->len -= 2;
+		} else {
+			if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) {
+
+				d8 = *(u8 *)dspi->tx;
+				dspi->tx++;
+			} else {
+				d8 = (u8)dspi->void_write_data;
+			}
+
+			dspi_pushr = SPI_PUSHR_TXDATA(d8) |
+				SPI_PUSHR_PCS(dspi->cs) |
+				SPI_PUSHR_CTAS(dspi->cs) |
+				SPI_PUSHR_CONT;
+
+			dspi->len--;
+		}
+
+		if (dspi->len == 0
+				|| tx_count == DSPI_FIFO_SIZE - 1) {
+			/* last transfer in the queue */
+			dspi_pushr |= SPI_PUSHR_EOQ;
+			if ((dspi->cs_change)
+					&& (!dspi->len))
+				dspi_pushr &= ~SPI_PUSHR_CONT;
+		} else if (tx_word && (dspi->len == 1))
+			dspi_pushr |= SPI_PUSHR_EOQ;
+
+		if (first) {
+			first = 0;
+			dspi_pushr |= SPI_PUSHR_CTCNT; /* clear counter */
+		}
+
+		writel(dspi_pushr, dspi->base + SPI_PUSHR);
+		tx_count++;
+	}
+
+	return tx_count * (tx_word + 1);
+}
+static int dspi_transfer_read(struct fsl_dspi *dspi)
+{
+	int rx_count = 0;
+	int rx_word = is_word_transfer(dspi);
+	u16 d;
+	while ((dspi->rx < dspi->rx_end)
+			&& (rx_count < DSPI_FIFO_SIZE)) {
+		if (rx_word) {
+			if ((dspi->rx_end - dspi->rx) == 1)
+				break;
+
+			d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR));
+
+			if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
+				*(u16 *)dspi->rx = d;
+			dspi->rx += 2;
+
+		} else {
+			d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR));
+			if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
+				*(u8 *)dspi->rx = d;
+			dspi->rx++;
+		}
+		rx_count++;
+	}
+
+	return rx_count;
+}
+
+static int dspi_transfer_one_message(struct spi_master *master,
+		struct spi_message *message)
+{
+	struct fsl_dspi *dspi = spi_master_get_devdata(master);
+	struct spi_device *spi = message->spi;
+	struct spi_transfer *transfer;
+	int status = 0;
+	message->actual_length = 0;
+
+	list_for_each_entry(transfer, &message->transfers, transfer_list) {
+		dspi->cur_msg = message;
+		dspi->cur_transfer = transfer;
+		dspi->cur_chip = spi_get_ctldata(spi);
+		dspi->cs = spi->chip_select;
+		if (dspi->cur_transfer->transfer_list.next
+				== &dspi->cur_msg->transfers)
+			transfer->cs_change = 1;
+		dspi->cs_change = transfer->cs_change;
+		dspi->void_write_data = dspi->cur_chip->void_write_data;
+
+		dspi_setup_chip(dspi);
+
+		dspi->dataflags = 0;
+		dspi->tx = (void *)transfer->tx_buf;
+		dspi->tx_end = dspi->tx + transfer->len;
+		dspi->rx = transfer->rx_buf;
+		dspi->rx_end = dspi->rx + transfer->len;
+		dspi->len = transfer->len;
+
+		if (!dspi->rx)
+			dspi->dataflags |= TRAN_STATE_RX_VOID;
+
+		if (!dspi->tx)
+			dspi->dataflags |= TRAN_STATE_TX_VOID;
+
+		if (transfer->speed_hz)
+			writel((dspi->cur_chip->ctar_val & ~0xf) |
+				hz_to_spi_baud(dspi->cur_chip->ctar.pbr,
+					dspi->cur_chip->ctar.dbr,
+					transfer->speed_hz,
+					clk_get_rate(dspi->clk)),
+					dspi->base + SPI_CTAR(dspi->cs));
+
+
+		message->actual_length += dspi_transfer_write(dspi);
+
+		wait_event_interruptible(dspi->waitq, dspi->waitflags);
+		dspi->waitflags = 0;
+
+
+		if (transfer->delay_usecs)
+			udelay(transfer->delay_usecs);
+	}
+	message->status = status;
+	spi_finalize_current_message(master);
+
+	return status;
+}
+
+static int dspi_prepare_transfer_hw(struct spi_master *master)
+{
+	struct fsl_dspi *dspi = spi_master_get_devdata(master);
+
+	pm_runtime_get_sync(&dspi->pdev->dev);
+
+	return 0;
+}
+
+static int dspi_unprepare_transfer_hw(struct spi_master *master)
+{
+	struct fsl_dspi *dspi = spi_master_get_devdata(master);
+
+	pm_runtime_put_sync(&dspi->pdev->dev);
+
+	return 0;
+}
+
+static int dspi_setup(struct spi_device *spi)
+{
+	struct chip_data *chip;
+	struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
+	struct device_node *np = spi->dev.of_node;
+	unsigned char br = 0;
+	unsigned int dbr = 0 , pbr = 0;
+
+	/* Only alloc on first setup */
+	chip = spi_get_ctldata(spi);
+	if (chip == NULL) {
+		chip = kcalloc(1, sizeof(struct chip_data), GFP_KERNEL);
+		if (!chip)
+			return -ENOMEM;
+	}
+
+	chip->mcr.master = 1;
+	chip->mcr.cont_scke = 0;
+	chip->mcr.dconf = 0;
+	chip->mcr.frz = 0;
+	chip->mcr.mtfe = 0;
+	chip->mcr.pcsse = 0;
+	chip->mcr.rooe = 0;
+	chip->mcr.pcsis = 0xFF;
+	chip->mcr.reserved15 = 0;
+	chip->mcr.mdis = 0;
+	chip->mcr.dis_tx = 0;
+	chip->mcr.dis_rxf = 0;
+	chip->mcr.clr_tx = 1;
+	chip->mcr.clr_rxf = 1;
+	chip->mcr.smpl_pt = 0;
+	chip->mcr.reserved71 = 0;
+	chip->mcr.halt = 0;
+
+	if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) {
+		chip->ctar.fmsz = spi->bits_per_word - 1;
+	} else {
+		printk(KERN_ERR "Invalid wordsize\n");
+		kfree(chip);
+		return -ENODEV;
+	}
+
+	chip->void_write_data = 0;
+	chip->ctar.cpha = (spi->mode & SPI_CPHA) ? 1 : 0;
+	chip->ctar.cpol = (spi->mode & SPI_CPOL) ? 1 : 0;
+	chip->ctar.lsbfe = (spi->mode & SPI_LSB_FIRST) ? 1 : 0;
+	of_property_read_u32(np, "dspi,ctar-dbr", &dbr);
+	of_property_read_u32(np, "dspi,ctar-pbr", &pbr);
+	chip->ctar.dbr = dbr;
+	chip->ctar.pbr = pbr;
+	if (spi->max_speed_hz == 0)
+		return -ENODEV;
+	br = hz_to_spi_baud(chip->ctar.pbr, chip->ctar.dbr,
+			spi->max_speed_hz, clk_get_rate(dspi->clk));
+	chip->ctar.br = br;
+	chip->ctar.pcssck = 0;
+	chip->ctar.pasc = 0;
+	chip->ctar.pdt = 0;
+	chip->ctar.cssck = 0;
+	chip->ctar.asc = 0;
+	chip->ctar.dt = 0;
+
+	spi_set_ctldata(spi, chip);
+
+	return 0;
+}
+
+static void dspi_cleanup(struct spi_device *spi)
+{
+	struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
+
+	dev_dbg(&spi->dev, "spi_device %u.%u cleanup\n",
+			spi->master->bus_num, spi->chip_select);
+
+	kfree(chip);
+}
+
+static irqreturn_t dspi_interrupt(int irq, void *dev_id)
+{
+	struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;
+	struct spi_message *msg = dspi->cur_msg;
+
+	writel(SPI_SR_EOQF, dspi->base + SPI_SR);
+
+	if (!dspi->cur_msg) {
+		u32 irq_status = readl(dspi->base + SPI_SR);
+		printk(KERN_ERR "Bad message or transfer state handler. "
+				"IRQ status = %x\n", irq_status);
+		return IRQ_HANDLED;
+	}
+
+	dspi_transfer_read(dspi);
+
+	if (!dspi->len) {
+		/*
+		 * Finished now - fall through and schedule next
+		 * transfer tasklet
+		 */
+		if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM)
+			set_16bit_transfer_mode(dspi);
+		dspi->waitflags = 1;
+		wake_up_interruptible(&dspi->waitq);
+
+	} else {
+		/* not finished yet - keep going */
+		msg->actual_length += dspi_transfer_write(dspi);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct of_device_id fsl_dspi_dt_ids[] = {
+	{ .compatible = "fsl,vf610-dspi", .data = NULL, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids);
+
+#ifdef CONFIG_PM_SLEEP
+static int dspi_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct fsl_dspi *dspi = spi_master_get_devdata(master);
+
+	spi_master_suspend(master);
+	clk_disable_unprepare(dspi->clk);
+
+	return 0;
+}
+
+static int dspi_resume(struct device *dev)
+{
+
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct fsl_dspi *dspi = spi_master_get_devdata(master);
+
+	clk_prepare_enable(dspi->clk);
+	spi_master_resume(master);
+
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops dspi_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(dspi_suspend, dspi_resume)
+};
+
+static int dspi_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct spi_master *master;
+	struct fsl_dspi *dspi;
+	struct resource *res;
+	int ret = 0, cs_num, bus_num;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
+	if (!master)
+		return -ENOMEM;
+
+	dspi = spi_master_get_devdata(master);
+	dspi->master = master;
+
+	master->cleanup = dspi_cleanup;
+	master->setup = dspi_setup;
+	master->transfer = NULL;
+	master->transfer_one_message = dspi_transfer_one_message;
+	master->prepare_transfer_hardware = dspi_prepare_transfer_hw;
+	master->unprepare_transfer_hardware = dspi_unprepare_transfer_hw;
+	master->mode_bits = SPI_CPOL | SPI_CPHA;
+	master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) |
+					SPI_BPW_MASK(16);
+	master->dev.of_node = pdev->dev.of_node;
+
+	ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num);
+	if (ret < 0)
+		goto fail;
+	master->num_chipselect = cs_num;
+
+	ret = of_property_read_u32(np, "bus-num", &bus_num);
+	if (ret < 0)
+		goto fail;
+	master->bus_num = bus_num;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "can't get platform resource\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	dspi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (!dspi->base) {
+		ret = EINVAL;
+		goto fail;
+	}
+
+	dspi->irq = platform_get_irq(pdev, 0);
+	if (dspi->irq < 0) {
+		dev_err(&pdev->dev, "can't get platform irq\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, 0,
+			pdev->name, dspi);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n");
+		goto fail;
+	}
+
+	dspi->clk = devm_clk_get(&pdev->dev, "dspi");
+	if (IS_ERR(dspi->clk)) {
+		dev_err(&pdev->dev, "unable to get clock\n");
+		goto fail;
+	}
+	clk_prepare_enable(dspi->clk);
+
+	init_waitqueue_head(&dspi->waitq);
+
+	/* Register with the SPI framework */
+	platform_set_drvdata(pdev, dspi);
+	ret = spi_register_master(master);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Problem registering DSPI master\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	printk(KERN_INFO "Freescale DSPI master initialized\n");
+	return ret;
+
+fail:
+	spi_master_put(master);
+	return ret;
+}
+
+static int dspi_remove(struct platform_device *pdev)
+{
+	struct fsl_dspi *dspi = platform_get_drvdata(pdev);
+
+	if (!dspi)
+		return 0;
+
+	clk_disable_unprepare(dspi->clk);
+	clk_put(dspi->clk);
+
+	/* Disconnect from the SPI framework */
+	spi_unregister_master(dspi->master);
+	spi_master_put(dspi->master);
+
+	/* Prevent double remove */
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver fsl_dspi_driver = {
+	.driver.name    = DRIVER_NAME,
+	.driver.of_match_table = fsl_dspi_dt_ids,
+	.driver.owner   = THIS_MODULE,
+	.driver.pm = &dspi_pm,
+	.probe          = dspi_probe,
+	.remove		= dspi_remove,
+};
+module_platform_driver(fsl_dspi_driver);
+
+MODULE_DESCRIPTION("Freescale DSPI Controller Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes
  2013-07-08  8:37 [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Chao Fu
@ 2013-07-08  8:37 ` Chao Fu
  2013-07-08 11:35   ` Mark Brown
  2013-07-08  8:37 ` [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a Chao Fu
  2013-07-09 15:02 ` [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Mark Brown
  2 siblings, 1 reply; 11+ messages in thread
From: Chao Fu @ 2013-07-08  8:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chao Fu <B44548@freescale.com>

Add Freescale DSPI node into vf610 dts.

Signed-off-by: Chao Fu <b44548@freescale.com>
---
 arch/arm/boot/dts/vf610.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index e1eb7da..fc80f4a 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -87,6 +87,17 @@
 				arm,tag-latency = <2 2 2>;
 			};
 
+			dspi0: dspi0 at 4002c000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,vf610-dspi";
+				reg = <0x4002c000 0x1000>;
+				interrupts = <0 67 0x04>;
+				clocks = <&clks VF610_CLK_DSPI0>;
+				clock-names = "dspi";
+				status = "disabled";
+			};
+
 			uart0: serial at 40027000 {
 				compatible = "fsl,vf610-lpuart";
 				reg = <0x40027000 0x1000>;
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-08  8:37 [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Chao Fu
  2013-07-08  8:37 ` [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes Chao Fu
@ 2013-07-08  8:37 ` Chao Fu
  2013-07-08 11:36   ` Mark Brown
  2013-07-09 15:02 ` [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Mark Brown
  2 siblings, 1 reply; 11+ messages in thread
From: Chao Fu @ 2013-07-08  8:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chao Fu <B44548@freescale.com>

This patch enables DSPI0 and at26df081a flash device for Vybrid VF610 TOWER board.

Signed-off-by: Chao Fu <b44548@freescale.com>
---
 arch/arm/boot/dts/vf610-twr.dts | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index b3905f5..bc5bf9d 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -36,6 +36,28 @@
 
 };
 
+&dspi0 {
+	spi-num-chipselects = <1>;
+	bus-num = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_dspi0_1>;
+	status = "okay";
+
+	sflash: at26df081a at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "atmel,at26df081a";
+		spi-max-frequency = <16000000>;
+		spi-cpol;
+		spi-cpha;
+		dspi,ctar-dbr = <0>;
+		dspi,ctar-pbr = <0>;
+		reg = <0>;
+		linux,modalias = "m25p80";
+		modal = "at26df081a";
+	};
+};
+
 &fec0 {
 	phy-mode = "rmii";
 	pinctrl-names = "default";
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes
  2013-07-08  8:37 ` [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes Chao Fu
@ 2013-07-08 11:35   ` Mark Brown
  0 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2013-07-08 11:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 08, 2013 at 04:37:01PM +0800, Chao Fu wrote:
> From: Chao Fu <B44548@freescale.com>
> 
> Add Freescale DSPI node into vf610 dts.
> 
> Signed-off-by: Chao Fu <b44548@freescale.com>

Acked-by: Mark Brown <broonie@linaro.org>

This should be fine to merge via arm-soc, it's no real dependency on the
driver itself or driver specific bindings.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130708/6012ee64/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-08  8:37 ` [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a Chao Fu
@ 2013-07-08 11:36   ` Mark Brown
  2013-07-09  5:29     ` Shawn Guo
  0 siblings, 1 reply; 11+ messages in thread
From: Mark Brown @ 2013-07-08 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 08, 2013 at 04:37:02PM +0800, Chao Fu wrote:
> From: Chao Fu <B44548@freescale.com>
> 
> This patch enables DSPI0 and at26df081a flash device for Vybrid VF610 TOWER board.

Acked-by: Mark Brown <broonie@linaro.org>

This should be fine to merge via arm-soc, it's no real dependency on the
actual SPI driver.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130708/b9f66886/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-08 11:36   ` Mark Brown
@ 2013-07-09  5:29     ` Shawn Guo
  2013-07-09 10:07       ` Mark Brown
  0 siblings, 1 reply; 11+ messages in thread
From: Shawn Guo @ 2013-07-09  5:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 08, 2013 at 12:36:01PM +0100, Mark Brown wrote:
> On Mon, Jul 08, 2013 at 04:37:02PM +0800, Chao Fu wrote:
> > From: Chao Fu <B44548@freescale.com>
> > 
> > This patch enables DSPI0 and at26df081a flash device for Vybrid VF610 TOWER board.
> 
> Acked-by: Mark Brown <broonie@linaro.org>
> 
> This should be fine to merge via arm-soc, it's no real dependency on the
> actual SPI driver.

It has dependency on the actual SPI driver where the DT bindings are
defined, so I would only take the patches after the driver parts gets
accepted.

Shawn

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-09  5:29     ` Shawn Guo
@ 2013-07-09 10:07       ` Mark Brown
  2013-07-09 12:52         ` Shawn Guo
  0 siblings, 1 reply; 11+ messages in thread
From: Mark Brown @ 2013-07-09 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 09, 2013 at 01:29:27PM +0800, Shawn Guo wrote:
> On Mon, Jul 08, 2013 at 12:36:01PM +0100, Mark Brown wrote:

> > This should be fine to merge via arm-soc, it's no real dependency on the
> > actual SPI driver.

> It has dependency on the actual SPI driver where the DT bindings are
> defined, so I would only take the patches after the driver parts gets
> accepted.

The bindings are all totally generic ones for a SPI controller, there's
nothing controversial or even device specific about them so I'm happy to
say the bindings are fine as-is.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130709/06099851/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-09 10:07       ` Mark Brown
@ 2013-07-09 12:52         ` Shawn Guo
  2013-07-09 14:44           ` Mark Brown
  0 siblings, 1 reply; 11+ messages in thread
From: Shawn Guo @ 2013-07-09 12:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 09, 2013 at 11:07:23AM +0100, Mark Brown wrote:
> On Tue, Jul 09, 2013 at 01:29:27PM +0800, Shawn Guo wrote:
> > On Mon, Jul 08, 2013 at 12:36:01PM +0100, Mark Brown wrote:
> 
> > > This should be fine to merge via arm-soc, it's no real dependency on the
> > > actual SPI driver.
> 
> > It has dependency on the actual SPI driver where the DT bindings are
> > defined, so I would only take the patches after the driver parts gets
> > accepted.
> 
> The bindings are all totally generic ones for a SPI controller, there's
> nothing controversial or even device specific about them so I'm happy to
> say the bindings are fine as-is.

Am I missing something?  I do not even see a bindings doc in patch #1.
How can I think the bindings are fine?

Shawn

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-09 12:52         ` Shawn Guo
@ 2013-07-09 14:44           ` Mark Brown
  2013-07-09 15:02             ` Shawn Guo
  0 siblings, 1 reply; 11+ messages in thread
From: Mark Brown @ 2013-07-09 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 09, 2013 at 08:52:41PM +0800, Shawn Guo wrote:
> On Tue, Jul 09, 2013 at 11:07:23AM +0100, Mark Brown wrote:

> > The bindings are all totally generic ones for a SPI controller, there's
> > nothing controversial or even device specific about them so I'm happy to
> > say the bindings are fine as-is.

> Am I missing something?  I do not even see a bindings doc in patch #1.
> How can I think the bindings are fine?

Hrm, I was sure I was seeing one...  though in any case there's nothing
here except for interrupt and DMA hookup so any additional properties
aren't going to affect this patch.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130709/6540129f/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a
  2013-07-09 14:44           ` Mark Brown
@ 2013-07-09 15:02             ` Shawn Guo
  0 siblings, 0 replies; 11+ messages in thread
From: Shawn Guo @ 2013-07-09 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 09, 2013 at 03:44:25PM +0100, Mark Brown wrote:
> On Tue, Jul 09, 2013 at 08:52:41PM +0800, Shawn Guo wrote:
> > On Tue, Jul 09, 2013 at 11:07:23AM +0100, Mark Brown wrote:
> 
> > > The bindings are all totally generic ones for a SPI controller, there's
> > > nothing controversial or even device specific about them so I'm happy to
> > > say the bindings are fine as-is.
> 
> > Am I missing something?  I do not even see a bindings doc in patch #1.
> > How can I think the bindings are fine?
> 
> Hrm, I was sure I was seeing one...  though in any case there's nothing
> here except for interrupt and DMA hookup so any additional properties
> aren't going to affect this patch.

You are probably talking about patch #2.  But this patch does add two
properties "spi-num-chipselects" and "bus-num".

Shawn

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform
  2013-07-08  8:37 [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Chao Fu
  2013-07-08  8:37 ` [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes Chao Fu
  2013-07-08  8:37 ` [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a Chao Fu
@ 2013-07-09 15:02 ` Mark Brown
  2 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2013-07-09 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 08, 2013 at 04:37:00PM +0800, Chao Fu wrote:

>  drivers/spi/Kconfig        |   6 +
>  drivers/spi/Makefile       |   1 +
>  drivers/spi/spi-fsl-dspi.c | 675 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 682 insertions(+)

There is no binding documentation here.  Binding documentation is
mandatory for any new bindings.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130709/46480b04/attachment.sig>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-07-09 15:02 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-08  8:37 [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Chao Fu
2013-07-08  8:37 ` [PATCH 2/3] ARM:dts: vf610: Add DSPI nodes Chao Fu
2013-07-08 11:35   ` Mark Brown
2013-07-08  8:37 ` [PATCH 3/3] ARM:dts:vf610-twr:Enable DSPI0 devices and Flash at26df081a Chao Fu
2013-07-08 11:36   ` Mark Brown
2013-07-09  5:29     ` Shawn Guo
2013-07-09 10:07       ` Mark Brown
2013-07-09 12:52         ` Shawn Guo
2013-07-09 14:44           ` Mark Brown
2013-07-09 15:02             ` Shawn Guo
2013-07-09 15:02 ` [PATCH 1/3] spi:Add Freescale DSPI driver for Vybrid VF610 platform Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.