Browse Source

Merge remote-tracking branches 'spi/topic/omap-uwire', 'spi/topic/omap100k', 'spi/topic/omap2', 'spi/topic/orion', 'spi/topic/pl022', 'spi/topic/qup', 'spi/topic/rspi' and 'spi/topic/s3c24xx' into spi-next

Mark Brown 11 năm trước cách đây

+ 85 - 0
Documentation/devicetree/bindings/spi/qcom,spi-qup.txt

@@ -0,0 +1,85 @@
+Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI)
+
+The QUP core is an AHB slave that provides a common data path (an output FIFO
+and an input FIFO) for serial peripheral interface (SPI) mini-core.
+
+SPI in master mode supports up to 50MHz, up to four chip selects, programmable
+data path from 4 bits to 32 bits and numerous protocol variants.
+
+Required properties:
+- compatible:     Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
+- reg:            Should contain base register location and length
+- interrupts:     Interrupt number used by this controller
+
+- clocks:         Should contain the core clock and the AHB clock.
+- clock-names:    Should be "core" for the core clock and "iface" for the
+                  AHB clock.
+
+- #address-cells: Number of cells required to define a chip select
+                  address on the SPI bus. Should be set to 1.
+- #size-cells:    Should be zero.
+
+Optional properties:
+- spi-max-frequency: Specifies maximum SPI clock frequency,
+                     Units - Hz. Definition as per
+                     Documentation/devicetree/bindings/spi/spi-bus.txt
+
+SPI slave nodes must be children of the SPI master node and can contain
+properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+
+	spi_8: spi@f9964000 { /* BLSP2 QUP2 */
+
+		compatible = "qcom,spi-qup-v2";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0xf9964000 0x1000>;
+		interrupts = <0 102 0>;
+		spi-max-frequency = <19200000>;
+
+		clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+		clock-names = "core", "iface";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi8_default>;
+
+		device@0 {
+			compatible = "arm,pl022-dummy";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0>; /* Chip select 0 */
+			spi-max-frequency = <19200000>;
+			spi-cpol;
+		};
+
+		device@1 {
+			compatible = "arm,pl022-dummy";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <1>; /* Chip select 1 */
+			spi-max-frequency = <9600000>;
+			spi-cpha;
+		};
+
+		device@2 {
+			compatible = "arm,pl022-dummy";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <2>; /* Chip select 2 */
+			spi-max-frequency = <19200000>;
+			spi-cpol;
+			spi-cpha;
+		};
+
+		device@3 {
+			compatible = "arm,pl022-dummy";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <3>; /* Chip select 3 */
+			spi-max-frequency = <19200000>;
+			spi-cpol;
+			spi-cpha;
+			spi-cs-high;
+		};
+	};

+ 61 - 0
Documentation/devicetree/bindings/spi/spi-rspi.txt

@@ -0,0 +1,61 @@
+Device tree configuration for Renesas RSPI/QSPI driver
+
+Required properties:
+- compatible       : For Renesas Serial Peripheral Interface on legacy SH:
+		     "renesas,rspi-<soctype>", "renesas,rspi" as fallback.
+		     For Renesas Serial Peripheral Interface on RZ/A1H:
+		     "renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
+		     For Quad Serial Peripheral Interface on R-Car Gen2:
+		     "renesas,qspi-<soctype>", "renesas,qspi" as fallback.
+		     Examples with soctypes are:
+		        - "renesas,rspi-sh7757" (SH)
+			- "renesas,rspi-r7s72100" (RZ/A1H)
+			- "renesas,qspi-r8a7790" (R-Car H2)
+			- "renesas,qspi-r8a7791" (R-Car M2)
+- reg              : Address start and address range size of the device
+- interrupts       : A list of interrupt-specifiers, one for each entry in
+		     interrupt-names.
+		     If interrupt-names is not present, an interrupt specifier
+		     for a single muxed interrupt.
+- interrupt-names  : A list of interrupt names. Should contain (if present):
+		       - "error" for SPEI,
+		       - "rx" for SPRI,
+		       - "tx" to SPTI,
+		       - "mux" for a single muxed interrupt.
+- interrupt-parent : The phandle for the interrupt controller that
+		     services interrupts for this device.
+- num-cs	   : Number of chip selects. Some RSPI cores have more than 1.
+- #address-cells   : Must be <1>
+- #size-cells      : Must be <0>
+
+Optional properties:
+- clocks           : Must contain a reference to the functional clock.
+
+Pinctrl properties might be needed, too.  See
+Documentation/devicetree/bindings/pinctrl/renesas,*.
+
+Examples:
+
+	spi0: spi@e800c800 {
+		compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz";
+		reg = <0xe800c800 0x24>;
+		interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 239 IRQ_TYPE_LEVEL_HIGH>,
+			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "error", "rx", "tx";
+		interrupt-parent = <&gic>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	spi: spi@e6b10000 {
+		compatible = "renesas,qspi-r8a7791", "renesas,qspi";
+		reg = <0 0xe6b10000 0 0x2c>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};

+ 1 - 2
drivers/base/power/Makefile

@@ -1,6 +1,5 @@
-obj-$(CONFIG_PM)	+= sysfs.o generic_ops.o common.o qos.o
+obj-$(CONFIG_PM)	+= sysfs.o generic_ops.o common.o qos.o runtime.o
 obj-$(CONFIG_PM_SLEEP)	+= main.o wakeup.o
 obj-$(CONFIG_PM_SLEEP)	+= main.o wakeup.o
-obj-$(CONFIG_PM_RUNTIME)	+= runtime.o
 obj-$(CONFIG_PM_TRACE_RTC)	+= trace.o
 obj-$(CONFIG_PM_TRACE_RTC)	+= trace.o
 obj-$(CONFIG_PM_OPP)	+= opp.o
 obj-$(CONFIG_PM_OPP)	+= opp.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS)	+=  domain.o domain_governor.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS)	+=  domain.o domain_governor.o

+ 123 - 39
drivers/base/power/runtime.c

@@ -13,6 +13,43 @@
 #include <trace/events/rpm.h>
 #include <trace/events/rpm.h>
 #include "power.h"
 #include "power.h"
 
 
+#define RPM_GET_CALLBACK(dev, cb)				\
+({								\
+	int (*__rpm_cb)(struct device *__d);			\
+								\
+	if (dev->pm_domain)					\
+		__rpm_cb = dev->pm_domain->ops.cb;		\
+	else if (dev->type && dev->type->pm)			\
+		__rpm_cb = dev->type->pm->cb;			\
+	else if (dev->class && dev->class->pm)			\
+		__rpm_cb = dev->class->pm->cb;			\
+	else if (dev->bus && dev->bus->pm)			\
+		__rpm_cb = dev->bus->pm->cb;			\
+	else							\
+		__rpm_cb = NULL;				\
+								\
+	if (!__rpm_cb && dev->driver && dev->driver->pm)	\
+		__rpm_cb = dev->driver->pm->cb;			\
+								\
+	__rpm_cb;						\
+})
+
+static int (*rpm_get_suspend_cb(struct device *dev))(struct device *)
+{
+	return RPM_GET_CALLBACK(dev, runtime_suspend);
+}
+
+static int (*rpm_get_resume_cb(struct device *dev))(struct device *)
+{
+	return RPM_GET_CALLBACK(dev, runtime_resume);
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int (*rpm_get_idle_cb(struct device *dev))(struct device *)
+{
+	return RPM_GET_CALLBACK(dev, runtime_idle);
+}
+
 static int rpm_resume(struct device *dev, int rpmflags);
 static int rpm_resume(struct device *dev, int rpmflags);
 static int rpm_suspend(struct device *dev, int rpmflags);
 static int rpm_suspend(struct device *dev, int rpmflags);
 
 
@@ -310,19 +347,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
 
 
 	dev->power.idle_notification = true;
 	dev->power.idle_notification = true;
 
 
-	if (dev->pm_domain)
-		callback = dev->pm_domain->ops.runtime_idle;
-	else if (dev->type && dev->type->pm)
-		callback = dev->type->pm->runtime_idle;
-	else if (dev->class && dev->class->pm)
-		callback = dev->class->pm->runtime_idle;
-	else if (dev->bus && dev->bus->pm)
-		callback = dev->bus->pm->runtime_idle;
-	else
-		callback = NULL;
-
-	if (!callback && dev->driver && dev->driver->pm)
-		callback = dev->driver->pm->runtime_idle;
+	callback = rpm_get_idle_cb(dev);
 
 
 	if (callback)
 	if (callback)
 		retval = __rpm_callback(callback, dev);
 		retval = __rpm_callback(callback, dev);
@@ -492,19 +517,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 
 
 	__update_runtime_status(dev, RPM_SUSPENDING);
 	__update_runtime_status(dev, RPM_SUSPENDING);
 
 
-	if (dev->pm_domain)
-		callback = dev->pm_domain->ops.runtime_suspend;
-	else if (dev->type && dev->type->pm)
-		callback = dev->type->pm->runtime_suspend;
-	else if (dev->class && dev->class->pm)
-		callback = dev->class->pm->runtime_suspend;
-	else if (dev->bus && dev->bus->pm)
-		callback = dev->bus->pm->runtime_suspend;
-	else
-		callback = NULL;
-
-	if (!callback && dev->driver && dev->driver->pm)
-		callback = dev->driver->pm->runtime_suspend;
+	callback = rpm_get_suspend_cb(dev);
 
 
 	retval = rpm_callback(callback, dev);
 	retval = rpm_callback(callback, dev);
 	if (retval)
 	if (retval)
@@ -724,19 +737,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
 
 	__update_runtime_status(dev, RPM_RESUMING);
 	__update_runtime_status(dev, RPM_RESUMING);
 
 
-	if (dev->pm_domain)
-		callback = dev->pm_domain->ops.runtime_resume;
-	else if (dev->type && dev->type->pm)
-		callback = dev->type->pm->runtime_resume;
-	else if (dev->class && dev->class->pm)
-		callback = dev->class->pm->runtime_resume;
-	else if (dev->bus && dev->bus->pm)
-		callback = dev->bus->pm->runtime_resume;
-	else
-		callback = NULL;
-
-	if (!callback && dev->driver && dev->driver->pm)
-		callback = dev->driver->pm->runtime_resume;
+	callback = rpm_get_resume_cb(dev);
 
 
 	retval = rpm_callback(callback, dev);
 	retval = rpm_callback(callback, dev);
 	if (retval) {
 	if (retval) {
@@ -1401,3 +1402,86 @@ void pm_runtime_remove(struct device *dev)
 	if (dev->power.irq_safe && dev->parent)
 	if (dev->power.irq_safe && dev->parent)
 		pm_runtime_put(dev->parent);
 		pm_runtime_put(dev->parent);
 }
 }
+#endif
+
+/**
+ * pm_runtime_force_suspend - Force a device into suspend state if needed.
+ * @dev: Device to suspend.
+ *
+ * Disable runtime PM so we safely can check the device's runtime PM status and
+ * if it is active, invoke it's .runtime_suspend callback to bring it into
+ * suspend state. Keep runtime PM disabled to preserve the state unless we
+ * encounter errors.
+ *
+ * Typically this function may be invoked from a system suspend callback to make
+ * sure the device is put into low power state.
+ */
+int pm_runtime_force_suspend(struct device *dev)
+{
+	int (*callback)(struct device *);
+	int ret = 0;
+
+	pm_runtime_disable(dev);
+
+	/*
+	 * Note that pm_runtime_status_suspended() returns false while
+	 * !CONFIG_PM_RUNTIME, which means the device will be put into low
+	 * power state.
+	 */
+	if (pm_runtime_status_suspended(dev))
+		return 0;
+
+	callback = rpm_get_suspend_cb(dev);
+
+	if (!callback) {
+		ret = -ENOSYS;
+		goto err;
+	}
+
+	ret = callback(dev);
+	if (ret)
+		goto err;
+
+	pm_runtime_set_suspended(dev);
+	return 0;
+err:
+	pm_runtime_enable(dev);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_force_suspend);
+
+/**
+ * pm_runtime_force_resume - Force a device into resume state.
+ * @dev: Device to resume.
+ *
+ * Prior invoking this function we expect the user to have brought the device
+ * into low power state by a call to pm_runtime_force_suspend(). Here we reverse
+ * those actions and brings the device into full power. We update the runtime PM
+ * status and re-enables runtime PM.
+ *
+ * Typically this function may be invoked from a system resume callback to make
+ * sure the device is put into full power state.
+ */
+int pm_runtime_force_resume(struct device *dev)
+{
+	int (*callback)(struct device *);
+	int ret = 0;
+
+	callback = rpm_get_resume_cb(dev);
+
+	if (!callback) {
+		ret = -ENOSYS;
+		goto out;
+	}
+
+	ret = callback(dev);
+	if (ret)
+		goto out;
+
+	pm_runtime_set_active(dev);
+	pm_runtime_mark_last_busy(dev);
+out:
+	pm_runtime_enable(dev);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_force_resume);

+ 14 - 1
drivers/spi/Kconfig

@@ -307,7 +307,7 @@ config SPI_OMAP_UWIRE
 
 
 config SPI_OMAP24XX
 config SPI_OMAP24XX
 	tristate "McSPI driver for OMAP"
 	tristate "McSPI driver for OMAP"
-	depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SH
+	depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH
 	depends on ARCH_OMAP2PLUS || COMPILE_TEST
 	depends on ARCH_OMAP2PLUS || COMPILE_TEST
 	help
 	help
 	  SPI master controller for OMAP24XX and later Multichannel SPI
 	  SPI master controller for OMAP24XX and later Multichannel SPI
@@ -381,6 +381,19 @@ config SPI_RSPI
 	help
 	help
 	  SPI driver for Renesas RSPI and QSPI blocks.
 	  SPI driver for Renesas RSPI and QSPI blocks.
 
 
+config SPI_QUP
+	tristate "Qualcomm SPI controller with QUP interface"
+	depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
+	help
+	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that
+	  provides a common data path (an output FIFO and an input FIFO)
+	  for serial peripheral interface (SPI) mini-core. SPI in master
+	  mode supports up to 50MHz, up to four chip selects, programmable
+	  data path from 4 bits to 32 bits and numerous protocol variants.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called spi_qup.
+
 config SPI_S3C24XX
 config SPI_S3C24XX
 	tristate "Samsung S3C24XX series SPI"
 	tristate "Samsung S3C24XX series SPI"
 	depends on ARCH_S3C24XX
 	depends on ARCH_S3C24XX

+ 1 - 0
drivers/spi/Makefile

@@ -59,6 +59,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_PXADMA)	+= spi-pxa2xx-pxadma.o
 spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA)	+= spi-pxa2xx-dma.o
 spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA)	+= spi-pxa2xx-dma.o
 obj-$(CONFIG_SPI_PXA2XX)		+= spi-pxa2xx-platform.o
 obj-$(CONFIG_SPI_PXA2XX)		+= spi-pxa2xx-platform.o
 obj-$(CONFIG_SPI_PXA2XX_PCI)		+= spi-pxa2xx-pci.o
 obj-$(CONFIG_SPI_PXA2XX_PCI)		+= spi-pxa2xx-pci.o
+obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
 obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
 obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
 obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o
 obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o
 spi-s3c24xx-hw-y			:= spi-s3c24xx.o
 spi-s3c24xx-hw-y			:= spi-s3c24xx.o

+ 19 - 33
drivers/spi/spi-omap-100k.c

@@ -83,15 +83,11 @@
 #define SPI_SHUTDOWN	1
 #define SPI_SHUTDOWN	1
 
 
 struct omap1_spi100k {
 struct omap1_spi100k {
-	struct spi_master       *master;
 	struct clk              *ick;
 	struct clk              *ick;
 	struct clk              *fck;
 	struct clk              *fck;
 
 
 	/* Virtual base address of the controller */
 	/* Virtual base address of the controller */
 	void __iomem            *base;
 	void __iomem            *base;
-
-	/* State of the SPI */
-	unsigned int		state;
 };
 };
 
 
 struct omap1_spi100k_cs {
 struct omap1_spi100k_cs {
@@ -99,13 +95,6 @@ struct omap1_spi100k_cs {
 	int                     word_len;
 	int                     word_len;
 };
 };
 
 
-#define MOD_REG_BIT(val, mask, set) do { \
-	if (set) \
-		val |= mask; \
-	else \
-		val &= ~mask; \
-} while (0)
-
 static void spi100k_enable_clock(struct spi_master *master)
 static void spi100k_enable_clock(struct spi_master *master)
 {
 {
 	unsigned int val;
 	unsigned int val;
@@ -139,7 +128,7 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)
 	}
 	}
 
 
 	spi100k_enable_clock(master);
 	spi100k_enable_clock(master);
-	writew( data , spi100k->base + SPI_TX_MSB);
+	writew(data , spi100k->base + SPI_TX_MSB);
 
 
 	writew(SPI_CTRL_SEN(0) |
 	writew(SPI_CTRL_SEN(0) |
 	       SPI_CTRL_WORD_SIZE(len) |
 	       SPI_CTRL_WORD_SIZE(len) |
@@ -147,7 +136,8 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)
 	       spi100k->base + SPI_CTRL);
 	       spi100k->base + SPI_CTRL);
 
 
 	/* Wait for bit ack send change */
 	/* Wait for bit ack send change */
-	while((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_WE) != SPI_STATUS_WE);
+	while ((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_WE) != SPI_STATUS_WE)
+		;
 	udelay(1000);
 	udelay(1000);
 
 
 	spi100k_disable_clock(master);
 	spi100k_disable_clock(master);
@@ -155,7 +145,7 @@ static void spi100k_write_data(struct spi_master *master, int len, int data)
 
 
 static int spi100k_read_data(struct spi_master *master, int len)
 static int spi100k_read_data(struct spi_master *master, int len)
 {
 {
-	int dataH,dataL;
+	int dataH, dataL;
 	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
 	struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
 
 
 	/* Always do at least 16 bits */
 	/* Always do at least 16 bits */
@@ -168,7 +158,8 @@ static int spi100k_read_data(struct spi_master *master, int len)
 	       SPI_CTRL_RD,
 	       SPI_CTRL_RD,
 	       spi100k->base + SPI_CTRL);
 	       spi100k->base + SPI_CTRL);
 
 
-	while((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_RD) != SPI_STATUS_RD);
+	while ((readw(spi100k->base + SPI_STATUS) & SPI_STATUS_RD) != SPI_STATUS_RD)
+		;
 	udelay(1000);
 	udelay(1000);
 
 
 	dataL = readw(spi100k->base + SPI_RX_LSB);
 	dataL = readw(spi100k->base + SPI_RX_LSB);
@@ -204,12 +195,10 @@ static void omap1_spi100k_force_cs(struct omap1_spi100k *spi100k, int enable)
 static unsigned
 static unsigned
 omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
 omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
 {
 {
-	struct omap1_spi100k    *spi100k;
 	struct omap1_spi100k_cs *cs = spi->controller_state;
 	struct omap1_spi100k_cs *cs = spi->controller_state;
 	unsigned int            count, c;
 	unsigned int            count, c;
 	int                     word_len;
 	int                     word_len;
 
 
-	spi100k = spi_master_get_devdata(spi->master);
 	count = xfer->len;
 	count = xfer->len;
 	c = count;
 	c = count;
 	word_len = cs->word_len;
 	word_len = cs->word_len;
@@ -221,12 +210,12 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
 		rx = xfer->rx_buf;
 		rx = xfer->rx_buf;
 		tx = xfer->tx_buf;
 		tx = xfer->tx_buf;
 		do {
 		do {
-			c-=1;
+			c -= 1;
 			if (xfer->tx_buf != NULL)
 			if (xfer->tx_buf != NULL)
 				spi100k_write_data(spi->master, word_len, *tx++);
 				spi100k_write_data(spi->master, word_len, *tx++);
 			if (xfer->rx_buf != NULL)
 			if (xfer->rx_buf != NULL)
 				*rx++ = spi100k_read_data(spi->master, word_len);
 				*rx++ = spi100k_read_data(spi->master, word_len);
-		} while(c);
+		} while (c);
 	} else if (word_len <= 16) {
 	} else if (word_len <= 16) {
 		u16             *rx;
 		u16             *rx;
 		const u16       *tx;
 		const u16       *tx;
@@ -234,12 +223,12 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
 		rx = xfer->rx_buf;
 		rx = xfer->rx_buf;
 		tx = xfer->tx_buf;
 		tx = xfer->tx_buf;
 		do {
 		do {
-			c-=2;
+			c -= 2;
 			if (xfer->tx_buf != NULL)
 			if (xfer->tx_buf != NULL)
-				spi100k_write_data(spi->master,word_len, *tx++);
+				spi100k_write_data(spi->master, word_len, *tx++);
 			if (xfer->rx_buf != NULL)
 			if (xfer->rx_buf != NULL)
-				*rx++ = spi100k_read_data(spi->master,word_len);
-		} while(c);
+				*rx++ = spi100k_read_data(spi->master, word_len);
+		} while (c);
 	} else if (word_len <= 32) {
 	} else if (word_len <= 32) {
 		u32             *rx;
 		u32             *rx;
 		const u32       *tx;
 		const u32       *tx;
@@ -247,12 +236,12 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
 		rx = xfer->rx_buf;
 		rx = xfer->rx_buf;
 		tx = xfer->tx_buf;
 		tx = xfer->tx_buf;
 		do {
 		do {
-			c-=4;
+			c -= 4;
 			if (xfer->tx_buf != NULL)
 			if (xfer->tx_buf != NULL)
-				spi100k_write_data(spi->master,word_len, *tx);
+				spi100k_write_data(spi->master, word_len, *tx);
 			if (xfer->rx_buf != NULL)
 			if (xfer->rx_buf != NULL)
-				*rx = spi100k_read_data(spi->master,word_len);
-		} while(c);
+				*rx = spi100k_read_data(spi->master, word_len);
+		} while (c);
 	}
 	}
 	return count - c;
 	return count - c;
 }
 }
@@ -294,7 +283,7 @@ static int omap1_spi100k_setup(struct spi_device *spi)
 	spi100k = spi_master_get_devdata(spi->master);
 	spi100k = spi_master_get_devdata(spi->master);
 
 
 	if (!cs) {
 	if (!cs) {
-		cs = kzalloc(sizeof *cs, GFP_KERNEL);
+		cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL);
 		if (!cs)
 		if (!cs)
 			return -ENOMEM;
 			return -ENOMEM;
 		cs->base = spi100k->base + spi->chip_select * 0x14;
 		cs->base = spi100k->base + spi->chip_select * 0x14;
@@ -411,14 +400,14 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
 	if (!pdev->id)
 	if (!pdev->id)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	master = spi_alloc_master(&pdev->dev, sizeof *spi100k);
+	master = spi_alloc_master(&pdev->dev, sizeof(*spi100k));
 	if (master == NULL) {
 	if (master == NULL) {
 		dev_dbg(&pdev->dev, "master allocation failed\n");
 		dev_dbg(&pdev->dev, "master allocation failed\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
 	if (pdev->id != -1)
 	if (pdev->id != -1)
-	       master->bus_num = pdev->id;
+		master->bus_num = pdev->id;
 
 
 	master->setup = omap1_spi100k_setup;
 	master->setup = omap1_spi100k_setup;
 	master->transfer_one_message = omap1_spi100k_transfer_one_message;
 	master->transfer_one_message = omap1_spi100k_transfer_one_message;
@@ -434,7 +423,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, master);
 	platform_set_drvdata(pdev, master);
 
 
 	spi100k = spi_master_get_devdata(master);
 	spi100k = spi_master_get_devdata(master);
-	spi100k->master = master;
 
 
 	/*
 	/*
 	 * The memory region base address is taken as the platform_data.
 	 * The memory region base address is taken as the platform_data.
@@ -461,8 +449,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
 	if (status < 0)
 	if (status < 0)
 		goto err;
 		goto err;
 
 
-	spi100k->state = SPI_RUNNING;
-
 	return status;
 	return status;
 
 
 err:
 err:

+ 3 - 20
drivers/spi/spi-omap-uwire.c

@@ -99,7 +99,6 @@ struct uwire_spi {
 };
 };
 
 
 struct uwire_state {
 struct uwire_state {
-	unsigned	bits_per_word;
 	unsigned	div1_idx;
 	unsigned	div1_idx;
 };
 };
 
 
@@ -210,9 +209,8 @@ static void uwire_chipselect(struct spi_device *spi, int value)
 
 
 static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
 static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
 {
 {
-	struct uwire_state *ust = spi->controller_state;
 	unsigned	len = t->len;
 	unsigned	len = t->len;
-	unsigned	bits = ust->bits_per_word;
+	unsigned	bits = t->bits_per_word ? : spi->bits_per_word;
 	unsigned	bytes;
 	unsigned	bytes;
 	u16		val, w;
 	u16		val, w;
 	int		status = 0;
 	int		status = 0;
@@ -220,10 +218,6 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
 	if (!t->tx_buf && !t->rx_buf)
 	if (!t->tx_buf && !t->rx_buf)
 		return 0;
 		return 0;
 
 
-	/* Microwire doesn't read and write concurrently */
-	if (t->tx_buf && t->rx_buf)
-		return -EPERM;
-
 	w = spi->chip_select << 10;
 	w = spi->chip_select << 10;
 	w |= CS_CMD;
 	w |= CS_CMD;
 
 
@@ -322,7 +316,6 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 	struct uwire_state	*ust = spi->controller_state;
 	struct uwire_state	*ust = spi->controller_state;
 	struct uwire_spi	*uwire;
 	struct uwire_spi	*uwire;
 	unsigned		flags = 0;
 	unsigned		flags = 0;
-	unsigned		bits;
 	unsigned		hz;
 	unsigned		hz;
 	unsigned long		rate;
 	unsigned long		rate;
 	int			div1_idx;
 	int			div1_idx;
@@ -332,17 +325,6 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 
 
 	uwire = spi_master_get_devdata(spi->master);
 	uwire = spi_master_get_devdata(spi->master);
 
 
-	bits = spi->bits_per_word;
-	if (t != NULL && t->bits_per_word)
-		bits = t->bits_per_word;
-
-	if (bits > 16) {
-		pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits);
-		status = -ENODEV;
-		goto done;
-	}
-	ust->bits_per_word = bits;
-
 	/* mode 0..3, clock inverted separately;
 	/* mode 0..3, clock inverted separately;
 	 * standard nCS signaling;
 	 * standard nCS signaling;
 	 * don't treat DI=high as "not ready"
 	 * don't treat DI=high as "not ready"
@@ -496,6 +478,7 @@ static int uwire_probe(struct platform_device *pdev)
 		status = PTR_ERR(uwire->ck);
 		status = PTR_ERR(uwire->ck);
 		dev_dbg(&pdev->dev, "no functional clock?\n");
 		dev_dbg(&pdev->dev, "no functional clock?\n");
 		spi_master_put(master);
 		spi_master_put(master);
+		iounmap(uwire_base);
 		return status;
 		return status;
 	}
 	}
 	clk_enable(uwire->ck);
 	clk_enable(uwire->ck);
@@ -509,7 +492,7 @@ static int uwire_probe(struct platform_device *pdev)
 
 
 	/* the spi->mode bits understood by this driver: */
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
 	master->flags = SPI_MASTER_HALF_DUPLEX;
 	master->flags = SPI_MASTER_HALF_DUPLEX;
 
 
 	master->bus_num = 2;	/* "official" */
 	master->bus_num = 2;	/* "official" */

+ 44 - 20
drivers/spi/spi-omap2-mcspi.c

@@ -44,6 +44,7 @@
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
 
 #define OMAP2_MCSPI_MAX_FREQ		48000000
 #define OMAP2_MCSPI_MAX_FREQ		48000000
+#define OMAP2_MCSPI_MAX_DIVIDER		4096
 #define OMAP2_MCSPI_MAX_FIFODEPTH	64
 #define OMAP2_MCSPI_MAX_FIFODEPTH	64
 #define OMAP2_MCSPI_MAX_FIFOWCNT	0xFFFF
 #define OMAP2_MCSPI_MAX_FIFOWCNT	0xFFFF
 #define SPI_AUTOSUSPEND_TIMEOUT		2000
 #define SPI_AUTOSUSPEND_TIMEOUT		2000
@@ -88,6 +89,7 @@
 #define OMAP2_MCSPI_CHCONF_FORCE	BIT(20)
 #define OMAP2_MCSPI_CHCONF_FORCE	BIT(20)
 #define OMAP2_MCSPI_CHCONF_FFET		BIT(27)
 #define OMAP2_MCSPI_CHCONF_FFET		BIT(27)
 #define OMAP2_MCSPI_CHCONF_FFER		BIT(28)
 #define OMAP2_MCSPI_CHCONF_FFER		BIT(28)
+#define OMAP2_MCSPI_CHCONF_CLKG		BIT(29)
 
 
 #define OMAP2_MCSPI_CHSTAT_RXS		BIT(0)
 #define OMAP2_MCSPI_CHSTAT_RXS		BIT(0)
 #define OMAP2_MCSPI_CHSTAT_TXS		BIT(1)
 #define OMAP2_MCSPI_CHSTAT_TXS		BIT(1)
@@ -95,6 +97,7 @@
 #define OMAP2_MCSPI_CHSTAT_TXFFE	BIT(3)
 #define OMAP2_MCSPI_CHSTAT_TXFFE	BIT(3)
 
 
 #define OMAP2_MCSPI_CHCTRL_EN		BIT(0)
 #define OMAP2_MCSPI_CHCTRL_EN		BIT(0)
+#define OMAP2_MCSPI_CHCTRL_EXTCLK_MASK	(0xff << 8)
 
 
 #define OMAP2_MCSPI_WAKEUPENABLE_WKEN	BIT(0)
 #define OMAP2_MCSPI_WAKEUPENABLE_WKEN	BIT(0)
 
 
@@ -148,7 +151,7 @@ struct omap2_mcspi_cs {
 	int			word_len;
 	int			word_len;
 	struct list_head	node;
 	struct list_head	node;
 	/* Context save and restore shadow register */
 	/* Context save and restore shadow register */
-	u32			chconf0;
+	u32			chconf0, chctrl0;
 };
 };
 
 
 static inline void mcspi_write_reg(struct spi_master *master,
 static inline void mcspi_write_reg(struct spi_master *master,
@@ -229,10 +232,16 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
 
 
 static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)
 static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)
 {
 {
+	struct omap2_mcspi_cs *cs = spi->controller_state;
 	u32 l;
 	u32 l;
 
 
-	l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0;
-	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, l);
+	l = cs->chctrl0;
+	if (enable)
+		l |= OMAP2_MCSPI_CHCTRL_EN;
+	else
+		l &= ~OMAP2_MCSPI_CHCTRL_EN;
+	cs->chctrl0 = l;
+	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);
 	/* Flash post-writes */
 	/* Flash post-writes */
 	mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
 	mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0);
 }
 }
