[Armadeus-commitlog] armadeus branch, master, updated. armadeus-5.0-35-gea1a5ff
Brought to you by:
sszy
|
From: Gwenhael Goavec-M. <gwe...@us...> - 2012-09-22 08:02:22
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via ea1a5ff76b8d8da7845c6cf541d51ee6a78e00d9 (commit)
via 712d3f8229f4d23e0ec3e9d804a58ec176987b1c (commit)
via 96625d16bc3c9be56e6d51590d305d73c81a765f (commit)
via 67dfad106be58c15769ecdd68d5d1723d6caf5df (commit)
from a5415a08cf0de85b3ca448ac577c79b304a81ba7 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ea1a5ff76b8d8da7845c6cf541d51ee6a78e00d9
Author: Gwenhael Goavec-Merou <gw...@tr...>
Date: Sat Sep 22 10:01:23 2012 +0200
[LINUX][3.5] apf28 config: Select SPI by default
commit 712d3f8229f4d23e0ec3e9d804a58ec176987b1c
Author: Gwenhael Goavec-Merou <gw...@tr...>
Date: Sat Sep 22 10:00:34 2012 +0200
[LINUX][3.5] apf28 dts: Add support for ssp0 as MMC and ssp2 as SPI
commit 96625d16bc3c9be56e6d51590d305d73c81a765f
Author: Gwenhael Goavec-Merou <gw...@tr...>
Date: Sat Sep 22 09:58:51 2012 +0200
[LINUX][3.5] mx28: Select MXS_HAVE_PLATFORM_MXS_SPI for SOC_IMX28
commit 67dfad106be58c15769ecdd68d5d1723d6caf5df
Author: Gwenhael Goavec-Merou <gw...@tr...>
Date: Sat Sep 22 09:57:03 2012 +0200
[LINUX][3.5] APF28: Backport patches for SPI drivers integration
-----------------------------------------------------------------------
Summary of changes:
.../device/armadeus/apf28/apf28-linux-3.5.config | 1 +
.../3.5/0403-armadeus-Add-apf28-dts-files.patch | 39 ++-
...406-armadeus-mx28-add_SPI_support_kconfig.patch | 12 +
...P_register_definitions_into_separate_file.patch | 254 ++++++++++
...x28-mmc_spi_Rename_IMX2x_MMC_to_IMX2x_SSP.patch | 116 +++++
...mmc_spi_Add_necessary_bits_into_mxs-spi-h.patch | 95 ++++
...Pull_out_parts_shared_between_MMC_and_SPI.patch | 381 +++++++++++++++
..._out_the_SSP_clock_configuration_function.patch | 179 +++++++
...ix-mx28-spi_Add_SPI_driver_for_mx233_mx28.patch | 503 ++++++++++++++++++++
...pi_Pull_out_common_DMA_parts_from_MXS_MMC.patch | 318 ++++++++++++
...-mx28-spi_Add_DMA_support_into_SPI_driver.patch | 345 ++++++++++++++
...spi_Add_SSP_SPI_device_tree_documentation.patch | 49 ++
...ronix-mx28_Add_SPI_pinmux_into_imx28_dtsi.patch | 72 +++
.../0417-pengutronix-mx28-Add_SPI_ressources.patch | 154 ++++++
14 files changed, 2517 insertions(+), 1 deletions(-)
create mode 100644 patches/linux/3.5/0406-armadeus-mx28-add_SPI_support_kconfig.patch
create mode 100644 patches/linux/3.5/0407-pengutronix-mx28-Move_SSP_register_definitions_into_separate_file.patch
create mode 100644 patches/linux/3.5/0408-pengutronix-mx28-mmc_spi_Rename_IMX2x_MMC_to_IMX2x_SSP.patch
create mode 100644 patches/linux/3.5/0409-pengutronix-mx28-mmc_spi_Add_necessary_bits_into_mxs-spi-h.patch
create mode 100644 patches/linux/3.5/0410-pengutronix-mx28-mmc_spi_Pull_out_parts_shared_between_MMC_and_SPI.patch
create mode 100644 patches/linux/3.5/0411-pengutronix-mx28-mmc_spi_Pull_out_the_SSP_clock_configuration_function.patch
create mode 100644 patches/linux/3.5/0412-pengutronix-mx28-spi_Add_SPI_driver_for_mx233_mx28.patch
create mode 100644 patches/linux/3.5/0413-pengutronix-mx28-mmc_spi_Pull_out_common_DMA_parts_from_MXS_MMC.patch
create mode 100644 patches/linux/3.5/0414-pengutronix-mx28-spi_Add_DMA_support_into_SPI_driver.patch
create mode 100644 patches/linux/3.5/0415-pengutronix-mx28-spi_Add_SSP_SPI_device_tree_documentation.patch
create mode 100644 patches/linux/3.5/0416-pengutronix-mx28_Add_SPI_pinmux_into_imx28_dtsi.patch
create mode 100644 patches/linux/3.5/0417-pengutronix-mx28-Add_SPI_ressources.patch
diff --git a/buildroot/target/device/armadeus/apf28/apf28-linux-3.5.config b/buildroot/target/device/armadeus/apf28/apf28-linux-3.5.config
index 15f272c..54c5792 100644
--- a/buildroot/target/device/armadeus/apf28/apf28-linux-3.5.config
+++ b/buildroot/target/device/armadeus/apf28/apf28-linux-3.5.config
@@ -98,6 +98,7 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MXS=y
CONFIG_SPI=y
CONFIG_SPI_BITBANG=m
+CONFIG_SPI_MXS=y
CONFIG_SPI_SPIDEV=m
CONFIG_GPIO_SYSFS=y
CONFIG_HWMON=m
diff --git a/patches/linux/3.5/0403-armadeus-Add-apf28-dts-files.patch b/patches/linux/3.5/0403-armadeus-Add-apf28-dts-files.patch
index 92a36bb..681522f 100644
--- a/patches/linux/3.5/0403-armadeus-Add-apf28-dts-files.patch
+++ b/patches/linux/3.5/0403-armadeus-Add-apf28-dts-files.patch
@@ -2,7 +2,7 @@ Index: linux-3.5/arch/arm/boot/dts/imx28-apf28.dts
===================================================================
--- /dev/null
+++ linux-3.5/arch/arm/boot/dts/imx28-apf28.dts
-@@ -0,0 +1,82 @@
+@@ -0,0 +1,119 @@
+/*
+ * Copyright 2012 Armadeus Systems - <su...@ar...>
+ *
@@ -64,6 +64,33 @@ Index: linux-3.5/arch/arm/boot/dts/imx28-apf28.dts
+ reg = <0xd00000 0xf300000>;
+ };
+ };
++
++ ssp0: ssp@80010000 {
++ compatible = "fsl,imx28-mmc";
++ pinctrl-names = "default";
++ pinctrl-0 = <&mmc0_8bit_pins_a
++ &mmc0_cd_cfg &mmc0_sck_cfg>;
++ bus-width = <8>;
++ wp-gpios = <&gpio2 12 0>;
++ vmmc-supply = <®_vddio_sd0>;
++ status = "okay";
++ };
++
++ ssp2: ssp@80014000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "fsl,imx28-spi";
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins_a>;
++ status = "okay";
++ device@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "spidev";
++ reg = <0>; //Chip select 0
++ spi-max-frequency = <3125000>;
++ };
++ };
+ };
+
+ apbx@80040000 {
@@ -84,4 +111,14 @@ Index: linux-3.5/arch/arm/boot/dts/imx28-apf28.dts
+ status = "okay";
+ };
+ };
++ regulators {
++ compatible = "simple-bus";
++ reg_vddio_sd0: vddio-sd0 {
++ compatible = "regulator-fixed";
++ regulator-name = "vddio-sd0";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio3 28 0>;
++ };
++ };
+};
diff --git a/patches/linux/3.5/0406-armadeus-mx28-add_SPI_support_kconfig.patch b/patches/linux/3.5/0406-armadeus-mx28-add_SPI_support_kconfig.patch
new file mode 100644
index 0000000..70ba0f7
--- /dev/null
+++ b/patches/linux/3.5/0406-armadeus-mx28-add_SPI_support_kconfig.patch
@@ -0,0 +1,12 @@
+Index: linux-3.5/arch/arm/mach-mxs/Kconfig
+===================================================================
+--- linux-3.5.orig/arch/arm/mach-mxs/Kconfig
++++ linux-3.5/arch/arm/mach-mxs/Kconfig
+@@ -10,6 +10,7 @@ config SOC_IMX23
+ select ARM_AMBA
+ select CPU_ARM926T
+ select HAVE_PWM
++ select MXS_HAVE_PLATFORM_MXS_SPI
+ select PINCTRL_IMX23
+
+ config SOC_IMX28
diff --git a/patches/linux/3.5/0407-pengutronix-mx28-Move_SSP_register_definitions_into_separate_file.patch b/patches/linux/3.5/0407-pengutronix-mx28-Move_SSP_register_definitions_into_separate_file.patch
new file mode 100644
index 0000000..b4c1676
--- /dev/null
+++ b/patches/linux/3.5/0407-pengutronix-mx28-Move_SSP_register_definitions_into_separate_file.patch
@@ -0,0 +1,254 @@
+Move the definitions into separate file so separate SPI driver can be
+implemented. The SSP controller in MXS can act both as a MMC host and
+as a SPI host.
+
+Based on previous attempt by:
+Fabio Estevam <fab...@fr...>
+
+Signed-off-by: Fabio Estevam <fab...@fr...>
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ drivers/mmc/host/mxs-mmc.c | 87 ++--------------------------------
+ include/linux/spi/mxs-spi.h | 109 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 112 insertions(+), 84 deletions(-)
+ create mode 100644 include/linux/spi/mxs-spi.h
+
+diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
+index a51f930..26c95dc 100644
+--- a/drivers/mmc/host/mxs-mmc.c
++++ b/drivers/mmc/host/mxs-mmc.c
+@@ -45,87 +45,10 @@
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/stmp_device.h>
+ #include <linux/mmc/mxs-mmc.h>
++#include <linux/spi/mxs-spi.h>
+
+ #define DRIVER_NAME "mxs-mmc"
+
+-/* card detect polling timeout */
+-#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
+-
+-#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
+-
+-/* SSP registers */
+-#define HW_SSP_CTRL0 0x000
+-#define BM_SSP_CTRL0_RUN (1 << 29)
+-#define BM_SSP_CTRL0_SDIO_IRQ_CHECK (1 << 28)
+-#define BM_SSP_CTRL0_IGNORE_CRC (1 << 26)
+-#define BM_SSP_CTRL0_READ (1 << 25)
+-#define BM_SSP_CTRL0_DATA_XFER (1 << 24)
+-#define BP_SSP_CTRL0_BUS_WIDTH (22)
+-#define BM_SSP_CTRL0_BUS_WIDTH (0x3 << 22)
+-#define BM_SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
+-#define BM_SSP_CTRL0_LONG_RESP (1 << 19)
+-#define BM_SSP_CTRL0_GET_RESP (1 << 17)
+-#define BM_SSP_CTRL0_ENABLE (1 << 16)
+-#define BP_SSP_CTRL0_XFER_COUNT (0)
+-#define BM_SSP_CTRL0_XFER_COUNT (0xffff)
+-#define HW_SSP_CMD0 0x010
+-#define BM_SSP_CMD0_DBL_DATA_RATE_EN (1 << 25)
+-#define BM_SSP_CMD0_SLOW_CLKING_EN (1 << 22)
+-#define BM_SSP_CMD0_CONT_CLKING_EN (1 << 21)
+-#define BM_SSP_CMD0_APPEND_8CYC (1 << 20)
+-#define BP_SSP_CMD0_BLOCK_SIZE (16)
+-#define BM_SSP_CMD0_BLOCK_SIZE (0xf << 16)
+-#define BP_SSP_CMD0_BLOCK_COUNT (8)
+-#define BM_SSP_CMD0_BLOCK_COUNT (0xff << 8)
+-#define BP_SSP_CMD0_CMD (0)
+-#define BM_SSP_CMD0_CMD (0xff)
+-#define HW_SSP_CMD1 0x020
+-#define HW_SSP_XFER_SIZE 0x030
+-#define HW_SSP_BLOCK_SIZE 0x040
+-#define BP_SSP_BLOCK_SIZE_BLOCK_COUNT (4)
+-#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
+-#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
+-#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
+-#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
+-#define BP_SSP_TIMING_TIMEOUT (16)
+-#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
+-#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
+-#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
+-#define BP_SSP_TIMING_CLOCK_RATE (0)
+-#define BM_SSP_TIMING_CLOCK_RATE (0xff)
+-#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
+-#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
+-#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
+-#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
+-#define BM_SSP_CTRL1_RESP_ERR_IRQ_EN (1 << 28)
+-#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ (1 << 27)
+-#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN (1 << 26)
+-#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ (1 << 25)
+-#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN (1 << 24)
+-#define BM_SSP_CTRL1_DATA_CRC_IRQ (1 << 23)
+-#define BM_SSP_CTRL1_DATA_CRC_IRQ_EN (1 << 22)
+-#define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ (1 << 21)
+-#define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ_EN (1 << 20)
+-#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ (1 << 17)
+-#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN (1 << 16)
+-#define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ (1 << 15)
+-#define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN (1 << 14)
+-#define BM_SSP_CTRL1_DMA_ENABLE (1 << 13)
+-#define BM_SSP_CTRL1_POLARITY (1 << 9)
+-#define BP_SSP_CTRL1_WORD_LENGTH (4)
+-#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
+-#define BP_SSP_CTRL1_SSP_MODE (0)
+-#define BM_SSP_CTRL1_SSP_MODE (0xf)
+-#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
+-#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
+-#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
+-#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
+-#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
+-#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
+-#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
+-
+-#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
+-
+ #define MXS_MMC_IRQ_BITS (BM_SSP_CTRL1_SDIO_IRQ | \
+ BM_SSP_CTRL1_RESP_ERR_IRQ | \
+ BM_SSP_CTRL1_RESP_TIMEOUT_IRQ | \
+@@ -135,12 +58,8 @@
+ BM_SSP_CTRL1_RECV_TIMEOUT_IRQ | \
+ BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+
+-#define SSP_PIO_NUM 3
+-
+-enum mxs_mmc_id {
+- IMX23_MMC,
+- IMX28_MMC,
+-};
++/* card detect polling timeout */
++#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
+
+ struct mxs_mmc_host {
+ struct mmc_host *mmc;
+diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
+new file mode 100644
+index 0000000..b7ccd57
+--- /dev/null
++++ b/include/linux/spi/mxs-spi.h
+@@ -0,0 +1,109 @@
++/*
++ * include/linux/spi/mxs-spi.h
++ *
++ * Freescale i.MX233/i.MX28 SPI controller register definition
++ *
++ * Copyright 2008 Embedded Alley Solutions, Inc.
++ * Copyright 2009-2011 Freescale Semiconductor, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#ifndef __LINUX_SPI_MXS_SPI_H__
++#define __LINUX_SPI_MXS_SPI_H__
++
++#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
++
++/* SSP registers */
++#define HW_SSP_CTRL0 0x000
++#define BM_SSP_CTRL0_RUN (1 << 29)
++#define BM_SSP_CTRL0_SDIO_IRQ_CHECK (1 << 28)
++#define BM_SSP_CTRL0_IGNORE_CRC (1 << 26)
++#define BM_SSP_CTRL0_READ (1 << 25)
++#define BM_SSP_CTRL0_DATA_XFER (1 << 24)
++#define BP_SSP_CTRL0_BUS_WIDTH 22
++#define BM_SSP_CTRL0_BUS_WIDTH (0x3 << 22)
++#define BM_SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
++#define BM_SSP_CTRL0_LONG_RESP (1 << 19)
++#define BM_SSP_CTRL0_GET_RESP (1 << 17)
++#define BM_SSP_CTRL0_ENABLE (1 << 16)
++#define BP_SSP_CTRL0_XFER_COUNT 0
++#define BM_SSP_CTRL0_XFER_COUNT 0xffff
++#define HW_SSP_CMD0 0x010
++#define BM_SSP_CMD0_DBL_DATA_RATE_EN (1 << 25)
++#define BM_SSP_CMD0_SLOW_CLKING_EN (1 << 22)
++#define BM_SSP_CMD0_CONT_CLKING_EN (1 << 21)
++#define BM_SSP_CMD0_APPEND_8CYC (1 << 20)
++#define BP_SSP_CMD0_BLOCK_SIZE 16
++#define BM_SSP_CMD0_BLOCK_SIZE (0xf << 16)
++#define BP_SSP_CMD0_BLOCK_COUNT 8
++#define BM_SSP_CMD0_BLOCK_COUNT (0xff << 8)
++#define BP_SSP_CMD0_CMD 0
++#define BM_SSP_CMD0_CMD 0xff
++#define HW_SSP_CMD1 0x020
++#define HW_SSP_XFER_SIZE 0x030
++#define HW_SSP_BLOCK_SIZE 0x040
++#define BP_SSP_BLOCK_SIZE_BLOCK_COUNT 4
++#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
++#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE 0
++#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE 0xf
++#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
++#define BP_SSP_TIMING_TIMEOUT 16
++#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
++#define BP_SSP_TIMING_CLOCK_DIVIDE 8
++#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
++#define BP_SSP_TIMING_CLOCK_RATE 0
++#define BM_SSP_TIMING_CLOCK_RATE 0xff
++#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
++#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
++#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
++#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
++#define BM_SSP_CTRL1_RESP_ERR_IRQ_EN (1 << 28)
++#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ (1 << 27)
++#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN (1 << 26)
++#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ (1 << 25)
++#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN (1 << 24)
++#define BM_SSP_CTRL1_DATA_CRC_IRQ (1 << 23)
++#define BM_SSP_CTRL1_DATA_CRC_IRQ_EN (1 << 22)
++#define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ (1 << 21)
++#define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ_EN (1 << 20)
++#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ (1 << 17)
++#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN (1 << 16)
++#define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ (1 << 15)
++#define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN (1 << 14)
++#define BM_SSP_CTRL1_DMA_ENABLE (1 << 13)
++#define BM_SSP_CTRL1_POLARITY (1 << 9)
++#define BP_SSP_CTRL1_WORD_LENGTH 4
++#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
++#define BP_SSP_CTRL1_SSP_MODE 0
++#define BM_SSP_CTRL1_SSP_MODE 0xf
++#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
++#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
++#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
++#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
++#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
++#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
++#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
++
++#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
++
++#define SSP_PIO_NUM 3
++
++enum mxs_mmc_id {
++ IMX23_MMC,
++ IMX28_MMC,
++};
++
++#endif /* __LINUX_SPI_MXS_SPI_H__ */
+--
+1.7.10.4
+
+
+_______________________________________________
+linux-arm-kernel mailing list
+lin...@li...
+http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+
diff --git a/patches/linux/3.5/0408-pengutronix-mx28-mmc_spi_Rename_IMX2x_MMC_to_IMX2x_SSP.patch b/patches/linux/3.5/0408-pengutronix-mx28-mmc_spi_Rename_IMX2x_MMC_to_IMX2x_SSP.patch
new file mode 100644
index 0000000..1ecabac
--- /dev/null
+++ b/patches/linux/3.5/0408-pengutronix-mx28-mmc_spi_Rename_IMX2x_MMC_to_IMX2x_SSP.patch
@@ -0,0 +1,116 @@
+Since the SSP controller can act as both SPI and MMC host,
+renaming the enum to properly reflect the naming seems
+appropriate.
+
+Based on previous attempt by:
+Fabio Estevam <fab...@fr...>
+
+Signed-off-by: Fabio Estevam <fab...@fr...>
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ drivers/mmc/host/mxs-mmc.c | 18 +++++++++---------
+ include/linux/spi/mxs-spi.h | 8 ++++----
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
+index 26c95dc..e80c2b6 100644
+--- a/drivers/mmc/host/mxs-mmc.c
++++ b/drivers/mmc/host/mxs-mmc.c
+@@ -78,7 +78,7 @@ struct mxs_mmc_host {
+ enum dma_transfer_direction slave_dirn;
+ u32 ssp_pio_words[SSP_PIO_NUM];
+
+- enum mxs_mmc_id devid;
++ enum mxs_ssp_id devid;
+ unsigned char bus_width;
+ spinlock_t lock;
+ int sdio_irq_en;
+@@ -601,22 +601,22 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
+ return true;
+ }
+
+-static struct platform_device_id mxs_mmc_ids[] = {
++static struct platform_device_id mxs_ssp_ids[] = {
+ {
+ .name = "imx23-mmc",
+- .driver_data = IMX23_MMC,
++ .driver_data = IMX23_SSP,
+ }, {
+ .name = "imx28-mmc",
+- .driver_data = IMX28_MMC,
++ .driver_data = IMX28_SSP,
+ }, {
+ /* sentinel */
+ }
+ };
+-MODULE_DEVICE_TABLE(platform, mxs_mmc_ids);
++MODULE_DEVICE_TABLE(platform, mxs_ssp_ids);
+
+ static const struct of_device_id mxs_mmc_dt_ids[] = {
+- { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, },
+- { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, },
++ { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_SSP, },
++ { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_SSP, },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
+@@ -655,7 +655,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+ }
+
+ if (np) {
+- host->devid = (enum mxs_mmc_id) of_id->data;
++ host->devid = (enum mxs_ssp_id) of_id->data;
+ /*
+ * TODO: This is a temporary solution and should be changed
+ * to use generic DMA binding later when the helpers get in.
+@@ -829,7 +829,7 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
+ static struct platform_driver mxs_mmc_driver = {
+ .probe = mxs_mmc_probe,
+ .remove = mxs_mmc_remove,
+- .id_table = mxs_mmc_ids,
++ .id_table = mxs_ssp_ids,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
+index b7ccd57..c08aef5 100644
+--- a/include/linux/spi/mxs-spi.h
++++ b/include/linux/spi/mxs-spi.h
+@@ -24,7 +24,7 @@
+ #ifndef __LINUX_SPI_MXS_SPI_H__
+ #define __LINUX_SPI_MXS_SPI_H__
+
+-#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
++#define ssp_is_old(host) ((host)->devid == IMX23_SSP)
+
+ /* SSP registers */
+ #define HW_SSP_CTRL0 0x000
+@@ -101,9 +101,9 @@
+
+ #define SSP_PIO_NUM 3
+
+-enum mxs_mmc_id {
+- IMX23_MMC,
+- IMX28_MMC,
++enum mxs_ssp_id {
++ IMX23_SSP,
++ IMX28_SSP,
+ };
+
+ #endif /* __LINUX_SPI_MXS_SPI_H__ */
+--
+1.7.10.4
+
+
+_______________________________________________
+linux-arm-kernel mailing list
+lin...@li...
+http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+
diff --git a/patches/linux/3.5/0409-pengutronix-mx28-mmc_spi_Add_necessary_bits_into_mxs-spi-h.patch b/patches/linux/3.5/0409-pengutronix-mx28-mmc_spi_Add_necessary_bits_into_mxs-spi-h.patch
new file mode 100644
index 0000000..2b42796
--- /dev/null
+++ b/patches/linux/3.5/0409-pengutronix-mx28-mmc_spi_Add_necessary_bits_into_mxs-spi-h.patch
@@ -0,0 +1,95 @@
+Add missing register bits and registers into mxs-spi.h .
+These will be used by the SPI driver.
+
+Based on previous attempt by:
+Fabio Estevam <fab...@fr...>
+
+Signed-off-by: Fabio Estevam <fab...@fr...>
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ include/linux/spi/mxs-spi.h | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
+index c08aef5..7dfa1d7 100644
+--- a/include/linux/spi/mxs-spi.h
++++ b/include/linux/spi/mxs-spi.h
+@@ -30,12 +30,14 @@
+ #define HW_SSP_CTRL0 0x000
+ #define BM_SSP_CTRL0_RUN (1 << 29)
+ #define BM_SSP_CTRL0_SDIO_IRQ_CHECK (1 << 28)
++#define BM_SSP_CTRL0_LOCK_CS (1 << 27)
+ #define BM_SSP_CTRL0_IGNORE_CRC (1 << 26)
+ #define BM_SSP_CTRL0_READ (1 << 25)
+ #define BM_SSP_CTRL0_DATA_XFER (1 << 24)
+ #define BP_SSP_CTRL0_BUS_WIDTH 22
+ #define BM_SSP_CTRL0_BUS_WIDTH (0x3 << 22)
+ #define BM_SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
++#define BM_SSP_CTRL0_WAIT_FOR_CMD (1 << 20)
+ #define BM_SSP_CTRL0_LONG_RESP (1 << 19)
+ #define BM_SSP_CTRL0_GET_RESP (1 << 17)
+ #define BM_SSP_CTRL0_ENABLE (1 << 16)
+@@ -64,8 +66,12 @@
+ #define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
+ #define BP_SSP_TIMING_CLOCK_DIVIDE 8
+ #define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
++#define BF_SSP_TIMING_CLOCK_DIVIDE(v) \
++ (((v) << 8) & BM_SSP_TIMING_CLOCK_DIVIDE)
+ #define BP_SSP_TIMING_CLOCK_RATE 0
+ #define BM_SSP_TIMING_CLOCK_RATE 0xff
++#define BF_SSP_TIMING_CLOCK_RATE(v) \
++ (((v) << 0) & BM_SSP_TIMING_CLOCK_RATE)
+ #define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
+ #define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
+ #define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
+@@ -84,11 +90,26 @@
+ #define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ (1 << 15)
+ #define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN (1 << 14)
+ #define BM_SSP_CTRL1_DMA_ENABLE (1 << 13)
++#define BM_SSP_CTRL1_PHASE (1 << 10)
+ #define BM_SSP_CTRL1_POLARITY (1 << 9)
+ #define BP_SSP_CTRL1_WORD_LENGTH 4
+ #define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
++#define BF_SSP_CTRL1_WORD_LENGTH(v) \
++ (((v) << 4) & BM_SSP_CTRL1_WORD_LENGTH)
++#define BV_SSP_CTRL1_WORD_LENGTH__FOUR_BITS 0x3
++#define BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS 0x7
++#define BV_SSP_CTRL1_WORD_LENGTH__SIXTEEN_BITS 0xF
+ #define BP_SSP_CTRL1_SSP_MODE 0
+ #define BM_SSP_CTRL1_SSP_MODE 0xf
++#define BF_SSP_CTRL1_SSP_MODE(v) \
++ (((v) << 0) & BM_SSP_CTRL1_SSP_MODE)
++#define BV_SSP_CTRL1_SSP_MODE__SPI 0x0
++#define BV_SSP_CTRL1_SSP_MODE__SSI 0x1
++#define BV_SSP_CTRL1_SSP_MODE__SD_MMC 0x3
++#define BV_SSP_CTRL1_SSP_MODE__MS 0x4
++
++#define HW_SSP_DATA(h) (ssp_is_old(h) ? 0x070 : 0x090)
++
+ #define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
+ #define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
+ #define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
+@@ -96,6 +117,7 @@
+ #define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
+ #define BM_SSP_STATUS_CARD_DETECT (1 << 28)
+ #define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
++#define BM_SSP_STATUS_FIFO_EMPTY (1 << 5)
+
+ #define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
+
+--
+1.7.10.4
+
+
+_______________________________________________
+linux-arm-kernel mailing list
+lin...@li...
+http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+
diff --git a/patches/linux/3.5/0410-pengutronix-mx28-mmc_spi_Pull_out_parts_shared_between_MMC_and_SPI.patch b/patches/linux/3.5/0410-pengutronix-mx28-mmc_spi_Pull_out_parts_shared_between_MMC_and_SPI.patch
new file mode 100644
index 0000000..0ce2f71
--- /dev/null
+++ b/patches/linux/3.5/0410-pengutronix-mx28-mmc_spi_Pull_out_parts_shared_between_MMC_and_SPI.patch
@@ -0,0 +1,381 @@
+Abstract out the common part of private data shared between MMC
+and SPI. These shall later allow to use common clock configuration
+function.
+
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Fabio Estevam <fab...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ drivers/mmc/host/mxs-mmc.c | 107 ++++++++++++++++++++++++-------------------
+ include/linux/spi/mxs-spi.h | 8 ++++
+ 2 files changed, 67 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
+index e80c2b6..7b85e03 100644
+--- a/drivers/mmc/host/mxs-mmc.c
++++ b/drivers/mmc/host/mxs-mmc.c
+@@ -62,23 +62,20 @@
+ #define MXS_MMC_DETECT_TIMEOUT (HZ/2)
+
+ struct mxs_mmc_host {
++ struct mxs_ssp ssp;
++
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+
+- void __iomem *base;
+ int dma_channel;
+- struct clk *clk;
+- unsigned int clk_rate;
+-
+ struct dma_chan *dmach;
+ struct mxs_dma_data dma_data;
+ unsigned int dma_dir;
+ enum dma_transfer_direction slave_dirn;
+ u32 ssp_pio_words[SSP_PIO_NUM];
+
+- enum mxs_ssp_id devid;
+ unsigned char bus_width;
+ spinlock_t lock;
+ int sdio_irq_en;
+@@ -98,16 +95,18 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
+ static int mxs_mmc_get_cd(struct mmc_host *mmc)
+ {
+ struct mxs_mmc_host *host = mmc_priv(mmc);
++ struct mxs_ssp *ssp = &host->ssp;
+
+- return !(readl(host->base + HW_SSP_STATUS(host)) &
++ return !(readl(ssp->base + HW_SSP_STATUS(ssp)) &
+ BM_SSP_STATUS_CARD_DETECT);
+ }
+
+ static void mxs_mmc_reset(struct mxs_mmc_host *host)
+ {
++ struct mxs_ssp *ssp = &host->ssp;
+ u32 ctrl0, ctrl1;
+
+- stmp_reset_block(host->base);
++ stmp_reset_block(ssp->base);
+
+ ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
+ ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
+@@ -123,15 +122,15 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
+ writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
+ BF_SSP(2, TIMING_CLOCK_DIVIDE) |
+ BF_SSP(0, TIMING_CLOCK_RATE),
+- host->base + HW_SSP_TIMING(host));
++ ssp->base + HW_SSP_TIMING(ssp));
+
+ if (host->sdio_irq_en) {
+ ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+ ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN;
+ }
+
+- writel(ctrl0, host->base + HW_SSP_CTRL0);
+- writel(ctrl1, host->base + HW_SSP_CTRL1(host));
++ writel(ctrl0, ssp->base + HW_SSP_CTRL0);
++ writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp));
+ }
+
+ static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
+@@ -142,15 +141,16 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
+ struct mmc_command *cmd = host->cmd;
+ struct mmc_data *data = host->data;
+ struct mmc_request *mrq = host->mrq;
++ struct mxs_ssp *ssp = &host->ssp;
+
+ if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
+ if (mmc_resp_type(cmd) & MMC_RSP_136) {
+- cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
+- cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
+- cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
+- cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
++ cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
++ cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp));
++ cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp));
++ cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp));
+ } else {
+- cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
++ cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
+ }
+ }
+
+@@ -189,13 +189,14 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
+ struct mxs_mmc_host *host = dev_id;
+ struct mmc_command *cmd = host->cmd;
+ struct mmc_data *data = host->data;
++ struct mxs_ssp *ssp = &host->ssp;
+ u32 stat;
+
+ spin_lock(&host->lock);
+
+- stat = readl(host->base + HW_SSP_CTRL1(host));
++ stat = readl(ssp->base + HW_SSP_CTRL1(ssp));
+ writel(stat & MXS_MMC_IRQ_BITS,
+- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
++ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
+
+ if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
+ mmc_signal_sdio_irq(host->mmc);
+@@ -359,6 +360,8 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
+ unsigned int data_size = 0, log2_blksz;
+ unsigned int blocks = data->blocks;
+
++ struct mxs_ssp *ssp = &host->ssp;
++
+ u32 ignore_crc, get_resp, long_resp, read;
+ u32 ctrl0, cmd0, cmd1, val;
+
+@@ -401,15 +404,15 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
+ blocks = 1;
+
+ /* xfer count, block size and count need to be set differently */
+- if (ssp_is_old(host)) {
++ if (ssp_is_old(ssp)) {
+ ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
+ cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
+ BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
+ } else {
+- writel(data_size, host->base + HW_SSP_XFER_SIZE);
++ writel(data_size, ssp->base + HW_SSP_XFER_SIZE);
+ writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
+ BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
+- host->base + HW_SSP_BLOCK_SIZE);
++ ssp->base + HW_SSP_BLOCK_SIZE);
+ }
+
+ if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
+@@ -424,11 +427,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
+ }
+
+ /* set the timeout count */
+- timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
+- val = readl(host->base + HW_SSP_TIMING(host));
++ timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns);
++ val = readl(ssp->base + HW_SSP_TIMING(ssp));
+ val &= ~(BM_SSP_TIMING_TIMEOUT);
+ val |= BF_SSP(timeout, TIMING_TIMEOUT);
+- writel(val, host->base + HW_SSP_TIMING(host));
++ writel(val, ssp->base + HW_SSP_TIMING(ssp));
+
+ /* pio */
+ host->ssp_pio_words[0] = ctrl0;
+@@ -493,11 +496,12 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+
+ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
+ {
++ struct mxs_ssp *ssp = &host->ssp;
+ unsigned int ssp_clk, ssp_sck;
+ u32 clock_divide, clock_rate;
+ u32 val;
+
+- ssp_clk = clk_get_rate(host->clk);
++ ssp_clk = clk_get_rate(ssp->clk);
+
+ for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
+ clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
+@@ -514,13 +518,13 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
+
+ ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
+
+- val = readl(host->base + HW_SSP_TIMING(host));
++ val = readl(ssp->base + HW_SSP_TIMING(ssp));
+ val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
+ val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
+ val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
+- writel(val, host->base + HW_SSP_TIMING(host));
++ writel(val, ssp->base + HW_SSP_TIMING(ssp));
+
+- host->clk_rate = ssp_sck;
++ ssp->clk_rate = ssp_sck;
+
+ dev_dbg(mmc_dev(host->mmc),
+ "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
+@@ -545,6 +549,7 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ {
+ struct mxs_mmc_host *host = mmc_priv(mmc);
++ struct mxs_ssp *ssp = &host->ssp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+@@ -553,19 +558,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+
+ if (enable) {
+ writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
+- host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
+ writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
+- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
++ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
+
+- if (readl(host->base + HW_SSP_STATUS(host)) &
++ if (readl(ssp->base + HW_SSP_STATUS(ssp)) &
+ BM_SSP_STATUS_SDIO_IRQ)
+ mmc_signal_sdio_irq(host->mmc);
+
+ } else {
+ writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
+- host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
+- host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
++ ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
+ }
+
+ spin_unlock_irqrestore(&host->lock, flags);
+@@ -626,6 +631,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+ struct pinctrl *pinctrl;
+ int ret = 0, irq_err, irq_dma;
+ dma_cap_mask_t mask;
++ struct mxs_ssp *ssp;
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+@@ -639,14 +645,16 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ host = mmc_priv(mmc);
+- host->base = devm_request_and_ioremap(&pdev->dev, iores);
+- if (!host->base) {
++ ssp = &host->ssp;
++ ssp->dev = &pdev->dev;
++ ssp->base = devm_request_and_ioremap(&pdev->dev, iores);
++ if (!ssp->base) {
+ ret = -EADDRNOTAVAIL;
+ goto out_mmc_free;
+ }
+
+ if (np) {
+- host->devid = (enum mxs_ssp_id) of_id->data;
++ ssp->devid = (enum mxs_ssp_id) of_id->data;
+ /*
+ * TODO: This is a temporary solution and should be changed
+ * to use generic DMA binding later when the helpers get in.
+@@ -659,7 +667,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+ goto out_mmc_free;
+ }
+ } else {
+- host->devid = pdev->id_entry->driver_data;
++ ssp->devid = pdev->id_entry->driver_data;
+ host->dma_channel = dmares->start;
+ }
+
+@@ -672,12 +680,12 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+ goto out_mmc_free;
+ }
+
+- host->clk = clk_get(&pdev->dev, NULL);
+- if (IS_ERR(host->clk)) {
+- ret = PTR_ERR(host->clk);
++ ssp->clk = clk_get(&pdev->dev, NULL);
++ if (IS_ERR(ssp->clk)) {
++ ret = PTR_ERR(ssp->clk);
+ goto out_mmc_free;
+ }
+- clk_prepare_enable(host->clk);
++ clk_prepare_enable(ssp->clk);
+
+ mxs_mmc_reset(host);
+
+@@ -719,8 +727,8 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+
+ mmc->max_segs = 52;
+ mmc->max_blk_size = 1 << 0xf;
+- mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
+- mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
++ mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
++ mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
+ mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
+
+ platform_set_drvdata(pdev, mmc);
+@@ -744,8 +752,8 @@ out_free_dma:
+ if (host->dmach)
+ dma_release_channel(host->dmach);
+ out_clk_put:
+- clk_disable_unprepare(host->clk);
+- clk_put(host->clk);
++ clk_disable_unprepare(ssp->clk);
++ clk_put(ssp->clk);
+ out_mmc_free:
+ mmc_free_host(mmc);
+ return ret;
+@@ -755,6 +763,7 @@ static int mxs_mmc_remove(struct platform_device *pdev)
+ {
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct mxs_mmc_host *host = mmc_priv(mmc);
++ struct mxs_ssp *ssp = &host->ssp;
+
+ mmc_remove_host(mmc);
+
+@@ -763,8 +772,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
+ if (host->dmach)
+ dma_release_channel(host->dmach);
+
+- clk_disable_unprepare(host->clk);
+- clk_put(host->clk);
++ clk_disable_unprepare(ssp->clk);
++ clk_put(ssp->clk);
+
+ mmc_free_host(mmc);
+
+@@ -776,11 +785,12 @@ static int mxs_mmc_suspend(struct device *dev)
+ {
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mxs_mmc_host *host = mmc_priv(mmc);
++ struct mxs_ssp *ssp = &host->ssp;
+ int ret = 0;
+
+ ret = mmc_suspend_host(mmc);
+
+- clk_disable_unprepare(host->clk);
++ clk_disable_unprepare(ssp->clk);
+
+ return ret;
+ }
+@@ -789,9 +799,10 @@ static int mxs_mmc_resume(struct device *dev)
+ {
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct mxs_mmc_host *host = mmc_priv(mmc);
++ struct mxs_ssp *ssp = &host->ssp;
+ int ret = 0;
+
+- clk_prepare_enable(host->clk);
++ clk_prepare_enable(ssp->clk);
+
+ ret = mmc_resume_host(mmc);
+
+diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
+index 7dfa1d7..475f69f 100644
+--- a/include/linux/spi/mxs-spi.h
++++ b/include/linux/spi/mxs-spi.h
+@@ -128,4 +128,12 @@ enum mxs_ssp_id {
+ IMX28_SSP,
+ };
+
++struct mxs_ssp {
++ struct device *dev;
++ void __iomem *base;
++ struct clk *clk;
++ unsigned int clk_rate;
++ enum mxs_ssp_id devid;
++};
++
+ #endif /* __LINUX_SPI_MXS_SPI_H__ */
+--
+1.7.10.4
+
+
+_______________________________________________
+linux-arm-kernel mailing list
+lin...@li...
+http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+
diff --git a/patches/linux/3.5/0411-pengutronix-mx28-mmc_spi_Pull_out_the_SSP_clock_configuration_function.patch b/patches/linux/3.5/0411-pengutronix-mx28-mmc_spi_Pull_out_the_SSP_clock_configuration_function.patch
new file mode 100644
index 0000000..f167901
--- /dev/null
+++ b/patches/linux/3.5/0411-pengutronix-mx28-mmc_spi_Pull_out_the_SSP_clock_configuration_function.patch
@@ -0,0 +1,179 @@
+Pull out the MMC clock configuration function and make it
+into SSP clock configuration function, so it can be used by
+the SPI driver too.
+
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Fabio Estevam <fab...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ drivers/clk/mxs/Makefile | 2 +-
+ drivers/clk/mxs/clk-ssp.c | 62 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/mmc/host/mxs-mmc.c | 39 +--------------------------
+ include/linux/spi/mxs-spi.h | 2 ++
+ 4 files changed, 66 insertions(+), 39 deletions(-)
+ create mode 100644 drivers/clk/mxs/clk-ssp.c
+
+diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile
+index 7bedeec..a6a2223 100644
+--- a/drivers/clk/mxs/Makefile
++++ b/drivers/clk/mxs/Makefile
+@@ -2,7 +2,7 @@
+ # Makefile for mxs specific clk
+ #
+
+-obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o
++obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o clk-ssp.o
+
+ obj-$(CONFIG_SOC_IMX23) += clk-imx23.o
+ obj-$(CONFIG_SOC_IMX28) += clk-imx28.o
+diff --git a/drivers/clk/mxs/clk-ssp.c b/drivers/clk/mxs/clk-ssp.c
+new file mode 100644
+index 0000000..af7bdbf
+--- /dev/null
++++ b/drivers/clk/mxs/clk-ssp.c
+@@ -0,0 +1,62 @@
++/*
++ * Copyright 2012 DENX Software Engineering, GmbH
++ *
++ * Pulled from code:
++ * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
++ * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
++ *
++ * Copyright 2008 Embedded Alley Solutions, Inc.
++ * Copyright 2009-2011 Freescale Semiconductor, Inc.
++ *
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/spi/mxs-spi.h>
++
++void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate)
++{
++ unsigned int ssp_clk, ssp_sck;
++ u32 clock_divide, clock_rate;
++ u32 val;
++
++ ssp_clk = clk_get_rate(ssp->clk);
++
++ for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
++ clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
++ clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0;
++ if (clock_rate <= 255)
++ break;
++ }
++
++ if (clock_divide > 254) {
++ dev_err(ssp->dev,
++ "%s: cannot set clock to %d\n", __func__, rate);
++ return;
++ }
++
++ ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
++
++ val = readl(ssp->base + HW_SSP_TIMING(ssp));
++ val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
++ val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
++ val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
++ writel(val, ssp->base + HW_SSP_TIMING(ssp));
++
++ ssp->clk_rate = ssp_sck;
++
++ dev_dbg(ssp->dev,
++ "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
++ __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate);
++}
++EXPORT_SYMBOL_GPL(mxs_ssp_set_clk_rate);
+diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
+index 7b85e03..0813340 100644
+--- a/drivers/mmc/host/mxs-mmc.c
++++ b/drivers/mmc/host/mxs-mmc.c
+@@ -501,43 +501,6 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ mxs_mmc_start_cmd(host, mrq->cmd);
+ }
+
+-static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
+-{
+- struct mxs_ssp *ssp = &host->ssp;
+- unsigned int ssp_clk, ssp_sck;
+- u32 clock_divide, clock_rate;
+- u32 val;
+-
+- ssp_clk = clk_get_rate(ssp->clk);
+-
+- for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
+- clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
+- clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0;
+- if (clock_rate <= 255)
+- break;
+- }
+-
+- if (clock_divide > 254) {
+- dev_err(mmc_dev(host->mmc),
+- "%s: cannot set clock to %d\n", __func__, rate);
+- return;
+- }
+-
+- ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
+-
+- val = readl(ssp->base + HW_SSP_TIMING(ssp));
+- val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
+- val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
+- val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
+- writel(val, ssp->base + HW_SSP_TIMING(ssp));
+-
+- ssp->clk_rate = ssp_sck;
+-
+- dev_dbg(mmc_dev(host->mmc),
+- "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
+- __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate);
+-}
+-
+ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct mxs_mmc_host *host = mmc_priv(mmc);
+@@ -550,7 +513,7 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ host->bus_width = 0;
+
+ if (ios->clock)
+- mxs_mmc_set_clk_rate(host, ios->clock);
++ mxs_ssp_set_clk_rate(&host->ssp, ios->clock);
+ }
+
+ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
+index 475f69f..d07f8dc 100644
+--- a/include/linux/spi/mxs-spi.h
++++ b/include/linux/spi/mxs-spi.h
+@@ -136,4 +136,6 @@ struct mxs_ssp {
+ enum mxs_ssp_id devid;
+ };
+
++void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate);
++
+ #endif /* __LINUX_SPI_MXS_SPI_H__ */
+--
+1.7.10.4
+
+
+_______________________________________________
+linux-arm-kernel mailing list
+lin...@li...
+http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+
diff --git a/patches/linux/3.5/0412-pengutronix-mx28-spi_Add_SPI_driver_for_mx233_mx28.patch b/patches/linux/3.5/0412-pengutronix-mx28-spi_Add_SPI_driver_for_mx233_mx28.patch
new file mode 100644
index 0000000..fc35acc
--- /dev/null
+++ b/patches/linux/3.5/0412-pengutronix-mx28-spi_Add_SPI_driver_for_mx233_mx28.patch
@@ -0,0 +1,503 @@
+This is slightly reworked version of the SPI driver.
+Support for DT has been added and it's been converted
+to queued API.
+
+Based on previous attempt by:
+Fabio Estevam <fab...@fr...>
+
+Signed-off-by: Fabio Estevam <fab...@fr...>
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ drivers/spi/Kconfig | 7 +
+ drivers/spi/Makefile | 1 +
+ drivers/spi/spi-mxs.c | 431 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 439 insertions(+)
+ create mode 100644 drivers/spi/spi-mxs.c
+
+V3: Drop mxs_spi_cleanup()
+ Set "hz" unconditionally to dev->max_speed_hz and then trim it down.
+ Add comment about how Freescale is recycling random bits in CTRL0 register.
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 5f84b55..6992b30 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -364,6 +364,13 @@ config SPI_STMP3XXX
+ help
+ SPI driver for Freescale STMP37xx/378x SoC SSP interface
+
++config SPI_MXS
++ tristate "Freescale MXS SPI controller"
++ depends on ARCH_MXS
++ select STMP_DEVICE
++ help
++ SPI driver for Freescale MXS devices.
++
+ config SPI_TEGRA
+ tristate "Nvidia Tegra SPI controller"
+ depends on ARCH_TEGRA && (TEGRA_SYSTEM_DMA || TEGRA20_APB_DMA)
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 3920dcf..3b72d87 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -36,6 +36,7 @@ obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
+ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
+ obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
+ obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
++obj-$(CONFIG_SPI_MXS) += spi-mxs.o
+ obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
+ obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
+ obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
+diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
+new file mode 100644
+index 0000000..7bf826f
+--- /dev/null
++++ b/drivers/spi/spi-mxs.c
+@@ -0,0 +1,431 @@
++/*
++ * Freescale MXS SPI master driver
++ *
++ * Copyright 2012 DENX Software Engineering, GmbH.
++ * Copyright 2012 Freescale Semiconductor, Inc.
++ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
++ *
++ * Rework and transition to new API by:
++ * Marek Vasut <ma...@de...>
++ *
++ * Based on previous attempt by:
++ * Fabio Estevam <fab...@fr...>
++ *
++ * Based on code from U-Boot bootloader by:
++ * Marek Vasut <ma...@de...>
++ *
++ * Based on spi-stmp.c, which is:
++ * Author: Dmitry Pervushin <di...@em...>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * 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/kernel.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_gpio.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmaengine.h>
++#include <linux/highmem.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/completion.h>
++#include <linux/gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/module.h>
++#include <linux/fsl/mxs-dma.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/stmp_device.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/mxs-spi.h>
++
++#define DRIVER_NAME "mxs-spi"
++
++#define SSP_TIMEOUT 1000 /* 1000 ms */
++
++struct mxs_spi {
++ struct mxs_ssp ssp;
++};
++
++static int mxs_spi_setup_transfer(struct spi_device *dev,
++ struct spi_transfer *t)
++{
++ struct mxs_spi *spi = spi_master_get_devdata(dev->master);
++ struct mxs_ssp *ssp = &spi->ssp;
++ uint8_t bits_per_word;
++ uint32_t hz = 0;
++
++ bits_per_word = dev->bits_per_word;
++ if (t && t->bits_per_word)
++ bits_per_word = t->bits_per_word;
++
++ if (bits_per_word != 8) {
++ dev_err(&dev->dev, "%s, unsupported bits_per_word=%d\n",
++ __func__, bits_per_word);
++ return -EINVAL;
++ }
++
++ hz = dev->max_speed_hz;
++ if (t && t->speed_hz)
++ hz = min(hz, t->speed_hz);
++ if (hz == 0) {
++ dev_err(&dev->dev, "Cannot continue with zero clock\n");
++ return -EINVAL;
++ }
++
++ mxs_ssp_set_clk_rate(ssp, hz);
++
++ writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) |
++ BF_SSP_CTRL1_WORD_LENGTH
++ (BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) |
++ ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) |
++ ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0),
++ ssp->base + HW_SSP_CTRL1(ssp));
++
++ writel(0x0, ssp->base + HW_SSP_CMD0);
++ writel(0x0, ssp->base + HW_SSP_CMD1);
++
++ return 0;
++}
++
++static int mxs_spi_setup(struct spi_device *dev)
++{
++ int err = 0;
++
++ if (!dev->bits_per_word)
++ dev->bits_per_word = 8;
++
++ if (dev->mode & ~(SPI_CPOL | SPI_CPHA))
++ return -EINVAL;
++
++ err = mxs_spi_setup_transfer(dev, NULL);
++ if (err) {
++ dev_err(&dev->dev,
++ "Failed to setup transfer, error = %d\n", err);
++ }
++
++ return err;
++}
++
++static uint32_t mxs_spi_cs_to_reg(unsigned cs)
++{
++ uint32_t select = 0;
++
++ /*
++ * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0
++ *
++ * The bits BM_SSP_CTRL0_WAIT_FOR_CMD and BM_SSP_CTRL0_WAIT_FOR_IRQ
++ * in HW_SSP_CTRL0 register do have multiple usage, please refer to
++ * the datasheet for further details. In SPI mode, they are used to
++ * toggle the chip-select lines (nCS pins).
++ */
++ if (cs & 1)
++ select |= BM_SSP_CTRL0_WAIT_FOR_CMD;
++ if (cs & 2)
++ select |= BM_SSP_CTRL0_WAIT_FOR_IRQ;
++
++ return select;
++}
++
++static void mxs_spi_set_cs(struct mxs_spi *spi, unsigned cs)
++{
++ const uint32_t mask =
++ BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ;
++ uint32_t select;
++ struct mxs_ssp *ssp = &spi->ssp;
++
++ writel(mask, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
++ select = mxs_spi_cs_to_reg(cs);
++ writel(select, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++}
++
++static inline void mxs_spi_enable(struct mxs_spi *spi)
++{
++ struct mxs_ssp *ssp = &spi->ssp;
++
++ writel(BM_SSP_CTRL0_LOCK_CS,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++ writel(BM_SSP_CTRL0_IGNORE_CRC,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
++}
++
++static inline void mxs_spi_disable(struct mxs_spi *spi)
++{
++ struct mxs_ssp *ssp = &spi->ssp;
++
++ writel(BM_SSP_CTRL0_LOCK_CS,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
++ writel(BM_SSP_CTRL0_IGNORE_CRC,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++}
++
++static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set)
++{
++ unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT);
++ struct mxs_ssp *ssp = &spi->ssp;
++ uint32_t reg;
++
++ while (1) {
++ reg = readl_relaxed(ssp->base + offset);
++
++ if (set && ((reg & mask) == mask))
++ break;
++
++ if (!set && ((~reg & mask) == mask))
++ break;
++
++ udelay(1);
++
++ if (time_after(jiffies, timeout))
++ return -ETIMEDOUT;
++ }
++ return 0;
++}
++
++static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
++ unsigned char *buf, int len,
++ int *first, int *last, int write)
++{
++ struct mxs_ssp *ssp = &spi->ssp;
++
++ if (*first)
++ mxs_spi_enable(spi);
++
++ mxs_spi_set_cs(spi, cs);
++
++ while (len--) {
++ if (*last && len == 0)
++ mxs_spi_disable(spi);
++
++ if (ssp->devid == IMX23_SSP) {
++ writel(BM_SSP_CTRL0_XFER_COUNT,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
++ writel(1,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++ } else {
++ writel(1, ssp->base + HW_SSP_XFER_SIZE);
++ }
++
++ if (write)
++ writel(BM_SSP_CTRL0_READ,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
++ else
++ writel(BM_SSP_CTRL0_READ,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++
++ writel(BM_SSP_CTRL0_RUN,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++
++ if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1))
++ return -ETIMEDOUT;
++
++ if (write)
++ writel(*buf, ssp->base + HW_SSP_DATA(ssp));
++
++ writel(BM_SSP_CTRL0_DATA_XFER,
++ ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
++
++ if (!write) {
++ if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp),
++ BM_SSP_STATUS_FIFO_EMPTY, 0))
++ return -ETIMEDOUT;
++
++ *buf = (readl(ssp->base + HW_SSP_DATA(ssp)) & 0xff);
++ }
++
++ if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 0))
++ return -ETIMEDOUT;
++
++ buf++;
++ }
++
++ if (len <= 0)
++ return 0;
++
++ return -ETIMEDOUT;
++}
++
++static int mxs_spi_transfer_one(struct spi_master *master,
++ struct spi_message *m)
++{
++ struct mxs_spi *spi = spi_master_get_devdata(master);
++ struct mxs_ssp *ssp = &spi->ssp;
++ int first, last;
++ struct spi_transfer *t, *tmp_t;
++ int status = 0;
++ int cs;
++
++ first = last = 0;
++
++ cs = m->spi->chip_select;
++
++ list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) {
++
++ status = mxs_spi_setup_transfer(m->spi, t);
++ if (status)
++ break;
++
++ if (&t->transfer_list == m->transfers.next)
++ first = 1;
++ if (&t->transfer_list == m->transfers.prev)
++ last = 1;
++ if (t->rx_buf && t->tx_buf) {
++ dev_err(ssp->dev,
++ "Cannot send and receive simultaneously\n");
++ status = -EINVAL;
++ break;
++ }
++
++ if (t->tx_buf)
++ status = mxs_spi_txrx_pio(spi, cs, (void *)t->tx_buf,
++ t->len, &first, &last, 1);
++ if (t->rx_buf)
++ status = mxs_spi_txrx_pio(spi, cs, t->rx_buf,
++ t->len, &first, &last, 0);
++
++ m->actual_length += t->len;
++ if (status)
++ break;
++
++ first = last = 0;
++ }
++
++ m->status = 0;
++ spi_finalize_current_message(master);
++
++ return status;
++}
++
++static const struct of_device_id mxs_spi_dt_ids[] = {
++ { .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, },
++ { .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mxs_spi_dt_ids);
++
++static int __devinit mxs_spi_probe(struct platform_device *pdev)
++{
++ const struct of_device_id *of_id =
++ of_match_device(mxs_spi_dt_ids, &pdev->dev);
++ struct device_node *np = pdev->dev.of_node;
++ struct spi_master *master;
++ struct mxs_spi *spi;
++ struct mxs_ssp *ssp;
++ struct resource *iores;
++ struct pinctrl *pinctrl;
++ struct clk *clk;
++ void __iomem *base;
++ int devid;
++ int ret = 0;
++
++ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!iores)
++ return -EINVAL;
++
++ base = devm_request_and_ioremap(&pdev->dev, iores);
++ if (!base)
++ return -EADDRNOTAVAIL;
++
++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++ if (IS_ERR(pinctrl))
++ return PTR_ERR(pinctrl);
++
++ clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(clk))
++ return PTR_ERR(clk);
++
++ if (np)
++ devid = (enum mxs_ssp_id) of_id->data;
++ else
++ devid = pdev->id_entry->driver_data;
++
++ master = spi_alloc_master(&pdev->dev, sizeof(*spi));
++ if (!master)
++ return -ENOMEM;
++
++ master->transfer_one_message = mxs_spi_transfer_one;
++ master->setup = mxs_spi_setup;
++ master->mode_bits = SPI_CPOL | SPI_CPHA;
++ master->num_chipselect = 3;
++ master->dev.of_node = np;
++ master->flags = SPI_MASTER_HALF_DUPLEX;
++
++ spi = spi_master_get_devdata(master);
++ ssp = &spi->ssp;
++ ssp->dev = &pdev->dev;
++ ssp->clk = clk;
++ ssp->base = base;
++ ssp->devid = devid;
++
++ clk_prepare_enable(ssp->clk);
++ ssp->clk_rate = clk_get_rate(ssp->clk) / 1000;
++
++ stmp_reset_block(ssp->base);
++
++ platform_set_drvdata(pdev, master);
++
++ ret = spi_register_master(master);
++ if (ret) {
++ dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);
++ goto out_master_free;
++ }
++
++ return 0;
++
++out_master_free:
++ platform_set_drvdata(pdev, NULL);
++ clk_disable_unprepare(ssp->clk);
++ spi_master_put(master);
++ return ret;
++}
++
++static int __devexit mxs_spi_remove(struct platform_device *pdev)
++{
++ struct spi_master *master;
++ struct mxs_spi *spi;
++ struct mxs_ssp *ssp;
++
++ master = platform_get_drvdata(pdev);
++ spi = spi_master_get_devdata(master);
++ ssp = &spi->ssp;
++
++ spi_unregister_master(master);
++
++ platform_set_drvdata(pdev, NULL);
++
++ clk_disable_unprepare(ssp->clk);
++
++ spi_master_put(master);
++
++ return 0;
++}
++
++static struct platform_driver mxs_spi_driver = {
++ .probe = mxs_spi_probe,
++ .remove = __devexit_p(mxs_spi_remove),
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = mxs_spi_dt_ids,
++ },
++};
++
++module_platform_driver(mxs_spi_driver);
++
++MODULE_AUTHOR("Marek Vasut <ma...@de...>");
++MODULE_DESCRIPTION("MXS SPI master driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:mxs-spi");
+--
+1.7.10.4
+
+
+_______________________________________________
+linux-arm-kernel mailing list
+lin...@li...
+http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+
diff --git a/patches/linux/3.5/0413-pengutronix-mx28-mmc_spi_Pull_out_common_DMA_parts_from_MXS_MMC.patch b/patches/linux/3.5/0413-pengutronix-mx28-mmc_spi_Pull_out_common_DMA_parts_from_MXS_MMC.patch
new file mode 100644
index 0000000..a8add37
--- /dev/null
+++ b/patches/linux/3.5/0413-pengutronix-mx28-mmc_spi_Pull_out_common_DMA_parts_from_MXS_MMC.patch
@@ -0,0 +1,318 @@
+
+These parts will be used by the MXS SPI driver too.
+
+Signed-off-by: Marek Vasut <ma...@de...>
+Cc: Attila Kinali <at...@ki...>
+Cc: Chris Ball <cj...@la...>
+CC: Dong Aisheng <b2...@fr...>
+Cc: Fabio Estevam <fab...@fr...>
+Cc: Grant Likely <gra...@se...>
+Cc: Linux ARM kernel <lin...@li...>
+Cc: Mark Brown <br...@op...>
+CC: Shawn Guo <sha...@li...>
+---
+ drivers/mmc/host/mxs-mmc.c | 88 +++++++++++++++++++++----------------------
+ drivers/spi/spi-mxs.c | 1 -
+ include/linux/spi/mxs-spi.h | 9 +++++
+ 3 files changed, 51 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
+index 0813340..4da9966 100644
+--- a/drivers/mmc/host/mxs-mmc.c
++++ b/drivers/mmc/host/mxs-mmc.c
+@@ -41,7 +41,6 @@
+ #include <linux/gpio.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/module.h>
+-#include <linux/fsl/mxs-dma.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/stmp_device.h>
+ #include <linux/mmc/mxs-mmc.h>
+@@ -69,13 +68,6 @@ struct mxs_mmc_host {
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+
+- int dma_channel;
+- struct dma_chan *dmach;
+- struct mxs_dma_data dma_data;
+- unsigned int dma_dir;
+- enum dm...
[truncated message content] |