@@ -839,7 +848,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi *mcspi;
 	struct omap2_mcspi *mcspi;
 	struct spi_master *spi_cntrl;
 	struct spi_master *spi_cntrl;
-	u32 l = 0, div = 0;
+	u32 l = 0, clkd = 0, div, extclk = 0, clkg = 0;
 	u8 word_len = spi->bits_per_word;
 	u8 word_len = spi->bits_per_word;
 	u32 speed_hz = spi->max_speed_hz;
 	u32 speed_hz = spi->max_speed_hz;
 
 
@@ -855,7 +864,17 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
 		speed_hz = t->speed_hz;
 		speed_hz = t->speed_hz;
 
 
 	speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
 	speed_hz = min_t(u32, speed_hz, OMAP2_MCSPI_MAX_FREQ);
-	div = omap2_mcspi_calc_divisor(speed_hz);
+	if (speed_hz < (OMAP2_MCSPI_MAX_FREQ / OMAP2_MCSPI_MAX_DIVIDER)) {
+		clkd = omap2_mcspi_calc_divisor(speed_hz);
+		speed_hz = OMAP2_MCSPI_MAX_FREQ >> clkd;
+		clkg = 0;
+	} else {
+		div = (OMAP2_MCSPI_MAX_FREQ + speed_hz - 1) / speed_hz;
+		speed_hz = OMAP2_MCSPI_MAX_FREQ / div;
+		clkd = (div - 1) & 0xf;
+		extclk = (div - 1) >> 4;
+		clkg = OMAP2_MCSPI_CHCONF_CLKG;
+	}
 
 
 	l = mcspi_cached_chconf0(spi);
 	l = mcspi_cached_chconf0(spi);
 
 
@@ -884,7 +903,16 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
 
 
 	/* set clock divisor */
 	/* set clock divisor */
 	l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
 	l &= ~OMAP2_MCSPI_CHCONF_CLKD_MASK;
-	l |= div << 2;
+	l |= clkd << 2;
+
+	/* set clock granularity */
+	l &= ~OMAP2_MCSPI_CHCONF_CLKG;
+	l |= clkg;
+	if (clkg) {
+		cs->chctrl0 &= ~OMAP2_MCSPI_CHCTRL_EXTCLK_MASK;
+		cs->chctrl0 |= extclk << 8;
+		mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, cs->chctrl0);
+	}
 
 
 	/* set SPI mode 0..3 */
 	/* set SPI mode 0..3 */
 	if (spi->mode & SPI_CPOL)
 	if (spi->mode & SPI_CPOL)
@@ -899,7 +927,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
 	mcspi_write_chconf0(spi, l);
 	mcspi_write_chconf0(spi, l);
 
 
 	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
 	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
-			OMAP2_MCSPI_MAX_FREQ >> div,
+			speed_hz,
 			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
 			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
 			(spi->mode & SPI_CPOL) ? "inverted" : "normal");
 			(spi->mode & SPI_CPOL) ? "inverted" : "normal");
 
 
@@ -971,6 +999,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
 		cs->base = mcspi->base + spi->chip_select * 0x14;
 		cs->base = mcspi->base + spi->chip_select * 0x14;
 		cs->phys = mcspi->phys + spi->chip_select * 0x14;
 		cs->phys = mcspi->phys + spi->chip_select * 0x14;
 		cs->chconf0 = 0;
 		cs->chconf0 = 0;
+		cs->chctrl0 = 0;
 		spi->controller_state = cs;
 		spi->controller_state = cs;
 		/* Link this to context save list */
 		/* Link this to context save list */
 		list_add_tail(&cs->node, &ctx->cs);
 		list_add_tail(&cs->node, &ctx->cs);
@@ -1056,12 +1085,15 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
 			status = -EINVAL;
 			status = -EINVAL;
 			break;
 			break;
 		}
 		}
-		if (par_override || t->speed_hz || t->bits_per_word) {
+		if (par_override ||
+		    (t->speed_hz != spi->max_speed_hz) ||
+		    (t->bits_per_word != spi->bits_per_word)) {
 			par_override = 1;
 			par_override = 1;
 			status = omap2_mcspi_setup_transfer(spi, t);
 			status = omap2_mcspi_setup_transfer(spi, t);
 			if (status < 0)
 			if (status < 0)
 				break;
 				break;
-			if (!t->speed_hz && !t->bits_per_word)
+			if (t->speed_hz == spi->max_speed_hz &&
+			    t->bits_per_word == spi->bits_per_word)
 				par_override = 0;
 				par_override = 0;
 		}
 		}
 		if (cd && cd->cs_per_word) {
 		if (cd && cd->cs_per_word) {
@@ -1175,16 +1207,12 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
 	m->actual_length = 0;
 	m->actual_length = 0;
 	m->status = 0;
 	m->status = 0;
 
 
-	/* reject invalid messages and transfers */
-	if (list_empty(&m->transfers))
-		return -EINVAL;
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		const void	*tx_buf = t->tx_buf;
 		const void	*tx_buf = t->tx_buf;
 		void		*rx_buf = t->rx_buf;
 		void		*rx_buf = t->rx_buf;
 		unsigned	len = t->len;
 		unsigned	len = t->len;
 
 
-		if (t->speed_hz > OMAP2_MCSPI_MAX_FREQ
-				|| (len && !(rx_buf || tx_buf))) {
+		if ((len && !(rx_buf || tx_buf))) {
 			dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
 			dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
 					t->speed_hz,
 					t->speed_hz,
 					len,
 					len,
@@ -1193,12 +1221,6 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
 					t->bits_per_word);
 					t->bits_per_word);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
-		if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) {
-			dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n",
-					t->speed_hz,
-					OMAP2_MCSPI_MAX_FREQ >> 15);
-			return -EINVAL;
-		}
 
 
 		if (m->is_dma_mapped || len < DMA_MIN_BYTES)
 		if (m->is_dma_mapped || len < DMA_MIN_BYTES)
 			continue;
 			continue;
@@ -1310,6 +1332,8 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
 	master->transfer_one_message = omap2_mcspi_transfer_one_message;
 	master->transfer_one_message = omap2_mcspi_transfer_one_message;
 	master->cleanup = omap2_mcspi_cleanup;
 	master->cleanup = omap2_mcspi_cleanup;
 	master->dev.of_node = node;
 	master->dev.of_node = node;
+	master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ;
+	master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15;
 
 
 	platform_set_drvdata(pdev, master);
 	platform_set_drvdata(pdev, master);
 
 

+ 11 - 68
drivers/spi/spi-orion.c

@@ -42,8 +42,6 @@
 struct orion_spi {
 struct orion_spi {
 	struct spi_master	*master;
 	struct spi_master	*master;
 	void __iomem		*base;
 	void __iomem		*base;
-	unsigned int		max_speed;
-	unsigned int		min_speed;
 	struct clk              *clk;
 	struct clk              *clk;
 };
 };
 
 
@@ -74,23 +72,6 @@ orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask)
 	writel(val, reg_addr);
 	writel(val, reg_addr);
 }
 }
 
 
-static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size)
-{
-	if (size == 16) {
-		orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
-				  ORION_SPI_IF_8_16_BIT_MODE);
-	} else if (size == 8) {
-		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
-				  ORION_SPI_IF_8_16_BIT_MODE);
-	} else {
-		pr_debug("Bad bits per word value %d (only 8 or 16 are allowed).\n",
-			size);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
 static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
 {
 {
 	u32 tclk_hz;
 	u32 tclk_hz;
@@ -169,7 +150,14 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
 
 
-	return orion_spi_set_transfer_size(orion_spi, bits_per_word);
+	if (bits_per_word == 16)
+		orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
+				  ORION_SPI_IF_8_16_BIT_MODE);
+	else
+		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
+				  ORION_SPI_IF_8_16_BIT_MODE);
+
+	return 0;
 }
 }
 
 
 static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
 static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
@@ -259,11 +247,9 @@ orion_spi_write_read_16bit(struct spi_device *spi,
 static unsigned int
 static unsigned int
 orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
 orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
 {
 {
-	struct orion_spi *orion_spi;
 	unsigned int count;
 	unsigned int count;
 	int word_len;
 	int word_len;
 
 
-	orion_spi = spi_master_get_devdata(spi->master);
 	word_len = spi->bits_per_word;
 	word_len = spi->bits_per_word;
 	count = xfer->len;
 	count = xfer->len;
 
 
@@ -309,27 +295,6 @@ static int orion_spi_transfer_one_message(struct spi_master *master,
 		goto msg_done;
 		goto msg_done;
 
 
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 	list_for_each_entry(t, &m->transfers, transfer_list) {
-		/* make sure buffer length is even when working in 16
-		 * bit mode*/
-		if ((t->bits_per_word == 16) && (t->len & 1)) {
-			dev_err(&spi->dev,
-				"message rejected : "
-				"odd data length %d while in 16 bit mode\n",
-				t->len);
-			status = -EIO;
-			goto msg_done;
-		}
-
-		if (t->speed_hz && t->speed_hz < orion_spi->min_speed) {
-			dev_err(&spi->dev,
-				"message rejected : "
-				"device min speed (%d Hz) exceeds "
-				"required transfer speed (%d Hz)\n",
-				orion_spi->min_speed, t->speed_hz);
-			status = -EIO;
-			goto msg_done;
-		}
-
 		if (par_override || t->speed_hz || t->bits_per_word) {
 		if (par_override || t->speed_hz || t->bits_per_word) {
 			par_override = 1;
 			par_override = 1;
 			status = orion_spi_setup_transfer(spi, t);
 			status = orion_spi_setup_transfer(spi, t);
@@ -374,28 +339,6 @@ static int orion_spi_reset(struct orion_spi *orion_spi)
 	return 0;
 	return 0;
 }
 }
 
 
-static int orion_spi_setup(struct spi_device *spi)
-{
-	struct orion_spi *orion_spi;
-
-	orion_spi = spi_master_get_devdata(spi->master);
-
-	if ((spi->max_speed_hz == 0)
-			|| (spi->max_speed_hz > orion_spi->max_speed))
-		spi->max_speed_hz = orion_spi->max_speed;
-
-	if (spi->max_speed_hz < orion_spi->min_speed) {
-		dev_err(&spi->dev, "setup: requested speed too low %d Hz\n",
-			spi->max_speed_hz);
-		return -EINVAL;
-	}
-
-	/*
-	 * baudrate & width will be set orion_spi_setup_transfer
-	 */
-	return 0;
-}
-
 static int orion_spi_probe(struct platform_device *pdev)
 static int orion_spi_probe(struct platform_device *pdev)
 {
 {
 	struct spi_master *master;
 	struct spi_master *master;
@@ -424,9 +367,9 @@ static int orion_spi_probe(struct platform_device *pdev)
 	/* we support only mode 0, and no options */
 	/* we support only mode 0, and no options */
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 	master->mode_bits = SPI_CPHA | SPI_CPOL;
 
 
-	master->setup = orion_spi_setup;
 	master->transfer_one_message = orion_spi_transfer_one_message;
 	master->transfer_one_message = orion_spi_transfer_one_message;
 	master->num_chipselect = ORION_NUM_CHIPSELECTS;
 	master->num_chipselect = ORION_NUM_CHIPSELECTS;
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 
 
 	platform_set_drvdata(pdev, master);
 	platform_set_drvdata(pdev, master);
 
 
@@ -442,8 +385,8 @@ static int orion_spi_probe(struct platform_device *pdev)
 	clk_prepare(spi->clk);
 	clk_prepare(spi->clk);
 	clk_enable(spi->clk);
 	clk_enable(spi->clk);
 	tclk_hz = clk_get_rate(spi->clk);
 	tclk_hz = clk_get_rate(spi->clk);
-	spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
-	spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
+	master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4);
+	master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30);
 
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	spi->base = devm_ioremap_resource(&pdev->dev, r);
 	spi->base = devm_ioremap_resource(&pdev->dev, r);

+ 23 - 52
drivers/spi/spi-pl022.c

@@ -2108,8 +2108,6 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 	pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
 	pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
 					  GFP_KERNEL);
 					  GFP_KERNEL);
 
 
-	pinctrl_pm_select_default_state(dev);
-
 	/*
 	/*
 	 * Bus Number Which has been Assigned to this SSP controller
 	 * Bus Number Which has been Assigned to this SSP controller
 	 * on this board
 	 * on this board
@@ -2182,13 +2180,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 		goto err_no_clk;
 		goto err_no_clk;
 	}
 	}
 
 
-	status = clk_prepare(pl022->clk);
-	if (status) {
-		dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
-		goto  err_clk_prep;
-	}
-
-	status = clk_enable(pl022->clk);
+	status = clk_prepare_enable(pl022->clk);
 	if (status) {
 	if (status) {
 		dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
 		dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
 		goto err_no_clk_en;
 		goto err_no_clk_en;
@@ -2249,10 +2241,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 	if (platform_info->enable_dma)
 	if (platform_info->enable_dma)
 		pl022_dma_remove(pl022);
 		pl022_dma_remove(pl022);
  err_no_irq:
  err_no_irq:
-	clk_disable(pl022->clk);
+	clk_disable_unprepare(pl022->clk);
  err_no_clk_en:
  err_no_clk_en:
-	clk_unprepare(pl022->clk);
- err_clk_prep:
  err_no_clk:
  err_no_clk:
  err_no_ioremap:
  err_no_ioremap:
 	amba_release_regions(adev);
 	amba_release_regions(adev);
@@ -2280,42 +2270,13 @@ pl022_remove(struct amba_device *adev)
 	if (pl022->master_info->enable_dma)
 	if (pl022->master_info->enable_dma)
 		pl022_dma_remove(pl022);
 		pl022_dma_remove(pl022);
 
 
-	clk_disable(pl022->clk);
-	clk_unprepare(pl022->clk);
+	clk_disable_unprepare(pl022->clk);
 	amba_release_regions(adev);
 	amba_release_regions(adev);
 	tasklet_disable(&pl022->pump_transfers);
 	tasklet_disable(&pl022->pump_transfers);
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME)
-/*
- * These two functions are used from both suspend/resume and
- * the runtime counterparts to handle external resources like
- * clocks, pins and regulators when going to sleep.
- */
-static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
-{
-	clk_disable(pl022->clk);
-
-	if (runtime)
-		pinctrl_pm_select_idle_state(&pl022->adev->dev);
-	else
-		pinctrl_pm_select_sleep_state(&pl022->adev->dev);
-}
-
-static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
-{
-	/* First go to the default state */
-	pinctrl_pm_select_default_state(&pl022->adev->dev);
-	if (!runtime)
-		/* Then let's idle the pins until the next transfer happens */
-		pinctrl_pm_select_idle_state(&pl022->adev->dev);
-
-	clk_enable(pl022->clk);
-}
-#endif
-
-#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_PM_SLEEP
 static int pl022_suspend(struct device *dev)
 static int pl022_suspend(struct device *dev)
 {
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 	struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2327,8 +2288,13 @@ static int pl022_suspend(struct device *dev)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	pm_runtime_get_sync(dev);
-	pl022_suspend_resources(pl022, false);
+	ret = pm_runtime_force_suspend(dev);
+	if (ret) {
+		spi_master_resume(pl022->master);
+		return ret;
+	}
+
+	pinctrl_pm_select_sleep_state(dev);
 
 
 	dev_dbg(dev, "suspended\n");
 	dev_dbg(dev, "suspended\n");
 	return 0;
 	return 0;
@@ -2339,8 +2305,9 @@ static int pl022_resume(struct device *dev)
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 	int ret;
 	int ret;
 
 
-	pl022_resume_resources(pl022, false);
-	pm_runtime_put(dev);
+	ret = pm_runtime_force_resume(dev);
+	if (ret)
+		dev_err(dev, "problem resuming\n");
 
 
 	/* Start the queue running */
 	/* Start the queue running */
 	ret = spi_master_resume(pl022->master);
 	ret = spi_master_resume(pl022->master);
@@ -2351,14 +2318,16 @@ static int pl022_resume(struct device *dev)
 
 
 	return ret;
 	return ret;
 }
 }
-#endif	/* CONFIG_PM */
+#endif
 
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static int pl022_runtime_suspend(struct device *dev)
 static int pl022_runtime_suspend(struct device *dev)
 {
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 
 
-	pl022_suspend_resources(pl022, true);
+	clk_disable_unprepare(pl022->clk);
+	pinctrl_pm_select_idle_state(dev);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -2366,14 +2335,16 @@ static int pl022_runtime_resume(struct device *dev)
 {
 {
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 	struct pl022 *pl022 = dev_get_drvdata(dev);
 
 
-	pl022_resume_resources(pl022, true);
+	pinctrl_pm_select_default_state(dev);
+	clk_prepare_enable(pl022->clk);
+
 	return 0;
 	return 0;
 }
 }
 #endif
 #endif
 
 
 static const struct dev_pm_ops pl022_dev_pm_ops = {
 static const struct dev_pm_ops pl022_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
 	SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
-	SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
+	SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
 };
 };
 
 
 static struct vendor_data vendor_arm = {
 static struct vendor_data vendor_arm = {

+ 779 - 0
drivers/spi/spi-qup.c

@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2008-2014, The Linux foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License rev 2 and
+ * only rev 2 as published by the free Software foundation.
+ *
+ * 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/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+
+#define QUP_CONFIG			0x0000
+#define QUP_STATE			0x0004
+#define QUP_IO_M_MODES			0x0008
+#define QUP_SW_RESET			0x000c
+#define QUP_OPERATIONAL			0x0018
+#define QUP_ERROR_FLAGS			0x001c
+#define QUP_ERROR_FLAGS_EN		0x0020
+#define QUP_OPERATIONAL_MASK		0x0028
+#define QUP_HW_VERSION			0x0030
+#define QUP_MX_OUTPUT_CNT		0x0100
+#define QUP_OUTPUT_FIFO			0x0110
+#define QUP_MX_WRITE_CNT		0x0150
+#define QUP_MX_INPUT_CNT		0x0200
+#define QUP_MX_READ_CNT			0x0208
+#define QUP_INPUT_FIFO			0x0218
+
+#define SPI_CONFIG			0x0300
+#define SPI_IO_CONTROL			0x0304
+#define SPI_ERROR_FLAGS			0x0308
+#define SPI_ERROR_FLAGS_EN		0x030c
+
+/* QUP_CONFIG fields */
+#define QUP_CONFIG_SPI_MODE		(1 << 8)
+#define QUP_CONFIG_CLOCK_AUTO_GATE	BIT(13)
+#define QUP_CONFIG_NO_INPUT		BIT(7)
+#define QUP_CONFIG_NO_OUTPUT		BIT(6)
+#define QUP_CONFIG_N			0x001f
+
+/* QUP_STATE fields */
+#define QUP_STATE_VALID			BIT(2)
+#define QUP_STATE_RESET			0
+#define QUP_STATE_RUN			1
+#define QUP_STATE_PAUSE			3
+#define QUP_STATE_MASK			3
+#define QUP_STATE_CLEAR			2
+
+#define QUP_HW_VERSION_2_1_1		0x20010001
+
+/* QUP_IO_M_MODES fields */
+#define QUP_IO_M_PACK_EN		BIT(15)
+#define QUP_IO_M_UNPACK_EN		BIT(14)
+#define QUP_IO_M_INPUT_MODE_MASK_SHIFT	12
+#define QUP_IO_M_OUTPUT_MODE_MASK_SHIFT	10
+#define QUP_IO_M_INPUT_MODE_MASK	(3 << QUP_IO_M_INPUT_MODE_MASK_SHIFT)
+#define QUP_IO_M_OUTPUT_MODE_MASK	(3 << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT)
+
+#define QUP_IO_M_OUTPUT_BLOCK_SIZE(x)	(((x) & (0x03 << 0)) >> 0)
+#define QUP_IO_M_OUTPUT_FIFO_SIZE(x)	(((x) & (0x07 << 2)) >> 2)
+#define QUP_IO_M_INPUT_BLOCK_SIZE(x)	(((x) & (0x03 << 5)) >> 5)
+#define QUP_IO_M_INPUT_FIFO_SIZE(x)	(((x) & (0x07 << 7)) >> 7)
+
+#define QUP_IO_M_MODE_FIFO		0
+#define QUP_IO_M_MODE_BLOCK		1
+#define QUP_IO_M_MODE_DMOV		2
+#define QUP_IO_M_MODE_BAM		3
+
+/* QUP_OPERATIONAL fields */
+#define QUP_OP_MAX_INPUT_DONE_FLAG	BIT(11)
+#define QUP_OP_MAX_OUTPUT_DONE_FLAG	BIT(10)
+#define QUP_OP_IN_SERVICE_FLAG		BIT(9)
+#define QUP_OP_OUT_SERVICE_FLAG		BIT(8)
+#define QUP_OP_IN_FIFO_FULL		BIT(7)
+#define QUP_OP_OUT_FIFO_FULL		BIT(6)
+#define QUP_OP_IN_FIFO_NOT_EMPTY	BIT(5)
+#define QUP_OP_OUT_FIFO_NOT_EMPTY	BIT(4)
+
+/* QUP_ERROR_FLAGS and QUP_ERROR_FLAGS_EN fields */
+#define QUP_ERROR_OUTPUT_OVER_RUN	BIT(5)
+#define QUP_ERROR_INPUT_UNDER_RUN	BIT(4)
+#define QUP_ERROR_OUTPUT_UNDER_RUN	BIT(3)
+#define QUP_ERROR_INPUT_OVER_RUN	BIT(2)
+
+/* SPI_CONFIG fields */
+#define SPI_CONFIG_HS_MODE		BIT(10)
+#define SPI_CONFIG_INPUT_FIRST		BIT(9)
+#define SPI_CONFIG_LOOPBACK		BIT(8)
+
+/* SPI_IO_CONTROL fields */
+#define SPI_IO_C_FORCE_CS		BIT(11)
+#define SPI_IO_C_CLK_IDLE_HIGH		BIT(10)
+#define SPI_IO_C_MX_CS_MODE		BIT(8)
+#define SPI_IO_C_CS_N_POLARITY_0	BIT(4)
+#define SPI_IO_C_CS_SELECT(x)		(((x) & 3) << 2)
+#define SPI_IO_C_CS_SELECT_MASK		0x000c
+#define SPI_IO_C_TRISTATE_CS		BIT(1)
+#define SPI_IO_C_NO_TRI_STATE		BIT(0)
+
+/* SPI_ERROR_FLAGS and SPI_ERROR_FLAGS_EN fields */
+#define SPI_ERROR_CLK_OVER_RUN		BIT(1)
+#define SPI_ERROR_CLK_UNDER_RUN		BIT(0)
+
+#define SPI_NUM_CHIPSELECTS		4
+
+/* high speed mode is when bus rate is greater then 26MHz */
+#define SPI_HS_MIN_RATE			26000000
+#define SPI_MAX_RATE			50000000
+
+#define SPI_DELAY_THRESHOLD		1
+#define SPI_DELAY_RETRY			10
+
+struct spi_qup {
+	void __iomem		*base;
+	struct device		*dev;
+	struct clk		*cclk;	/* core clock */
+	struct clk		*iclk;	/* interface clock */
+	int			irq;
+	spinlock_t		lock;
+
+	int			in_fifo_sz;
+	int			out_fifo_sz;
+	int			in_blk_sz;
+	int			out_blk_sz;
+
+	struct spi_transfer	*xfer;
+	struct completion	done;
+	int			error;
+	int			w_size;	/* bytes per SPI word */
+	int			tx_bytes;
+	int			rx_bytes;
+};
+
+
+static inline bool spi_qup_is_valid_state(struct spi_qup *controller)
+{
+	u32 opstate = readl_relaxed(controller->base + QUP_STATE);
+
+	return opstate & QUP_STATE_VALID;
+}
+
+static int spi_qup_set_state(struct spi_qup *controller, u32 state)
+{
+	unsigned long loop;
+	u32 cur_state;
+
+	loop = 0;
+	while (!spi_qup_is_valid_state(controller)) {
+
+		usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2);
+
+		if (++loop > SPI_DELAY_RETRY)
+			return -EIO;
+	}
+
+	if (loop)
+		dev_dbg(controller->dev, "invalid state for %ld,us %d\n",
+			loop, state);
+
+	cur_state = readl_relaxed(controller->base + QUP_STATE);
+	/*
+	 * Per spec: for PAUSE_STATE to RESET_STATE, two writes
+	 * of (b10) are required
+	 */
+	if (((cur_state & QUP_STATE_MASK) == QUP_STATE_PAUSE) &&
+	    (state == QUP_STATE_RESET)) {
+		writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE);
+		writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE);
+	} else {
+		cur_state &= ~QUP_STATE_MASK;
+		cur_state |= state;
+		writel_relaxed(cur_state, controller->base + QUP_STATE);
+	}
+
+	loop = 0;
+	while (!spi_qup_is_valid_state(controller)) {
+
+		usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2);
+
+		if (++loop > SPI_DELAY_RETRY)
+			return -EIO;
+	}
+
+	return 0;
+}
+
+
+static void spi_qup_fifo_read(struct spi_qup *controller,
+			    struct spi_transfer *xfer)
+{
+	u8 *rx_buf = xfer->rx_buf;
+	u32 word, state;
+	int idx, shift, w_size;
+
+	w_size = controller->w_size;
+
+	while (controller->rx_bytes < xfer->len) {
+
+		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
+		if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
+			break;
+
+		word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
+
+		if (!rx_buf) {
+			controller->rx_bytes += w_size;
+			continue;
+		}
+
+		for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
+			/*
+			 * The data format depends on bytes per SPI word:
+			 *  4 bytes: 0x12345678
+			 *  2 bytes: 0x00001234
+			 *  1 byte : 0x00000012
+			 */
+			shift = BITS_PER_BYTE;
+			shift *= (w_size - idx - 1);
+			rx_buf[controller->rx_bytes] = word >> shift;
+		}
+	}
+}
+
+static void spi_qup_fifo_write(struct spi_qup *controller,
+			    struct spi_transfer *xfer)
+{
+	const u8 *tx_buf = xfer->tx_buf;
+	u32 word, state, data;
+	int idx, w_size;
+
+	w_size = controller->w_size;
+
+	while (controller->tx_bytes < xfer->len) {
+
+		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
+		if (state & QUP_OP_OUT_FIFO_FULL)
+			break;
+
+		word = 0;
+		for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
+
+			if (!tx_buf) {
+				controller->tx_bytes += w_size;
+				break;
+			}
+
+			data = tx_buf[controller->tx_bytes];
+			word |= data << (BITS_PER_BYTE * (3 - idx));
+		}
+
+		writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
+	}
+}
+
+static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
+{
+	struct spi_qup *controller = dev_id;
+	struct spi_transfer *xfer;
+	u32 opflags, qup_err, spi_err;
+	unsigned long flags;
+	int error = 0;
+
+	spin_lock_irqsave(&controller->lock, flags);
+	xfer = controller->xfer;
+	controller->xfer = NULL;
+	spin_unlock_irqrestore(&controller->lock, flags);
+
+	qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS);
+	spi_err = readl_relaxed(controller->base + SPI_ERROR_FLAGS);
+	opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
+
+	writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
+	writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
+	writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
+
+	if (!xfer) {
+		dev_err_ratelimited(controller->dev, "unexpected irq %x08 %x08 %x08\n",
+				    qup_err, spi_err, opflags);
+		return IRQ_HANDLED;
+	}
+
+	if (qup_err) {
+		if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN)
+			dev_warn(controller->dev, "OUTPUT_OVER_RUN\n");
+		if (qup_err & QUP_ERROR_INPUT_UNDER_RUN)
+			dev_warn(controller->dev, "INPUT_UNDER_RUN\n");
+		if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN)
+			dev_warn(controller->dev, "OUTPUT_UNDER_RUN\n");
+		if (qup_err & QUP_ERROR_INPUT_OVER_RUN)
+			dev_warn(controller->dev, "INPUT_OVER_RUN\n");
+
+		error = -EIO;
+	}
+
+	if (spi_err) {
+		if (spi_err & SPI_ERROR_CLK_OVER_RUN)
+			dev_warn(controller->dev, "CLK_OVER_RUN\n");
+		if (spi_err & SPI_ERROR_CLK_UNDER_RUN)
+			dev_warn(controller->dev, "CLK_UNDER_RUN\n");
+
+		error = -EIO;
+	}
+
+	if (opflags & QUP_OP_IN_SERVICE_FLAG)
+		spi_qup_fifo_read(controller, xfer);
+
+	if (opflags & QUP_OP_OUT_SERVICE_FLAG)
+		spi_qup_fifo_write(controller, xfer);
+
+	spin_lock_irqsave(&controller->lock, flags);
+	controller->error = error;
+	controller->xfer = xfer;
+	spin_unlock_irqrestore(&controller->lock, flags);
+
+	if (controller->rx_bytes == xfer->len || error)
+		complete(&controller->done);
+
+	return IRQ_HANDLED;
+}
+
+
+/* set clock freq ... bits per word */
+static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
+{
+	struct spi_qup *controller = spi_master_get_devdata(spi->master);
+	u32 config, iomode, mode;
+	int ret, n_words, w_size;
+
+	if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
+		dev_err(controller->dev, "too big size for loopback %d > %d\n",
+			xfer->len, controller->in_fifo_sz);
+		return -EIO;
+	}
+
+	ret = clk_set_rate(controller->cclk, xfer->speed_hz);
+	if (ret) {
+		dev_err(controller->dev, "fail to set frequency %d",
+			xfer->speed_hz);
+		return -EIO;
+	}
+
+	if (spi_qup_set_state(controller, QUP_STATE_RESET)) {
+		dev_err(controller->dev, "cannot set RESET state\n");
+		return -EIO;
+	}
+
+	w_size = 4;
+	if (xfer->bits_per_word <= 8)
+		w_size = 1;
+	else if (xfer->bits_per_word <= 16)
+		w_size = 2;
+
+	n_words = xfer->len / w_size;
+	controller->w_size = w_size;
+
+	if (n_words <= controller->in_fifo_sz) {
+		mode = QUP_IO_M_MODE_FIFO;
+		writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
+		writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
+		/* must be zero for FIFO */
+		writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
+		writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
+	} else {
+		mode = QUP_IO_M_MODE_BLOCK;
+		writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
+		writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
+		/* must be zero for BLOCK and BAM */
+		writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
+		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
+	}
+
+	iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
+	/* Set input and output transfer mode */
+	iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
+	iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
+	iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
+	iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
+
+	writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
+
+	config = readl_relaxed(controller->base + SPI_CONFIG);
+
+	if (spi->mode & SPI_LOOP)
+		config |= SPI_CONFIG_LOOPBACK;
+	else
+		config &= ~SPI_CONFIG_LOOPBACK;
+
+	if (spi->mode & SPI_CPHA)
+		config &= ~SPI_CONFIG_INPUT_FIRST;
+	else
+		config |= SPI_CONFIG_INPUT_FIRST;
+
+	/*
+	 * HS_MODE improves signal stability for spi-clk high rates,
+	 * but is invalid in loop back mode.
+	 */
+	if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(spi->mode & SPI_LOOP))
+		config |= SPI_CONFIG_HS_MODE;
+	else
+		config &= ~SPI_CONFIG_HS_MODE;
+
+	writel_relaxed(config, controller->base + SPI_CONFIG);
+
+	config = readl_relaxed(controller->base + QUP_CONFIG);
+	config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
+	config |= xfer->bits_per_word - 1;
+	config |= QUP_CONFIG_SPI_MODE;
+	writel_relaxed(config, controller->base + QUP_CONFIG);
+
+	writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
+	return 0;
+}
+
+static void spi_qup_set_cs(struct spi_device *spi, bool enable)
+{
+	struct spi_qup *controller = spi_master_get_devdata(spi->master);
+
+	u32 iocontol, mask;
+
+	iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
+
+	/* Disable auto CS toggle and use manual */
+	iocontol &= ~SPI_IO_C_MX_CS_MODE;
+	iocontol |= SPI_IO_C_FORCE_CS;
+
+	iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
+	iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
+
+	mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
+
+	if (enable)
+		iocontol |= mask;
+	else
+		iocontol &= ~mask;
+
+	writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
+}
+
+static int spi_qup_transfer_one(struct spi_master *master,
+			      struct spi_device *spi,
+			      struct spi_transfer *xfer)
+{
+	struct spi_qup *controller = spi_master_get_devdata(master);
+	unsigned long timeout, flags;
+	int ret = -EIO;
+
+	ret = spi_qup_io_config(spi, xfer);
+	if (ret)
+		return ret;
+
+	timeout = DIV_ROUND_UP(xfer->speed_hz, MSEC_PER_SEC);
+	timeout = DIV_ROUND_UP(xfer->len * 8, timeout);
+	timeout = 100 * msecs_to_jiffies(timeout);
+
+	reinit_completion(&controller->done);
+
+	spin_lock_irqsave(&controller->lock, flags);
+	controller->xfer     = xfer;
+	controller->error    = 0;
+	controller->rx_bytes = 0;
+	controller->tx_bytes = 0;
+	spin_unlock_irqrestore(&controller->lock, flags);
+
+	if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
+		dev_warn(controller->dev, "cannot set RUN state\n");
+		goto exit;
+	}
+
+	if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
+		dev_warn(controller->dev, "cannot set PAUSE state\n");
+		goto exit;
+	}
+
+	spi_qup_fifo_write(controller, xfer);
+
+	if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
+		dev_warn(controller->dev, "cannot set EXECUTE state\n");
+		goto exit;
+	}
+
+	if (!wait_for_completion_timeout(&controller->done, timeout))
+		ret = -ETIMEDOUT;
+exit:
+	spi_qup_set_state(controller, QUP_STATE_RESET);
+	spin_lock_irqsave(&controller->lock, flags);
+	controller->xfer = NULL;
+	if (!ret)
+		ret = controller->error;
+	spin_unlock_irqrestore(&controller->lock, flags);
+	return ret;
+}
+
+static int spi_qup_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct clk *iclk, *cclk;
+	struct spi_qup *controller;
+	struct resource *res;
+	struct device *dev;
+	void __iomem *base;
+	u32 data, max_freq, iomode;
+	int ret, irq, size;
+
+	dev = &pdev->dev;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	cclk = devm_clk_get(dev, "core");
+	if (IS_ERR(cclk))
+		return PTR_ERR(cclk);
+
+	iclk = devm_clk_get(dev, "iface");
+	if (IS_ERR(iclk))
+		return PTR_ERR(iclk);
+
+	/* This is optional parameter */
+	if (of_property_read_u32(dev->of_node, "spi-max-frequency", &max_freq))
+		max_freq = SPI_MAX_RATE;
+
+	if (!max_freq || max_freq > SPI_MAX_RATE) {
+		dev_err(dev, "invalid clock frequency %d\n", max_freq);
+		return -ENXIO;
+	}
+
+	ret = clk_prepare_enable(cclk);
+	if (ret) {
+		dev_err(dev, "cannot enable core clock\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(iclk);
+	if (ret) {
+		clk_disable_unprepare(cclk);
+		dev_err(dev, "cannot enable iface clock\n");
+		return ret;
+	}
+
+	data = readl_relaxed(base + QUP_HW_VERSION);
+
+	if (data < QUP_HW_VERSION_2_1_1) {
+		clk_disable_unprepare(cclk);
+		clk_disable_unprepare(iclk);
+		dev_err(dev, "v.%08x is not supported\n", data);
+		return -ENXIO;
+	}
+
+	master = spi_alloc_master(dev, sizeof(struct spi_qup));
+	if (!master) {
+		clk_disable_unprepare(cclk);
+		clk_disable_unprepare(iclk);
+		dev_err(dev, "cannot allocate master\n");
+		return -ENOMEM;
+	}
+
+	master->bus_num = pdev->id;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
+	master->num_chipselect = SPI_NUM_CHIPSELECTS;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+	master->max_speed_hz = max_freq;
+	master->set_cs = spi_qup_set_cs;
+	master->transfer_one = spi_qup_transfer_one;
+	master->dev.of_node = pdev->dev.of_node;
+	master->auto_runtime_pm = true;
+
+	platform_set_drvdata(pdev, master);
+
+	controller = spi_master_get_devdata(master);
+
+	controller->dev = dev;
+	controller->base = base;
+	controller->iclk = iclk;
+	controller->cclk = cclk;
+	controller->irq = irq;
+
+	spin_lock_init(&controller->lock);
+	init_completion(&controller->done);
+
+	iomode = readl_relaxed(base + QUP_IO_M_MODES);
+
+	size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode);
+	if (size)
+		controller->out_blk_sz = size * 16;
+	else
+		controller->out_blk_sz = 4;
+
+	size = QUP_IO_M_INPUT_BLOCK_SIZE(iomode);
+	if (size)
+		controller->in_blk_sz = size * 16;
+	else
+		controller->in_blk_sz = 4;
+
+	size = QUP_IO_M_OUTPUT_FIFO_SIZE(iomode);
+	controller->out_fifo_sz = controller->out_blk_sz * (2 << size);
+
+	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
+	controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
+
+	dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
+		 data, controller->in_blk_sz, controller->in_fifo_sz,
+		 controller->out_blk_sz, controller->out_fifo_sz);
+
+	writel_relaxed(1, base + QUP_SW_RESET);
+
+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+	if (ret) {
+		dev_err(dev, "cannot set RESET state\n");
+		goto error;
+	}
+
+	writel_relaxed(0, base + QUP_OPERATIONAL);
+	writel_relaxed(0, base + QUP_IO_M_MODES);
+	writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
+	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
+		       base + SPI_ERROR_FLAGS_EN);
+
+	writel_relaxed(0, base + SPI_CONFIG);
+	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
+
+	ret = devm_request_irq(dev, irq, spi_qup_qup_irq,
+			       IRQF_TRIGGER_HIGH, pdev->name, controller);
+	if (ret)
+		goto error;
+
+	ret = devm_spi_register_master(dev, master);
+	if (ret)
+		goto error;
+
+	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	return 0;
+
+error:
+	clk_disable_unprepare(cclk);
+	clk_disable_unprepare(iclk);
+	spi_master_put(master);
+	return ret;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int spi_qup_pm_suspend_runtime(struct device *device)
+{
+	struct spi_master *master = dev_get_drvdata(device);
+	struct spi_qup *controller = spi_master_get_devdata(master);
+	u32 config;
+
+	/* Enable clocks auto gaiting */
+	config = readl(controller->base + QUP_CONFIG);
+	config |= QUP_CONFIG_CLOCK_AUTO_GATE;
+	writel_relaxed(config, controller->base + QUP_CONFIG);
+	return 0;
+}
+
+static int spi_qup_pm_resume_runtime(struct device *device)
+{
+	struct spi_master *master = dev_get_drvdata(device);
+	struct spi_qup *controller = spi_master_get_devdata(master);
+	u32 config;
+
+	/* Disable clocks auto gaiting */
+	config = readl_relaxed(controller->base + QUP_CONFIG);
+	config &= ~QUP_CONFIG_CLOCK_AUTO_GATE;
+	writel_relaxed(config, controller->base + QUP_CONFIG);
+	return 0;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM_SLEEP
+static int spi_qup_suspend(struct device *device)
+{
+	struct spi_master *master = dev_get_drvdata(device);
+	struct spi_qup *controller = spi_master_get_devdata(master);
+	int ret;
+
+	ret = spi_master_suspend(master);
+	if (ret)
+		return ret;
+
+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(controller->cclk);
+	clk_disable_unprepare(controller->iclk);
+	return 0;
+}
+
+static int spi_qup_resume(struct device *device)
+{
+	struct spi_master *master = dev_get_drvdata(device);
+	struct spi_qup *controller = spi_master_get_devdata(master);
+	int ret;
+
+	ret = clk_prepare_enable(controller->iclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(controller->cclk);
+	if (ret)
+		return ret;
+
+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+	if (ret)
+		return ret;
+
+	return spi_master_resume(master);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static int spi_qup_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = dev_get_drvdata(&pdev->dev);
+	struct spi_qup *controller = spi_master_get_devdata(master);
+	int ret;
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(controller->cclk);
+	clk_disable_unprepare(controller->iclk);
+
+	pm_runtime_put_noidle(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static struct of_device_id spi_qup_dt_match[] = {
+	{ .compatible = "qcom,spi-qup-v2.1.1", },
+	{ .compatible = "qcom,spi-qup-v2.2.1", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, spi_qup_dt_match);
+
+static const struct dev_pm_ops spi_qup_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(spi_qup_suspend, spi_qup_resume)
+	SET_RUNTIME_PM_OPS(spi_qup_pm_suspend_runtime,
+			   spi_qup_pm_resume_runtime,
+			   NULL)
+};
+
+static struct platform_driver spi_qup_driver = {
+	.driver = {
+		.name		= "spi_qup",
+		.owner		= THIS_MODULE,
+		.pm		= &spi_qup_dev_pm_ops,
+		.of_match_table = spi_qup_dt_match,
+	},
+	.probe = spi_qup_probe,
+	.remove = spi_qup_remove,
+};
+module_platform_driver(spi_qup_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:spi_qup");

+ 560 - 282
drivers/spi/spi-rspi.c

@@ -1,7 +1,8 @@
 /*
 /*
  * SH RSPI driver
  * SH RSPI driver
  *
  *
- * Copyright (C) 2012  Renesas Solutions Corp.
+ * Copyright (C) 2012, 2013  Renesas Solutions Corp.
+ * Copyright (C) 2014 Glider bvba
  *
  *
  * Based on spi-sh.c:
  * Based on spi-sh.c:
  * Copyright (C) 2011 Renesas Solutions Corp.
  * Copyright (C) 2011 Renesas Solutions Corp.
@@ -25,14 +26,14 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/sh_dma.h>
 #include <linux/sh_dma.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/rspi.h>
 #include <linux/spi/rspi.h>
@@ -49,7 +50,7 @@
 #define RSPI_SPCKD		0x0c	/* Clock Delay Register */
 #define RSPI_SPCKD		0x0c	/* Clock Delay Register */
 #define RSPI_SSLND		0x0d	/* Slave Select Negation Delay Register */
 #define RSPI_SSLND		0x0d	/* Slave Select Negation Delay Register */
 #define RSPI_SPND		0x0e	/* Next-Access Delay Register */
 #define RSPI_SPND		0x0e	/* Next-Access Delay Register */
-#define RSPI_SPCR2		0x0f	/* Control Register 2 */
+#define RSPI_SPCR2		0x0f	/* Control Register 2 (SH only) */
 #define RSPI_SPCMD0		0x10	/* Command Register 0 */
 #define RSPI_SPCMD0		0x10	/* Command Register 0 */
 #define RSPI_SPCMD1		0x12	/* Command Register 1 */
 #define RSPI_SPCMD1		0x12	/* Command Register 1 */
 #define RSPI_SPCMD2		0x14	/* Command Register 2 */
 #define RSPI_SPCMD2		0x14	/* Command Register 2 */
@@ -58,16 +59,23 @@
 #define RSPI_SPCMD5		0x1a	/* Command Register 5 */
 #define RSPI_SPCMD5		0x1a	/* Command Register 5 */
 #define RSPI_SPCMD6		0x1c	/* Command Register 6 */
 #define RSPI_SPCMD6		0x1c	/* Command Register 6 */
 #define RSPI_SPCMD7		0x1e	/* Command Register 7 */
 #define RSPI_SPCMD7		0x1e	/* Command Register 7 */
+#define RSPI_SPCMD(i)		(RSPI_SPCMD0 + (i) * 2)
+#define RSPI_NUM_SPCMD		8
+#define RSPI_RZ_NUM_SPCMD	4
+#define QSPI_NUM_SPCMD		4
+
+/* RSPI on RZ only */
 #define RSPI_SPBFCR		0x20	/* Buffer Control Register */
 #define RSPI_SPBFCR		0x20	/* Buffer Control Register */
 #define RSPI_SPBFDR		0x22	/* Buffer Data Count Setting Register */
 #define RSPI_SPBFDR		0x22	/* Buffer Data Count Setting Register */
 
 
-/*qspi only */
+/* QSPI only */
 #define QSPI_SPBFCR		0x18	/* Buffer Control Register */
 #define QSPI_SPBFCR		0x18	/* Buffer Control Register */
 #define QSPI_SPBDCR		0x1a	/* Buffer Data Count Register */
 #define QSPI_SPBDCR		0x1a	/* Buffer Data Count Register */
 #define QSPI_SPBMUL0		0x1c	/* Transfer Data Length Multiplier Setting Register 0 */
 #define QSPI_SPBMUL0		0x1c	/* Transfer Data Length Multiplier Setting Register 0 */
 #define QSPI_SPBMUL1		0x20	/* Transfer Data Length Multiplier Setting Register 1 */
 #define QSPI_SPBMUL1		0x20	/* Transfer Data Length Multiplier Setting Register 1 */
 #define QSPI_SPBMUL2		0x24	/* Transfer Data Length Multiplier Setting Register 2 */
 #define QSPI_SPBMUL2		0x24	/* Transfer Data Length Multiplier Setting Register 2 */
 #define QSPI_SPBMUL3		0x28	/* Transfer Data Length Multiplier Setting Register 3 */
 #define QSPI_SPBMUL3		0x28	/* Transfer Data Length Multiplier Setting Register 3 */
+#define QSPI_SPBMUL(i)		(QSPI_SPBMUL0 + (i) * 4)
 
 
 /* SPCR - Control Register */
 /* SPCR - Control Register */
 #define SPCR_SPRIE		0x80	/* Receive Interrupt Enable */
 #define SPCR_SPRIE		0x80	/* Receive Interrupt Enable */
@@ -104,7 +112,7 @@
 #define SPSR_PERF		0x08	/* Parity Error Flag */
 #define SPSR_PERF		0x08	/* Parity Error Flag */
 #define SPSR_MODF		0x04	/* Mode Fault Error Flag */
 #define SPSR_MODF		0x04	/* Mode Fault Error Flag */
 #define SPSR_IDLNF		0x02	/* RSPI Idle Flag */
 #define SPSR_IDLNF		0x02	/* RSPI Idle Flag */
-#define SPSR_OVRF		0x01	/* Overrun Error Flag */
+#define SPSR_OVRF		0x01	/* Overrun Error Flag (RSPI only) */
 
 
 /* SPSCR - Sequence Control Register */
 /* SPSCR - Sequence Control Register */
 #define SPSCR_SPSLN_MASK	0x07	/* Sequence Length Specification */
 #define SPSCR_SPSLN_MASK	0x07	/* Sequence Length Specification */
@@ -121,13 +129,13 @@
 #define SPDCR_SPLWORD		SPDCR_SPLW1
 #define SPDCR_SPLWORD		SPDCR_SPLW1
 #define SPDCR_SPLBYTE		SPDCR_SPLW0
 #define SPDCR_SPLBYTE		SPDCR_SPLW0
 #define SPDCR_SPLW		0x20	/* Access Width Specification (SH) */
 #define SPDCR_SPLW		0x20	/* Access Width Specification (SH) */
-#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select */
+#define SPDCR_SPRDTD		0x10	/* Receive Transmit Data Select (SH) */
 #define SPDCR_SLSEL1		0x08
 #define SPDCR_SLSEL1		0x08
 #define SPDCR_SLSEL0		0x04
 #define SPDCR_SLSEL0		0x04
-#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select */
+#define SPDCR_SLSEL_MASK	0x0c	/* SSL1 Output Select (SH) */
 #define SPDCR_SPFC1		0x02
 #define SPDCR_SPFC1		0x02
 #define SPDCR_SPFC0		0x01
 #define SPDCR_SPFC0		0x01
-#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) */
+#define SPDCR_SPFC_MASK		0x03	/* Frame Count Setting (1-4) (SH) */
 
 
 /* SPCKD - Clock Delay Register */
 /* SPCKD - Clock Delay Register */
 #define SPCKD_SCKDL_MASK	0x07	/* Clock Delay Setting (1-8) */
 #define SPCKD_SCKDL_MASK	0x07	/* Clock Delay Setting (1-8) */
@@ -151,7 +159,7 @@
 #define SPCMD_LSBF		0x1000	/* LSB First */
 #define SPCMD_LSBF		0x1000	/* LSB First */
 #define SPCMD_SPB_MASK		0x0f00	/* Data Length Setting */
 #define SPCMD_SPB_MASK		0x0f00	/* Data Length Setting */
 #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
 #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
-#define SPCMD_SPB_8BIT		0x0000	/* qspi only */
+#define SPCMD_SPB_8BIT		0x0000	/* QSPI only */
 #define SPCMD_SPB_16BIT		0x0100
 #define SPCMD_SPB_16BIT		0x0100
 #define SPCMD_SPB_20BIT		0x0000
 #define SPCMD_SPB_20BIT		0x0000
 #define SPCMD_SPB_24BIT		0x0100
 #define SPCMD_SPB_24BIT		0x0100
@@ -170,8 +178,8 @@
 #define SPCMD_CPHA		0x0001	/* Clock Phase Setting */
 #define SPCMD_CPHA		0x0001	/* Clock Phase Setting */
 
 
 /* SPBFCR - Buffer Control Register */
 /* SPBFCR - Buffer Control Register */
-#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset (qspi only) */
-#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset (qspi only) */
+#define SPBFCR_TXRST		0x80	/* Transmit Buffer Data Reset */
+#define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset */
 #define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */
 #define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */
 #define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */
 #define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */
 
 
@@ -181,22 +189,21 @@ struct rspi_data {
 	void __iomem *addr;
 	void __iomem *addr;
 	u32 max_speed_hz;
 	u32 max_speed_hz;
 	struct spi_master *master;
 	struct spi_master *master;
-	struct list_head queue;
-	struct work_struct ws;
 	wait_queue_head_t wait;
 	wait_queue_head_t wait;
-	spinlock_t lock;
 	struct clk *clk;
 	struct clk *clk;
-	u8 spsr;
 	u16 spcmd;
 	u16 spcmd;
+	u8 spsr;
+	u8 sppcr;
+	int rx_irq, tx_irq;
 	const struct spi_ops *ops;
 	const struct spi_ops *ops;
 
 
 	/* for dmaengine */
 	/* for dmaengine */
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_rx;
 	struct dma_chan *chan_rx;
-	int irq;
 
 
 	unsigned dma_width_16bit:1;
 	unsigned dma_width_16bit:1;
 	unsigned dma_callbacked:1;
 	unsigned dma_callbacked:1;
+	unsigned byte_access:1;
 };
 };
 
 
 static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
 static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
@@ -224,34 +231,47 @@ static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
 	return ioread16(rspi->addr + offset);
 	return ioread16(rspi->addr + offset);
 }
 }
 
 
+static void rspi_write_data(const struct rspi_data *rspi, u16 data)
+{
+	if (rspi->byte_access)
+		rspi_write8(rspi, data, RSPI_SPDR);
+	else /* 16 bit */
+		rspi_write16(rspi, data, RSPI_SPDR);
+}
+
+static u16 rspi_read_data(const struct rspi_data *rspi)
+{
+	if (rspi->byte_access)
+		return rspi_read8(rspi, RSPI_SPDR);
+	else /* 16 bit */
+		return rspi_read16(rspi, RSPI_SPDR);
+}
+
 /* optional functions */
 /* optional functions */
 struct spi_ops {
 struct spi_ops {
-	int (*set_config_register)(const struct rspi_data *rspi,
-				   int access_size);
-	int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg,
-			struct spi_transfer *t);
-	int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg,
-			   struct spi_transfer *t);
-
+	int (*set_config_register)(struct rspi_data *rspi, int access_size);
+	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
+			    struct spi_transfer *xfer);
+	u16 mode_bits;
 };
 };
 
 
 /*
 /*
- * functions for RSPI
+ * functions for RSPI on legacy SH
  */
  */
-static int rspi_set_config_register(const struct rspi_data *rspi,
-				    int access_size)
+static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 {
 	int spbr;
 	int spbr;
 
 
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 
 	/* Sets transfer bit rate */
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 
 
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	/* Disable dummy transmission, set 16-bit word access, 1 frame */
+	rspi_write8(rspi, 0, RSPI_SPDCR);
+	rspi->byte_access = 0;
 
 
 	/* Sets RSPCK, SSL, next-access delay value */
 	/* Sets RSPCK, SSL, next-access delay value */
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -262,8 +282,41 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
 	rspi_write8(rspi, 0x00, RSPI_SPCR2);
 	rspi_write8(rspi, 0x00, RSPI_SPCR2);
 
 
 	/* Sets SPCMD */
 	/* Sets SPCMD */
-	rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | rspi->spcmd,
-		     RSPI_SPCMD0);
+	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
+
+	/* Sets RSPI mode */
+	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
+
+	return 0;
+}
+
+/*
+ * functions for RSPI on RZ
+ */
+static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
+{
+	int spbr;
+
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
+
+	/* Sets transfer bit rate */
+	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
+	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
+
+	/* Disable dummy transmission, set byte access */
+	rspi_write8(rspi, SPDCR_SPLBYTE, RSPI_SPDCR);
+	rspi->byte_access = 1;
+
+	/* Sets RSPCK, SSL, next-access delay value */
+	rspi_write8(rspi, 0x00, RSPI_SPCKD);
+	rspi_write8(rspi, 0x00, RSPI_SSLND);
+	rspi_write8(rspi, 0x00, RSPI_SPND);
+
+	/* Sets SPCMD */
+	rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
 
 
 	/* Sets RSPI mode */
 	/* Sets RSPI mode */
 	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
 	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
@@ -274,21 +327,20 @@ static int rspi_set_config_register(const struct rspi_data *rspi,
 /*
 /*
  * functions for QSPI
  * functions for QSPI
  */
  */
-static int qspi_set_config_register(const struct rspi_data *rspi,
-				    int access_size)
+static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 {
-	u16 spcmd;
 	int spbr;
 	int spbr;
 
 
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+	/* Sets output mode, MOSI signal, and (optionally) loopback */
+	rspi_write8(rspi, rspi->sppcr, RSPI_SPPCR);
 
 
 	/* Sets transfer bit rate */
 	/* Sets transfer bit rate */
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
 	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
 
 
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	/* Disable dummy transmission, set byte access */
+	rspi_write8(rspi, 0, RSPI_SPDCR);
+	rspi->byte_access = 1;
 
 
 	/* Sets RSPCK, SSL, next-access delay value */
 	/* Sets RSPCK, SSL, next-access delay value */
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
 	rspi_write8(rspi, 0x00, RSPI_SPCKD);
@@ -297,13 +349,13 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
 
 
 	/* Data Length Setting */
 	/* Data Length Setting */
 	if (access_size == 8)
 	if (access_size == 8)
-		spcmd = SPCMD_SPB_8BIT;
+		rspi->spcmd |= SPCMD_SPB_8BIT;
 	else if (access_size == 16)
 	else if (access_size == 16)
-		spcmd = SPCMD_SPB_16BIT;
+		rspi->spcmd |= SPCMD_SPB_16BIT;
 	else
 	else
-		spcmd = SPCMD_SPB_32BIT;
+		rspi->spcmd |= SPCMD_SPB_32BIT;
 
 
-	spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | rspi->spcmd | SPCMD_SPNDEN;
+	rspi->spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SPNDEN;
 
 
 	/* Resets transfer data length */
 	/* Resets transfer data length */
 	rspi_write32(rspi, 0, QSPI_SPBMUL0);
 	rspi_write32(rspi, 0, QSPI_SPBMUL0);
@@ -314,9 +366,9 @@ static int qspi_set_config_register(const struct rspi_data *rspi,
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
 
 
 	/* Sets SPCMD */
 	/* Sets SPCMD */
-	rspi_write16(rspi, spcmd, RSPI_SPCMD0);
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
 
 
-	/* Enables SPI function in a master mode */
+	/* Enables SPI function in master mode */
 	rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);
 	rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);
 
 
 	return 0;
 	return 0;
@@ -340,6 +392,9 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
 	int ret;
 	int ret;
 
 
 	rspi->spsr = rspi_read8(rspi, RSPI_SPSR);
 	rspi->spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (rspi->spsr & wait_mask)
+		return 0;
+
 	rspi_enable_irq(rspi, enable_bit);
 	rspi_enable_irq(rspi, enable_bit);
 	ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ);
 	ret = wait_event_timeout(rspi->wait, rspi->spsr & wait_mask, HZ);
 	if (ret == 0 && !(rspi->spsr & wait_mask))
 	if (ret == 0 && !(rspi->spsr & wait_mask))
@@ -348,78 +403,39 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask,
 	return 0;
 	return 0;
 }
 }
 
 
-static void rspi_assert_ssl(const struct rspi_data *rspi)
-{
-	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
-}
-
-static void rspi_negate_ssl(const struct rspi_data *rspi)
+static int rspi_data_out(struct rspi_data *rspi, u8 data)
 {
 {
-	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+	if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
+		dev_err(&rspi->master->dev, "transmit timeout\n");
+		return -ETIMEDOUT;
+	}
+	rspi_write_data(rspi, data);
+	return 0;
 }
 }
 
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			 struct spi_transfer *t)
+static int rspi_data_in(struct rspi_data *rspi)
 {
 {
-	int remain = t->len;
-	const u8 *data = t->tx_buf;
-	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
-			    RSPI_SPCR);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
+	u8 data;
 
 
-		rspi_write16(rspi, *data, RSPI_SPDR);
-		data++;
-		remain--;
+	if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+		dev_err(&rspi->master->dev, "receive timeout\n");
+		return -ETIMEDOUT;
 	}
 	}
-
-	/* Waiting for the last transmission */
-	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
-
-	return 0;
+	data = rspi_read_data(rspi);
+	return data;
 }
 }
 
 
-static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			 struct spi_transfer *t)
+static int rspi_data_out_in(struct rspi_data *rspi, u8 data)
 {
 {
-	int remain = t->len;
-	const u8 *data = t->tx_buf;
-
-	rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR);
-	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
-
-	while (remain > 0) {
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		rspi_write8(rspi, *data++, RSPI_SPDR);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		rspi_read8(rspi, RSPI_SPDR);
-
-		remain--;
-	}
+	int ret;
 
 
-	/* Waiting for the last transmission */
-	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+	ret = rspi_data_out(rspi, data);
+	if (ret < 0)
+		return ret;
 
 
-	return 0;
+	return rspi_data_in(rspi);
 }
 }
 
 
-#define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t)
-
 static void rspi_dma_complete(void *arg)
 static void rspi_dma_complete(void *arg)
 {
 {
 	struct rspi_data *rspi = arg;
 	struct rspi_data *rspi = arg;
@@ -471,7 +487,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	struct scatterlist sg;
 	struct scatterlist sg;
 	const void *buf = NULL;
 	const void *buf = NULL;
 	struct dma_async_tx_descriptor *desc;
 	struct dma_async_tx_descriptor *desc;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 	int ret = 0;
 
 
 	if (rspi->dma_width_16bit) {
 	if (rspi->dma_width_16bit) {
@@ -509,7 +525,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
 
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE);
 	rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -528,7 +544,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE);
 	rspi_disable_irq(rspi, SPCR_SPTIE);
 
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
 
 
 end:
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
 	rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -545,46 +561,17 @@ static void rspi_receive_init(const struct rspi_data *rspi)
 
 
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	if (spsr & SPSR_SPRF)
 	if (spsr & SPSR_SPRF)
-		rspi_read16(rspi, RSPI_SPDR);	/* dummy read */
+		rspi_read_data(rspi);	/* dummy read */
 	if (spsr & SPSR_OVRF)
 	if (spsr & SPSR_OVRF)
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
 		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
 			    RSPI_SPSR);
 			    RSPI_SPSR);
 }
 }
 
 
-static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			    struct spi_transfer *t)
+static void rspi_rz_receive_init(const struct rspi_data *rspi)
 {
 {
-	int remain = t->len;
-	u8 *data;
-
 	rspi_receive_init(rspi);
 	rspi_receive_init(rspi);
-
-	data = t->rx_buf;
-	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD,
-			    RSPI_SPCR);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		/* dummy write for generate clock */
-		rspi_write16(rspi, DUMMY_DATA, RSPI_SPDR);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		/* SPDR allows 16 or 32-bit access only */
-		*data = (u8)rspi_read16(rspi, RSPI_SPDR);
-
-		data++;
-		remain--;
-	}
-
-	return 0;
+	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, RSPI_SPBFCR);
+	rspi_write8(rspi, 0, RSPI_SPBFCR);
 }
 }
 
 
 static void qspi_receive_init(const struct rspi_data *rspi)
 static void qspi_receive_init(const struct rspi_data *rspi)
@@ -593,51 +580,17 @@ static void qspi_receive_init(const struct rspi_data *rspi)
 
 
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	spsr = rspi_read8(rspi, RSPI_SPSR);
 	if (spsr & SPSR_SPRF)
 	if (spsr & SPSR_SPRF)
-		rspi_read8(rspi, RSPI_SPDR);   /* dummy read */
+		rspi_read_data(rspi);   /* dummy read */
 	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
 	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
-	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
+	rspi_write8(rspi, 0, QSPI_SPBFCR);
 }
 }
 
 
-static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
-			    struct spi_transfer *t)
-{
-	int remain = t->len;
-	u8 *data;
-
-	qspi_receive_init(rspi);
-
-	data = t->rx_buf;
-	while (remain > 0) {
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: tx empty timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		/* dummy write for generate clock */
-		rspi_write8(rspi, DUMMY_DATA, RSPI_SPDR);
-
-		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
-			dev_err(&rspi->master->dev,
-				"%s: receive timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
-		/* SPDR allows 8, 16 or 32-bit access */
-		*data++ = rspi_read8(rspi, RSPI_SPDR);
-		remain--;
-	}
-
-	return 0;
-}
-
-#define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t)
-
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 {
 {
 	struct scatterlist sg, sg_dummy;
 	struct scatterlist sg, sg_dummy;
 	void *dummy = NULL, *rx_buf = NULL;
 	void *dummy = NULL, *rx_buf = NULL;
 	struct dma_async_tx_descriptor *desc, *desc_dummy;
 	struct dma_async_tx_descriptor *desc, *desc_dummy;
-	unsigned len;
+	unsigned int len;
 	int ret = 0;
 	int ret = 0;
 
 
 	if (rspi->dma_width_16bit) {
 	if (rspi->dma_width_16bit) {
@@ -695,7 +648,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 * called. So, this driver disables the IRQ while DMA transfer.
 	 */
 	 */
-	disable_irq(rspi->irq);
+	disable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		disable_irq(rspi->rx_irq);
 
 
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
 	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
 	rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -718,7 +673,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 		ret = -ETIMEDOUT;
 		ret = -ETIMEDOUT;
 	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
 	rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
 
 
-	enable_irq(rspi->irq);
+	enable_irq(rspi->tx_irq);
+	if (rspi->rx_irq != rspi->tx_irq)
+		enable_irq(rspi->rx_irq);
 
 
 end:
 end:
 	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
 	rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -746,56 +703,175 @@ static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t)
 	return 0;
 	return 0;
 }
 }
 
 
-static void rspi_work(struct work_struct *work)
+static int rspi_transfer_out_in(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
 {
 {
-	struct rspi_data *rspi = container_of(work, struct rspi_data, ws);
-	struct spi_message *mesg;
-	struct spi_transfer *t;
-	unsigned long flags;
-	int ret;
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 spcr, data;
 
 
-	while (1) {
-		spin_lock_irqsave(&rspi->lock, flags);
-		if (list_empty(&rspi->queue)) {
-			spin_unlock_irqrestore(&rspi->lock, flags);
-			break;
-		}
-		mesg = list_entry(rspi->queue.next, struct spi_message, queue);
-		list_del_init(&mesg->queue);
-		spin_unlock_irqrestore(&rspi->lock, flags);
-
-		rspi_assert_ssl(rspi);
-
-		list_for_each_entry(t, &mesg->transfers, transfer_list) {
-			if (t->tx_buf) {
-				if (rspi_is_dma(rspi, t))
-					ret = rspi_send_dma(rspi, t);
-				else
-					ret = send_pio(rspi, mesg, t);
-				if (ret < 0)
-					goto error;
-			}
-			if (t->rx_buf) {
-				if (rspi_is_dma(rspi, t))
-					ret = rspi_receive_dma(rspi, t);
-				else
-					ret = receive_pio(rspi, mesg, t);
-				if (ret < 0)
-					goto error;
-			}
-			mesg->actual_length += t->len;
+	rspi_receive_init(rspi);
+
+	spcr = rspi_read8(rspi, RSPI_SPCR);
+	if (rx_buf)
+		spcr &= ~SPCR_TXMD;
+	else
+		spcr |= SPCR_TXMD;
+	rspi_write8(rspi, spcr, RSPI_SPCR);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf) {
+			ret = rspi_data_in(rspi);
+			if (ret < 0)
+				return ret;
+			*rx_buf++ = ret;
 		}
 		}
-		rspi_negate_ssl(rspi);
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret;
+
+	if (!rspi_is_dma(rspi, xfer))
+		return rspi_transfer_out_in(rspi, xfer);
+
+	if (xfer->tx_buf) {
+		ret = rspi_send_dma(rspi, xfer);
+		if (ret < 0)
+			return ret;
+	}
+	if (xfer->rx_buf)
+		return rspi_receive_dma(rspi, xfer);
+
+	return 0;
+}
+
+static int rspi_rz_transfer_out_in(struct rspi_data *rspi,
+				   struct spi_transfer *xfer)
+{
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 data;
+
+	rspi_rz_receive_init(rspi);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out_in(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf)
+			*rx_buf++ = ret;
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int rspi_rz_transfer_one(struct spi_master *master,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	return rspi_rz_transfer_out_in(rspi, xfer);
+}
+
+static int qspi_transfer_out_in(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
+{
+	int remain = xfer->len, ret;
+	const u8 *tx_buf = xfer->tx_buf;
+	u8 *rx_buf = xfer->rx_buf;
+	u8 data;
 
 
-		mesg->status = 0;
-		mesg->complete(mesg->context);
+	qspi_receive_init(rspi);
+
+	while (remain > 0) {
+		data = tx_buf ? *tx_buf++ : DUMMY_DATA;
+		ret = rspi_data_out_in(rspi, data);
+		if (ret < 0)
+			return ret;
+		if (rx_buf)
+			*rx_buf++ = ret;
+		remain--;
+	}
+
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
+
+	return 0;
+}
+
+static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
+{
+	const u8 *buf = xfer->tx_buf;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < xfer->len; i++) {
+		ret = rspi_data_out(rspi, *buf++);
+		if (ret < 0)
+			return ret;
 	}
 	}
 
 
-	return;
+	/* Wait for the last transmission */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
 
 
-error:
-	mesg->status = ret;
-	mesg->complete(mesg->context);
+	return 0;
+}
+
+static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
+{
+	u8 *buf = xfer->rx_buf;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < xfer->len; i++) {
+		ret = rspi_data_in(rspi);
+		if (ret < 0)
+			return ret;
+		*buf++ = ret;
+	}
+
+	return 0;
+}
+
+static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi,
+			     struct spi_transfer *xfer)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	if (spi->mode & SPI_LOOP) {
+		return qspi_transfer_out_in(rspi, xfer);
+	} else if (xfer->tx_buf && xfer->tx_nbits > SPI_NBITS_SINGLE) {
+		/* Quad or Dual SPI Write */
+		return qspi_transfer_out(rspi, xfer);
+	} else if (xfer->rx_buf && xfer->rx_nbits > SPI_NBITS_SINGLE) {
+		/* Quad or Dual SPI Read */
+		return qspi_transfer_in(rspi, xfer);
+	} else {
+		/* Single SPI Transfer */
+		return qspi_transfer_out_in(rspi, xfer);
+	}
 }
 }
 
 
 static int rspi_setup(struct spi_device *spi)
 static int rspi_setup(struct spi_device *spi)
@@ -810,32 +886,115 @@ static int rspi_setup(struct spi_device *spi)
 	if (spi->mode & SPI_CPHA)
 	if (spi->mode & SPI_CPHA)
 		rspi->spcmd |= SPCMD_CPHA;
 		rspi->spcmd |= SPCMD_CPHA;
 
 
+	/* CMOS output mode and MOSI signal from previous transfer */
+	rspi->sppcr = 0;
+	if (spi->mode & SPI_LOOP)
+		rspi->sppcr |= SPPCR_SPLP;
+
 	set_config_register(rspi, 8);
 	set_config_register(rspi, 8);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int rspi_transfer(struct spi_device *spi, struct spi_message *mesg)
+static u16 qspi_transfer_mode(const struct spi_transfer *xfer)
 {
 {
-	struct rspi_data *rspi = spi_master_get_devdata(spi->master);
-	unsigned long flags;
+	if (xfer->tx_buf)
+		switch (xfer->tx_nbits) {
+		case SPI_NBITS_QUAD:
+			return SPCMD_SPIMOD_QUAD;
+		case SPI_NBITS_DUAL:
+			return SPCMD_SPIMOD_DUAL;
+		default:
+			return 0;
+		}
+	if (xfer->rx_buf)
+		switch (xfer->rx_nbits) {
+		case SPI_NBITS_QUAD:
+			return SPCMD_SPIMOD_QUAD | SPCMD_SPRW;
+		case SPI_NBITS_DUAL:
+			return SPCMD_SPIMOD_DUAL | SPCMD_SPRW;
+		default:
+			return 0;
+		}
+
+	return 0;
+}
 
 
-	mesg->actual_length = 0;
-	mesg->status = -EINPROGRESS;
+static int qspi_setup_sequencer(struct rspi_data *rspi,
+				const struct spi_message *msg)
+{
+	const struct spi_transfer *xfer;
+	unsigned int i = 0, len = 0;
+	u16 current_mode = 0xffff, mode;
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		mode = qspi_transfer_mode(xfer);
+		if (mode == current_mode) {
+			len += xfer->len;
+			continue;
+		}
+
+		/* Transfer mode change */
+		if (i) {
+			/* Set transfer data length of previous transfer */
+			rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
+		}
 
 
-	spin_lock_irqsave(&rspi->lock, flags);
-	list_add_tail(&mesg->queue, &rspi->queue);
-	schedule_work(&rspi->ws);
-	spin_unlock_irqrestore(&rspi->lock, flags);
+		if (i >= QSPI_NUM_SPCMD) {
+			dev_err(&msg->spi->dev,
+				"Too many different transfer modes");
+			return -EINVAL;
+		}
+
+		/* Program transfer mode for this transfer */
+		rspi_write16(rspi, rspi->spcmd | mode, RSPI_SPCMD(i));
+		current_mode = mode;
+		len = xfer->len;
+		i++;
+	}
+	if (i) {
+		/* Set final transfer data length and sequence length */
+		rspi_write32(rspi, len, QSPI_SPBMUL(i - 1));
+		rspi_write8(rspi, i - 1, RSPI_SPSCR);
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static void rspi_cleanup(struct spi_device *spi)
+static int rspi_prepare_message(struct spi_master *master,
+				struct spi_message *msg)
 {
 {
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+	int ret;
+
+	if (msg->spi->mode &
+	    (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) {
+		/* Setup sequencer for messages with multiple transfer modes */
+		ret = qspi_setup_sequencer(rspi, msg);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Enable SPI function in master mode */
+	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_SPE, RSPI_SPCR);
+	return 0;
 }
 }
 
 
-static irqreturn_t rspi_irq(int irq, void *_sr)
+static int rspi_unprepare_message(struct spi_master *master,
+				  struct spi_message *msg)
+{
+	struct rspi_data *rspi = spi_master_get_devdata(master);
+
+	/* Disable SPI function */
+	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
+
+	/* Reset sequencer for Single SPI Transfers */
+	rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
+	rspi_write8(rspi, 0, RSPI_SPSCR);
+	return 0;
+}
+
+static irqreturn_t rspi_irq_mux(int irq, void *_sr)
 {
 {
 	struct rspi_data *rspi = _sr;
 	struct rspi_data *rspi = _sr;
 	u8 spsr;
 	u8 spsr;
@@ -857,6 +1016,36 @@ static irqreturn_t rspi_irq(int irq, void *_sr)
 	return ret;
 	return ret;
 }
 }
 
 
+static irqreturn_t rspi_irq_rx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPRF) {
+		rspi_disable_irq(rspi, SPCR_SPRIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
+static irqreturn_t rspi_irq_tx(int irq, void *_sr)
+{
+	struct rspi_data *rspi = _sr;
+	u8 spsr;
+
+	rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPTEF) {
+		rspi_disable_irq(rspi, SPCR_SPTIE);
+		wake_up(&rspi->wait);
+		return IRQ_HANDLED;
+	}
+
+	return 0;
+}
+
 static int rspi_request_dma(struct rspi_data *rspi,
 static int rspi_request_dma(struct rspi_data *rspi,
 				      struct platform_device *pdev)
 				      struct platform_device *pdev)
 {
 {
@@ -923,34 +1112,89 @@ static int rspi_remove(struct platform_device *pdev)
 	struct rspi_data *rspi = platform_get_drvdata(pdev);
 	struct rspi_data *rspi = platform_get_drvdata(pdev);
 
 
 	rspi_release_dma(rspi);
 	rspi_release_dma(rspi);
-	clk_disable(rspi->clk);
+	pm_runtime_disable(&pdev->dev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct spi_ops rspi_ops = {
+	.set_config_register =		rspi_set_config_register,
+	.transfer_one =			rspi_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP,
+};
+
+static const struct spi_ops rspi_rz_ops = {
+	.set_config_register =		rspi_rz_set_config_register,
+	.transfer_one =			rspi_rz_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP,
+};
+
+static const struct spi_ops qspi_ops = {
+	.set_config_register =		qspi_set_config_register,
+	.transfer_one =			qspi_transfer_one,
+	.mode_bits =			SPI_CPHA | SPI_CPOL | SPI_LOOP |
+					SPI_TX_DUAL | SPI_TX_QUAD |
+					SPI_RX_DUAL | SPI_RX_QUAD,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id rspi_of_match[] = {
+	/* RSPI on legacy SH */
+	{ .compatible = "renesas,rspi", .data = &rspi_ops },
+	/* RSPI on RZ/A1H */
+	{ .compatible = "renesas,rspi-rz", .data = &rspi_rz_ops },
+	/* QSPI on R-Car Gen2 */
+	{ .compatible = "renesas,qspi", .data = &qspi_ops },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, rspi_of_match);
+
+static int rspi_parse_dt(struct device *dev, struct spi_master *master)
+{
+	u32 num_cs;
+	int error;
+
+	/* Parse DT properties */
+	error = of_property_read_u32(dev->of_node, "num-cs", &num_cs);
+	if (error) {
+		dev_err(dev, "of_property_read_u32 num-cs failed %d\n", error);
+		return error;
+	}
+
+	master->num_chipselect = num_cs;
+	return 0;
+}
+#else
+#define rspi_of_match	NULL
+static inline int rspi_parse_dt(struct device *dev, struct spi_master *master)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_OF */
+
+static int rspi_request_irq(struct device *dev, unsigned int irq,
+			    irq_handler_t handler, const char *suffix,
+			    void *dev_id)
+{
+	const char *base = dev_name(dev);
+	size_t len = strlen(base) + strlen(suffix) + 2;
+	char *name = devm_kzalloc(dev, len, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	snprintf(name, len, "%s:%s", base, suffix);
+	return devm_request_irq(dev, irq, handler, 0, name, dev_id);
+}
+
 static int rspi_probe(struct platform_device *pdev)
 static int rspi_probe(struct platform_device *pdev)
 {
 {
 	struct resource *res;
 	struct resource *res;
 	struct spi_master *master;
 	struct spi_master *master;
 	struct rspi_data *rspi;
 	struct rspi_data *rspi;
-	int ret, irq;
-	char clk_name[16];
-	const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
+	int ret;
+	const struct of_device_id *of_id;
+	const struct rspi_plat_data *rspi_pd;
 	const struct spi_ops *ops;
 	const struct spi_ops *ops;
-	const struct platform_device_id *id_entry = pdev->id_entry;
-
-	ops = (struct spi_ops *)id_entry->driver_data;
-	/* ops parameter check */
-	if (!ops->set_config_register) {
-		dev_err(&pdev->dev, "there is no set_config_register\n");
-		return -ENODEV;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "platform_get_irq error\n");
-		return -ENODEV;
-	}
 
 
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
 	if (master == NULL) {
 	if (master == NULL) {
@@ -958,6 +1202,28 @@ static int rspi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
+	of_id = of_match_device(rspi_of_match, &pdev->dev);
+	if (of_id) {
+		ops = of_id->data;
+		ret = rspi_parse_dt(&pdev->dev, master);
+		if (ret)
+			goto error1;
+	} else {
+		ops = (struct spi_ops *)pdev->id_entry->driver_data;
+		rspi_pd = dev_get_platdata(&pdev->dev);
+		if (rspi_pd && rspi_pd->num_chipselect)
+			master->num_chipselect = rspi_pd->num_chipselect;
+		else
+			master->num_chipselect = 2; /* default */
+	};
+
+	/* ops parameter check */
+	if (!ops->set_config_register) {
+		dev_err(&pdev->dev, "there is no set_config_register\n");
+		ret = -ENODEV;
+		goto error1;
+	}
+
 	rspi = spi_master_get_devdata(master);
 	rspi = spi_master_get_devdata(master);
 	platform_set_drvdata(pdev, rspi);
 	platform_set_drvdata(pdev, rspi);
 	rspi->ops = ops;
 	rspi->ops = ops;
@@ -970,39 +1236,61 @@ static int rspi_probe(struct platform_device *pdev)
 		goto error1;
 		goto error1;
 	}
 	}
 
 
-	snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
-	rspi->clk = devm_clk_get(&pdev->dev, clk_name);
+	rspi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(rspi->clk)) {
 	if (IS_ERR(rspi->clk)) {
 		dev_err(&pdev->dev, "cannot get clock\n");
 		dev_err(&pdev->dev, "cannot get clock\n");
 		ret = PTR_ERR(rspi->clk);
 		ret = PTR_ERR(rspi->clk);
 		goto error1;
 		goto error1;
 	}
 	}
-	clk_enable(rspi->clk);
 
 
-	INIT_LIST_HEAD(&rspi->queue);
-	spin_lock_init(&rspi->lock);
-	INIT_WORK(&rspi->ws, rspi_work);
-	init_waitqueue_head(&rspi->wait);
+	pm_runtime_enable(&pdev->dev);
 
 
-	if (rspi_pd && rspi_pd->num_chipselect)
-		master->num_chipselect = rspi_pd->num_chipselect;
-	else
-		master->num_chipselect = 2; /* default */
+	init_waitqueue_head(&rspi->wait);
 
 
 	master->bus_num = pdev->id;
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
 	master->setup = rspi_setup;
-	master->transfer = rspi_transfer;
-	master->cleanup = rspi_cleanup;
-	master->mode_bits = SPI_CPHA | SPI_CPOL;
+	master->auto_runtime_pm = true;
+	master->transfer_one = ops->transfer_one;
+	master->prepare_message = rspi_prepare_message;
+	master->unprepare_message = rspi_unprepare_message;
+	master->mode_bits = ops->mode_bits;
+	master->dev.of_node = pdev->dev.of_node;
+
+	ret = platform_get_irq_byname(pdev, "rx");
+	if (ret < 0) {
+		ret = platform_get_irq_byname(pdev, "mux");
+		if (ret < 0)
+			ret = platform_get_irq(pdev, 0);
+		if (ret >= 0)
+			rspi->rx_irq = rspi->tx_irq = ret;
+	} else {
+		rspi->rx_irq = ret;
+		ret = platform_get_irq_byname(pdev, "tx");
+		if (ret >= 0)
+			rspi->tx_irq = ret;
+	}
+	if (ret < 0) {
+		dev_err(&pdev->dev, "platform_get_irq error\n");
+		goto error2;
+	}
 
 
-	ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0,
-			       dev_name(&pdev->dev), rspi);
+	if (rspi->rx_irq == rspi->tx_irq) {
+		/* Single multiplexed interrupt */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
+				       "mux", rspi);
+	} else {
+		/* Multi-interrupt mode, only SPRI and SPTI are used */
+		ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
+				       "rx", rspi);
+		if (!ret)
+			ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
+					       rspi_irq_tx, "tx", rspi);
+	}
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "request_irq error\n");
 		dev_err(&pdev->dev, "request_irq error\n");
 		goto error2;
 		goto error2;
 	}
 	}
 
 
-	rspi->irq = irq;
 	ret = rspi_request_dma(rspi, pdev);
 	ret = rspi_request_dma(rspi, pdev);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "rspi_request_dma failed.\n");
 		dev_err(&pdev->dev, "rspi_request_dma failed.\n");
@@ -1022,27 +1310,16 @@ static int rspi_probe(struct platform_device *pdev)
 error3:
 error3:
 	rspi_release_dma(rspi);
 	rspi_release_dma(rspi);
 error2:
 error2:
-	clk_disable(rspi->clk);
+	pm_runtime_disable(&pdev->dev);
 error1:
 error1:
 	spi_master_put(master);
 	spi_master_put(master);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static struct spi_ops rspi_ops = {
-	.set_config_register =		rspi_set_config_register,
-	.send_pio =			rspi_send_pio,
-	.receive_pio =			rspi_receive_pio,
-};
-
-static struct spi_ops qspi_ops = {
-	.set_config_register =		qspi_set_config_register,
-	.send_pio =			qspi_send_pio,
-	.receive_pio =			qspi_receive_pio,
-};
-
 static struct platform_device_id spi_driver_ids[] = {
 static struct platform_device_id spi_driver_ids[] = {
 	{ "rspi",	(kernel_ulong_t)&rspi_ops },
 	{ "rspi",	(kernel_ulong_t)&rspi_ops },
+	{ "rspi-rz",	(kernel_ulong_t)&rspi_rz_ops },
 	{ "qspi",	(kernel_ulong_t)&qspi_ops },
 	{ "qspi",	(kernel_ulong_t)&qspi_ops },
 	{},
 	{},
 };
 };
@@ -1056,6 +1333,7 @@ static struct platform_driver rspi_driver = {
 	.driver		= {
 	.driver		= {
 		.name = "renesas_spi",
 		.name = "renesas_spi",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(rspi_of_match),
 	},
 	},
 };
 };
 module_platform_driver(rspi_driver);
 module_platform_driver(rspi_driver);

+ 7 - 11
drivers/spi/spi-s3c24xx.c

@@ -122,25 +122,15 @@ static int s3c24xx_spi_update_state(struct spi_device *spi,
 {
 {
 	struct s3c24xx_spi *hw = to_hw(spi);
 	struct s3c24xx_spi *hw = to_hw(spi);
 	struct s3c24xx_spi_devstate *cs = spi->controller_state;
 	struct s3c24xx_spi_devstate *cs = spi->controller_state;
-	unsigned int bpw;
 	unsigned int hz;
 	unsigned int hz;
 	unsigned int div;
 	unsigned int div;
 	unsigned long clk;
 	unsigned long clk;
 
 
-	bpw = t ? t->bits_per_word : spi->bits_per_word;
 	hz  = t ? t->speed_hz : spi->max_speed_hz;
 	hz  = t ? t->speed_hz : spi->max_speed_hz;
 
 
-	if (!bpw)
-		bpw = 8;
-
 	if (!hz)
 	if (!hz)
 		hz = spi->max_speed_hz;
 		hz = spi->max_speed_hz;
 
 
-	if (bpw != 8) {
-		dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
-		return -EINVAL;
-	}
-
 	if (spi->mode != cs->mode) {
 	if (spi->mode != cs->mode) {
 		u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK;
 		u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK;
 
 
@@ -543,6 +533,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
 
 
 	master->num_chipselect = hw->pdata->num_cs;
 	master->num_chipselect = hw->pdata->num_cs;
 	master->bus_num = pdata->bus_num;
 	master->bus_num = pdata->bus_num;
+	master->bits_per_word_mask = SPI_BPW_MASK(8);
 
 
 	/* setup the state for the bitbang driver */
 	/* setup the state for the bitbang driver */
 
 
@@ -642,6 +633,11 @@ static int s3c24xx_spi_remove(struct platform_device *dev)
 static int s3c24xx_spi_suspend(struct device *dev)
 static int s3c24xx_spi_suspend(struct device *dev)
 {
 {
 	struct s3c24xx_spi *hw = dev_get_drvdata(dev);
 	struct s3c24xx_spi *hw = dev_get_drvdata(dev);
+	int ret;
+
+	ret = spi_master_suspend(hw->master);
+	if (ret)
+		return ret;
 
 
 	if (hw->pdata && hw->pdata->gpio_setup)
 	if (hw->pdata && hw->pdata->gpio_setup)
 		hw->pdata->gpio_setup(hw->pdata, 0);
 		hw->pdata->gpio_setup(hw->pdata, 0);
@@ -655,7 +651,7 @@ static int s3c24xx_spi_resume(struct device *dev)
 	struct s3c24xx_spi *hw = dev_get_drvdata(dev);
 	struct s3c24xx_spi *hw = dev_get_drvdata(dev);
 
 
 	s3c24xx_spi_initialsetup(hw);
 	s3c24xx_spi_initialsetup(hw);
-	return 0;
+	return spi_master_resume(hw->master);
 }
 }
 
 
 static const struct dev_pm_ops s3c24xx_spi_pmops = {
 static const struct dev_pm_ops s3c24xx_spi_pmops = {

+ 4 - 0
include/linux/pm_runtime.h

@@ -26,9 +26,13 @@
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 extern int pm_generic_runtime_suspend(struct device *dev);
 extern int pm_generic_runtime_suspend(struct device *dev);
 extern int pm_generic_runtime_resume(struct device *dev);
 extern int pm_generic_runtime_resume(struct device *dev);
+extern int pm_runtime_force_suspend(struct device *dev);
+extern int pm_runtime_force_resume(struct device *dev);
 #else
 #else
 static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
+static inline int pm_runtime_force_suspend(struct device *dev) { return 0; }
+static inline int pm_runtime_force_resume(struct device *dev) { return 0; }
 #endif
 #endif
 
 
 #ifdef CONFIG_PM_RUNTIME
 #ifdef CONFIG_PM_RUNTIME