diff options
33 files changed, 2114 insertions, 1260 deletions
diff --git a/Documentation/devicetree/bindings/spi/mxs-spi.txt b/Documentation/devicetree/bindings/spi/mxs-spi.txt new file mode 100644 index 000000000000..e2e13957c2a4 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/mxs-spi.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | * Freescale MX233/MX28 SSP/SPI | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "fsl,<soc>-spi", where soc is "imx23" or "imx28" | ||
5 | - reg: Offset and length of the register set for the device | ||
6 | - interrupts: Should contain SSP interrupts (error irq first, dma irq second) | ||
7 | - fsl,ssp-dma-channel: APBX DMA channel for the SSP | ||
8 | |||
9 | Optional properties: | ||
10 | - clock-frequency : Input clock frequency to the SPI block in Hz. | ||
11 | Default is 160000000 Hz. | ||
12 | |||
13 | Example: | ||
14 | |||
15 | ssp0: ssp@80010000 { | ||
16 | #address-cells = <1>; | ||
17 | #size-cells = <0>; | ||
18 | compatible = "fsl,imx28-spi"; | ||
19 | reg = <0x80010000 0x2000>; | ||
20 | interrupts = <96 82>; | ||
21 | fsl,ssp-dma-channel = <0>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index e782add2e457..d2c33d0f533e 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt | |||
@@ -21,6 +21,9 @@ assumption that board specific platform code will be used to manage | |||
21 | chip selects. Individual drivers can define additional properties to | 21 | chip selects. Individual drivers can define additional properties to |
22 | support describing the chip select layout. | 22 | support describing the chip select layout. |
23 | 23 | ||
24 | Optional property: | ||
25 | - num-cs : total number of chipselects | ||
26 | |||
24 | SPI slave nodes must be children of the SPI master node and can | 27 | SPI slave nodes must be children of the SPI master node and can |
25 | contain the following properties. | 28 | contain the following properties. |
26 | - reg - (required) chip select address of device. | 29 | - reg - (required) chip select address of device. |
diff --git a/Documentation/devicetree/bindings/spi/spi-gpio.txt b/Documentation/devicetree/bindings/spi/spi-gpio.txt new file mode 100644 index 000000000000..8a824be15754 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-gpio.txt | |||
@@ -0,0 +1,29 @@ | |||
1 | SPI-GPIO devicetree bindings | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: should be set to "spi-gpio" | ||
6 | - #address-cells: should be set to <0x1> | ||
7 | - ranges | ||
8 | - gpio-sck: GPIO spec for the SCK line to use | ||
9 | - gpio-miso: GPIO spec for the MISO line to use | ||
10 | - gpio-mosi: GPIO spec for the MOSI line to use | ||
11 | - cs-gpios: GPIOs to use for chipselect lines | ||
12 | - num-chipselects: number of chipselect lines | ||
13 | |||
14 | Example: | ||
15 | |||
16 | spi { | ||
17 | compatible = "spi-gpio"; | ||
18 | #address-cells = <0x1>; | ||
19 | ranges; | ||
20 | |||
21 | gpio-sck = <&gpio 95 0>; | ||
22 | gpio-miso = <&gpio 98 0>; | ||
23 | gpio-mosi = <&gpio 97 0>; | ||
24 | cs-gpios = <&gpio 125 0>; | ||
25 | num-chipselects = <1>; | ||
26 | |||
27 | /* clients */ | ||
28 | }; | ||
29 | |||
diff --git a/Documentation/devicetree/bindings/spi/spi-sc18is602.txt b/Documentation/devicetree/bindings/spi/spi-sc18is602.txt new file mode 100644 index 000000000000..02f9033270a2 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-sc18is602.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | NXP SC18IS602/SCIS603 | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Should be one of | ||
5 | "nxp,sc18is602" | ||
6 | "nxp,sc18is602b" | ||
7 | "nxp,sc18is603" | ||
8 | - reg: I2C bus address | ||
9 | |||
10 | Optional properties: | ||
11 | - clock-frequency : external oscillator clock frequency. If not | ||
12 | specified, the SC18IS602 default frequency (7372000) will be used. | ||
13 | |||
14 | The clock-frequency property is relevant and needed only if the chip has an | ||
15 | external oscillator (SC18IS603). | ||
16 | |||
17 | Example: | ||
18 | |||
19 | sc18is603@28 { | ||
20 | compatible = "nxp,sc18is603"; | ||
21 | reg = <0x28>; | ||
22 | clock-frequency = <14744000>; | ||
23 | } | ||
diff --git a/Documentation/devicetree/bindings/spi/spi_pl022.txt b/Documentation/devicetree/bindings/spi/spi_pl022.txt index 306ec3ff3c0e..f158fd31cfda 100644 --- a/Documentation/devicetree/bindings/spi/spi_pl022.txt +++ b/Documentation/devicetree/bindings/spi/spi_pl022.txt | |||
@@ -6,7 +6,29 @@ Required properties: | |||
6 | - interrupts : Should contain SPI controller interrupt | 6 | - interrupts : Should contain SPI controller interrupt |
7 | 7 | ||
8 | Optional properties: | 8 | Optional properties: |
9 | - num-cs : total number of chipselects | ||
9 | - cs-gpios : should specify GPIOs used for chipselects. | 10 | - cs-gpios : should specify GPIOs used for chipselects. |
10 | The gpios will be referred to as reg = <index> in the SPI child nodes. | 11 | The gpios will be referred to as reg = <index> in the SPI child nodes. |
11 | If unspecified, a single SPI device without a chip select can be used. | 12 | If unspecified, a single SPI device without a chip select can be used. |
13 | - pl022,autosuspend-delay : delay in ms following transfer completion before | ||
14 | the runtime power management system suspends the | ||
15 | device. A setting of 0 indicates no delay and the | ||
16 | device will be suspended immediately | ||
17 | - pl022,rt : indicates the controller should run the message pump with realtime | ||
18 | priority to minimise the transfer latency on the bus (boolean) | ||
19 | |||
20 | |||
21 | SPI slave nodes must be children of the SPI master node and can | ||
22 | contain the following properties. | ||
23 | |||
24 | - pl022,interface : interface type: | ||
25 | 0: SPI | ||
26 | 1: Texas Instruments Synchronous Serial Frame Format | ||
27 | 2: Microwire (Half Duplex) | ||
28 | - pl022,com-mode : polling, interrupt or dma | ||
29 | - pl022,rx-level-trig : Rx FIFO watermark level | ||
30 | - pl022,tx-level-trig : Tx FIFO watermark level | ||
31 | - pl022,ctrl-len : Microwire interface: Control length | ||
32 | - pl022,wait-state : Microwire interface: Wait state | ||
33 | - pl022,duplex : Microwire interface: Full/Half duplex | ||
12 | 34 | ||
diff --git a/Documentation/spi/spi-sc18is602 b/Documentation/spi/spi-sc18is602 new file mode 100644 index 000000000000..a45702865a38 --- /dev/null +++ b/Documentation/spi/spi-sc18is602 | |||
@@ -0,0 +1,36 @@ | |||
1 | Kernel driver spi-sc18is602 | ||
2 | =========================== | ||
3 | |||
4 | Supported chips: | ||
5 | * NXP SI18IS602/602B/603 | ||
6 | Datasheet: http://www.nxp.com/documents/data_sheet/SC18IS602_602B_603.pdf | ||
7 | |||
8 | Author: | ||
9 | Guenter Roeck <linux@roeck-us.net> | ||
10 | |||
11 | |||
12 | Description | ||
13 | ----------- | ||
14 | |||
15 | This driver provides connects a NXP SC18IS602/603 I2C-bus to SPI bridge to the | ||
16 | kernel's SPI core subsystem. | ||
17 | |||
18 | The driver does not probe for supported chips, since the SI18IS602/603 does not | ||
19 | support Chip ID registers. You will have to instantiate the devices explicitly. | ||
20 | Please see Documentation/i2c/instantiating-devices for details. | ||
21 | |||
22 | |||
23 | Usage Notes | ||
24 | ----------- | ||
25 | |||
26 | This driver requires the I2C adapter driver to support raw I2C messages. I2C | ||
27 | adapter drivers which can only handle the SMBus protocol are not supported. | ||
28 | |||
29 | The maximum SPI message size supported by SC18IS602/603 is 200 bytes. Attempts | ||
30 | to initiate longer transfers will fail with -EINVAL. EEPROM read operations and | ||
31 | similar large accesses have to be split into multiple chunks of no more than | ||
32 | 200 bytes per SPI message (128 bytes of data per message is recommended). This | ||
33 | means that programs such as "cp" or "od", which automatically use large block | ||
34 | sizes to access a device, can not be used directly to read data from EEPROM. | ||
35 | Programs such as dd, where the block size can be specified, should be used | ||
36 | instead. | ||
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index ef6f602b7e48..b8efac4daed8 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
@@ -1557,9 +1557,6 @@ static struct u300_mux_hog u300_mux_hogs[] = { | |||
1557 | .dev = &uart0_device.dev, | 1557 | .dev = &uart0_device.dev, |
1558 | }, | 1558 | }, |
1559 | { | 1559 | { |
1560 | .dev = &pl022_device.dev, | ||
1561 | }, | ||
1562 | { | ||
1563 | .dev = &mmcsd_device.dev, | 1560 | .dev = &mmcsd_device.dev, |
1564 | }, | 1561 | }, |
1565 | }; | 1562 | }; |
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile index 7bedeec08524..a6a22237e860 100644 --- a/drivers/clk/mxs/Makefile +++ b/drivers/clk/mxs/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for mxs specific clk | 2 | # Makefile for mxs specific clk |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o | 5 | obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o clk-ssp.o |
6 | 6 | ||
7 | obj-$(CONFIG_SOC_IMX23) += clk-imx23.o | 7 | obj-$(CONFIG_SOC_IMX23) += clk-imx23.o |
8 | obj-$(CONFIG_SOC_IMX28) += clk-imx28.o | 8 | 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 000000000000..af7bdbf9ebd7 --- /dev/null +++ b/drivers/clk/mxs/clk-ssp.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright 2012 DENX Software Engineering, GmbH | ||
3 | * | ||
4 | * Pulled from code: | ||
5 | * Portions copyright (C) 2003 Russell King, PXA MMCI Driver | ||
6 | * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver | ||
7 | * | ||
8 | * Copyright 2008 Embedded Alley Solutions, Inc. | ||
9 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * The code contained herein is licensed under the GNU General Public | ||
12 | * License. You may obtain a copy of the GNU General Public License | ||
13 | * Version 2 or later at the following locations: | ||
14 | * | ||
15 | * http://www.opensource.org/licenses/gpl-license.html | ||
16 | * http://www.gnu.org/copyleft/gpl.html | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/spi/mxs-spi.h> | ||
26 | |||
27 | void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate) | ||
28 | { | ||
29 | unsigned int ssp_clk, ssp_sck; | ||
30 | u32 clock_divide, clock_rate; | ||
31 | u32 val; | ||
32 | |||
33 | ssp_clk = clk_get_rate(ssp->clk); | ||
34 | |||
35 | for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { | ||
36 | clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); | ||
37 | clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0; | ||
38 | if (clock_rate <= 255) | ||
39 | break; | ||
40 | } | ||
41 | |||
42 | if (clock_divide > 254) { | ||
43 | dev_err(ssp->dev, | ||
44 | "%s: cannot set clock to %d\n", __func__, rate); | ||
45 | return; | ||
46 | } | ||
47 | |||
48 | ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); | ||
49 | |||
50 | val = readl(ssp->base + HW_SSP_TIMING(ssp)); | ||
51 | val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); | ||
52 | val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); | ||
53 | val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); | ||
54 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); | ||
55 | |||
56 | ssp->clk_rate = ssp_sck; | ||
57 | |||
58 | dev_dbg(ssp->dev, | ||
59 | "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", | ||
60 | __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate); | ||
61 | } | ||
62 | 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 ad3fcea1269e..bb4c2bf04d09 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -41,91 +41,13 @@ | |||
41 | #include <linux/gpio.h> | 41 | #include <linux/gpio.h> |
42 | #include <linux/regulator/consumer.h> | 42 | #include <linux/regulator/consumer.h> |
43 | #include <linux/module.h> | 43 | #include <linux/module.h> |
44 | #include <linux/fsl/mxs-dma.h> | ||
45 | #include <linux/pinctrl/consumer.h> | 44 | #include <linux/pinctrl/consumer.h> |
46 | #include <linux/stmp_device.h> | 45 | #include <linux/stmp_device.h> |
47 | #include <linux/mmc/mxs-mmc.h> | 46 | #include <linux/mmc/mxs-mmc.h> |
47 | #include <linux/spi/mxs-spi.h> | ||
48 | 48 | ||
49 | #define DRIVER_NAME "mxs-mmc" | 49 | #define DRIVER_NAME "mxs-mmc" |
50 | 50 | ||
51 | /* card detect polling timeout */ | ||
52 | #define MXS_MMC_DETECT_TIMEOUT (HZ/2) | ||
53 | |||
54 | #define ssp_is_old(host) ((host)->devid == IMX23_MMC) | ||
55 | |||
56 | /* SSP registers */ | ||
57 | #define HW_SSP_CTRL0 0x000 | ||
58 | #define BM_SSP_CTRL0_RUN (1 << 29) | ||
59 | #define BM_SSP_CTRL0_SDIO_IRQ_CHECK (1 << 28) | ||
60 | #define BM_SSP_CTRL0_IGNORE_CRC (1 << 26) | ||
61 | #define BM_SSP_CTRL0_READ (1 << 25) | ||
62 | #define BM_SSP_CTRL0_DATA_XFER (1 << 24) | ||
63 | #define BP_SSP_CTRL0_BUS_WIDTH (22) | ||
64 | #define BM_SSP_CTRL0_BUS_WIDTH (0x3 << 22) | ||
65 | #define BM_SSP_CTRL0_WAIT_FOR_IRQ (1 << 21) | ||
66 | #define BM_SSP_CTRL0_LONG_RESP (1 << 19) | ||
67 | #define BM_SSP_CTRL0_GET_RESP (1 << 17) | ||
68 | #define BM_SSP_CTRL0_ENABLE (1 << 16) | ||
69 | #define BP_SSP_CTRL0_XFER_COUNT (0) | ||
70 | #define BM_SSP_CTRL0_XFER_COUNT (0xffff) | ||
71 | #define HW_SSP_CMD0 0x010 | ||
72 | #define BM_SSP_CMD0_DBL_DATA_RATE_EN (1 << 25) | ||
73 | #define BM_SSP_CMD0_SLOW_CLKING_EN (1 << 22) | ||
74 | #define BM_SSP_CMD0_CONT_CLKING_EN (1 << 21) | ||
75 | #define BM_SSP_CMD0_APPEND_8CYC (1 << 20) | ||
76 | #define BP_SSP_CMD0_BLOCK_SIZE (16) | ||
77 | #define BM_SSP_CMD0_BLOCK_SIZE (0xf << 16) | ||
78 | #define BP_SSP_CMD0_BLOCK_COUNT (8) | ||
79 | #define BM_SSP_CMD0_BLOCK_COUNT (0xff << 8) | ||
80 | #define BP_SSP_CMD0_CMD (0) | ||
81 | #define BM_SSP_CMD0_CMD (0xff) | ||
82 | #define HW_SSP_CMD1 0x020 | ||
83 | #define HW_SSP_XFER_SIZE 0x030 | ||
84 | #define HW_SSP_BLOCK_SIZE 0x040 | ||
85 | #define BP_SSP_BLOCK_SIZE_BLOCK_COUNT (4) | ||
86 | #define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) | ||
87 | #define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0) | ||
88 | #define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf) | ||
89 | #define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070) | ||
90 | #define BP_SSP_TIMING_TIMEOUT (16) | ||
91 | #define BM_SSP_TIMING_TIMEOUT (0xffff << 16) | ||
92 | #define BP_SSP_TIMING_CLOCK_DIVIDE (8) | ||
93 | #define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) | ||
94 | #define BP_SSP_TIMING_CLOCK_RATE (0) | ||
95 | #define BM_SSP_TIMING_CLOCK_RATE (0xff) | ||
96 | #define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080) | ||
97 | #define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) | ||
98 | #define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) | ||
99 | #define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) | ||
100 | #define BM_SSP_CTRL1_RESP_ERR_IRQ_EN (1 << 28) | ||
101 | #define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ (1 << 27) | ||
102 | #define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN (1 << 26) | ||
103 | #define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ (1 << 25) | ||
104 | #define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN (1 << 24) | ||
105 | #define BM_SSP_CTRL1_DATA_CRC_IRQ (1 << 23) | ||
106 | #define BM_SSP_CTRL1_DATA_CRC_IRQ_EN (1 << 22) | ||
107 | #define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ (1 << 21) | ||
108 | #define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ_EN (1 << 20) | ||
109 | #define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ (1 << 17) | ||
110 | #define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN (1 << 16) | ||
111 | #define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ (1 << 15) | ||
112 | #define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN (1 << 14) | ||
113 | #define BM_SSP_CTRL1_DMA_ENABLE (1 << 13) | ||
114 | #define BM_SSP_CTRL1_POLARITY (1 << 9) | ||
115 | #define BP_SSP_CTRL1_WORD_LENGTH (4) | ||
116 | #define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) | ||
117 | #define BP_SSP_CTRL1_SSP_MODE (0) | ||
118 | #define BM_SSP_CTRL1_SSP_MODE (0xf) | ||
119 | #define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0) | ||
120 | #define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0) | ||
121 | #define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0) | ||
122 | #define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0) | ||
123 | #define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100) | ||
124 | #define BM_SSP_STATUS_CARD_DETECT (1 << 28) | ||
125 | #define BM_SSP_STATUS_SDIO_IRQ (1 << 17) | ||
126 | |||
127 | #define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field) | ||
128 | |||
129 | #define MXS_MMC_IRQ_BITS (BM_SSP_CTRL1_SDIO_IRQ | \ | 51 | #define MXS_MMC_IRQ_BITS (BM_SSP_CTRL1_SDIO_IRQ | \ |
130 | BM_SSP_CTRL1_RESP_ERR_IRQ | \ | 52 | BM_SSP_CTRL1_RESP_ERR_IRQ | \ |
131 | BM_SSP_CTRL1_RESP_TIMEOUT_IRQ | \ | 53 | BM_SSP_CTRL1_RESP_TIMEOUT_IRQ | \ |
@@ -135,31 +57,17 @@ | |||
135 | BM_SSP_CTRL1_RECV_TIMEOUT_IRQ | \ | 57 | BM_SSP_CTRL1_RECV_TIMEOUT_IRQ | \ |
136 | BM_SSP_CTRL1_FIFO_OVERRUN_IRQ) | 58 | BM_SSP_CTRL1_FIFO_OVERRUN_IRQ) |
137 | 59 | ||
138 | #define SSP_PIO_NUM 3 | 60 | /* card detect polling timeout */ |
139 | 61 | #define MXS_MMC_DETECT_TIMEOUT (HZ/2) | |
140 | enum mxs_mmc_id { | ||
141 | IMX23_MMC, | ||
142 | IMX28_MMC, | ||
143 | }; | ||
144 | 62 | ||
145 | struct mxs_mmc_host { | 63 | struct mxs_mmc_host { |
64 | struct mxs_ssp ssp; | ||
65 | |||
146 | struct mmc_host *mmc; | 66 | struct mmc_host *mmc; |
147 | struct mmc_request *mrq; | 67 | struct mmc_request *mrq; |
148 | struct mmc_command *cmd; | 68 | struct mmc_command *cmd; |
149 | struct mmc_data *data; | 69 | struct mmc_data *data; |
150 | 70 | ||
151 | void __iomem *base; | ||
152 | int dma_channel; | ||
153 | struct clk *clk; | ||
154 | unsigned int clk_rate; | ||
155 | |||
156 | struct dma_chan *dmach; | ||
157 | struct mxs_dma_data dma_data; | ||
158 | unsigned int dma_dir; | ||
159 | enum dma_transfer_direction slave_dirn; | ||
160 | u32 ssp_pio_words[SSP_PIO_NUM]; | ||
161 | |||
162 | enum mxs_mmc_id devid; | ||
163 | unsigned char bus_width; | 71 | unsigned char bus_width; |
164 | spinlock_t lock; | 72 | spinlock_t lock; |
165 | int sdio_irq_en; | 73 | int sdio_irq_en; |
@@ -186,16 +94,18 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc) | |||
186 | static int mxs_mmc_get_cd(struct mmc_host *mmc) | 94 | static int mxs_mmc_get_cd(struct mmc_host *mmc) |
187 | { | 95 | { |
188 | struct mxs_mmc_host *host = mmc_priv(mmc); | 96 | struct mxs_mmc_host *host = mmc_priv(mmc); |
97 | struct mxs_ssp *ssp = &host->ssp; | ||
189 | 98 | ||
190 | return !(readl(host->base + HW_SSP_STATUS(host)) & | 99 | return !(readl(ssp->base + HW_SSP_STATUS(ssp)) & |
191 | BM_SSP_STATUS_CARD_DETECT); | 100 | BM_SSP_STATUS_CARD_DETECT); |
192 | } | 101 | } |
193 | 102 | ||
194 | static void mxs_mmc_reset(struct mxs_mmc_host *host) | 103 | static void mxs_mmc_reset(struct mxs_mmc_host *host) |
195 | { | 104 | { |
105 | struct mxs_ssp *ssp = &host->ssp; | ||
196 | u32 ctrl0, ctrl1; | 106 | u32 ctrl0, ctrl1; |
197 | 107 | ||
198 | stmp_reset_block(host->base); | 108 | stmp_reset_block(ssp->base); |
199 | 109 | ||
200 | ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; | 110 | ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; |
201 | ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | | 111 | ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | |
@@ -211,15 +121,15 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host) | |||
211 | writel(BF_SSP(0xffff, TIMING_TIMEOUT) | | 121 | writel(BF_SSP(0xffff, TIMING_TIMEOUT) | |
212 | BF_SSP(2, TIMING_CLOCK_DIVIDE) | | 122 | BF_SSP(2, TIMING_CLOCK_DIVIDE) | |
213 | BF_SSP(0, TIMING_CLOCK_RATE), | 123 | BF_SSP(0, TIMING_CLOCK_RATE), |
214 | host->base + HW_SSP_TIMING(host)); | 124 | ssp->base + HW_SSP_TIMING(ssp)); |
215 | 125 | ||
216 | if (host->sdio_irq_en) { | 126 | if (host->sdio_irq_en) { |
217 | ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; | 127 | ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; |
218 | ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN; | 128 | ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN; |
219 | } | 129 | } |
220 | 130 | ||
221 | writel(ctrl0, host->base + HW_SSP_CTRL0); | 131 | writel(ctrl0, ssp->base + HW_SSP_CTRL0); |
222 | writel(ctrl1, host->base + HW_SSP_CTRL1(host)); | 132 | writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp)); |
223 | } | 133 | } |
224 | 134 | ||
225 | static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, | 135 | static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, |
@@ -230,21 +140,22 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host) | |||
230 | struct mmc_command *cmd = host->cmd; | 140 | struct mmc_command *cmd = host->cmd; |
231 | struct mmc_data *data = host->data; | 141 | struct mmc_data *data = host->data; |
232 | struct mmc_request *mrq = host->mrq; | 142 | struct mmc_request *mrq = host->mrq; |
143 | struct mxs_ssp *ssp = &host->ssp; | ||
233 | 144 | ||
234 | if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { | 145 | if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { |
235 | if (mmc_resp_type(cmd) & MMC_RSP_136) { | 146 | if (mmc_resp_type(cmd) & MMC_RSP_136) { |
236 | cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host)); | 147 | cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp)); |
237 | cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host)); | 148 | cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp)); |
238 | cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host)); | 149 | cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp)); |
239 | cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host)); | 150 | cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp)); |
240 | } else { | 151 | } else { |
241 | cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host)); | 152 | cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp)); |
242 | } | 153 | } |
243 | } | 154 | } |
244 | 155 | ||
245 | if (data) { | 156 | if (data) { |
246 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 157 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
247 | data->sg_len, host->dma_dir); | 158 | data->sg_len, ssp->dma_dir); |
248 | /* | 159 | /* |
249 | * If there was an error on any block, we mark all | 160 | * If there was an error on any block, we mark all |
250 | * data blocks as being in error. | 161 | * data blocks as being in error. |
@@ -277,13 +188,14 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) | |||
277 | struct mxs_mmc_host *host = dev_id; | 188 | struct mxs_mmc_host *host = dev_id; |
278 | struct mmc_command *cmd = host->cmd; | 189 | struct mmc_command *cmd = host->cmd; |
279 | struct mmc_data *data = host->data; | 190 | struct mmc_data *data = host->data; |
191 | struct mxs_ssp *ssp = &host->ssp; | ||
280 | u32 stat; | 192 | u32 stat; |
281 | 193 | ||
282 | spin_lock(&host->lock); | 194 | spin_lock(&host->lock); |
283 | 195 | ||
284 | stat = readl(host->base + HW_SSP_CTRL1(host)); | 196 | stat = readl(ssp->base + HW_SSP_CTRL1(ssp)); |
285 | writel(stat & MXS_MMC_IRQ_BITS, | 197 | writel(stat & MXS_MMC_IRQ_BITS, |
286 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); | 198 | ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR); |
287 | 199 | ||
288 | spin_unlock(&host->lock); | 200 | spin_unlock(&host->lock); |
289 | 201 | ||
@@ -312,6 +224,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) | |||
312 | static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( | 224 | static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( |
313 | struct mxs_mmc_host *host, unsigned long flags) | 225 | struct mxs_mmc_host *host, unsigned long flags) |
314 | { | 226 | { |
227 | struct mxs_ssp *ssp = &host->ssp; | ||
315 | struct dma_async_tx_descriptor *desc; | 228 | struct dma_async_tx_descriptor *desc; |
316 | struct mmc_data *data = host->data; | 229 | struct mmc_data *data = host->data; |
317 | struct scatterlist * sgl; | 230 | struct scatterlist * sgl; |
@@ -320,24 +233,24 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( | |||
320 | if (data) { | 233 | if (data) { |
321 | /* data */ | 234 | /* data */ |
322 | dma_map_sg(mmc_dev(host->mmc), data->sg, | 235 | dma_map_sg(mmc_dev(host->mmc), data->sg, |
323 | data->sg_len, host->dma_dir); | 236 | data->sg_len, ssp->dma_dir); |
324 | sgl = data->sg; | 237 | sgl = data->sg; |
325 | sg_len = data->sg_len; | 238 | sg_len = data->sg_len; |
326 | } else { | 239 | } else { |
327 | /* pio */ | 240 | /* pio */ |
328 | sgl = (struct scatterlist *) host->ssp_pio_words; | 241 | sgl = (struct scatterlist *) ssp->ssp_pio_words; |
329 | sg_len = SSP_PIO_NUM; | 242 | sg_len = SSP_PIO_NUM; |
330 | } | 243 | } |
331 | 244 | ||
332 | desc = dmaengine_prep_slave_sg(host->dmach, | 245 | desc = dmaengine_prep_slave_sg(ssp->dmach, |
333 | sgl, sg_len, host->slave_dirn, flags); | 246 | sgl, sg_len, ssp->slave_dirn, flags); |
334 | if (desc) { | 247 | if (desc) { |
335 | desc->callback = mxs_mmc_dma_irq_callback; | 248 | desc->callback = mxs_mmc_dma_irq_callback; |
336 | desc->callback_param = host; | 249 | desc->callback_param = host; |
337 | } else { | 250 | } else { |
338 | if (data) | 251 | if (data) |
339 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 252 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
340 | data->sg_len, host->dma_dir); | 253 | data->sg_len, ssp->dma_dir); |
341 | } | 254 | } |
342 | 255 | ||
343 | return desc; | 256 | return desc; |
@@ -345,6 +258,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( | |||
345 | 258 | ||
346 | static void mxs_mmc_bc(struct mxs_mmc_host *host) | 259 | static void mxs_mmc_bc(struct mxs_mmc_host *host) |
347 | { | 260 | { |
261 | struct mxs_ssp *ssp = &host->ssp; | ||
348 | struct mmc_command *cmd = host->cmd; | 262 | struct mmc_command *cmd = host->cmd; |
349 | struct dma_async_tx_descriptor *desc; | 263 | struct dma_async_tx_descriptor *desc; |
350 | u32 ctrl0, cmd0, cmd1; | 264 | u32 ctrl0, cmd0, cmd1; |
@@ -358,17 +272,17 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) | |||
358 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; | 272 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; |
359 | } | 273 | } |
360 | 274 | ||
361 | host->ssp_pio_words[0] = ctrl0; | 275 | ssp->ssp_pio_words[0] = ctrl0; |
362 | host->ssp_pio_words[1] = cmd0; | 276 | ssp->ssp_pio_words[1] = cmd0; |
363 | host->ssp_pio_words[2] = cmd1; | 277 | ssp->ssp_pio_words[2] = cmd1; |
364 | host->dma_dir = DMA_NONE; | 278 | ssp->dma_dir = DMA_NONE; |
365 | host->slave_dirn = DMA_TRANS_NONE; | 279 | ssp->slave_dirn = DMA_TRANS_NONE; |
366 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); | 280 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); |
367 | if (!desc) | 281 | if (!desc) |
368 | goto out; | 282 | goto out; |
369 | 283 | ||
370 | dmaengine_submit(desc); | 284 | dmaengine_submit(desc); |
371 | dma_async_issue_pending(host->dmach); | 285 | dma_async_issue_pending(ssp->dmach); |
372 | return; | 286 | return; |
373 | 287 | ||
374 | out: | 288 | out: |
@@ -378,6 +292,7 @@ out: | |||
378 | 292 | ||
379 | static void mxs_mmc_ac(struct mxs_mmc_host *host) | 293 | static void mxs_mmc_ac(struct mxs_mmc_host *host) |
380 | { | 294 | { |
295 | struct mxs_ssp *ssp = &host->ssp; | ||
381 | struct mmc_command *cmd = host->cmd; | 296 | struct mmc_command *cmd = host->cmd; |
382 | struct dma_async_tx_descriptor *desc; | 297 | struct dma_async_tx_descriptor *desc; |
383 | u32 ignore_crc, get_resp, long_resp; | 298 | u32 ignore_crc, get_resp, long_resp; |
@@ -399,17 +314,17 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) | |||
399 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; | 314 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; |
400 | } | 315 | } |
401 | 316 | ||
402 | host->ssp_pio_words[0] = ctrl0; | 317 | ssp->ssp_pio_words[0] = ctrl0; |
403 | host->ssp_pio_words[1] = cmd0; | 318 | ssp->ssp_pio_words[1] = cmd0; |
404 | host->ssp_pio_words[2] = cmd1; | 319 | ssp->ssp_pio_words[2] = cmd1; |
405 | host->dma_dir = DMA_NONE; | 320 | ssp->dma_dir = DMA_NONE; |
406 | host->slave_dirn = DMA_TRANS_NONE; | 321 | ssp->slave_dirn = DMA_TRANS_NONE; |
407 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); | 322 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); |
408 | if (!desc) | 323 | if (!desc) |
409 | goto out; | 324 | goto out; |
410 | 325 | ||
411 | dmaengine_submit(desc); | 326 | dmaengine_submit(desc); |
412 | dma_async_issue_pending(host->dmach); | 327 | dma_async_issue_pending(ssp->dmach); |
413 | return; | 328 | return; |
414 | 329 | ||
415 | out: | 330 | out: |
@@ -447,6 +362,8 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
447 | unsigned int data_size = 0, log2_blksz; | 362 | unsigned int data_size = 0, log2_blksz; |
448 | unsigned int blocks = data->blocks; | 363 | unsigned int blocks = data->blocks; |
449 | 364 | ||
365 | struct mxs_ssp *ssp = &host->ssp; | ||
366 | |||
450 | u32 ignore_crc, get_resp, long_resp, read; | 367 | u32 ignore_crc, get_resp, long_resp, read; |
451 | u32 ctrl0, cmd0, cmd1, val; | 368 | u32 ctrl0, cmd0, cmd1, val; |
452 | 369 | ||
@@ -489,15 +406,15 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
489 | blocks = 1; | 406 | blocks = 1; |
490 | 407 | ||
491 | /* xfer count, block size and count need to be set differently */ | 408 | /* xfer count, block size and count need to be set differently */ |
492 | if (ssp_is_old(host)) { | 409 | if (ssp_is_old(ssp)) { |
493 | ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); | 410 | ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); |
494 | cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | | 411 | cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | |
495 | BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); | 412 | BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); |
496 | } else { | 413 | } else { |
497 | writel(data_size, host->base + HW_SSP_XFER_SIZE); | 414 | writel(data_size, ssp->base + HW_SSP_XFER_SIZE); |
498 | writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) | | 415 | writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) | |
499 | BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT), | 416 | BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT), |
500 | host->base + HW_SSP_BLOCK_SIZE); | 417 | ssp->base + HW_SSP_BLOCK_SIZE); |
501 | } | 418 | } |
502 | 419 | ||
503 | if ((cmd->opcode == MMC_STOP_TRANSMISSION) || | 420 | if ((cmd->opcode == MMC_STOP_TRANSMISSION) || |
@@ -512,18 +429,18 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
512 | } | 429 | } |
513 | 430 | ||
514 | /* set the timeout count */ | 431 | /* set the timeout count */ |
515 | timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns); | 432 | timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns); |
516 | val = readl(host->base + HW_SSP_TIMING(host)); | 433 | val = readl(ssp->base + HW_SSP_TIMING(ssp)); |
517 | val &= ~(BM_SSP_TIMING_TIMEOUT); | 434 | val &= ~(BM_SSP_TIMING_TIMEOUT); |
518 | val |= BF_SSP(timeout, TIMING_TIMEOUT); | 435 | val |= BF_SSP(timeout, TIMING_TIMEOUT); |
519 | writel(val, host->base + HW_SSP_TIMING(host)); | 436 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); |
520 | 437 | ||
521 | /* pio */ | 438 | /* pio */ |
522 | host->ssp_pio_words[0] = ctrl0; | 439 | ssp->ssp_pio_words[0] = ctrl0; |
523 | host->ssp_pio_words[1] = cmd0; | 440 | ssp->ssp_pio_words[1] = cmd0; |
524 | host->ssp_pio_words[2] = cmd1; | 441 | ssp->ssp_pio_words[2] = cmd1; |
525 | host->dma_dir = DMA_NONE; | 442 | ssp->dma_dir = DMA_NONE; |
526 | host->slave_dirn = DMA_TRANS_NONE; | 443 | ssp->slave_dirn = DMA_TRANS_NONE; |
527 | desc = mxs_mmc_prep_dma(host, 0); | 444 | desc = mxs_mmc_prep_dma(host, 0); |
528 | if (!desc) | 445 | if (!desc) |
529 | goto out; | 446 | goto out; |
@@ -531,14 +448,14 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
531 | /* append data sg */ | 448 | /* append data sg */ |
532 | WARN_ON(host->data != NULL); | 449 | WARN_ON(host->data != NULL); |
533 | host->data = data; | 450 | host->data = data; |
534 | host->dma_dir = dma_data_dir; | 451 | ssp->dma_dir = dma_data_dir; |
535 | host->slave_dirn = slave_dirn; | 452 | ssp->slave_dirn = slave_dirn; |
536 | desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 453 | desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
537 | if (!desc) | 454 | if (!desc) |
538 | goto out; | 455 | goto out; |
539 | 456 | ||
540 | dmaengine_submit(desc); | 457 | dmaengine_submit(desc); |
541 | dma_async_issue_pending(host->dmach); | 458 | dma_async_issue_pending(ssp->dmach); |
542 | return; | 459 | return; |
543 | out: | 460 | out: |
544 | dev_warn(mmc_dev(host->mmc), | 461 | dev_warn(mmc_dev(host->mmc), |
@@ -579,42 +496,6 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
579 | mxs_mmc_start_cmd(host, mrq->cmd); | 496 | mxs_mmc_start_cmd(host, mrq->cmd); |
580 | } | 497 | } |
581 | 498 | ||
582 | static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) | ||
583 | { | ||
584 | unsigned int ssp_clk, ssp_sck; | ||
585 | u32 clock_divide, clock_rate; | ||
586 | u32 val; | ||
587 | |||
588 | ssp_clk = clk_get_rate(host->clk); | ||
589 | |||
590 | for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { | ||
591 | clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); | ||
592 | clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0; | ||
593 | if (clock_rate <= 255) | ||
594 | break; | ||
595 | } | ||
596 | |||
597 | if (clock_divide > 254) { | ||
598 | dev_err(mmc_dev(host->mmc), | ||
599 | "%s: cannot set clock to %d\n", __func__, rate); | ||
600 | return; | ||
601 | } | ||
602 | |||
603 | ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); | ||
604 | |||
605 | val = readl(host->base + HW_SSP_TIMING(host)); | ||
606 | val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); | ||
607 | val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); | ||
608 | val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); | ||
609 | writel(val, host->base + HW_SSP_TIMING(host)); | ||
610 | |||
611 | host->clk_rate = ssp_sck; | ||
612 | |||
613 | dev_dbg(mmc_dev(host->mmc), | ||
614 | "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", | ||
615 | __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate); | ||
616 | } | ||
617 | |||
618 | static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 499 | static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
619 | { | 500 | { |
620 | struct mxs_mmc_host *host = mmc_priv(mmc); | 501 | struct mxs_mmc_host *host = mmc_priv(mmc); |
@@ -627,12 +508,13 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
627 | host->bus_width = 0; | 508 | host->bus_width = 0; |
628 | 509 | ||
629 | if (ios->clock) | 510 | if (ios->clock) |
630 | mxs_mmc_set_clk_rate(host, ios->clock); | 511 | mxs_ssp_set_clk_rate(&host->ssp, ios->clock); |
631 | } | 512 | } |
632 | 513 | ||
633 | static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | 514 | static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) |
634 | { | 515 | { |
635 | struct mxs_mmc_host *host = mmc_priv(mmc); | 516 | struct mxs_mmc_host *host = mmc_priv(mmc); |
517 | struct mxs_ssp *ssp = &host->ssp; | ||
636 | unsigned long flags; | 518 | unsigned long flags; |
637 | 519 | ||
638 | spin_lock_irqsave(&host->lock, flags); | 520 | spin_lock_irqsave(&host->lock, flags); |
@@ -641,19 +523,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
641 | 523 | ||
642 | if (enable) { | 524 | if (enable) { |
643 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, | 525 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, |
644 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | 526 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); |
645 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, | 527 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, |
646 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); | 528 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); |
647 | } else { | 529 | } else { |
648 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, | 530 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, |
649 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | 531 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); |
650 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, | 532 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, |
651 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); | 533 | ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR); |
652 | } | 534 | } |
653 | 535 | ||
654 | spin_unlock_irqrestore(&host->lock, flags); | 536 | spin_unlock_irqrestore(&host->lock, flags); |
655 | 537 | ||
656 | if (enable && readl(host->base + HW_SSP_STATUS(host)) & | 538 | if (enable && readl(ssp->base + HW_SSP_STATUS(ssp)) & |
657 | BM_SSP_STATUS_SDIO_IRQ) | 539 | BM_SSP_STATUS_SDIO_IRQ) |
658 | mmc_signal_sdio_irq(host->mmc); | 540 | mmc_signal_sdio_irq(host->mmc); |
659 | 541 | ||
@@ -670,34 +552,35 @@ static const struct mmc_host_ops mxs_mmc_ops = { | |||
670 | static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param) | 552 | static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param) |
671 | { | 553 | { |
672 | struct mxs_mmc_host *host = param; | 554 | struct mxs_mmc_host *host = param; |
555 | struct mxs_ssp *ssp = &host->ssp; | ||
673 | 556 | ||
674 | if (!mxs_dma_is_apbh(chan)) | 557 | if (!mxs_dma_is_apbh(chan)) |
675 | return false; | 558 | return false; |
676 | 559 | ||
677 | if (chan->chan_id != host->dma_channel) | 560 | if (chan->chan_id != ssp->dma_channel) |
678 | return false; | 561 | return false; |
679 | 562 | ||
680 | chan->private = &host->dma_data; | 563 | chan->private = &ssp->dma_data; |
681 | 564 | ||
682 | return true; | 565 | return true; |
683 | } | 566 | } |
684 | 567 | ||
685 | static struct platform_device_id mxs_mmc_ids[] = { | 568 | static struct platform_device_id mxs_ssp_ids[] = { |
686 | { | 569 | { |
687 | .name = "imx23-mmc", | 570 | .name = "imx23-mmc", |
688 | .driver_data = IMX23_MMC, | 571 | .driver_data = IMX23_SSP, |
689 | }, { | 572 | }, { |
690 | .name = "imx28-mmc", | 573 | .name = "imx28-mmc", |
691 | .driver_data = IMX28_MMC, | 574 | .driver_data = IMX28_SSP, |
692 | }, { | 575 | }, { |
693 | /* sentinel */ | 576 | /* sentinel */ |
694 | } | 577 | } |
695 | }; | 578 | }; |
696 | MODULE_DEVICE_TABLE(platform, mxs_mmc_ids); | 579 | MODULE_DEVICE_TABLE(platform, mxs_ssp_ids); |
697 | 580 | ||
698 | static const struct of_device_id mxs_mmc_dt_ids[] = { | 581 | static const struct of_device_id mxs_mmc_dt_ids[] = { |
699 | { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, }, | 582 | { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_SSP, }, |
700 | { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, }, | 583 | { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_SSP, }, |
701 | { /* sentinel */ } | 584 | { /* sentinel */ } |
702 | }; | 585 | }; |
703 | MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids); | 586 | MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids); |
@@ -716,6 +599,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
716 | dma_cap_mask_t mask; | 599 | dma_cap_mask_t mask; |
717 | struct regulator *reg_vmmc; | 600 | struct regulator *reg_vmmc; |
718 | enum of_gpio_flags flags; | 601 | enum of_gpio_flags flags; |
602 | struct mxs_ssp *ssp; | ||
719 | 603 | ||
720 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 604 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
721 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 605 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -729,28 +613,30 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
729 | return -ENOMEM; | 613 | return -ENOMEM; |
730 | 614 | ||
731 | host = mmc_priv(mmc); | 615 | host = mmc_priv(mmc); |
732 | host->base = devm_request_and_ioremap(&pdev->dev, iores); | 616 | ssp = &host->ssp; |
733 | if (!host->base) { | 617 | ssp->dev = &pdev->dev; |
618 | ssp->base = devm_request_and_ioremap(&pdev->dev, iores); | ||
619 | if (!ssp->base) { | ||
734 | ret = -EADDRNOTAVAIL; | 620 | ret = -EADDRNOTAVAIL; |
735 | goto out_mmc_free; | 621 | goto out_mmc_free; |
736 | } | 622 | } |
737 | 623 | ||
738 | if (np) { | 624 | if (np) { |
739 | host->devid = (enum mxs_mmc_id) of_id->data; | 625 | ssp->devid = (enum mxs_ssp_id) of_id->data; |
740 | /* | 626 | /* |
741 | * TODO: This is a temporary solution and should be changed | 627 | * TODO: This is a temporary solution and should be changed |
742 | * to use generic DMA binding later when the helpers get in. | 628 | * to use generic DMA binding later when the helpers get in. |
743 | */ | 629 | */ |
744 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", | 630 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", |
745 | &host->dma_channel); | 631 | &ssp->dma_channel); |
746 | if (ret) { | 632 | if (ret) { |
747 | dev_err(mmc_dev(host->mmc), | 633 | dev_err(mmc_dev(host->mmc), |
748 | "failed to get dma channel\n"); | 634 | "failed to get dma channel\n"); |
749 | goto out_mmc_free; | 635 | goto out_mmc_free; |
750 | } | 636 | } |
751 | } else { | 637 | } else { |
752 | host->devid = pdev->id_entry->driver_data; | 638 | ssp->devid = pdev->id_entry->driver_data; |
753 | host->dma_channel = dmares->start; | 639 | ssp->dma_channel = dmares->start; |
754 | } | 640 | } |
755 | 641 | ||
756 | host->mmc = mmc; | 642 | host->mmc = mmc; |
@@ -772,20 +658,20 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
772 | goto out_mmc_free; | 658 | goto out_mmc_free; |
773 | } | 659 | } |
774 | 660 | ||
775 | host->clk = clk_get(&pdev->dev, NULL); | 661 | ssp->clk = clk_get(&pdev->dev, NULL); |
776 | if (IS_ERR(host->clk)) { | 662 | if (IS_ERR(ssp->clk)) { |
777 | ret = PTR_ERR(host->clk); | 663 | ret = PTR_ERR(ssp->clk); |
778 | goto out_mmc_free; | 664 | goto out_mmc_free; |
779 | } | 665 | } |
780 | clk_prepare_enable(host->clk); | 666 | clk_prepare_enable(ssp->clk); |
781 | 667 | ||
782 | mxs_mmc_reset(host); | 668 | mxs_mmc_reset(host); |
783 | 669 | ||
784 | dma_cap_zero(mask); | 670 | dma_cap_zero(mask); |
785 | dma_cap_set(DMA_SLAVE, mask); | 671 | dma_cap_set(DMA_SLAVE, mask); |
786 | host->dma_data.chan_irq = irq_dma; | 672 | ssp->dma_data.chan_irq = irq_dma; |
787 | host->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host); | 673 | ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host); |
788 | if (!host->dmach) { | 674 | if (!ssp->dmach) { |
789 | dev_err(mmc_dev(host->mmc), | 675 | dev_err(mmc_dev(host->mmc), |
790 | "%s: failed to request dma\n", __func__); | 676 | "%s: failed to request dma\n", __func__); |
791 | goto out_clk_put; | 677 | goto out_clk_put; |
@@ -822,9 +708,9 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
822 | 708 | ||
823 | mmc->max_segs = 52; | 709 | mmc->max_segs = 52; |
824 | mmc->max_blk_size = 1 << 0xf; | 710 | mmc->max_blk_size = 1 << 0xf; |
825 | mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff; | 711 | mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff; |
826 | mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff; | 712 | mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff; |
827 | mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); | 713 | mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev); |
828 | 714 | ||
829 | platform_set_drvdata(pdev, mmc); | 715 | platform_set_drvdata(pdev, mmc); |
830 | 716 | ||
@@ -844,11 +730,11 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
844 | return 0; | 730 | return 0; |
845 | 731 | ||
846 | out_free_dma: | 732 | out_free_dma: |
847 | if (host->dmach) | 733 | if (ssp->dmach) |
848 | dma_release_channel(host->dmach); | 734 | dma_release_channel(ssp->dmach); |
849 | out_clk_put: | 735 | out_clk_put: |
850 | clk_disable_unprepare(host->clk); | 736 | clk_disable_unprepare(ssp->clk); |
851 | clk_put(host->clk); | 737 | clk_put(ssp->clk); |
852 | out_mmc_free: | 738 | out_mmc_free: |
853 | mmc_free_host(mmc); | 739 | mmc_free_host(mmc); |
854 | return ret; | 740 | return ret; |
@@ -858,16 +744,17 @@ static int mxs_mmc_remove(struct platform_device *pdev) | |||
858 | { | 744 | { |
859 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 745 | struct mmc_host *mmc = platform_get_drvdata(pdev); |
860 | struct mxs_mmc_host *host = mmc_priv(mmc); | 746 | struct mxs_mmc_host *host = mmc_priv(mmc); |
747 | struct mxs_ssp *ssp = &host->ssp; | ||
861 | 748 | ||
862 | mmc_remove_host(mmc); | 749 | mmc_remove_host(mmc); |
863 | 750 | ||
864 | platform_set_drvdata(pdev, NULL); | 751 | platform_set_drvdata(pdev, NULL); |
865 | 752 | ||
866 | if (host->dmach) | 753 | if (ssp->dmach) |
867 | dma_release_channel(host->dmach); | 754 | dma_release_channel(ssp->dmach); |
868 | 755 | ||
869 | clk_disable_unprepare(host->clk); | 756 | clk_disable_unprepare(ssp->clk); |
870 | clk_put(host->clk); | 757 | clk_put(ssp->clk); |
871 | 758 | ||
872 | mmc_free_host(mmc); | 759 | mmc_free_host(mmc); |
873 | 760 | ||
@@ -879,11 +766,12 @@ static int mxs_mmc_suspend(struct device *dev) | |||
879 | { | 766 | { |
880 | struct mmc_host *mmc = dev_get_drvdata(dev); | 767 | struct mmc_host *mmc = dev_get_drvdata(dev); |
881 | struct mxs_mmc_host *host = mmc_priv(mmc); | 768 | struct mxs_mmc_host *host = mmc_priv(mmc); |
769 | struct mxs_ssp *ssp = &host->ssp; | ||
882 | int ret = 0; | 770 | int ret = 0; |
883 | 771 | ||
884 | ret = mmc_suspend_host(mmc); | 772 | ret = mmc_suspend_host(mmc); |
885 | 773 | ||
886 | clk_disable_unprepare(host->clk); | 774 | clk_disable_unprepare(ssp->clk); |
887 | 775 | ||
888 | return ret; | 776 | return ret; |
889 | } | 777 | } |
@@ -892,9 +780,10 @@ static int mxs_mmc_resume(struct device *dev) | |||
892 | { | 780 | { |
893 | struct mmc_host *mmc = dev_get_drvdata(dev); | 781 | struct mmc_host *mmc = dev_get_drvdata(dev); |
894 | struct mxs_mmc_host *host = mmc_priv(mmc); | 782 | struct mxs_mmc_host *host = mmc_priv(mmc); |
783 | struct mxs_ssp *ssp = &host->ssp; | ||
895 | int ret = 0; | 784 | int ret = 0; |
896 | 785 | ||
897 | clk_prepare_enable(host->clk); | 786 | clk_prepare_enable(ssp->clk); |
898 | 787 | ||
899 | ret = mmc_resume_host(mmc); | 788 | ret = mmc_resume_host(mmc); |
900 | 789 | ||
@@ -910,7 +799,7 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = { | |||
910 | static struct platform_driver mxs_mmc_driver = { | 799 | static struct platform_driver mxs_mmc_driver = { |
911 | .probe = mxs_mmc_probe, | 800 | .probe = mxs_mmc_probe, |
912 | .remove = mxs_mmc_remove, | 801 | .remove = mxs_mmc_remove, |
913 | .id_table = mxs_mmc_ids, | 802 | .id_table = mxs_ssp_ids, |
914 | .driver = { | 803 | .driver = { |
915 | .name = DRIVER_NAME, | 804 | .name = DRIVER_NAME, |
916 | .owner = THIS_MODULE, | 805 | .owner = THIS_MODULE, |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2d198a01a410..ecc31a1f73fc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -325,6 +325,12 @@ config SPI_S3C64XX | |||
325 | help | 325 | help |
326 | SPI driver for Samsung S3C64XX and newer SoCs. | 326 | SPI driver for Samsung S3C64XX and newer SoCs. |
327 | 327 | ||
328 | config SPI_SC18IS602 | ||
329 | tristate "NXP SC18IS602/602B/603 I2C to SPI bridge" | ||
330 | depends on I2C | ||
331 | help | ||
332 | SPI driver for NXP SC18IS602/602B/603 I2C to SPI bridge. | ||
333 | |||
328 | config SPI_SH_MSIOF | 334 | config SPI_SH_MSIOF |
329 | tristate "SuperH MSIOF SPI controller" | 335 | tristate "SuperH MSIOF SPI controller" |
330 | depends on SUPERH && HAVE_CLK | 336 | depends on SUPERH && HAVE_CLK |
@@ -364,11 +370,12 @@ config SPI_STMP3XXX | |||
364 | help | 370 | help |
365 | SPI driver for Freescale STMP37xx/378x SoC SSP interface | 371 | SPI driver for Freescale STMP37xx/378x SoC SSP interface |
366 | 372 | ||
367 | config SPI_TEGRA | 373 | config SPI_MXS |
368 | tristate "Nvidia Tegra SPI controller" | 374 | tristate "Freescale MXS SPI controller" |
369 | depends on ARCH_TEGRA && TEGRA20_APB_DMA | 375 | depends on ARCH_MXS |
376 | select STMP_DEVICE | ||
370 | help | 377 | help |
371 | SPI driver for NVidia Tegra SoCs | 378 | SPI driver for Freescale MXS devices. |
372 | 379 | ||
373 | config SPI_TI_SSP | 380 | config SPI_TI_SSP |
374 | tristate "TI Sequencer Serial Port - SPI Support" | 381 | tristate "TI Sequencer Serial Port - SPI Support" |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 3920dcf4c740..22fd3a7251bc 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -36,6 +36,7 @@ obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o | |||
36 | obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o | 36 | obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o |
37 | obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o | 37 | obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o |
38 | obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o | 38 | obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o |
39 | obj-$(CONFIG_SPI_MXS) += spi-mxs.o | ||
39 | obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o | 40 | obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o |
40 | obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o | 41 | obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o |
41 | obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o | 42 | obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o |
@@ -51,13 +52,13 @@ obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o | |||
51 | spi-s3c24xx-hw-y := spi-s3c24xx.o | 52 | spi-s3c24xx-hw-y := spi-s3c24xx.o |
52 | spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o | 53 | spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o |
53 | obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o | 54 | obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o |
55 | obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o | ||
54 | obj-$(CONFIG_SPI_SH) += spi-sh.o | 56 | obj-$(CONFIG_SPI_SH) += spi-sh.o |
55 | obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o | 57 | obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o |
56 | obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o | 58 | obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o |
57 | obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o | 59 | obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o |
58 | obj-$(CONFIG_SPI_SIRF) += spi-sirf.o | 60 | obj-$(CONFIG_SPI_SIRF) += spi-sirf.o |
59 | obj-$(CONFIG_SPI_STMP3XXX) += spi-stmp.o | 61 | obj-$(CONFIG_SPI_STMP3XXX) += spi-stmp.o |
60 | obj-$(CONFIG_SPI_TEGRA) += spi-tegra.o | ||
61 | obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp.o | 62 | obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp.o |
62 | obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o | 63 | obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o |
63 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o | 64 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o |
diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index c00d00e96ee4..f1fec2a19d10 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c | |||
@@ -307,8 +307,6 @@ static const struct of_device_id altera_spi_match[] = { | |||
307 | {}, | 307 | {}, |
308 | }; | 308 | }; |
309 | MODULE_DEVICE_TABLE(of, altera_spi_match); | 309 | MODULE_DEVICE_TABLE(of, altera_spi_match); |
310 | #else /* CONFIG_OF */ | ||
311 | #define altera_spi_match NULL | ||
312 | #endif /* CONFIG_OF */ | 310 | #endif /* CONFIG_OF */ |
313 | 311 | ||
314 | static struct platform_driver altera_spi_driver = { | 312 | static struct platform_driver altera_spi_driver = { |
@@ -318,7 +316,7 @@ static struct platform_driver altera_spi_driver = { | |||
318 | .name = DRV_NAME, | 316 | .name = DRV_NAME, |
319 | .owner = THIS_MODULE, | 317 | .owner = THIS_MODULE, |
320 | .pm = NULL, | 318 | .pm = NULL, |
321 | .of_match_table = altera_spi_match, | 319 | .of_match_table = of_match_ptr(altera_spi_match), |
322 | }, | 320 | }, |
323 | }; | 321 | }; |
324 | module_platform_driver(altera_spi_driver); | 322 | module_platform_driver(altera_spi_driver); |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 0b56cfc71fab..a2b50c516b31 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/of_device.h> | ||
26 | #include <linux/of_gpio.h> | ||
25 | 27 | ||
26 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/spi_bitbang.h> | 29 | #include <linux/spi/spi_bitbang.h> |
@@ -46,6 +48,7 @@ struct spi_gpio { | |||
46 | struct spi_bitbang bitbang; | 48 | struct spi_bitbang bitbang; |
47 | struct spi_gpio_platform_data pdata; | 49 | struct spi_gpio_platform_data pdata; |
48 | struct platform_device *pdev; | 50 | struct platform_device *pdev; |
51 | int cs_gpios[0]; | ||
49 | }; | 52 | }; |
50 | 53 | ||
51 | /*----------------------------------------------------------------------*/ | 54 | /*----------------------------------------------------------------------*/ |
@@ -89,15 +92,21 @@ struct spi_gpio { | |||
89 | 92 | ||
90 | /*----------------------------------------------------------------------*/ | 93 | /*----------------------------------------------------------------------*/ |
91 | 94 | ||
92 | static inline const struct spi_gpio_platform_data * __pure | 95 | static inline struct spi_gpio * __pure |
93 | spi_to_pdata(const struct spi_device *spi) | 96 | spi_to_spi_gpio(const struct spi_device *spi) |
94 | { | 97 | { |
95 | const struct spi_bitbang *bang; | 98 | const struct spi_bitbang *bang; |
96 | const struct spi_gpio *spi_gpio; | 99 | struct spi_gpio *spi_gpio; |
97 | 100 | ||
98 | bang = spi_master_get_devdata(spi->master); | 101 | bang = spi_master_get_devdata(spi->master); |
99 | spi_gpio = container_of(bang, struct spi_gpio, bitbang); | 102 | spi_gpio = container_of(bang, struct spi_gpio, bitbang); |
100 | return &spi_gpio->pdata; | 103 | return spi_gpio; |
104 | } | ||
105 | |||
106 | static inline struct spi_gpio_platform_data * __pure | ||
107 | spi_to_pdata(const struct spi_device *spi) | ||
108 | { | ||
109 | return &spi_to_spi_gpio(spi)->pdata; | ||
101 | } | 110 | } |
102 | 111 | ||
103 | /* this is #defined to avoid unused-variable warnings when inlining */ | 112 | /* this is #defined to avoid unused-variable warnings when inlining */ |
@@ -210,7 +219,8 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, | |||
210 | 219 | ||
211 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | 220 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) |
212 | { | 221 | { |
213 | unsigned long cs = (unsigned long) spi->controller_data; | 222 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
223 | unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; | ||
214 | 224 | ||
215 | /* set initial clock polarity */ | 225 | /* set initial clock polarity */ |
216 | if (is_active) | 226 | if (is_active) |
@@ -224,12 +234,27 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | |||
224 | 234 | ||
225 | static int spi_gpio_setup(struct spi_device *spi) | 235 | static int spi_gpio_setup(struct spi_device *spi) |
226 | { | 236 | { |
227 | unsigned long cs = (unsigned long) spi->controller_data; | 237 | unsigned int cs; |
228 | int status = 0; | 238 | int status = 0; |
239 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | ||
240 | struct device_node *np = spi->master->dev.of_node; | ||
229 | 241 | ||
230 | if (spi->bits_per_word > 32) | 242 | if (spi->bits_per_word > 32) |
231 | return -EINVAL; | 243 | return -EINVAL; |
232 | 244 | ||
245 | if (np) { | ||
246 | /* | ||
247 | * In DT environments, the CS GPIOs have already been | ||
248 | * initialized from the "cs-gpios" property of the node. | ||
249 | */ | ||
250 | cs = spi_gpio->cs_gpios[spi->chip_select]; | ||
251 | } else { | ||
252 | /* | ||
253 | * ... otherwise, take it from spi->controller_data | ||
254 | */ | ||
255 | cs = (unsigned int) spi->controller_data; | ||
256 | } | ||
257 | |||
233 | if (!spi->controller_state) { | 258 | if (!spi->controller_state) { |
234 | if (cs != SPI_GPIO_NO_CHIPSELECT) { | 259 | if (cs != SPI_GPIO_NO_CHIPSELECT) { |
235 | status = gpio_request(cs, dev_name(&spi->dev)); | 260 | status = gpio_request(cs, dev_name(&spi->dev)); |
@@ -239,8 +264,12 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
239 | !(spi->mode & SPI_CS_HIGH)); | 264 | !(spi->mode & SPI_CS_HIGH)); |
240 | } | 265 | } |
241 | } | 266 | } |
242 | if (!status) | 267 | if (!status) { |
243 | status = spi_bitbang_setup(spi); | 268 | status = spi_bitbang_setup(spi); |
269 | /* in case it was initialized from static board data */ | ||
270 | spi_gpio->cs_gpios[spi->chip_select] = cs; | ||
271 | } | ||
272 | |||
244 | if (status) { | 273 | if (status) { |
245 | if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT) | 274 | if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT) |
246 | gpio_free(cs); | 275 | gpio_free(cs); |
@@ -250,7 +279,8 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
250 | 279 | ||
251 | static void spi_gpio_cleanup(struct spi_device *spi) | 280 | static void spi_gpio_cleanup(struct spi_device *spi) |
252 | { | 281 | { |
253 | unsigned long cs = (unsigned long) spi->controller_data; | 282 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
283 | unsigned int cs = spi_gpio->cs_gpios[spi->chip_select]; | ||
254 | 284 | ||
255 | if (cs != SPI_GPIO_NO_CHIPSELECT) | 285 | if (cs != SPI_GPIO_NO_CHIPSELECT) |
256 | gpio_free(cs); | 286 | gpio_free(cs); |
@@ -313,6 +343,55 @@ done: | |||
313 | return value; | 343 | return value; |
314 | } | 344 | } |
315 | 345 | ||
346 | #ifdef CONFIG_OF | ||
347 | static struct of_device_id spi_gpio_dt_ids[] = { | ||
348 | { .compatible = "spi-gpio" }, | ||
349 | {} | ||
350 | }; | ||
351 | MODULE_DEVICE_TABLE(of, spi_gpio_dt_ids); | ||
352 | |||
353 | static int spi_gpio_probe_dt(struct platform_device *pdev) | ||
354 | { | ||
355 | int ret; | ||
356 | u32 tmp; | ||
357 | struct spi_gpio_platform_data *pdata; | ||
358 | struct device_node *np = pdev->dev.of_node; | ||
359 | const struct of_device_id *of_id = | ||
360 | of_match_device(spi_gpio_dt_ids, &pdev->dev); | ||
361 | |||
362 | if (!of_id) | ||
363 | return 0; | ||
364 | |||
365 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
366 | if (!pdata) | ||
367 | return -ENOMEM; | ||
368 | |||
369 | pdata->sck = of_get_named_gpio(np, "gpio-sck", 0); | ||
370 | pdata->miso = of_get_named_gpio(np, "gpio-miso", 0); | ||
371 | pdata->mosi = of_get_named_gpio(np, "gpio-mosi", 0); | ||
372 | |||
373 | ret = of_property_read_u32(np, "num-chipselects", &tmp); | ||
374 | if (ret < 0) { | ||
375 | dev_err(&pdev->dev, "num-chipselects property not found\n"); | ||
376 | goto error_free; | ||
377 | } | ||
378 | |||
379 | pdata->num_chipselect = tmp; | ||
380 | pdev->dev.platform_data = pdata; | ||
381 | |||
382 | return 1; | ||
383 | |||
384 | error_free: | ||
385 | devm_kfree(&pdev->dev, pdata); | ||
386 | return ret; | ||
387 | } | ||
388 | #else | ||
389 | static inline int spi_gpio_probe_dt(struct platform_device *pdev) | ||
390 | { | ||
391 | return 0; | ||
392 | } | ||
393 | #endif | ||
394 | |||
316 | static int __devinit spi_gpio_probe(struct platform_device *pdev) | 395 | static int __devinit spi_gpio_probe(struct platform_device *pdev) |
317 | { | 396 | { |
318 | int status; | 397 | int status; |
@@ -320,6 +399,13 @@ static int __devinit spi_gpio_probe(struct platform_device *pdev) | |||
320 | struct spi_gpio *spi_gpio; | 399 | struct spi_gpio *spi_gpio; |
321 | struct spi_gpio_platform_data *pdata; | 400 | struct spi_gpio_platform_data *pdata; |
322 | u16 master_flags = 0; | 401 | u16 master_flags = 0; |
402 | bool use_of = 0; | ||
403 | |||
404 | status = spi_gpio_probe_dt(pdev); | ||
405 | if (status < 0) | ||
406 | return status; | ||
407 | if (status > 0) | ||
408 | use_of = 1; | ||
323 | 409 | ||
324 | pdata = pdev->dev.platform_data; | 410 | pdata = pdev->dev.platform_data; |
325 | #ifdef GENERIC_BITBANG | 411 | #ifdef GENERIC_BITBANG |
@@ -331,7 +417,8 @@ static int __devinit spi_gpio_probe(struct platform_device *pdev) | |||
331 | if (status < 0) | 417 | if (status < 0) |
332 | return status; | 418 | return status; |
333 | 419 | ||
334 | master = spi_alloc_master(&pdev->dev, sizeof *spi_gpio); | 420 | master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) + |
421 | (sizeof(int) * SPI_N_CHIPSEL)); | ||
335 | if (!master) { | 422 | if (!master) { |
336 | status = -ENOMEM; | 423 | status = -ENOMEM; |
337 | goto gpio_free; | 424 | goto gpio_free; |
@@ -348,6 +435,23 @@ static int __devinit spi_gpio_probe(struct platform_device *pdev) | |||
348 | master->num_chipselect = SPI_N_CHIPSEL; | 435 | master->num_chipselect = SPI_N_CHIPSEL; |
349 | master->setup = spi_gpio_setup; | 436 | master->setup = spi_gpio_setup; |
350 | master->cleanup = spi_gpio_cleanup; | 437 | master->cleanup = spi_gpio_cleanup; |
438 | #ifdef CONFIG_OF | ||
439 | master->dev.of_node = pdev->dev.of_node; | ||
440 | |||
441 | if (use_of) { | ||
442 | int i; | ||
443 | struct device_node *np = pdev->dev.of_node; | ||
444 | |||
445 | /* | ||
446 | * In DT environments, take the CS GPIO from the "cs-gpios" | ||
447 | * property of the node. | ||
448 | */ | ||
449 | |||
450 | for (i = 0; i < SPI_N_CHIPSEL; i++) | ||
451 | spi_gpio->cs_gpios[i] = | ||
452 | of_get_named_gpio(np, "cs-gpios", i); | ||
453 | } | ||
454 | #endif | ||
351 | 455 | ||
352 | spi_gpio->bitbang.master = spi_master_get(master); | 456 | spi_gpio->bitbang.master = spi_master_get(master); |
353 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | 457 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; |
@@ -408,8 +512,11 @@ static int __devexit spi_gpio_remove(struct platform_device *pdev) | |||
408 | MODULE_ALIAS("platform:" DRIVER_NAME); | 512 | MODULE_ALIAS("platform:" DRIVER_NAME); |
409 | 513 | ||
410 | static struct platform_driver spi_gpio_driver = { | 514 | static struct platform_driver spi_gpio_driver = { |
411 | .driver.name = DRIVER_NAME, | 515 | .driver = { |
412 | .driver.owner = THIS_MODULE, | 516 | .name = DRIVER_NAME, |
517 | .owner = THIS_MODULE, | ||
518 | .of_match_table = of_match_ptr(spi_gpio_dt_ids), | ||
519 | }, | ||
413 | .probe = spi_gpio_probe, | 520 | .probe = spi_gpio_probe, |
414 | .remove = __devexit_p(spi_gpio_remove), | 521 | .remove = __devexit_p(spi_gpio_remove), |
415 | }; | 522 | }; |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index de7ebb65e535..c9a0d8467de6 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -197,6 +197,7 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, | |||
197 | #define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) | 197 | #define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) |
198 | #define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) | 198 | #define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) |
199 | #define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) | 199 | #define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) |
200 | #define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20)) | ||
200 | 201 | ||
201 | #define MX51_ECSPI_INT 0x10 | 202 | #define MX51_ECSPI_INT 0x10 |
202 | #define MX51_ECSPI_INT_TEEN (1 << 0) | 203 | #define MX51_ECSPI_INT_TEEN (1 << 0) |
@@ -287,9 +288,10 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | |||
287 | if (config->mode & SPI_CPHA) | 288 | if (config->mode & SPI_CPHA) |
288 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); | 289 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); |
289 | 290 | ||
290 | if (config->mode & SPI_CPOL) | 291 | if (config->mode & SPI_CPOL) { |
291 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs); | 292 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs); |
292 | 293 | cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs); | |
294 | } | ||
293 | if (config->mode & SPI_CS_HIGH) | 295 | if (config->mode & SPI_CS_HIGH) |
294 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); | 296 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); |
295 | 297 | ||
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 4c63f772780a..0a1e39e94d06 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c | |||
@@ -494,7 +494,7 @@ free_master: | |||
494 | 494 | ||
495 | static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) | 495 | static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) |
496 | { | 496 | { |
497 | struct spi_master *master = dev_get_drvdata(dev); | 497 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); |
498 | struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); | 498 | struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); |
499 | 499 | ||
500 | flush_workqueue(mps->workqueue); | 500 | flush_workqueue(mps->workqueue); |
@@ -503,6 +503,7 @@ static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) | |||
503 | free_irq(mps->irq, mps); | 503 | free_irq(mps->irq, mps); |
504 | if (mps->psc) | 504 | if (mps->psc) |
505 | iounmap(mps->psc); | 505 | iounmap(mps->psc); |
506 | spi_master_put(master); | ||
506 | 507 | ||
507 | return 0; | 508 | return 0; |
508 | } | 509 | } |
diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index 66047156d90d..bd47d262d53f 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c | |||
@@ -481,7 +481,7 @@ static int __devinit mpc52xx_psc_spi_of_probe(struct platform_device *op) | |||
481 | 481 | ||
482 | static int __devexit mpc52xx_psc_spi_of_remove(struct platform_device *op) | 482 | static int __devexit mpc52xx_psc_spi_of_remove(struct platform_device *op) |
483 | { | 483 | { |
484 | struct spi_master *master = dev_get_drvdata(&op->dev); | 484 | struct spi_master *master = spi_master_get(dev_get_drvdata(&op->dev)); |
485 | struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master); | 485 | struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master); |
486 | 486 | ||
487 | flush_workqueue(mps->workqueue); | 487 | flush_workqueue(mps->workqueue); |
@@ -490,6 +490,7 @@ static int __devexit mpc52xx_psc_spi_of_remove(struct platform_device *op) | |||
490 | free_irq(mps->irq, mps); | 490 | free_irq(mps->irq, mps); |
491 | if (mps->psc) | 491 | if (mps->psc) |
492 | iounmap(mps->psc); | 492 | iounmap(mps->psc); |
493 | spi_master_put(master); | ||
493 | 494 | ||
494 | return 0; | 495 | return 0; |
495 | } | 496 | } |
diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index cb3a3830b0a5..045410650212 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c | |||
@@ -454,7 +454,7 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op) | |||
454 | GFP_KERNEL); | 454 | GFP_KERNEL); |
455 | if (!ms->gpio_cs) { | 455 | if (!ms->gpio_cs) { |
456 | rc = -ENOMEM; | 456 | rc = -ENOMEM; |
457 | goto err_alloc; | 457 | goto err_alloc_gpio; |
458 | } | 458 | } |
459 | 459 | ||
460 | for (i = 0; i < ms->gpio_cs_count; i++) { | 460 | for (i = 0; i < ms->gpio_cs_count; i++) { |
@@ -514,12 +514,13 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op) | |||
514 | 514 | ||
515 | err_register: | 515 | err_register: |
516 | dev_err(&ms->master->dev, "initialization failed\n"); | 516 | dev_err(&ms->master->dev, "initialization failed\n"); |
517 | spi_master_put(master); | ||
518 | err_gpio: | 517 | err_gpio: |
519 | while (i-- > 0) | 518 | while (i-- > 0) |
520 | gpio_free(ms->gpio_cs[i]); | 519 | gpio_free(ms->gpio_cs[i]); |
521 | 520 | ||
522 | kfree(ms->gpio_cs); | 521 | kfree(ms->gpio_cs); |
522 | err_alloc_gpio: | ||
523 | spi_master_put(master); | ||
523 | err_alloc: | 524 | err_alloc: |
524 | err_init: | 525 | err_init: |
525 | iounmap(regs); | 526 | iounmap(regs); |
@@ -528,7 +529,7 @@ static int __devinit mpc52xx_spi_probe(struct platform_device *op) | |||
528 | 529 | ||
529 | static int __devexit mpc52xx_spi_remove(struct platform_device *op) | 530 | static int __devexit mpc52xx_spi_remove(struct platform_device *op) |
530 | { | 531 | { |
531 | struct spi_master *master = dev_get_drvdata(&op->dev); | 532 | struct spi_master *master = spi_master_get(dev_get_drvdata(&op->dev)); |
532 | struct mpc52xx_spi *ms = spi_master_get_devdata(master); | 533 | struct mpc52xx_spi *ms = spi_master_get_devdata(master); |
533 | int i; | 534 | int i; |
534 | 535 | ||
@@ -540,8 +541,8 @@ static int __devexit mpc52xx_spi_remove(struct platform_device *op) | |||
540 | 541 | ||
541 | kfree(ms->gpio_cs); | 542 | kfree(ms->gpio_cs); |
542 | spi_unregister_master(master); | 543 | spi_unregister_master(master); |
543 | spi_master_put(master); | ||
544 | iounmap(ms->regs); | 544 | iounmap(ms->regs); |
545 | spi_master_put(master); | ||
545 | 546 | ||
546 | return 0; | 547 | return 0; |
547 | } | 548 | } |
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c new file mode 100644 index 000000000000..edf1360ab09e --- /dev/null +++ b/drivers/spi/spi-mxs.c | |||
@@ -0,0 +1,674 @@ | |||
1 | /* | ||
2 | * Freescale MXS SPI master driver | ||
3 | * | ||
4 | * Copyright 2012 DENX Software Engineering, GmbH. | ||
5 | * Copyright 2012 Freescale Semiconductor, Inc. | ||
6 | * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. | ||
7 | * | ||
8 | * Rework and transition to new API by: | ||
9 | * Marek Vasut <marex@denx.de> | ||
10 | * | ||
11 | * Based on previous attempt by: | ||
12 | * Fabio Estevam <fabio.estevam@freescale.com> | ||
13 | * | ||
14 | * Based on code from U-Boot bootloader by: | ||
15 | * Marek Vasut <marex@denx.de> | ||
16 | * | ||
17 | * Based on spi-stmp.c, which is: | ||
18 | * Author: Dmitry Pervushin <dimka@embeddedalley.com> | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or modify | ||
21 | * it under the terms of the GNU General Public License as published by | ||
22 | * the Free Software Foundation; either version 2 of the License, or | ||
23 | * (at your option) any later version. | ||
24 | * | ||
25 | * This program is distributed in the hope that it will be useful, | ||
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
28 | * GNU General Public License for more details. | ||
29 | */ | ||
30 | |||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/ioport.h> | ||
34 | #include <linux/of.h> | ||
35 | #include <linux/of_device.h> | ||
36 | #include <linux/of_gpio.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/delay.h> | ||
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/dma-mapping.h> | ||
41 | #include <linux/dmaengine.h> | ||
42 | #include <linux/highmem.h> | ||
43 | #include <linux/clk.h> | ||
44 | #include <linux/err.h> | ||
45 | #include <linux/completion.h> | ||
46 | #include <linux/gpio.h> | ||
47 | #include <linux/regulator/consumer.h> | ||
48 | #include <linux/module.h> | ||
49 | #include <linux/pinctrl/consumer.h> | ||
50 | #include <linux/stmp_device.h> | ||
51 | #include <linux/spi/spi.h> | ||
52 | #include <linux/spi/mxs-spi.h> | ||
53 | |||
54 | #define DRIVER_NAME "mxs-spi" | ||
55 | |||
56 | /* Use 10S timeout for very long transfers, it should suffice. */ | ||
57 | #define SSP_TIMEOUT 10000 | ||
58 | |||
59 | #define SG_MAXLEN 0xff00 | ||
60 | |||
61 | struct mxs_spi { | ||
62 | struct mxs_ssp ssp; | ||
63 | struct completion c; | ||
64 | }; | ||
65 | |||
66 | static int mxs_spi_setup_transfer(struct spi_device *dev, | ||
67 | struct spi_transfer *t) | ||
68 | { | ||
69 | struct mxs_spi *spi = spi_master_get_devdata(dev->master); | ||
70 | struct mxs_ssp *ssp = &spi->ssp; | ||
71 | uint8_t bits_per_word; | ||
72 | uint32_t hz = 0; | ||
73 | |||
74 | bits_per_word = dev->bits_per_word; | ||
75 | if (t && t->bits_per_word) | ||
76 | bits_per_word = t->bits_per_word; | ||
77 | |||
78 | if (bits_per_word != 8) { | ||
79 | dev_err(&dev->dev, "%s, unsupported bits_per_word=%d\n", | ||
80 | __func__, bits_per_word); | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | hz = dev->max_speed_hz; | ||
85 | if (t && t->speed_hz) | ||
86 | hz = min(hz, t->speed_hz); | ||
87 | if (hz == 0) { | ||
88 | dev_err(&dev->dev, "Cannot continue with zero clock\n"); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | mxs_ssp_set_clk_rate(ssp, hz); | ||
93 | |||
94 | writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) | | ||
95 | BF_SSP_CTRL1_WORD_LENGTH | ||
96 | (BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) | | ||
97 | ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) | | ||
98 | ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0), | ||
99 | ssp->base + HW_SSP_CTRL1(ssp)); | ||
100 | |||
101 | writel(0x0, ssp->base + HW_SSP_CMD0); | ||
102 | writel(0x0, ssp->base + HW_SSP_CMD1); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int mxs_spi_setup(struct spi_device *dev) | ||
108 | { | ||
109 | int err = 0; | ||
110 | |||
111 | if (!dev->bits_per_word) | ||
112 | dev->bits_per_word = 8; | ||
113 | |||
114 | if (dev->mode & ~(SPI_CPOL | SPI_CPHA)) | ||
115 | return -EINVAL; | ||
116 | |||
117 | err = mxs_spi_setup_transfer(dev, NULL); | ||
118 | if (err) { | ||
119 | dev_err(&dev->dev, | ||
120 | "Failed to setup transfer, error = %d\n", err); | ||
121 | } | ||
122 | |||
123 | return err; | ||
124 | } | ||
125 | |||
126 | static uint32_t mxs_spi_cs_to_reg(unsigned cs) | ||
127 | { | ||
128 | uint32_t select = 0; | ||
129 | |||
130 | /* | ||
131 | * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0 | ||
132 | * | ||
133 | * The bits BM_SSP_CTRL0_WAIT_FOR_CMD and BM_SSP_CTRL0_WAIT_FOR_IRQ | ||
134 | * in HW_SSP_CTRL0 register do have multiple usage, please refer to | ||
135 | * the datasheet for further details. In SPI mode, they are used to | ||
136 | * toggle the chip-select lines (nCS pins). | ||
137 | */ | ||
138 | if (cs & 1) | ||
139 | select |= BM_SSP_CTRL0_WAIT_FOR_CMD; | ||
140 | if (cs & 2) | ||
141 | select |= BM_SSP_CTRL0_WAIT_FOR_IRQ; | ||
142 | |||
143 | return select; | ||
144 | } | ||
145 | |||
146 | static void mxs_spi_set_cs(struct mxs_spi *spi, unsigned cs) | ||
147 | { | ||
148 | const uint32_t mask = | ||
149 | BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ; | ||
150 | uint32_t select; | ||
151 | struct mxs_ssp *ssp = &spi->ssp; | ||
152 | |||
153 | writel(mask, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
154 | select = mxs_spi_cs_to_reg(cs); | ||
155 | writel(select, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
156 | } | ||
157 | |||
158 | static inline void mxs_spi_enable(struct mxs_spi *spi) | ||
159 | { | ||
160 | struct mxs_ssp *ssp = &spi->ssp; | ||
161 | |||
162 | writel(BM_SSP_CTRL0_LOCK_CS, | ||
163 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
164 | writel(BM_SSP_CTRL0_IGNORE_CRC, | ||
165 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
166 | } | ||
167 | |||
168 | static inline void mxs_spi_disable(struct mxs_spi *spi) | ||
169 | { | ||
170 | struct mxs_ssp *ssp = &spi->ssp; | ||
171 | |||
172 | writel(BM_SSP_CTRL0_LOCK_CS, | ||
173 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
174 | writel(BM_SSP_CTRL0_IGNORE_CRC, | ||
175 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
176 | } | ||
177 | |||
178 | static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set) | ||
179 | { | ||
180 | const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT); | ||
181 | struct mxs_ssp *ssp = &spi->ssp; | ||
182 | uint32_t reg; | ||
183 | |||
184 | do { | ||
185 | reg = readl_relaxed(ssp->base + offset); | ||
186 | |||
187 | if (!set) | ||
188 | reg = ~reg; | ||
189 | |||
190 | reg &= mask; | ||
191 | |||
192 | if (reg == mask) | ||
193 | return 0; | ||
194 | } while (time_before(jiffies, timeout)); | ||
195 | |||
196 | return -ETIMEDOUT; | ||
197 | } | ||
198 | |||
199 | static void mxs_ssp_dma_irq_callback(void *param) | ||
200 | { | ||
201 | struct mxs_spi *spi = param; | ||
202 | complete(&spi->c); | ||
203 | } | ||
204 | |||
205 | static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id) | ||
206 | { | ||
207 | struct mxs_ssp *ssp = dev_id; | ||
208 | dev_err(ssp->dev, "%s[%i] CTRL1=%08x STATUS=%08x\n", | ||
209 | __func__, __LINE__, | ||
210 | readl(ssp->base + HW_SSP_CTRL1(ssp)), | ||
211 | readl(ssp->base + HW_SSP_STATUS(ssp))); | ||
212 | return IRQ_HANDLED; | ||
213 | } | ||
214 | |||
215 | static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs, | ||
216 | unsigned char *buf, int len, | ||
217 | int *first, int *last, int write) | ||
218 | { | ||
219 | struct mxs_ssp *ssp = &spi->ssp; | ||
220 | struct dma_async_tx_descriptor *desc = NULL; | ||
221 | const bool vmalloced_buf = is_vmalloc_addr(buf); | ||
222 | const int desc_len = vmalloced_buf ? PAGE_SIZE : SG_MAXLEN; | ||
223 | const int sgs = DIV_ROUND_UP(len, desc_len); | ||
224 | int sg_count; | ||
225 | int min, ret; | ||
226 | uint32_t ctrl0; | ||
227 | struct page *vm_page; | ||
228 | void *sg_buf; | ||
229 | struct { | ||
230 | uint32_t pio[4]; | ||
231 | struct scatterlist sg; | ||
232 | } *dma_xfer; | ||
233 | |||
234 | if (!len) | ||
235 | return -EINVAL; | ||
236 | |||
237 | dma_xfer = kzalloc(sizeof(*dma_xfer) * sgs, GFP_KERNEL); | ||
238 | if (!dma_xfer) | ||
239 | return -ENOMEM; | ||
240 | |||
241 | INIT_COMPLETION(spi->c); | ||
242 | |||
243 | ctrl0 = readl(ssp->base + HW_SSP_CTRL0); | ||
244 | ctrl0 |= BM_SSP_CTRL0_DATA_XFER | mxs_spi_cs_to_reg(cs); | ||
245 | |||
246 | if (*first) | ||
247 | ctrl0 |= BM_SSP_CTRL0_LOCK_CS; | ||
248 | if (!write) | ||
249 | ctrl0 |= BM_SSP_CTRL0_READ; | ||
250 | |||
251 | /* Queue the DMA data transfer. */ | ||
252 | for (sg_count = 0; sg_count < sgs; sg_count++) { | ||
253 | min = min(len, desc_len); | ||
254 | |||
255 | /* Prepare the transfer descriptor. */ | ||
256 | if ((sg_count + 1 == sgs) && *last) | ||
257 | ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC; | ||
258 | |||
259 | if (ssp->devid == IMX23_SSP) | ||
260 | ctrl0 |= min; | ||
261 | |||
262 | dma_xfer[sg_count].pio[0] = ctrl0; | ||
263 | dma_xfer[sg_count].pio[3] = min; | ||
264 | |||
265 | if (vmalloced_buf) { | ||
266 | vm_page = vmalloc_to_page(buf); | ||
267 | if (!vm_page) { | ||
268 | ret = -ENOMEM; | ||
269 | goto err_vmalloc; | ||
270 | } | ||
271 | sg_buf = page_address(vm_page) + | ||
272 | ((size_t)buf & ~PAGE_MASK); | ||
273 | } else { | ||
274 | sg_buf = buf; | ||
275 | } | ||
276 | |||
277 | sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min); | ||
278 | ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, | ||
279 | write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
280 | |||
281 | len -= min; | ||
282 | buf += min; | ||
283 | |||
284 | /* Queue the PIO register write transfer. */ | ||
285 | desc = dmaengine_prep_slave_sg(ssp->dmach, | ||
286 | (struct scatterlist *)dma_xfer[sg_count].pio, | ||
287 | (ssp->devid == IMX23_SSP) ? 1 : 4, | ||
288 | DMA_TRANS_NONE, | ||
289 | sg_count ? DMA_PREP_INTERRUPT : 0); | ||
290 | if (!desc) { | ||
291 | dev_err(ssp->dev, | ||
292 | "Failed to get PIO reg. write descriptor.\n"); | ||
293 | ret = -EINVAL; | ||
294 | goto err_mapped; | ||
295 | } | ||
296 | |||
297 | desc = dmaengine_prep_slave_sg(ssp->dmach, | ||
298 | &dma_xfer[sg_count].sg, 1, | ||
299 | write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, | ||
300 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
301 | |||
302 | if (!desc) { | ||
303 | dev_err(ssp->dev, | ||
304 | "Failed to get DMA data write descriptor.\n"); | ||
305 | ret = -EINVAL; | ||
306 | goto err_mapped; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * The last descriptor must have this callback, | ||
312 | * to finish the DMA transaction. | ||
313 | */ | ||
314 | desc->callback = mxs_ssp_dma_irq_callback; | ||
315 | desc->callback_param = spi; | ||
316 | |||
317 | /* Start the transfer. */ | ||
318 | dmaengine_submit(desc); | ||
319 | dma_async_issue_pending(ssp->dmach); | ||
320 | |||
321 | ret = wait_for_completion_timeout(&spi->c, | ||
322 | msecs_to_jiffies(SSP_TIMEOUT)); | ||
323 | if (!ret) { | ||
324 | dev_err(ssp->dev, "DMA transfer timeout\n"); | ||
325 | ret = -ETIMEDOUT; | ||
326 | goto err_vmalloc; | ||
327 | } | ||
328 | |||
329 | ret = 0; | ||
330 | |||
331 | err_vmalloc: | ||
332 | while (--sg_count >= 0) { | ||
333 | err_mapped: | ||
334 | dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, | ||
335 | write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
336 | } | ||
337 | |||
338 | kfree(dma_xfer); | ||
339 | |||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs, | ||
344 | unsigned char *buf, int len, | ||
345 | int *first, int *last, int write) | ||
346 | { | ||
347 | struct mxs_ssp *ssp = &spi->ssp; | ||
348 | |||
349 | if (*first) | ||
350 | mxs_spi_enable(spi); | ||
351 | |||
352 | mxs_spi_set_cs(spi, cs); | ||
353 | |||
354 | while (len--) { | ||
355 | if (*last && len == 0) | ||
356 | mxs_spi_disable(spi); | ||
357 | |||
358 | if (ssp->devid == IMX23_SSP) { | ||
359 | writel(BM_SSP_CTRL0_XFER_COUNT, | ||
360 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
361 | writel(1, | ||
362 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
363 | } else { | ||
364 | writel(1, ssp->base + HW_SSP_XFER_SIZE); | ||
365 | } | ||
366 | |||
367 | if (write) | ||
368 | writel(BM_SSP_CTRL0_READ, | ||
369 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | ||
370 | else | ||
371 | writel(BM_SSP_CTRL0_READ, | ||
372 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
373 | |||
374 | writel(BM_SSP_CTRL0_RUN, | ||
375 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
376 | |||
377 | if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1)) | ||
378 | return -ETIMEDOUT; | ||
379 | |||
380 | if (write) | ||
381 | writel(*buf, ssp->base + HW_SSP_DATA(ssp)); | ||
382 | |||
383 | writel(BM_SSP_CTRL0_DATA_XFER, | ||
384 | ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | ||
385 | |||
386 | if (!write) { | ||
387 | if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp), | ||
388 | BM_SSP_STATUS_FIFO_EMPTY, 0)) | ||
389 | return -ETIMEDOUT; | ||
390 | |||
391 | *buf = (readl(ssp->base + HW_SSP_DATA(ssp)) & 0xff); | ||
392 | } | ||
393 | |||
394 | if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 0)) | ||
395 | return -ETIMEDOUT; | ||
396 | |||
397 | buf++; | ||
398 | } | ||
399 | |||
400 | if (len <= 0) | ||
401 | return 0; | ||
402 | |||
403 | return -ETIMEDOUT; | ||
404 | } | ||
405 | |||
406 | static int mxs_spi_transfer_one(struct spi_master *master, | ||
407 | struct spi_message *m) | ||
408 | { | ||
409 | struct mxs_spi *spi = spi_master_get_devdata(master); | ||
410 | struct mxs_ssp *ssp = &spi->ssp; | ||
411 | int first, last; | ||
412 | struct spi_transfer *t, *tmp_t; | ||
413 | int status = 0; | ||
414 | int cs; | ||
415 | |||
416 | first = last = 0; | ||
417 | |||
418 | cs = m->spi->chip_select; | ||
419 | |||
420 | list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) { | ||
421 | |||
422 | status = mxs_spi_setup_transfer(m->spi, t); | ||
423 | if (status) | ||
424 | break; | ||
425 | |||
426 | if (&t->transfer_list == m->transfers.next) | ||
427 | first = 1; | ||
428 | if (&t->transfer_list == m->transfers.prev) | ||
429 | last = 1; | ||
430 | if ((t->rx_buf && t->tx_buf) || (t->rx_dma && t->tx_dma)) { | ||
431 | dev_err(ssp->dev, | ||
432 | "Cannot send and receive simultaneously\n"); | ||
433 | status = -EINVAL; | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * Small blocks can be transfered via PIO. | ||
439 | * Measured by empiric means: | ||
440 | * | ||
441 | * dd if=/dev/mtdblock0 of=/dev/null bs=1024k count=1 | ||
442 | * | ||
443 | * DMA only: 2.164808 seconds, 473.0KB/s | ||
444 | * Combined: 1.676276 seconds, 610.9KB/s | ||
445 | */ | ||
446 | if (t->len < 32) { | ||
447 | writel(BM_SSP_CTRL1_DMA_ENABLE, | ||
448 | ssp->base + HW_SSP_CTRL1(ssp) + | ||
449 | STMP_OFFSET_REG_CLR); | ||
450 | |||
451 | if (t->tx_buf) | ||
452 | status = mxs_spi_txrx_pio(spi, cs, | ||
453 | (void *)t->tx_buf, | ||
454 | t->len, &first, &last, 1); | ||
455 | if (t->rx_buf) | ||
456 | status = mxs_spi_txrx_pio(spi, cs, | ||
457 | t->rx_buf, t->len, | ||
458 | &first, &last, 0); | ||
459 | } else { | ||
460 | writel(BM_SSP_CTRL1_DMA_ENABLE, | ||
461 | ssp->base + HW_SSP_CTRL1(ssp) + | ||
462 | STMP_OFFSET_REG_SET); | ||
463 | |||
464 | if (t->tx_buf) | ||
465 | status = mxs_spi_txrx_dma(spi, cs, | ||
466 | (void *)t->tx_buf, t->len, | ||
467 | &first, &last, 1); | ||
468 | if (t->rx_buf) | ||
469 | status = mxs_spi_txrx_dma(spi, cs, | ||
470 | t->rx_buf, t->len, | ||
471 | &first, &last, 0); | ||
472 | } | ||
473 | |||
474 | if (status) { | ||
475 | stmp_reset_block(ssp->base); | ||
476 | break; | ||
477 | } | ||
478 | |||
479 | m->actual_length += t->len; | ||
480 | first = last = 0; | ||
481 | } | ||
482 | |||
483 | m->status = 0; | ||
484 | spi_finalize_current_message(master); | ||
485 | |||
486 | return status; | ||
487 | } | ||
488 | |||
489 | static bool mxs_ssp_dma_filter(struct dma_chan *chan, void *param) | ||
490 | { | ||
491 | struct mxs_ssp *ssp = param; | ||
492 | |||
493 | if (!mxs_dma_is_apbh(chan)) | ||
494 | return false; | ||
495 | |||
496 | if (chan->chan_id != ssp->dma_channel) | ||
497 | return false; | ||
498 | |||
499 | chan->private = &ssp->dma_data; | ||
500 | |||
501 | return true; | ||
502 | } | ||
503 | |||
504 | static const struct of_device_id mxs_spi_dt_ids[] = { | ||
505 | { .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, }, | ||
506 | { .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, }, | ||
507 | { /* sentinel */ } | ||
508 | }; | ||
509 | MODULE_DEVICE_TABLE(of, mxs_spi_dt_ids); | ||
510 | |||
511 | static int __devinit mxs_spi_probe(struct platform_device *pdev) | ||
512 | { | ||
513 | const struct of_device_id *of_id = | ||
514 | of_match_device(mxs_spi_dt_ids, &pdev->dev); | ||
515 | struct device_node *np = pdev->dev.of_node; | ||
516 | struct spi_master *master; | ||
517 | struct mxs_spi *spi; | ||
518 | struct mxs_ssp *ssp; | ||
519 | struct resource *iores, *dmares; | ||
520 | struct pinctrl *pinctrl; | ||
521 | struct clk *clk; | ||
522 | void __iomem *base; | ||
523 | int devid, dma_channel, clk_freq; | ||
524 | int ret = 0, irq_err, irq_dma; | ||
525 | dma_cap_mask_t mask; | ||
526 | |||
527 | /* | ||
528 | * Default clock speed for the SPI core. 160MHz seems to | ||
529 | * work reasonably well with most SPI flashes, so use this | ||
530 | * as a default. Override with "clock-frequency" DT prop. | ||
531 | */ | ||
532 | const int clk_freq_default = 160000000; | ||
533 | |||
534 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
535 | irq_err = platform_get_irq(pdev, 0); | ||
536 | irq_dma = platform_get_irq(pdev, 1); | ||
537 | if (!iores || irq_err < 0 || irq_dma < 0) | ||
538 | return -EINVAL; | ||
539 | |||
540 | base = devm_request_and_ioremap(&pdev->dev, iores); | ||
541 | if (!base) | ||
542 | return -EADDRNOTAVAIL; | ||
543 | |||
544 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
545 | if (IS_ERR(pinctrl)) | ||
546 | return PTR_ERR(pinctrl); | ||
547 | |||
548 | clk = devm_clk_get(&pdev->dev, NULL); | ||
549 | if (IS_ERR(clk)) | ||
550 | return PTR_ERR(clk); | ||
551 | |||
552 | if (np) { | ||
553 | devid = (enum mxs_ssp_id) of_id->data; | ||
554 | /* | ||
555 | * TODO: This is a temporary solution and should be changed | ||
556 | * to use generic DMA binding later when the helpers get in. | ||
557 | */ | ||
558 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", | ||
559 | &dma_channel); | ||
560 | if (ret) { | ||
561 | dev_err(&pdev->dev, | ||
562 | "Failed to get DMA channel\n"); | ||
563 | return -EINVAL; | ||
564 | } | ||
565 | |||
566 | ret = of_property_read_u32(np, "clock-frequency", | ||
567 | &clk_freq); | ||
568 | if (ret) | ||
569 | clk_freq = clk_freq_default; | ||
570 | } else { | ||
571 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
572 | if (!dmares) | ||
573 | return -EINVAL; | ||
574 | devid = pdev->id_entry->driver_data; | ||
575 | dma_channel = dmares->start; | ||
576 | clk_freq = clk_freq_default; | ||
577 | } | ||
578 | |||
579 | master = spi_alloc_master(&pdev->dev, sizeof(*spi)); | ||
580 | if (!master) | ||
581 | return -ENOMEM; | ||
582 | |||
583 | master->transfer_one_message = mxs_spi_transfer_one; | ||
584 | master->setup = mxs_spi_setup; | ||
585 | master->mode_bits = SPI_CPOL | SPI_CPHA; | ||
586 | master->num_chipselect = 3; | ||
587 | master->dev.of_node = np; | ||
588 | master->flags = SPI_MASTER_HALF_DUPLEX; | ||
589 | |||
590 | spi = spi_master_get_devdata(master); | ||
591 | ssp = &spi->ssp; | ||
592 | ssp->dev = &pdev->dev; | ||
593 | ssp->clk = clk; | ||
594 | ssp->base = base; | ||
595 | ssp->devid = devid; | ||
596 | ssp->dma_channel = dma_channel; | ||
597 | |||
598 | init_completion(&spi->c); | ||
599 | |||
600 | ret = devm_request_irq(&pdev->dev, irq_err, mxs_ssp_irq_handler, 0, | ||
601 | DRIVER_NAME, ssp); | ||
602 | if (ret) | ||
603 | goto out_master_free; | ||
604 | |||
605 | dma_cap_zero(mask); | ||
606 | dma_cap_set(DMA_SLAVE, mask); | ||
607 | ssp->dma_data.chan_irq = irq_dma; | ||
608 | ssp->dmach = dma_request_channel(mask, mxs_ssp_dma_filter, ssp); | ||
609 | if (!ssp->dmach) { | ||
610 | dev_err(ssp->dev, "Failed to request DMA\n"); | ||
611 | goto out_master_free; | ||
612 | } | ||
613 | |||
614 | clk_prepare_enable(ssp->clk); | ||
615 | clk_set_rate(ssp->clk, clk_freq); | ||
616 | ssp->clk_rate = clk_get_rate(ssp->clk) / 1000; | ||
617 | |||
618 | stmp_reset_block(ssp->base); | ||
619 | |||
620 | platform_set_drvdata(pdev, master); | ||
621 | |||
622 | ret = spi_register_master(master); | ||
623 | if (ret) { | ||
624 | dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret); | ||
625 | goto out_free_dma; | ||
626 | } | ||
627 | |||
628 | return 0; | ||
629 | |||
630 | out_free_dma: | ||
631 | dma_release_channel(ssp->dmach); | ||
632 | clk_disable_unprepare(ssp->clk); | ||
633 | out_master_free: | ||
634 | spi_master_put(master); | ||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | static int __devexit mxs_spi_remove(struct platform_device *pdev) | ||
639 | { | ||
640 | struct spi_master *master; | ||
641 | struct mxs_spi *spi; | ||
642 | struct mxs_ssp *ssp; | ||
643 | |||
644 | master = spi_master_get(platform_get_drvdata(pdev)); | ||
645 | spi = spi_master_get_devdata(master); | ||
646 | ssp = &spi->ssp; | ||
647 | |||
648 | spi_unregister_master(master); | ||
649 | |||
650 | dma_release_channel(ssp->dmach); | ||
651 | |||
652 | clk_disable_unprepare(ssp->clk); | ||
653 | |||
654 | spi_master_put(master); | ||
655 | |||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static struct platform_driver mxs_spi_driver = { | ||
660 | .probe = mxs_spi_probe, | ||
661 | .remove = __devexit_p(mxs_spi_remove), | ||
662 | .driver = { | ||
663 | .name = DRIVER_NAME, | ||
664 | .owner = THIS_MODULE, | ||
665 | .of_match_table = mxs_spi_dt_ids, | ||
666 | }, | ||
667 | }; | ||
668 | |||
669 | module_platform_driver(mxs_spi_driver); | ||
670 | |||
671 | MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); | ||
672 | MODULE_DESCRIPTION("MXS SPI master driver"); | ||
673 | MODULE_LICENSE("GPL"); | ||
674 | MODULE_ALIAS("platform:mxs-spi"); | ||
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 5d59a69a9064..474e2174e08a 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
39 | #include <linux/of.h> | 39 | #include <linux/of.h> |
40 | #include <linux/of_device.h> | 40 | #include <linux/of_device.h> |
41 | #include <linux/pinctrl/consumer.h> | ||
42 | #include <linux/err.h> | ||
41 | 43 | ||
42 | #include <linux/spi/spi.h> | 44 | #include <linux/spi/spi.h> |
43 | 45 | ||
@@ -140,13 +142,6 @@ struct omap2_mcspi_cs { | |||
140 | u32 chconf0; | 142 | u32 chconf0; |
141 | }; | 143 | }; |
142 | 144 | ||
143 | #define MOD_REG_BIT(val, mask, set) do { \ | ||
144 | if (set) \ | ||
145 | val |= mask; \ | ||
146 | else \ | ||
147 | val &= ~mask; \ | ||
148 | } while (0) | ||
149 | |||
150 | static inline void mcspi_write_reg(struct spi_master *master, | 145 | static inline void mcspi_write_reg(struct spi_master *master, |
151 | int idx, u32 val) | 146 | int idx, u32 val) |
152 | { | 147 | { |
@@ -205,7 +200,11 @@ static void omap2_mcspi_set_dma_req(const struct spi_device *spi, | |||
205 | else | 200 | else |
206 | rw = OMAP2_MCSPI_CHCONF_DMAW; | 201 | rw = OMAP2_MCSPI_CHCONF_DMAW; |
207 | 202 | ||
208 | MOD_REG_BIT(l, rw, enable); | 203 | if (enable) |
204 | l |= rw; | ||
205 | else | ||
206 | l &= ~rw; | ||
207 | |||
209 | mcspi_write_chconf0(spi, l); | 208 | mcspi_write_chconf0(spi, l); |
210 | } | 209 | } |
211 | 210 | ||
@@ -224,7 +223,11 @@ static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active) | |||
224 | u32 l; | 223 | u32 l; |
225 | 224 | ||
226 | l = mcspi_cached_chconf0(spi); | 225 | l = mcspi_cached_chconf0(spi); |
227 | MOD_REG_BIT(l, OMAP2_MCSPI_CHCONF_FORCE, cs_active); | 226 | if (cs_active) |
227 | l |= OMAP2_MCSPI_CHCONF_FORCE; | ||
228 | else | ||
229 | l &= ~OMAP2_MCSPI_CHCONF_FORCE; | ||
230 | |||
228 | mcspi_write_chconf0(spi, l); | 231 | mcspi_write_chconf0(spi, l); |
229 | } | 232 | } |
230 | 233 | ||
@@ -239,9 +242,8 @@ static void omap2_mcspi_set_master_mode(struct spi_master *master) | |||
239 | * to single-channel master mode | 242 | * to single-channel master mode |
240 | */ | 243 | */ |
241 | l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL); | 244 | l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL); |
242 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_STEST, 0); | 245 | l &= ~(OMAP2_MCSPI_MODULCTRL_STEST | OMAP2_MCSPI_MODULCTRL_MS); |
243 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0); | 246 | l |= OMAP2_MCSPI_MODULCTRL_SINGLE; |
244 | MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1); | ||
245 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); | 247 | mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l); |
246 | 248 | ||
247 | ctx->modulctrl = l; | 249 | ctx->modulctrl = l; |
@@ -260,16 +262,6 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | |||
260 | list_for_each_entry(cs, &ctx->cs, node) | 262 | list_for_each_entry(cs, &ctx->cs, node) |
261 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | 263 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); |
262 | } | 264 | } |
263 | static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) | ||
264 | { | ||
265 | pm_runtime_mark_last_busy(mcspi->dev); | ||
266 | pm_runtime_put_autosuspend(mcspi->dev); | ||
267 | } | ||
268 | |||
269 | static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) | ||
270 | { | ||
271 | return pm_runtime_get_sync(mcspi->dev); | ||
272 | } | ||
273 | 265 | ||
274 | static int omap2_prepare_transfer(struct spi_master *master) | 266 | static int omap2_prepare_transfer(struct spi_master *master) |
275 | { | 267 | { |
@@ -325,49 +317,27 @@ static void omap2_mcspi_tx_callback(void *data) | |||
325 | omap2_mcspi_set_dma_req(spi, 0, 0); | 317 | omap2_mcspi_set_dma_req(spi, 0, 0); |
326 | } | 318 | } |
327 | 319 | ||
328 | static unsigned | 320 | static void omap2_mcspi_tx_dma(struct spi_device *spi, |
329 | omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | 321 | struct spi_transfer *xfer, |
322 | struct dma_slave_config cfg) | ||
330 | { | 323 | { |
331 | struct omap2_mcspi *mcspi; | 324 | struct omap2_mcspi *mcspi; |
332 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
333 | struct omap2_mcspi_dma *mcspi_dma; | 325 | struct omap2_mcspi_dma *mcspi_dma; |
334 | unsigned int count; | 326 | unsigned int count; |
335 | int word_len, element_count; | ||
336 | int elements = 0; | ||
337 | u32 l; | ||
338 | u8 * rx; | 327 | u8 * rx; |
339 | const u8 * tx; | 328 | const u8 * tx; |
340 | void __iomem *chstat_reg; | 329 | void __iomem *chstat_reg; |
341 | struct dma_slave_config cfg; | 330 | struct omap2_mcspi_cs *cs = spi->controller_state; |
342 | enum dma_slave_buswidth width; | ||
343 | unsigned es; | ||
344 | 331 | ||
345 | mcspi = spi_master_get_devdata(spi->master); | 332 | mcspi = spi_master_get_devdata(spi->master); |
346 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 333 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
347 | l = mcspi_cached_chconf0(spi); | 334 | count = xfer->len; |
348 | 335 | ||
336 | rx = xfer->rx_buf; | ||
337 | tx = xfer->tx_buf; | ||
349 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; | 338 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; |
350 | 339 | ||
351 | if (cs->word_len <= 8) { | 340 | if (mcspi_dma->dma_tx) { |
352 | width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
353 | es = 1; | ||
354 | } else if (cs->word_len <= 16) { | ||
355 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
356 | es = 2; | ||
357 | } else { | ||
358 | width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
359 | es = 4; | ||
360 | } | ||
361 | |||
362 | memset(&cfg, 0, sizeof(cfg)); | ||
363 | cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0; | ||
364 | cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0; | ||
365 | cfg.src_addr_width = width; | ||
366 | cfg.dst_addr_width = width; | ||
367 | cfg.src_maxburst = 1; | ||
368 | cfg.dst_maxburst = 1; | ||
369 | |||
370 | if (xfer->tx_buf && mcspi_dma->dma_tx) { | ||
371 | struct dma_async_tx_descriptor *tx; | 341 | struct dma_async_tx_descriptor *tx; |
372 | struct scatterlist sg; | 342 | struct scatterlist sg; |
373 | 343 | ||
@@ -378,7 +348,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
378 | sg_dma_len(&sg) = xfer->len; | 348 | sg_dma_len(&sg) = xfer->len; |
379 | 349 | ||
380 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1, | 350 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1, |
381 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 351 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
382 | if (tx) { | 352 | if (tx) { |
383 | tx->callback = omap2_mcspi_tx_callback; | 353 | tx->callback = omap2_mcspi_tx_callback; |
384 | tx->callback_param = spi; | 354 | tx->callback_param = spi; |
@@ -387,8 +357,50 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
387 | /* FIXME: fall back to PIO? */ | 357 | /* FIXME: fall back to PIO? */ |
388 | } | 358 | } |
389 | } | 359 | } |
360 | dma_async_issue_pending(mcspi_dma->dma_tx); | ||
361 | omap2_mcspi_set_dma_req(spi, 0, 1); | ||
362 | |||
363 | wait_for_completion(&mcspi_dma->dma_tx_completion); | ||
364 | dma_unmap_single(mcspi->dev, xfer->tx_dma, count, | ||
365 | DMA_TO_DEVICE); | ||
366 | |||
367 | /* for TX_ONLY mode, be sure all words have shifted out */ | ||
368 | if (rx == NULL) { | ||
369 | if (mcspi_wait_for_reg_bit(chstat_reg, | ||
370 | OMAP2_MCSPI_CHSTAT_TXS) < 0) | ||
371 | dev_err(&spi->dev, "TXS timed out\n"); | ||
372 | else if (mcspi_wait_for_reg_bit(chstat_reg, | ||
373 | OMAP2_MCSPI_CHSTAT_EOT) < 0) | ||
374 | dev_err(&spi->dev, "EOT timed out\n"); | ||
375 | } | ||
376 | } | ||
377 | |||
378 | static unsigned | ||
379 | omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | ||
380 | struct dma_slave_config cfg, | ||
381 | unsigned es) | ||
382 | { | ||
383 | struct omap2_mcspi *mcspi; | ||
384 | struct omap2_mcspi_dma *mcspi_dma; | ||
385 | unsigned int count; | ||
386 | u32 l; | ||
387 | int elements = 0; | ||
388 | int word_len, element_count; | ||
389 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
390 | mcspi = spi_master_get_devdata(spi->master); | ||
391 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | ||
392 | count = xfer->len; | ||
393 | word_len = cs->word_len; | ||
394 | l = mcspi_cached_chconf0(spi); | ||
390 | 395 | ||
391 | if (xfer->rx_buf && mcspi_dma->dma_rx) { | 396 | if (word_len <= 8) |
397 | element_count = count; | ||
398 | else if (word_len <= 16) | ||
399 | element_count = count >> 1; | ||
400 | else /* word_len <= 32 */ | ||
401 | element_count = count >> 2; | ||
402 | |||
403 | if (mcspi_dma->dma_rx) { | ||
392 | struct dma_async_tx_descriptor *tx; | 404 | struct dma_async_tx_descriptor *tx; |
393 | struct scatterlist sg; | 405 | struct scatterlist sg; |
394 | size_t len = xfer->len - es; | 406 | size_t len = xfer->len - es; |
@@ -403,108 +415,120 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
403 | sg_dma_len(&sg) = len; | 415 | sg_dma_len(&sg) = len; |
404 | 416 | ||
405 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, | 417 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, |
406 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 418 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | |
419 | DMA_CTRL_ACK); | ||
407 | if (tx) { | 420 | if (tx) { |
408 | tx->callback = omap2_mcspi_rx_callback; | 421 | tx->callback = omap2_mcspi_rx_callback; |
409 | tx->callback_param = spi; | 422 | tx->callback_param = spi; |
410 | dmaengine_submit(tx); | 423 | dmaengine_submit(tx); |
411 | } else { | 424 | } else { |
412 | /* FIXME: fall back to PIO? */ | 425 | /* FIXME: fall back to PIO? */ |
413 | } | ||
414 | } | ||
415 | |||
416 | count = xfer->len; | ||
417 | word_len = cs->word_len; | ||
418 | |||
419 | rx = xfer->rx_buf; | ||
420 | tx = xfer->tx_buf; | ||
421 | |||
422 | if (word_len <= 8) { | ||
423 | element_count = count; | ||
424 | } else if (word_len <= 16) { | ||
425 | element_count = count >> 1; | ||
426 | } else /* word_len <= 32 */ { | ||
427 | element_count = count >> 2; | ||
428 | } | ||
429 | |||
430 | if (tx != NULL) { | ||
431 | dma_async_issue_pending(mcspi_dma->dma_tx); | ||
432 | omap2_mcspi_set_dma_req(spi, 0, 1); | ||
433 | } | ||
434 | |||
435 | if (rx != NULL) { | ||
436 | dma_async_issue_pending(mcspi_dma->dma_rx); | ||
437 | omap2_mcspi_set_dma_req(spi, 1, 1); | ||
438 | } | ||
439 | |||
440 | if (tx != NULL) { | ||
441 | wait_for_completion(&mcspi_dma->dma_tx_completion); | ||
442 | dma_unmap_single(mcspi->dev, xfer->tx_dma, count, | ||
443 | DMA_TO_DEVICE); | ||
444 | |||
445 | /* for TX_ONLY mode, be sure all words have shifted out */ | ||
446 | if (rx == NULL) { | ||
447 | if (mcspi_wait_for_reg_bit(chstat_reg, | ||
448 | OMAP2_MCSPI_CHSTAT_TXS) < 0) | ||
449 | dev_err(&spi->dev, "TXS timed out\n"); | ||
450 | else if (mcspi_wait_for_reg_bit(chstat_reg, | ||
451 | OMAP2_MCSPI_CHSTAT_EOT) < 0) | ||
452 | dev_err(&spi->dev, "EOT timed out\n"); | ||
453 | } | 426 | } |
454 | } | 427 | } |
455 | 428 | ||
456 | if (rx != NULL) { | 429 | dma_async_issue_pending(mcspi_dma->dma_rx); |
457 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 430 | omap2_mcspi_set_dma_req(spi, 1, 1); |
458 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, | ||
459 | DMA_FROM_DEVICE); | ||
460 | omap2_mcspi_set_enable(spi, 0); | ||
461 | 431 | ||
462 | elements = element_count - 1; | 432 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
433 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, | ||
434 | DMA_FROM_DEVICE); | ||
435 | omap2_mcspi_set_enable(spi, 0); | ||
463 | 436 | ||
464 | if (l & OMAP2_MCSPI_CHCONF_TURBO) { | 437 | elements = element_count - 1; |
465 | elements--; | ||
466 | 438 | ||
467 | if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) | 439 | if (l & OMAP2_MCSPI_CHCONF_TURBO) { |
468 | & OMAP2_MCSPI_CHSTAT_RXS)) { | 440 | elements--; |
469 | u32 w; | ||
470 | |||
471 | w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); | ||
472 | if (word_len <= 8) | ||
473 | ((u8 *)xfer->rx_buf)[elements++] = w; | ||
474 | else if (word_len <= 16) | ||
475 | ((u16 *)xfer->rx_buf)[elements++] = w; | ||
476 | else /* word_len <= 32 */ | ||
477 | ((u32 *)xfer->rx_buf)[elements++] = w; | ||
478 | } else { | ||
479 | dev_err(&spi->dev, | ||
480 | "DMA RX penultimate word empty"); | ||
481 | count -= (word_len <= 8) ? 2 : | ||
482 | (word_len <= 16) ? 4 : | ||
483 | /* word_len <= 32 */ 8; | ||
484 | omap2_mcspi_set_enable(spi, 1); | ||
485 | return count; | ||
486 | } | ||
487 | } | ||
488 | 441 | ||
489 | if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) | 442 | if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) |
490 | & OMAP2_MCSPI_CHSTAT_RXS)) { | 443 | & OMAP2_MCSPI_CHSTAT_RXS)) { |
491 | u32 w; | 444 | u32 w; |
492 | 445 | ||
493 | w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); | 446 | w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); |
494 | if (word_len <= 8) | 447 | if (word_len <= 8) |
495 | ((u8 *)xfer->rx_buf)[elements] = w; | 448 | ((u8 *)xfer->rx_buf)[elements++] = w; |
496 | else if (word_len <= 16) | 449 | else if (word_len <= 16) |
497 | ((u16 *)xfer->rx_buf)[elements] = w; | 450 | ((u16 *)xfer->rx_buf)[elements++] = w; |
498 | else /* word_len <= 32 */ | 451 | else /* word_len <= 32 */ |
499 | ((u32 *)xfer->rx_buf)[elements] = w; | 452 | ((u32 *)xfer->rx_buf)[elements++] = w; |
500 | } else { | 453 | } else { |
501 | dev_err(&spi->dev, "DMA RX last word empty"); | 454 | dev_err(&spi->dev, "DMA RX penultimate word empty"); |
502 | count -= (word_len <= 8) ? 1 : | 455 | count -= (word_len <= 8) ? 2 : |
503 | (word_len <= 16) ? 2 : | 456 | (word_len <= 16) ? 4 : |
504 | /* word_len <= 32 */ 4; | 457 | /* word_len <= 32 */ 8; |
458 | omap2_mcspi_set_enable(spi, 1); | ||
459 | return count; | ||
505 | } | 460 | } |
506 | omap2_mcspi_set_enable(spi, 1); | ||
507 | } | 461 | } |
462 | if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) | ||
463 | & OMAP2_MCSPI_CHSTAT_RXS)) { | ||
464 | u32 w; | ||
465 | |||
466 | w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); | ||
467 | if (word_len <= 8) | ||
468 | ((u8 *)xfer->rx_buf)[elements] = w; | ||
469 | else if (word_len <= 16) | ||
470 | ((u16 *)xfer->rx_buf)[elements] = w; | ||
471 | else /* word_len <= 32 */ | ||
472 | ((u32 *)xfer->rx_buf)[elements] = w; | ||
473 | } else { | ||
474 | dev_err(&spi->dev, "DMA RX last word empty"); | ||
475 | count -= (word_len <= 8) ? 1 : | ||
476 | (word_len <= 16) ? 2 : | ||
477 | /* word_len <= 32 */ 4; | ||
478 | } | ||
479 | omap2_mcspi_set_enable(spi, 1); | ||
480 | return count; | ||
481 | } | ||
482 | |||
483 | static unsigned | ||
484 | omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | ||
485 | { | ||
486 | struct omap2_mcspi *mcspi; | ||
487 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
488 | struct omap2_mcspi_dma *mcspi_dma; | ||
489 | unsigned int count; | ||
490 | u32 l; | ||
491 | u8 *rx; | ||
492 | const u8 *tx; | ||
493 | struct dma_slave_config cfg; | ||
494 | enum dma_slave_buswidth width; | ||
495 | unsigned es; | ||
496 | |||
497 | mcspi = spi_master_get_devdata(spi->master); | ||
498 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | ||
499 | l = mcspi_cached_chconf0(spi); | ||
500 | |||
501 | |||
502 | if (cs->word_len <= 8) { | ||
503 | width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
504 | es = 1; | ||
505 | } else if (cs->word_len <= 16) { | ||
506 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
507 | es = 2; | ||
508 | } else { | ||
509 | width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
510 | es = 4; | ||
511 | } | ||
512 | |||
513 | memset(&cfg, 0, sizeof(cfg)); | ||
514 | cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0; | ||
515 | cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0; | ||
516 | cfg.src_addr_width = width; | ||
517 | cfg.dst_addr_width = width; | ||
518 | cfg.src_maxburst = 1; | ||
519 | cfg.dst_maxburst = 1; | ||
520 | |||
521 | rx = xfer->rx_buf; | ||
522 | tx = xfer->tx_buf; | ||
523 | |||
524 | count = xfer->len; | ||
525 | |||
526 | if (tx != NULL) | ||
527 | omap2_mcspi_tx_dma(spi, xfer, cfg); | ||
528 | |||
529 | if (rx != NULL) | ||
530 | return omap2_mcspi_rx_dma(spi, xfer, cfg, es); | ||
531 | |||
508 | return count; | 532 | return count; |
509 | } | 533 | } |
510 | 534 | ||
@@ -848,12 +872,13 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
848 | return ret; | 872 | return ret; |
849 | } | 873 | } |
850 | 874 | ||
851 | ret = omap2_mcspi_enable_clocks(mcspi); | 875 | ret = pm_runtime_get_sync(mcspi->dev); |
852 | if (ret < 0) | 876 | if (ret < 0) |
853 | return ret; | 877 | return ret; |
854 | 878 | ||
855 | ret = omap2_mcspi_setup_transfer(spi, NULL); | 879 | ret = omap2_mcspi_setup_transfer(spi, NULL); |
856 | omap2_mcspi_disable_clocks(mcspi); | 880 | pm_runtime_mark_last_busy(mcspi->dev); |
881 | pm_runtime_put_autosuspend(mcspi->dev); | ||
857 | 882 | ||
858 | return ret; | 883 | return ret; |
859 | } | 884 | } |
@@ -1067,7 +1092,7 @@ static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | |||
1067 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | 1092 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
1068 | int ret = 0; | 1093 | int ret = 0; |
1069 | 1094 | ||
1070 | ret = omap2_mcspi_enable_clocks(mcspi); | 1095 | ret = pm_runtime_get_sync(mcspi->dev); |
1071 | if (ret < 0) | 1096 | if (ret < 0) |
1072 | return ret; | 1097 | return ret; |
1073 | 1098 | ||
@@ -1076,7 +1101,8 @@ static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | |||
1076 | ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN; | 1101 | ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN; |
1077 | 1102 | ||
1078 | omap2_mcspi_set_master_mode(master); | 1103 | omap2_mcspi_set_master_mode(master); |
1079 | omap2_mcspi_disable_clocks(mcspi); | 1104 | pm_runtime_mark_last_busy(mcspi->dev); |
1105 | pm_runtime_put_autosuspend(mcspi->dev); | ||
1080 | return 0; | 1106 | return 0; |
1081 | } | 1107 | } |
1082 | 1108 | ||
@@ -1124,6 +1150,7 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1124 | static int bus_num = 1; | 1150 | static int bus_num = 1; |
1125 | struct device_node *node = pdev->dev.of_node; | 1151 | struct device_node *node = pdev->dev.of_node; |
1126 | const struct of_device_id *match; | 1152 | const struct of_device_id *match; |
1153 | struct pinctrl *pinctrl; | ||
1127 | 1154 | ||
1128 | master = spi_alloc_master(&pdev->dev, sizeof *mcspi); | 1155 | master = spi_alloc_master(&pdev->dev, sizeof *mcspi); |
1129 | if (master == NULL) { | 1156 | if (master == NULL) { |
@@ -1219,6 +1246,11 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1219 | if (status < 0) | 1246 | if (status < 0) |
1220 | goto dma_chnl_free; | 1247 | goto dma_chnl_free; |
1221 | 1248 | ||
1249 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
1250 | if (IS_ERR(pinctrl)) | ||
1251 | dev_warn(&pdev->dev, | ||
1252 | "pins are not configured from the driver\n"); | ||
1253 | |||
1222 | pm_runtime_use_autosuspend(&pdev->dev); | 1254 | pm_runtime_use_autosuspend(&pdev->dev); |
1223 | pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); | 1255 | pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); |
1224 | pm_runtime_enable(&pdev->dev); | 1256 | pm_runtime_enable(&pdev->dev); |
@@ -1238,7 +1270,6 @@ dma_chnl_free: | |||
1238 | kfree(mcspi->dma_channels); | 1270 | kfree(mcspi->dma_channels); |
1239 | free_master: | 1271 | free_master: |
1240 | spi_master_put(master); | 1272 | spi_master_put(master); |
1241 | platform_set_drvdata(pdev, NULL); | ||
1242 | return status; | 1273 | return status; |
1243 | } | 1274 | } |
1244 | 1275 | ||
@@ -1252,12 +1283,11 @@ static int __devexit omap2_mcspi_remove(struct platform_device *pdev) | |||
1252 | mcspi = spi_master_get_devdata(master); | 1283 | mcspi = spi_master_get_devdata(master); |
1253 | dma_channels = mcspi->dma_channels; | 1284 | dma_channels = mcspi->dma_channels; |
1254 | 1285 | ||
1255 | omap2_mcspi_disable_clocks(mcspi); | 1286 | pm_runtime_put_sync(mcspi->dev); |
1256 | pm_runtime_disable(&pdev->dev); | 1287 | pm_runtime_disable(&pdev->dev); |
1257 | 1288 | ||
1258 | spi_unregister_master(master); | 1289 | spi_unregister_master(master); |
1259 | kfree(dma_channels); | 1290 | kfree(dma_channels); |
1260 | platform_set_drvdata(pdev, NULL); | ||
1261 | 1291 | ||
1262 | return 0; | 1292 | return 0; |
1263 | } | 1293 | } |
@@ -1278,20 +1308,21 @@ static int omap2_mcspi_resume(struct device *dev) | |||
1278 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | 1308 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
1279 | struct omap2_mcspi_cs *cs; | 1309 | struct omap2_mcspi_cs *cs; |
1280 | 1310 | ||
1281 | omap2_mcspi_enable_clocks(mcspi); | 1311 | pm_runtime_get_sync(mcspi->dev); |
1282 | list_for_each_entry(cs, &ctx->cs, node) { | 1312 | list_for_each_entry(cs, &ctx->cs, node) { |
1283 | if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { | 1313 | if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { |
1284 | /* | 1314 | /* |
1285 | * We need to toggle CS state for OMAP take this | 1315 | * We need to toggle CS state for OMAP take this |
1286 | * change in account. | 1316 | * change in account. |
1287 | */ | 1317 | */ |
1288 | MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1); | 1318 | cs->chconf0 |= OMAP2_MCSPI_CHCONF_FORCE; |
1289 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | 1319 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); |
1290 | MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0); | 1320 | cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE; |
1291 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | 1321 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); |
1292 | } | 1322 | } |
1293 | } | 1323 | } |
1294 | omap2_mcspi_disable_clocks(mcspi); | 1324 | pm_runtime_mark_last_busy(mcspi->dev); |
1325 | pm_runtime_put_autosuspend(mcspi->dev); | ||
1295 | return 0; | 1326 | return 0; |
1296 | } | 1327 | } |
1297 | #else | 1328 | #else |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 9b0caddce503..b17c09cf0a05 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
@@ -36,12 +36,6 @@ | |||
36 | #define ORION_SPI_CLK_PRESCALE_MASK 0x1F | 36 | #define ORION_SPI_CLK_PRESCALE_MASK 0x1F |
37 | 37 | ||
38 | struct orion_spi { | 38 | struct orion_spi { |
39 | struct work_struct work; | ||
40 | |||
41 | /* Lock access to transfer list. */ | ||
42 | spinlock_t lock; | ||
43 | |||
44 | struct list_head msg_queue; | ||
45 | struct spi_master *master; | 39 | struct spi_master *master; |
46 | void __iomem *base; | 40 | void __iomem *base; |
47 | unsigned int max_speed; | 41 | unsigned int max_speed; |
@@ -49,8 +43,6 @@ struct orion_spi { | |||
49 | struct clk *clk; | 43 | struct clk *clk; |
50 | }; | 44 | }; |
51 | 45 | ||
52 | static struct workqueue_struct *orion_spi_wq; | ||
53 | |||
54 | static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) | 46 | static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) |
55 | { | 47 | { |
56 | return orion_spi->base + reg; | 48 | return orion_spi->base + reg; |
@@ -277,73 +269,78 @@ out: | |||
277 | } | 269 | } |
278 | 270 | ||
279 | 271 | ||
280 | static void orion_spi_work(struct work_struct *work) | 272 | static int orion_spi_transfer_one_message(struct spi_master *master, |
273 | struct spi_message *m) | ||
281 | { | 274 | { |
282 | struct orion_spi *orion_spi = | 275 | struct orion_spi *orion_spi = spi_master_get_devdata(master); |
283 | container_of(work, struct orion_spi, work); | 276 | struct spi_device *spi = m->spi; |
284 | 277 | struct spi_transfer *t = NULL; | |
285 | spin_lock_irq(&orion_spi->lock); | 278 | int par_override = 0; |
286 | while (!list_empty(&orion_spi->msg_queue)) { | 279 | int status = 0; |
287 | struct spi_message *m; | 280 | int cs_active = 0; |
288 | struct spi_device *spi; | ||
289 | struct spi_transfer *t = NULL; | ||
290 | int par_override = 0; | ||
291 | int status = 0; | ||
292 | int cs_active = 0; | ||
293 | |||
294 | m = container_of(orion_spi->msg_queue.next, struct spi_message, | ||
295 | queue); | ||
296 | 281 | ||
297 | list_del_init(&m->queue); | 282 | /* Load defaults */ |
298 | spin_unlock_irq(&orion_spi->lock); | 283 | status = orion_spi_setup_transfer(spi, NULL); |
299 | 284 | ||
300 | spi = m->spi; | 285 | if (status < 0) |
286 | goto msg_done; | ||
301 | 287 | ||
302 | /* Load defaults */ | 288 | list_for_each_entry(t, &m->transfers, transfer_list) { |
303 | status = orion_spi_setup_transfer(spi, NULL); | 289 | /* make sure buffer length is even when working in 16 |
290 | * bit mode*/ | ||
291 | if ((t->bits_per_word == 16) && (t->len & 1)) { | ||
292 | dev_err(&spi->dev, | ||
293 | "message rejected : " | ||
294 | "odd data length %d while in 16 bit mode\n", | ||
295 | t->len); | ||
296 | status = -EIO; | ||
297 | goto msg_done; | ||
298 | } | ||
304 | 299 | ||
305 | if (status < 0) | 300 | if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { |
301 | dev_err(&spi->dev, | ||
302 | "message rejected : " | ||
303 | "device min speed (%d Hz) exceeds " | ||
304 | "required transfer speed (%d Hz)\n", | ||
305 | orion_spi->min_speed, t->speed_hz); | ||
306 | status = -EIO; | ||
306 | goto msg_done; | 307 | goto msg_done; |
308 | } | ||
307 | 309 | ||
308 | list_for_each_entry(t, &m->transfers, transfer_list) { | 310 | if (par_override || t->speed_hz || t->bits_per_word) { |
309 | if (par_override || t->speed_hz || t->bits_per_word) { | 311 | par_override = 1; |
310 | par_override = 1; | 312 | status = orion_spi_setup_transfer(spi, t); |
311 | status = orion_spi_setup_transfer(spi, t); | 313 | if (status < 0) |
312 | if (status < 0) | 314 | break; |
313 | break; | 315 | if (!t->speed_hz && !t->bits_per_word) |
314 | if (!t->speed_hz && !t->bits_per_word) | 316 | par_override = 0; |
315 | par_override = 0; | ||
316 | } | ||
317 | |||
318 | if (!cs_active) { | ||
319 | orion_spi_set_cs(orion_spi, 1); | ||
320 | cs_active = 1; | ||
321 | } | ||
322 | |||
323 | if (t->len) | ||
324 | m->actual_length += | ||
325 | orion_spi_write_read(spi, t); | ||
326 | |||
327 | if (t->delay_usecs) | ||
328 | udelay(t->delay_usecs); | ||
329 | |||
330 | if (t->cs_change) { | ||
331 | orion_spi_set_cs(orion_spi, 0); | ||
332 | cs_active = 0; | ||
333 | } | ||
334 | } | 317 | } |
335 | 318 | ||
336 | msg_done: | 319 | if (!cs_active) { |
337 | if (cs_active) | 320 | orion_spi_set_cs(orion_spi, 1); |
338 | orion_spi_set_cs(orion_spi, 0); | 321 | cs_active = 1; |
322 | } | ||
339 | 323 | ||
340 | m->status = status; | 324 | if (t->len) |
341 | m->complete(m->context); | 325 | m->actual_length += orion_spi_write_read(spi, t); |
342 | 326 | ||
343 | spin_lock_irq(&orion_spi->lock); | 327 | if (t->delay_usecs) |
328 | udelay(t->delay_usecs); | ||
329 | |||
330 | if (t->cs_change) { | ||
331 | orion_spi_set_cs(orion_spi, 0); | ||
332 | cs_active = 0; | ||
333 | } | ||
344 | } | 334 | } |
345 | 335 | ||
346 | spin_unlock_irq(&orion_spi->lock); | 336 | msg_done: |
337 | if (cs_active) | ||
338 | orion_spi_set_cs(orion_spi, 0); | ||
339 | |||
340 | m->status = status; | ||
341 | spi_finalize_current_message(master); | ||
342 | |||
343 | return 0; | ||
347 | } | 344 | } |
348 | 345 | ||
349 | static int __init orion_spi_reset(struct orion_spi *orion_spi) | 346 | static int __init orion_spi_reset(struct orion_spi *orion_spi) |
@@ -376,75 +373,6 @@ static int orion_spi_setup(struct spi_device *spi) | |||
376 | return 0; | 373 | return 0; |
377 | } | 374 | } |
378 | 375 | ||
379 | static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m) | ||
380 | { | ||
381 | struct orion_spi *orion_spi; | ||
382 | struct spi_transfer *t = NULL; | ||
383 | unsigned long flags; | ||
384 | |||
385 | m->actual_length = 0; | ||
386 | m->status = 0; | ||
387 | |||
388 | /* reject invalid messages and transfers */ | ||
389 | if (list_empty(&m->transfers) || !m->complete) | ||
390 | return -EINVAL; | ||
391 | |||
392 | orion_spi = spi_master_get_devdata(spi->master); | ||
393 | |||
394 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
395 | unsigned int bits_per_word = spi->bits_per_word; | ||
396 | |||
397 | if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { | ||
398 | dev_err(&spi->dev, | ||
399 | "message rejected : " | ||
400 | "invalid transfer data buffers\n"); | ||
401 | goto msg_rejected; | ||
402 | } | ||
403 | |||
404 | if (t->bits_per_word) | ||
405 | bits_per_word = t->bits_per_word; | ||
406 | |||
407 | if ((bits_per_word != 8) && (bits_per_word != 16)) { | ||
408 | dev_err(&spi->dev, | ||
409 | "message rejected : " | ||
410 | "invalid transfer bits_per_word (%d bits)\n", | ||
411 | bits_per_word); | ||
412 | goto msg_rejected; | ||
413 | } | ||
414 | /*make sure buffer length is even when working in 16 bit mode*/ | ||
415 | if ((t->bits_per_word == 16) && (t->len & 1)) { | ||
416 | dev_err(&spi->dev, | ||
417 | "message rejected : " | ||
418 | "odd data length (%d) while in 16 bit mode\n", | ||
419 | t->len); | ||
420 | goto msg_rejected; | ||
421 | } | ||
422 | |||
423 | if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { | ||
424 | dev_err(&spi->dev, | ||
425 | "message rejected : " | ||
426 | "device min speed (%d Hz) exceeds " | ||
427 | "required transfer speed (%d Hz)\n", | ||
428 | orion_spi->min_speed, t->speed_hz); | ||
429 | goto msg_rejected; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | |||
434 | spin_lock_irqsave(&orion_spi->lock, flags); | ||
435 | list_add_tail(&m->queue, &orion_spi->msg_queue); | ||
436 | queue_work(orion_spi_wq, &orion_spi->work); | ||
437 | spin_unlock_irqrestore(&orion_spi->lock, flags); | ||
438 | |||
439 | return 0; | ||
440 | msg_rejected: | ||
441 | /* Message rejected and not queued */ | ||
442 | m->status = -EINVAL; | ||
443 | if (m->complete) | ||
444 | m->complete(m->context); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | static int __init orion_spi_probe(struct platform_device *pdev) | 376 | static int __init orion_spi_probe(struct platform_device *pdev) |
449 | { | 377 | { |
450 | struct spi_master *master; | 378 | struct spi_master *master; |
@@ -474,7 +402,7 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
474 | master->mode_bits = 0; | 402 | master->mode_bits = 0; |
475 | 403 | ||
476 | master->setup = orion_spi_setup; | 404 | master->setup = orion_spi_setup; |
477 | master->transfer = orion_spi_transfer; | 405 | master->transfer_one_message = orion_spi_transfer_one_message; |
478 | master->num_chipselect = ORION_NUM_CHIPSELECTS; | 406 | master->num_chipselect = ORION_NUM_CHIPSELECTS; |
479 | 407 | ||
480 | dev_set_drvdata(&pdev->dev, master); | 408 | dev_set_drvdata(&pdev->dev, master); |
@@ -507,11 +435,6 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
507 | } | 435 | } |
508 | spi->base = ioremap(r->start, SZ_1K); | 436 | spi->base = ioremap(r->start, SZ_1K); |
509 | 437 | ||
510 | INIT_WORK(&spi->work, orion_spi_work); | ||
511 | |||
512 | spin_lock_init(&spi->lock); | ||
513 | INIT_LIST_HEAD(&spi->msg_queue); | ||
514 | |||
515 | if (orion_spi_reset(spi) < 0) | 438 | if (orion_spi_reset(spi) < 0) |
516 | goto out_rel_mem; | 439 | goto out_rel_mem; |
517 | 440 | ||
@@ -536,14 +459,12 @@ out: | |||
536 | static int __exit orion_spi_remove(struct platform_device *pdev) | 459 | static int __exit orion_spi_remove(struct platform_device *pdev) |
537 | { | 460 | { |
538 | struct spi_master *master; | 461 | struct spi_master *master; |
539 | struct orion_spi *spi; | ||
540 | struct resource *r; | 462 | struct resource *r; |
463 | struct orion_spi *spi; | ||
541 | 464 | ||
542 | master = dev_get_drvdata(&pdev->dev); | 465 | master = dev_get_drvdata(&pdev->dev); |
543 | spi = spi_master_get_devdata(master); | 466 | spi = spi_master_get_devdata(master); |
544 | 467 | ||
545 | cancel_work_sync(&spi->work); | ||
546 | |||
547 | clk_disable_unprepare(spi->clk); | 468 | clk_disable_unprepare(spi->clk); |
548 | clk_put(spi->clk); | 469 | clk_put(spi->clk); |
549 | 470 | ||
@@ -574,21 +495,13 @@ static struct platform_driver orion_spi_driver = { | |||
574 | 495 | ||
575 | static int __init orion_spi_init(void) | 496 | static int __init orion_spi_init(void) |
576 | { | 497 | { |
577 | orion_spi_wq = create_singlethread_workqueue( | ||
578 | orion_spi_driver.driver.name); | ||
579 | if (orion_spi_wq == NULL) | ||
580 | return -ENOMEM; | ||
581 | |||
582 | return platform_driver_probe(&orion_spi_driver, orion_spi_probe); | 498 | return platform_driver_probe(&orion_spi_driver, orion_spi_probe); |
583 | } | 499 | } |
584 | module_init(orion_spi_init); | 500 | module_init(orion_spi_init); |
585 | 501 | ||
586 | static void __exit orion_spi_exit(void) | 502 | static void __exit orion_spi_exit(void) |
587 | { | 503 | { |
588 | flush_workqueue(orion_spi_wq); | ||
589 | platform_driver_unregister(&orion_spi_driver); | 504 | platform_driver_unregister(&orion_spi_driver); |
590 | |||
591 | destroy_workqueue(orion_spi_wq); | ||
592 | } | 505 | } |
593 | module_exit(orion_spi_exit); | 506 | module_exit(orion_spi_exit); |
594 | 507 | ||
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 6abbe23c39b4..919464102d33 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. | 2 | * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2009 ST-Ericsson AB | 4 | * Copyright (C) 2008-2012 ST-Ericsson AB |
5 | * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. | 5 | * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. |
6 | * | 6 | * |
7 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 7 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
@@ -40,6 +40,9 @@ | |||
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
42 | #include <linux/pm_runtime.h> | 42 | #include <linux/pm_runtime.h> |
43 | #include <linux/gpio.h> | ||
44 | #include <linux/of_gpio.h> | ||
45 | #include <linux/pinctrl/consumer.h> | ||
43 | 46 | ||
44 | /* | 47 | /* |
45 | * This macro is used to define some register default values. | 48 | * This macro is used to define some register default values. |
@@ -356,6 +359,8 @@ struct vendor_data { | |||
356 | * @sgt_rx: scattertable for the RX transfer | 359 | * @sgt_rx: scattertable for the RX transfer |
357 | * @sgt_tx: scattertable for the TX transfer | 360 | * @sgt_tx: scattertable for the TX transfer |
358 | * @dummypage: a dummy page used for driving data on the bus with DMA | 361 | * @dummypage: a dummy page used for driving data on the bus with DMA |
362 | * @cur_cs: current chip select (gpio) | ||
363 | * @chipselects: list of chipselects (gpios) | ||
359 | */ | 364 | */ |
360 | struct pl022 { | 365 | struct pl022 { |
361 | struct amba_device *adev; | 366 | struct amba_device *adev; |
@@ -363,6 +368,10 @@ struct pl022 { | |||
363 | resource_size_t phybase; | 368 | resource_size_t phybase; |
364 | void __iomem *virtbase; | 369 | void __iomem *virtbase; |
365 | struct clk *clk; | 370 | struct clk *clk; |
371 | /* Two optional pin states - default & sleep */ | ||
372 | struct pinctrl *pinctrl; | ||
373 | struct pinctrl_state *pins_default; | ||
374 | struct pinctrl_state *pins_sleep; | ||
366 | struct spi_master *master; | 375 | struct spi_master *master; |
367 | struct pl022_ssp_controller *master_info; | 376 | struct pl022_ssp_controller *master_info; |
368 | /* Message per-transfer pump */ | 377 | /* Message per-transfer pump */ |
@@ -389,6 +398,8 @@ struct pl022 { | |||
389 | char *dummypage; | 398 | char *dummypage; |
390 | bool dma_running; | 399 | bool dma_running; |
391 | #endif | 400 | #endif |
401 | int cur_cs; | ||
402 | int *chipselects; | ||
392 | }; | 403 | }; |
393 | 404 | ||
394 | /** | 405 | /** |
@@ -433,6 +444,14 @@ static void null_cs_control(u32 command) | |||
433 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); | 444 | pr_debug("pl022: dummy chip select control, CS=0x%x\n", command); |
434 | } | 445 | } |
435 | 446 | ||
447 | static void pl022_cs_control(struct pl022 *pl022, u32 command) | ||
448 | { | ||
449 | if (gpio_is_valid(pl022->cur_cs)) | ||
450 | gpio_set_value(pl022->cur_cs, command); | ||
451 | else | ||
452 | pl022->cur_chip->cs_control(command); | ||
453 | } | ||
454 | |||
436 | /** | 455 | /** |
437 | * giveback - current spi_message is over, schedule next message and call | 456 | * giveback - current spi_message is over, schedule next message and call |
438 | * callback of this message. Assumes that caller already | 457 | * callback of this message. Assumes that caller already |
@@ -479,7 +498,7 @@ static void giveback(struct pl022 *pl022) | |||
479 | if (next_msg && next_msg->spi != pl022->cur_msg->spi) | 498 | if (next_msg && next_msg->spi != pl022->cur_msg->spi) |
480 | next_msg = NULL; | 499 | next_msg = NULL; |
481 | if (!next_msg || pl022->cur_msg->state == STATE_ERROR) | 500 | if (!next_msg || pl022->cur_msg->state == STATE_ERROR) |
482 | pl022->cur_chip->cs_control(SSP_CHIP_DESELECT); | 501 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); |
483 | else | 502 | else |
484 | pl022->next_msg_cs_active = true; | 503 | pl022->next_msg_cs_active = true; |
485 | 504 | ||
@@ -818,8 +837,7 @@ static void dma_callback(void *data) | |||
818 | /* Update total bytes transferred */ | 837 | /* Update total bytes transferred */ |
819 | msg->actual_length += pl022->cur_transfer->len; | 838 | msg->actual_length += pl022->cur_transfer->len; |
820 | if (pl022->cur_transfer->cs_change) | 839 | if (pl022->cur_transfer->cs_change) |
821 | pl022->cur_chip-> | 840 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); |
822 | cs_control(SSP_CHIP_DESELECT); | ||
823 | 841 | ||
824 | /* Move to next transfer */ | 842 | /* Move to next transfer */ |
825 | msg->state = next_transfer(pl022); | 843 | msg->state = next_transfer(pl022); |
@@ -1252,8 +1270,7 @@ static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id) | |||
1252 | /* Update total bytes transferred */ | 1270 | /* Update total bytes transferred */ |
1253 | msg->actual_length += pl022->cur_transfer->len; | 1271 | msg->actual_length += pl022->cur_transfer->len; |
1254 | if (pl022->cur_transfer->cs_change) | 1272 | if (pl022->cur_transfer->cs_change) |
1255 | pl022->cur_chip-> | 1273 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); |
1256 | cs_control(SSP_CHIP_DESELECT); | ||
1257 | /* Move to next transfer */ | 1274 | /* Move to next transfer */ |
1258 | msg->state = next_transfer(pl022); | 1275 | msg->state = next_transfer(pl022); |
1259 | tasklet_schedule(&pl022->pump_transfers); | 1276 | tasklet_schedule(&pl022->pump_transfers); |
@@ -1338,7 +1355,7 @@ static void pump_transfers(unsigned long data) | |||
1338 | 1355 | ||
1339 | /* Reselect chip select only if cs_change was requested */ | 1356 | /* Reselect chip select only if cs_change was requested */ |
1340 | if (previous->cs_change) | 1357 | if (previous->cs_change) |
1341 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); | 1358 | pl022_cs_control(pl022, SSP_CHIP_SELECT); |
1342 | } else { | 1359 | } else { |
1343 | /* STATE_START */ | 1360 | /* STATE_START */ |
1344 | message->state = STATE_RUNNING; | 1361 | message->state = STATE_RUNNING; |
@@ -1377,7 +1394,7 @@ static void do_interrupt_dma_transfer(struct pl022 *pl022) | |||
1377 | 1394 | ||
1378 | /* Enable target chip, if not already active */ | 1395 | /* Enable target chip, if not already active */ |
1379 | if (!pl022->next_msg_cs_active) | 1396 | if (!pl022->next_msg_cs_active) |
1380 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); | 1397 | pl022_cs_control(pl022, SSP_CHIP_SELECT); |
1381 | 1398 | ||
1382 | if (set_up_next_transfer(pl022, pl022->cur_transfer)) { | 1399 | if (set_up_next_transfer(pl022, pl022->cur_transfer)) { |
1383 | /* Error path */ | 1400 | /* Error path */ |
@@ -1429,12 +1446,12 @@ static void do_polling_transfer(struct pl022 *pl022) | |||
1429 | if (previous->delay_usecs) | 1446 | if (previous->delay_usecs) |
1430 | udelay(previous->delay_usecs); | 1447 | udelay(previous->delay_usecs); |
1431 | if (previous->cs_change) | 1448 | if (previous->cs_change) |
1432 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); | 1449 | pl022_cs_control(pl022, SSP_CHIP_SELECT); |
1433 | } else { | 1450 | } else { |
1434 | /* STATE_START */ | 1451 | /* STATE_START */ |
1435 | message->state = STATE_RUNNING; | 1452 | message->state = STATE_RUNNING; |
1436 | if (!pl022->next_msg_cs_active) | 1453 | if (!pl022->next_msg_cs_active) |
1437 | pl022->cur_chip->cs_control(SSP_CHIP_SELECT); | 1454 | pl022_cs_control(pl022, SSP_CHIP_SELECT); |
1438 | } | 1455 | } |
1439 | 1456 | ||
1440 | /* Configuration Changing Per Transfer */ | 1457 | /* Configuration Changing Per Transfer */ |
@@ -1466,7 +1483,7 @@ static void do_polling_transfer(struct pl022 *pl022) | |||
1466 | /* Update total byte transferred */ | 1483 | /* Update total byte transferred */ |
1467 | message->actual_length += pl022->cur_transfer->len; | 1484 | message->actual_length += pl022->cur_transfer->len; |
1468 | if (pl022->cur_transfer->cs_change) | 1485 | if (pl022->cur_transfer->cs_change) |
1469 | pl022->cur_chip->cs_control(SSP_CHIP_DESELECT); | 1486 | pl022_cs_control(pl022, SSP_CHIP_DESELECT); |
1470 | /* Move to next transfer */ | 1487 | /* Move to next transfer */ |
1471 | message->state = next_transfer(pl022); | 1488 | message->state = next_transfer(pl022); |
1472 | } | 1489 | } |
@@ -1495,6 +1512,7 @@ static int pl022_transfer_one_message(struct spi_master *master, | |||
1495 | 1512 | ||
1496 | /* Setup the SPI using the per chip configuration */ | 1513 | /* Setup the SPI using the per chip configuration */ |
1497 | pl022->cur_chip = spi_get_ctldata(msg->spi); | 1514 | pl022->cur_chip = spi_get_ctldata(msg->spi); |
1515 | pl022->cur_cs = pl022->chipselects[msg->spi->chip_select]; | ||
1498 | 1516 | ||
1499 | restore_state(pl022); | 1517 | restore_state(pl022); |
1500 | flush(pl022); | 1518 | flush(pl022); |
@@ -1766,12 +1784,14 @@ static const struct pl022_config_chip pl022_default_chip_info = { | |||
1766 | static int pl022_setup(struct spi_device *spi) | 1784 | static int pl022_setup(struct spi_device *spi) |
1767 | { | 1785 | { |
1768 | struct pl022_config_chip const *chip_info; | 1786 | struct pl022_config_chip const *chip_info; |
1787 | struct pl022_config_chip chip_info_dt; | ||
1769 | struct chip_data *chip; | 1788 | struct chip_data *chip; |
1770 | struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0}; | 1789 | struct ssp_clock_params clk_freq = { .cpsdvsr = 0, .scr = 0}; |
1771 | int status = 0; | 1790 | int status = 0; |
1772 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); | 1791 | struct pl022 *pl022 = spi_master_get_devdata(spi->master); |
1773 | unsigned int bits = spi->bits_per_word; | 1792 | unsigned int bits = spi->bits_per_word; |
1774 | u32 tmp; | 1793 | u32 tmp; |
1794 | struct device_node *np = spi->dev.of_node; | ||
1775 | 1795 | ||
1776 | if (!spi->max_speed_hz) | 1796 | if (!spi->max_speed_hz) |
1777 | return -EINVAL; | 1797 | return -EINVAL; |
@@ -1794,10 +1814,32 @@ static int pl022_setup(struct spi_device *spi) | |||
1794 | chip_info = spi->controller_data; | 1814 | chip_info = spi->controller_data; |
1795 | 1815 | ||
1796 | if (chip_info == NULL) { | 1816 | if (chip_info == NULL) { |
1797 | chip_info = &pl022_default_chip_info; | 1817 | if (np) { |
1798 | /* spi_board_info.controller_data not is supplied */ | 1818 | chip_info_dt = pl022_default_chip_info; |
1799 | dev_dbg(&spi->dev, | 1819 | |
1800 | "using default controller_data settings\n"); | 1820 | chip_info_dt.hierarchy = SSP_MASTER; |
1821 | of_property_read_u32(np, "pl022,interface", | ||
1822 | &chip_info_dt.iface); | ||
1823 | of_property_read_u32(np, "pl022,com-mode", | ||
1824 | &chip_info_dt.com_mode); | ||
1825 | of_property_read_u32(np, "pl022,rx-level-trig", | ||
1826 | &chip_info_dt.rx_lev_trig); | ||
1827 | of_property_read_u32(np, "pl022,tx-level-trig", | ||
1828 | &chip_info_dt.tx_lev_trig); | ||
1829 | of_property_read_u32(np, "pl022,ctrl-len", | ||
1830 | &chip_info_dt.ctrl_len); | ||
1831 | of_property_read_u32(np, "pl022,wait-state", | ||
1832 | &chip_info_dt.wait_state); | ||
1833 | of_property_read_u32(np, "pl022,duplex", | ||
1834 | &chip_info_dt.duplex); | ||
1835 | |||
1836 | chip_info = &chip_info_dt; | ||
1837 | } else { | ||
1838 | chip_info = &pl022_default_chip_info; | ||
1839 | /* spi_board_info.controller_data not is supplied */ | ||
1840 | dev_dbg(&spi->dev, | ||
1841 | "using default controller_data settings\n"); | ||
1842 | } | ||
1801 | } else | 1843 | } else |
1802 | dev_dbg(&spi->dev, | 1844 | dev_dbg(&spi->dev, |
1803 | "using user supplied controller_data settings\n"); | 1845 | "using user supplied controller_data settings\n"); |
@@ -1840,8 +1882,9 @@ static int pl022_setup(struct spi_device *spi) | |||
1840 | chip->xfer_type = chip_info->com_mode; | 1882 | chip->xfer_type = chip_info->com_mode; |
1841 | if (!chip_info->cs_control) { | 1883 | if (!chip_info->cs_control) { |
1842 | chip->cs_control = null_cs_control; | 1884 | chip->cs_control = null_cs_control; |
1843 | dev_warn(&spi->dev, | 1885 | if (!gpio_is_valid(pl022->chipselects[spi->chip_select])) |
1844 | "chip select function is NULL for this chip\n"); | 1886 | dev_warn(&spi->dev, |
1887 | "invalid chip select\n"); | ||
1845 | } else | 1888 | } else |
1846 | chip->cs_control = chip_info->cs_control; | 1889 | chip->cs_control = chip_info->cs_control; |
1847 | 1890 | ||
@@ -1986,6 +2029,34 @@ static void pl022_cleanup(struct spi_device *spi) | |||
1986 | kfree(chip); | 2029 | kfree(chip); |
1987 | } | 2030 | } |
1988 | 2031 | ||
2032 | static struct pl022_ssp_controller * | ||
2033 | pl022_platform_data_dt_get(struct device *dev) | ||
2034 | { | ||
2035 | struct device_node *np = dev->of_node; | ||
2036 | struct pl022_ssp_controller *pd; | ||
2037 | u32 tmp; | ||
2038 | |||
2039 | if (!np) { | ||
2040 | dev_err(dev, "no dt node defined\n"); | ||
2041 | return NULL; | ||
2042 | } | ||
2043 | |||
2044 | pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL); | ||
2045 | if (!pd) { | ||
2046 | dev_err(dev, "cannot allocate platform data memory\n"); | ||
2047 | return NULL; | ||
2048 | } | ||
2049 | |||
2050 | pd->bus_id = -1; | ||
2051 | of_property_read_u32(np, "num-cs", &tmp); | ||
2052 | pd->num_chipselect = tmp; | ||
2053 | of_property_read_u32(np, "pl022,autosuspend-delay", | ||
2054 | &pd->autosuspend_delay); | ||
2055 | pd->rt = of_property_read_bool(np, "pl022,rt"); | ||
2056 | |||
2057 | return pd; | ||
2058 | } | ||
2059 | |||
1989 | static int __devinit | 2060 | static int __devinit |
1990 | pl022_probe(struct amba_device *adev, const struct amba_id *id) | 2061 | pl022_probe(struct amba_device *adev, const struct amba_id *id) |
1991 | { | 2062 | { |
@@ -1993,22 +2064,31 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
1993 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; | 2064 | struct pl022_ssp_controller *platform_info = adev->dev.platform_data; |
1994 | struct spi_master *master; | 2065 | struct spi_master *master; |
1995 | struct pl022 *pl022 = NULL; /*Data for this driver */ | 2066 | struct pl022 *pl022 = NULL; /*Data for this driver */ |
1996 | int status = 0; | 2067 | struct device_node *np = adev->dev.of_node; |
2068 | int status = 0, i, num_cs; | ||
1997 | 2069 | ||
1998 | dev_info(&adev->dev, | 2070 | dev_info(&adev->dev, |
1999 | "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); | 2071 | "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid); |
2000 | if (platform_info == NULL) { | 2072 | if (!platform_info && IS_ENABLED(CONFIG_OF)) |
2001 | dev_err(&adev->dev, "probe - no platform data supplied\n"); | 2073 | platform_info = pl022_platform_data_dt_get(dev); |
2002 | status = -ENODEV; | 2074 | |
2003 | goto err_no_pdata; | 2075 | if (!platform_info) { |
2076 | dev_err(dev, "probe: no platform data defined\n"); | ||
2077 | return -ENODEV; | ||
2078 | } | ||
2079 | |||
2080 | if (platform_info->num_chipselect) { | ||
2081 | num_cs = platform_info->num_chipselect; | ||
2082 | } else { | ||
2083 | dev_err(dev, "probe: no chip select defined\n"); | ||
2084 | return -ENODEV; | ||
2004 | } | 2085 | } |
2005 | 2086 | ||
2006 | /* Allocate master with space for data */ | 2087 | /* Allocate master with space for data */ |
2007 | master = spi_alloc_master(dev, sizeof(struct pl022)); | 2088 | master = spi_alloc_master(dev, sizeof(struct pl022)); |
2008 | if (master == NULL) { | 2089 | if (master == NULL) { |
2009 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); | 2090 | dev_err(&adev->dev, "probe - cannot alloc SPI master\n"); |
2010 | status = -ENOMEM; | 2091 | return -ENOMEM; |
2011 | goto err_no_master; | ||
2012 | } | 2092 | } |
2013 | 2093 | ||
2014 | pl022 = spi_master_get_devdata(master); | 2094 | pl022 = spi_master_get_devdata(master); |
@@ -2016,19 +2096,71 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2016 | pl022->master_info = platform_info; | 2096 | pl022->master_info = platform_info; |
2017 | pl022->adev = adev; | 2097 | pl022->adev = adev; |
2018 | pl022->vendor = id->data; | 2098 | pl022->vendor = id->data; |
2099 | pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), | ||
2100 | GFP_KERNEL); | ||
2101 | |||
2102 | pl022->pinctrl = devm_pinctrl_get(dev); | ||
2103 | if (IS_ERR(pl022->pinctrl)) { | ||
2104 | status = PTR_ERR(pl022->pinctrl); | ||
2105 | goto err_no_pinctrl; | ||
2106 | } | ||
2107 | |||
2108 | pl022->pins_default = pinctrl_lookup_state(pl022->pinctrl, | ||
2109 | PINCTRL_STATE_DEFAULT); | ||
2110 | /* enable pins to be muxed in and configured */ | ||
2111 | if (!IS_ERR(pl022->pins_default)) { | ||
2112 | status = pinctrl_select_state(pl022->pinctrl, | ||
2113 | pl022->pins_default); | ||
2114 | if (status) | ||
2115 | dev_err(dev, "could not set default pins\n"); | ||
2116 | } else | ||
2117 | dev_err(dev, "could not get default pinstate\n"); | ||
2118 | |||
2119 | pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl, | ||
2120 | PINCTRL_STATE_SLEEP); | ||
2121 | if (IS_ERR(pl022->pins_sleep)) | ||
2122 | dev_dbg(dev, "could not get sleep pinstate\n"); | ||
2019 | 2123 | ||
2020 | /* | 2124 | /* |
2021 | * Bus Number Which has been Assigned to this SSP controller | 2125 | * Bus Number Which has been Assigned to this SSP controller |
2022 | * on this board | 2126 | * on this board |
2023 | */ | 2127 | */ |
2024 | master->bus_num = platform_info->bus_id; | 2128 | master->bus_num = platform_info->bus_id; |
2025 | master->num_chipselect = platform_info->num_chipselect; | 2129 | master->num_chipselect = num_cs; |
2026 | master->cleanup = pl022_cleanup; | 2130 | master->cleanup = pl022_cleanup; |
2027 | master->setup = pl022_setup; | 2131 | master->setup = pl022_setup; |
2028 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; | 2132 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; |
2029 | master->transfer_one_message = pl022_transfer_one_message; | 2133 | master->transfer_one_message = pl022_transfer_one_message; |
2030 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; | 2134 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; |
2031 | master->rt = platform_info->rt; | 2135 | master->rt = platform_info->rt; |
2136 | master->dev.of_node = dev->of_node; | ||
2137 | |||
2138 | if (platform_info->num_chipselect && platform_info->chipselects) { | ||
2139 | for (i = 0; i < num_cs; i++) | ||
2140 | pl022->chipselects[i] = platform_info->chipselects[i]; | ||
2141 | } else if (IS_ENABLED(CONFIG_OF)) { | ||
2142 | for (i = 0; i < num_cs; i++) { | ||
2143 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | ||
2144 | |||
2145 | if (cs_gpio == -EPROBE_DEFER) { | ||
2146 | status = -EPROBE_DEFER; | ||
2147 | goto err_no_gpio; | ||
2148 | } | ||
2149 | |||
2150 | pl022->chipselects[i] = cs_gpio; | ||
2151 | |||
2152 | if (gpio_is_valid(cs_gpio)) { | ||
2153 | if (devm_gpio_request(dev, cs_gpio, "ssp-pl022")) | ||
2154 | dev_err(&adev->dev, | ||
2155 | "could not request %d gpio\n", | ||
2156 | cs_gpio); | ||
2157 | else if (gpio_direction_output(cs_gpio, 1)) | ||
2158 | dev_err(&adev->dev, | ||
2159 | "could set gpio %d as output\n", | ||
2160 | cs_gpio); | ||
2161 | } | ||
2162 | } | ||
2163 | } | ||
2032 | 2164 | ||
2033 | /* | 2165 | /* |
2034 | * Supports mode 0-3, loopback, and active low CS. Transfers are | 2166 | * Supports mode 0-3, loopback, and active low CS. Transfers are |
@@ -2045,7 +2177,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2045 | goto err_no_ioregion; | 2177 | goto err_no_ioregion; |
2046 | 2178 | ||
2047 | pl022->phybase = adev->res.start; | 2179 | pl022->phybase = adev->res.start; |
2048 | pl022->virtbase = ioremap(adev->res.start, resource_size(&adev->res)); | 2180 | pl022->virtbase = devm_ioremap(dev, adev->res.start, |
2181 | resource_size(&adev->res)); | ||
2049 | if (pl022->virtbase == NULL) { | 2182 | if (pl022->virtbase == NULL) { |
2050 | status = -ENOMEM; | 2183 | status = -ENOMEM; |
2051 | goto err_no_ioremap; | 2184 | goto err_no_ioremap; |
@@ -2055,7 +2188,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2055 | 2188 | ||
2056 | pm_runtime_resume(dev); | 2189 | pm_runtime_resume(dev); |
2057 | 2190 | ||
2058 | pl022->clk = clk_get(&adev->dev, NULL); | 2191 | pl022->clk = devm_clk_get(&adev->dev, NULL); |
2059 | if (IS_ERR(pl022->clk)) { | 2192 | if (IS_ERR(pl022->clk)) { |
2060 | status = PTR_ERR(pl022->clk); | 2193 | status = PTR_ERR(pl022->clk); |
2061 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); | 2194 | dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n"); |
@@ -2083,8 +2216,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2083 | SSP_CR1(pl022->virtbase)); | 2216 | SSP_CR1(pl022->virtbase)); |
2084 | load_ssp_default_config(pl022); | 2217 | load_ssp_default_config(pl022); |
2085 | 2218 | ||
2086 | status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", | 2219 | status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler, |
2087 | pl022); | 2220 | 0, "pl022", pl022); |
2088 | if (status < 0) { | 2221 | if (status < 0) { |
2089 | dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status); | 2222 | dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status); |
2090 | goto err_no_irq; | 2223 | goto err_no_irq; |
@@ -2124,22 +2257,18 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2124 | err_spi_register: | 2257 | err_spi_register: |
2125 | if (platform_info->enable_dma) | 2258 | if (platform_info->enable_dma) |
2126 | pl022_dma_remove(pl022); | 2259 | pl022_dma_remove(pl022); |
2127 | |||
2128 | free_irq(adev->irq[0], pl022); | ||
2129 | err_no_irq: | 2260 | err_no_irq: |
2130 | clk_disable(pl022->clk); | 2261 | clk_disable(pl022->clk); |
2131 | err_no_clk_en: | 2262 | err_no_clk_en: |
2132 | clk_unprepare(pl022->clk); | 2263 | clk_unprepare(pl022->clk); |
2133 | err_clk_prep: | 2264 | err_clk_prep: |
2134 | clk_put(pl022->clk); | ||
2135 | err_no_clk: | 2265 | err_no_clk: |
2136 | iounmap(pl022->virtbase); | ||
2137 | err_no_ioremap: | 2266 | err_no_ioremap: |
2138 | amba_release_regions(adev); | 2267 | amba_release_regions(adev); |
2139 | err_no_ioregion: | 2268 | err_no_ioregion: |
2269 | err_no_gpio: | ||
2270 | err_no_pinctrl: | ||
2140 | spi_master_put(master); | 2271 | spi_master_put(master); |
2141 | err_no_master: | ||
2142 | err_no_pdata: | ||
2143 | return status; | 2272 | return status; |
2144 | } | 2273 | } |
2145 | 2274 | ||
@@ -2161,20 +2290,55 @@ pl022_remove(struct amba_device *adev) | |||
2161 | if (pl022->master_info->enable_dma) | 2290 | if (pl022->master_info->enable_dma) |
2162 | pl022_dma_remove(pl022); | 2291 | pl022_dma_remove(pl022); |
2163 | 2292 | ||
2164 | free_irq(adev->irq[0], pl022); | ||
2165 | clk_disable(pl022->clk); | 2293 | clk_disable(pl022->clk); |
2166 | clk_unprepare(pl022->clk); | 2294 | clk_unprepare(pl022->clk); |
2167 | clk_put(pl022->clk); | ||
2168 | pm_runtime_disable(&adev->dev); | 2295 | pm_runtime_disable(&adev->dev); |
2169 | iounmap(pl022->virtbase); | ||
2170 | amba_release_regions(adev); | 2296 | amba_release_regions(adev); |
2171 | tasklet_disable(&pl022->pump_transfers); | 2297 | tasklet_disable(&pl022->pump_transfers); |
2172 | spi_unregister_master(pl022->master); | 2298 | spi_unregister_master(pl022->master); |
2173 | spi_master_put(pl022->master); | ||
2174 | amba_set_drvdata(adev, NULL); | 2299 | amba_set_drvdata(adev, NULL); |
2175 | return 0; | 2300 | return 0; |
2176 | } | 2301 | } |
2177 | 2302 | ||
2303 | #if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME) | ||
2304 | /* | ||
2305 | * These two functions are used from both suspend/resume and | ||
2306 | * the runtime counterparts to handle external resources like | ||
2307 | * clocks, pins and regulators when going to sleep. | ||
2308 | */ | ||
2309 | static void pl022_suspend_resources(struct pl022 *pl022) | ||
2310 | { | ||
2311 | int ret; | ||
2312 | |||
2313 | clk_disable(pl022->clk); | ||
2314 | |||
2315 | /* Optionally let pins go into sleep states */ | ||
2316 | if (!IS_ERR(pl022->pins_sleep)) { | ||
2317 | ret = pinctrl_select_state(pl022->pinctrl, | ||
2318 | pl022->pins_sleep); | ||
2319 | if (ret) | ||
2320 | dev_err(&pl022->adev->dev, | ||
2321 | "could not set pins to sleep state\n"); | ||
2322 | } | ||
2323 | } | ||
2324 | |||
2325 | static void pl022_resume_resources(struct pl022 *pl022) | ||
2326 | { | ||
2327 | int ret; | ||
2328 | |||
2329 | /* Optionaly enable pins to be muxed in and configured */ | ||
2330 | if (!IS_ERR(pl022->pins_default)) { | ||
2331 | ret = pinctrl_select_state(pl022->pinctrl, | ||
2332 | pl022->pins_default); | ||
2333 | if (ret) | ||
2334 | dev_err(&pl022->adev->dev, | ||
2335 | "could not set default pins\n"); | ||
2336 | } | ||
2337 | |||
2338 | clk_enable(pl022->clk); | ||
2339 | } | ||
2340 | #endif | ||
2341 | |||
2178 | #ifdef CONFIG_SUSPEND | 2342 | #ifdef CONFIG_SUSPEND |
2179 | static int pl022_suspend(struct device *dev) | 2343 | static int pl022_suspend(struct device *dev) |
2180 | { | 2344 | { |
@@ -2186,6 +2350,7 @@ static int pl022_suspend(struct device *dev) | |||
2186 | dev_warn(dev, "cannot suspend master\n"); | 2350 | dev_warn(dev, "cannot suspend master\n"); |
2187 | return ret; | 2351 | return ret; |
2188 | } | 2352 | } |
2353 | pl022_suspend_resources(pl022); | ||
2189 | 2354 | ||
2190 | dev_dbg(dev, "suspended\n"); | 2355 | dev_dbg(dev, "suspended\n"); |
2191 | return 0; | 2356 | return 0; |
@@ -2196,6 +2361,8 @@ static int pl022_resume(struct device *dev) | |||
2196 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2361 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2197 | int ret; | 2362 | int ret; |
2198 | 2363 | ||
2364 | pl022_resume_resources(pl022); | ||
2365 | |||
2199 | /* Start the queue running */ | 2366 | /* Start the queue running */ |
2200 | ret = spi_master_resume(pl022->master); | 2367 | ret = spi_master_resume(pl022->master); |
2201 | if (ret) | 2368 | if (ret) |
@@ -2212,8 +2379,7 @@ static int pl022_runtime_suspend(struct device *dev) | |||
2212 | { | 2379 | { |
2213 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2380 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2214 | 2381 | ||
2215 | clk_disable(pl022->clk); | 2382 | pl022_suspend_resources(pl022); |
2216 | |||
2217 | return 0; | 2383 | return 0; |
2218 | } | 2384 | } |
2219 | 2385 | ||
@@ -2221,8 +2387,7 @@ static int pl022_runtime_resume(struct device *dev) | |||
2221 | { | 2387 | { |
2222 | struct pl022 *pl022 = dev_get_drvdata(dev); | 2388 | struct pl022 *pl022 = dev_get_drvdata(dev); |
2223 | 2389 | ||
2224 | clk_enable(pl022->clk); | 2390 | pl022_resume_resources(pl022); |
2225 | |||
2226 | return 0; | 2391 | return 0; |
2227 | } | 2392 | } |
2228 | #endif | 2393 | #endif |
diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index 8ee7d790ce49..a2a080b7f42b 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c | |||
@@ -611,6 +611,7 @@ static int __devinit s3c24xx_spi_probe(struct platform_device *pdev) | |||
611 | if (!pdata->set_cs) { | 611 | if (!pdata->set_cs) { |
612 | if (pdata->pin_cs < 0) { | 612 | if (pdata->pin_cs < 0) { |
613 | dev_err(&pdev->dev, "No chipselect pin\n"); | 613 | dev_err(&pdev->dev, "No chipselect pin\n"); |
614 | err = -EINVAL; | ||
614 | goto err_register; | 615 | goto err_register; |
615 | } | 616 | } |
616 | 617 | ||
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 0e2a02228d5e..1860c3aca7e2 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -976,7 +976,8 @@ err_msgq: | |||
976 | spi_set_ctldata(spi, NULL); | 976 | spi_set_ctldata(spi, NULL); |
977 | 977 | ||
978 | err_gpio_req: | 978 | err_gpio_req: |
979 | kfree(cs); | 979 | if (spi->dev.of_node) |
980 | kfree(cs); | ||
980 | 981 | ||
981 | return err; | 982 | return err; |
982 | } | 983 | } |
@@ -1409,7 +1410,7 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) | |||
1409 | #ifdef CONFIG_PM | 1410 | #ifdef CONFIG_PM |
1410 | static int s3c64xx_spi_suspend(struct device *dev) | 1411 | static int s3c64xx_spi_suspend(struct device *dev) |
1411 | { | 1412 | { |
1412 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 1413 | struct spi_master *master = dev_get_drvdata(dev); |
1413 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); | 1414 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); |
1414 | 1415 | ||
1415 | spi_master_suspend(master); | 1416 | spi_master_suspend(master); |
@@ -1428,7 +1429,7 @@ static int s3c64xx_spi_suspend(struct device *dev) | |||
1428 | 1429 | ||
1429 | static int s3c64xx_spi_resume(struct device *dev) | 1430 | static int s3c64xx_spi_resume(struct device *dev) |
1430 | { | 1431 | { |
1431 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 1432 | struct spi_master *master = dev_get_drvdata(dev); |
1432 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); | 1433 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); |
1433 | struct s3c64xx_spi_info *sci = sdd->cntrlr_info; | 1434 | struct s3c64xx_spi_info *sci = sdd->cntrlr_info; |
1434 | 1435 | ||
@@ -1452,7 +1453,7 @@ static int s3c64xx_spi_resume(struct device *dev) | |||
1452 | #ifdef CONFIG_PM_RUNTIME | 1453 | #ifdef CONFIG_PM_RUNTIME |
1453 | static int s3c64xx_spi_runtime_suspend(struct device *dev) | 1454 | static int s3c64xx_spi_runtime_suspend(struct device *dev) |
1454 | { | 1455 | { |
1455 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 1456 | struct spi_master *master = dev_get_drvdata(dev); |
1456 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); | 1457 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); |
1457 | 1458 | ||
1458 | clk_disable(sdd->clk); | 1459 | clk_disable(sdd->clk); |
@@ -1463,7 +1464,7 @@ static int s3c64xx_spi_runtime_suspend(struct device *dev) | |||
1463 | 1464 | ||
1464 | static int s3c64xx_spi_runtime_resume(struct device *dev) | 1465 | static int s3c64xx_spi_runtime_resume(struct device *dev) |
1465 | { | 1466 | { |
1466 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 1467 | struct spi_master *master = dev_get_drvdata(dev); |
1467 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); | 1468 | struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); |
1468 | 1469 | ||
1469 | clk_enable(sdd->src_clk); | 1470 | clk_enable(sdd->src_clk); |
diff --git a/drivers/spi/spi-sc18is602.c b/drivers/spi/spi-sc18is602.c new file mode 100644 index 000000000000..9eda21d739c6 --- /dev/null +++ b/drivers/spi/spi-sc18is602.c | |||
@@ -0,0 +1,364 @@ | |||
1 | /* | ||
2 | * NXP SC18IS602/603 SPI driver | ||
3 | * | ||
4 | * Copyright (C) Guenter Roeck <linux@roeck-us.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/pm_runtime.h> | ||
28 | #include <linux/of.h> | ||
29 | #include <linux/platform_data/sc18is602.h> | ||
30 | |||
31 | enum chips { sc18is602, sc18is602b, sc18is603 }; | ||
32 | |||
33 | #define SC18IS602_BUFSIZ 200 | ||
34 | #define SC18IS602_CLOCK 7372000 | ||
35 | |||
36 | #define SC18IS602_MODE_CPHA BIT(2) | ||
37 | #define SC18IS602_MODE_CPOL BIT(3) | ||
38 | #define SC18IS602_MODE_LSB_FIRST BIT(5) | ||
39 | #define SC18IS602_MODE_CLOCK_DIV_4 0x0 | ||
40 | #define SC18IS602_MODE_CLOCK_DIV_16 0x1 | ||
41 | #define SC18IS602_MODE_CLOCK_DIV_64 0x2 | ||
42 | #define SC18IS602_MODE_CLOCK_DIV_128 0x3 | ||
43 | |||
44 | struct sc18is602 { | ||
45 | struct spi_master *master; | ||
46 | struct device *dev; | ||
47 | u8 ctrl; | ||
48 | u32 freq; | ||
49 | u32 speed; | ||
50 | |||
51 | /* I2C data */ | ||
52 | struct i2c_client *client; | ||
53 | enum chips id; | ||
54 | u8 buffer[SC18IS602_BUFSIZ + 1]; | ||
55 | int tlen; /* Data queued for tx in buffer */ | ||
56 | int rindex; /* Receive data index in buffer */ | ||
57 | }; | ||
58 | |||
59 | static int sc18is602_wait_ready(struct sc18is602 *hw, int len) | ||
60 | { | ||
61 | int i, err; | ||
62 | int usecs = 1000000 * len / hw->speed + 1; | ||
63 | u8 dummy[1]; | ||
64 | |||
65 | for (i = 0; i < 10; i++) { | ||
66 | err = i2c_master_recv(hw->client, dummy, 1); | ||
67 | if (err >= 0) | ||
68 | return 0; | ||
69 | usleep_range(usecs, usecs * 2); | ||
70 | } | ||
71 | return -ETIMEDOUT; | ||
72 | } | ||
73 | |||
74 | static int sc18is602_txrx(struct sc18is602 *hw, struct spi_message *msg, | ||
75 | struct spi_transfer *t, bool do_transfer) | ||
76 | { | ||
77 | unsigned int len = t->len; | ||
78 | int ret; | ||
79 | |||
80 | if (hw->tlen == 0) { | ||
81 | /* First byte (I2C command) is chip select */ | ||
82 | hw->buffer[0] = 1 << msg->spi->chip_select; | ||
83 | hw->tlen = 1; | ||
84 | hw->rindex = 0; | ||
85 | } | ||
86 | /* | ||
87 | * We can not immediately send data to the chip, since each I2C message | ||
88 | * resembles a full SPI message (from CS active to CS inactive). | ||
89 | * Enqueue messages up to the first read or until do_transfer is true. | ||
90 | */ | ||
91 | if (t->tx_buf) { | ||
92 | memcpy(&hw->buffer[hw->tlen], t->tx_buf, len); | ||
93 | hw->tlen += len; | ||
94 | if (t->rx_buf) | ||
95 | do_transfer = true; | ||
96 | else | ||
97 | hw->rindex = hw->tlen - 1; | ||
98 | } else if (t->rx_buf) { | ||
99 | /* | ||
100 | * For receive-only transfers we still need to perform a dummy | ||
101 | * write to receive data from the SPI chip. | ||
102 | * Read data starts at the end of transmit data (minus 1 to | ||
103 | * account for CS). | ||
104 | */ | ||
105 | hw->rindex = hw->tlen - 1; | ||
106 | memset(&hw->buffer[hw->tlen], 0, len); | ||
107 | hw->tlen += len; | ||
108 | do_transfer = true; | ||
109 | } | ||
110 | |||
111 | if (do_transfer && hw->tlen > 1) { | ||
112 | ret = sc18is602_wait_ready(hw, SC18IS602_BUFSIZ); | ||
113 | if (ret < 0) | ||
114 | return ret; | ||
115 | ret = i2c_master_send(hw->client, hw->buffer, hw->tlen); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | if (ret != hw->tlen) | ||
119 | return -EIO; | ||
120 | |||
121 | if (t->rx_buf) { | ||
122 | int rlen = hw->rindex + len; | ||
123 | |||
124 | ret = sc18is602_wait_ready(hw, hw->tlen); | ||
125 | if (ret < 0) | ||
126 | return ret; | ||
127 | ret = i2c_master_recv(hw->client, hw->buffer, rlen); | ||
128 | if (ret < 0) | ||
129 | return ret; | ||
130 | if (ret != rlen) | ||
131 | return -EIO; | ||
132 | memcpy(t->rx_buf, &hw->buffer[hw->rindex], len); | ||
133 | } | ||
134 | hw->tlen = 0; | ||
135 | } | ||
136 | return len; | ||
137 | } | ||
138 | |||
139 | static int sc18is602_setup_transfer(struct sc18is602 *hw, u32 hz, u8 mode) | ||
140 | { | ||
141 | u8 ctrl = 0; | ||
142 | int ret; | ||
143 | |||
144 | if (mode & SPI_CPHA) | ||
145 | ctrl |= SC18IS602_MODE_CPHA; | ||
146 | if (mode & SPI_CPOL) | ||
147 | ctrl |= SC18IS602_MODE_CPOL; | ||
148 | if (mode & SPI_LSB_FIRST) | ||
149 | ctrl |= SC18IS602_MODE_LSB_FIRST; | ||
150 | |||
151 | /* Find the closest clock speed */ | ||
152 | if (hz >= hw->freq / 4) { | ||
153 | ctrl |= SC18IS602_MODE_CLOCK_DIV_4; | ||
154 | hw->speed = hw->freq / 4; | ||
155 | } else if (hz >= hw->freq / 16) { | ||
156 | ctrl |= SC18IS602_MODE_CLOCK_DIV_16; | ||
157 | hw->speed = hw->freq / 16; | ||
158 | } else if (hz >= hw->freq / 64) { | ||
159 | ctrl |= SC18IS602_MODE_CLOCK_DIV_64; | ||
160 | hw->speed = hw->freq / 64; | ||
161 | } else { | ||
162 | ctrl |= SC18IS602_MODE_CLOCK_DIV_128; | ||
163 | hw->speed = hw->freq / 128; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * Don't do anything if the control value did not change. The initial | ||
168 | * value of 0xff for hw->ctrl ensures that the correct mode will be set | ||
169 | * with the first call to this function. | ||
170 | */ | ||
171 | if (ctrl == hw->ctrl) | ||
172 | return 0; | ||
173 | |||
174 | ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl); | ||
175 | if (ret < 0) | ||
176 | return ret; | ||
177 | |||
178 | hw->ctrl = ctrl; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int sc18is602_check_transfer(struct spi_device *spi, | ||
184 | struct spi_transfer *t, int tlen) | ||
185 | { | ||
186 | int bpw; | ||
187 | uint32_t hz; | ||
188 | |||
189 | if (t && t->len + tlen > SC18IS602_BUFSIZ) | ||
190 | return -EINVAL; | ||
191 | |||
192 | bpw = spi->bits_per_word; | ||
193 | if (t && t->bits_per_word) | ||
194 | bpw = t->bits_per_word; | ||
195 | if (bpw != 8) | ||
196 | return -EINVAL; | ||
197 | |||
198 | hz = spi->max_speed_hz; | ||
199 | if (t && t->speed_hz) | ||
200 | hz = t->speed_hz; | ||
201 | if (hz == 0) | ||
202 | return -EINVAL; | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int sc18is602_transfer_one(struct spi_master *master, | ||
208 | struct spi_message *m) | ||
209 | { | ||
210 | struct sc18is602 *hw = spi_master_get_devdata(master); | ||
211 | struct spi_device *spi = m->spi; | ||
212 | struct spi_transfer *t; | ||
213 | int status = 0; | ||
214 | |||
215 | /* SC18IS602 does not support CS2 */ | ||
216 | if (hw->id == sc18is602 && spi->chip_select == 2) { | ||
217 | status = -ENXIO; | ||
218 | goto error; | ||
219 | } | ||
220 | |||
221 | hw->tlen = 0; | ||
222 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
223 | u32 hz = t->speed_hz ? : spi->max_speed_hz; | ||
224 | bool do_transfer; | ||
225 | |||
226 | status = sc18is602_check_transfer(spi, t, hw->tlen); | ||
227 | if (status < 0) | ||
228 | break; | ||
229 | |||
230 | status = sc18is602_setup_transfer(hw, hz, spi->mode); | ||
231 | if (status < 0) | ||
232 | break; | ||
233 | |||
234 | do_transfer = t->cs_change || list_is_last(&t->transfer_list, | ||
235 | &m->transfers); | ||
236 | |||
237 | if (t->len) { | ||
238 | status = sc18is602_txrx(hw, m, t, do_transfer); | ||
239 | if (status < 0) | ||
240 | break; | ||
241 | m->actual_length += status; | ||
242 | } | ||
243 | status = 0; | ||
244 | |||
245 | if (t->delay_usecs) | ||
246 | udelay(t->delay_usecs); | ||
247 | } | ||
248 | error: | ||
249 | m->status = status; | ||
250 | spi_finalize_current_message(master); | ||
251 | |||
252 | return status; | ||
253 | } | ||
254 | |||
255 | static int sc18is602_setup(struct spi_device *spi) | ||
256 | { | ||
257 | if (!spi->bits_per_word) | ||
258 | spi->bits_per_word = 8; | ||
259 | |||
260 | if (spi->mode & ~(SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST)) | ||
261 | return -EINVAL; | ||
262 | |||
263 | return sc18is602_check_transfer(spi, NULL, 0); | ||
264 | } | ||
265 | |||
266 | static int sc18is602_probe(struct i2c_client *client, | ||
267 | const struct i2c_device_id *id) | ||
268 | { | ||
269 | struct device *dev = &client->dev; | ||
270 | struct device_node *np = dev->of_node; | ||
271 | struct sc18is602_platform_data *pdata = dev_get_platdata(dev); | ||
272 | struct sc18is602 *hw; | ||
273 | struct spi_master *master; | ||
274 | int error; | ||
275 | |||
276 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | | ||
277 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
278 | return -EINVAL; | ||
279 | |||
280 | master = spi_alloc_master(dev, sizeof(struct sc18is602)); | ||
281 | if (!master) | ||
282 | return -ENOMEM; | ||
283 | |||
284 | hw = spi_master_get_devdata(master); | ||
285 | i2c_set_clientdata(client, hw); | ||
286 | |||
287 | hw->master = master; | ||
288 | hw->client = client; | ||
289 | hw->dev = dev; | ||
290 | hw->ctrl = 0xff; | ||
291 | |||
292 | hw->id = id->driver_data; | ||
293 | |||
294 | switch (hw->id) { | ||
295 | case sc18is602: | ||
296 | case sc18is602b: | ||
297 | master->num_chipselect = 4; | ||
298 | hw->freq = SC18IS602_CLOCK; | ||
299 | break; | ||
300 | case sc18is603: | ||
301 | master->num_chipselect = 2; | ||
302 | if (pdata) { | ||
303 | hw->freq = pdata->clock_frequency; | ||
304 | } else { | ||
305 | const __be32 *val; | ||
306 | int len; | ||
307 | |||
308 | val = of_get_property(np, "clock-frequency", &len); | ||
309 | if (val && len >= sizeof(__be32)) | ||
310 | hw->freq = be32_to_cpup(val); | ||
311 | } | ||
312 | if (!hw->freq) | ||
313 | hw->freq = SC18IS602_CLOCK; | ||
314 | break; | ||
315 | } | ||
316 | master->bus_num = client->adapter->nr; | ||
317 | master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; | ||
318 | master->setup = sc18is602_setup; | ||
319 | master->transfer_one_message = sc18is602_transfer_one; | ||
320 | master->dev.of_node = np; | ||
321 | |||
322 | error = spi_register_master(master); | ||
323 | if (error) | ||
324 | goto error_reg; | ||
325 | |||
326 | return 0; | ||
327 | |||
328 | error_reg: | ||
329 | spi_master_put(master); | ||
330 | return error; | ||
331 | } | ||
332 | |||
333 | static int sc18is602_remove(struct i2c_client *client) | ||
334 | { | ||
335 | struct sc18is602 *hw = i2c_get_clientdata(client); | ||
336 | struct spi_master *master = hw->master; | ||
337 | |||
338 | spi_unregister_master(master); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static const struct i2c_device_id sc18is602_id[] = { | ||
344 | { "sc18is602", sc18is602 }, | ||
345 | { "sc18is602b", sc18is602b }, | ||
346 | { "sc18is603", sc18is603 }, | ||
347 | { } | ||
348 | }; | ||
349 | MODULE_DEVICE_TABLE(i2c, sc18is602_id); | ||
350 | |||
351 | static struct i2c_driver sc18is602_driver = { | ||
352 | .driver = { | ||
353 | .name = "sc18is602", | ||
354 | }, | ||
355 | .probe = sc18is602_probe, | ||
356 | .remove = sc18is602_remove, | ||
357 | .id_table = sc18is602_id, | ||
358 | }; | ||
359 | |||
360 | module_i2c_driver(sc18is602_driver); | ||
361 | |||
362 | MODULE_DESCRIPTION("SC18IC602/603 SPI Master Driver"); | ||
363 | MODULE_AUTHOR("Guenter Roeck"); | ||
364 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 934138c7b3d3..796c077ef439 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c | |||
@@ -283,7 +283,7 @@ static int __devinit hspi_probe(struct platform_device *pdev) | |||
283 | ret = spi_register_master(master); | 283 | ret = spi_register_master(master); |
284 | if (ret < 0) { | 284 | if (ret < 0) { |
285 | dev_err(&pdev->dev, "spi_register_master error.\n"); | 285 | dev_err(&pdev->dev, "spi_register_master error.\n"); |
286 | goto error2; | 286 | goto error1; |
287 | } | 287 | } |
288 | 288 | ||
289 | pm_runtime_enable(&pdev->dev); | 289 | pm_runtime_enable(&pdev->dev); |
@@ -292,8 +292,6 @@ static int __devinit hspi_probe(struct platform_device *pdev) | |||
292 | 292 | ||
293 | return 0; | 293 | return 0; |
294 | 294 | ||
295 | error2: | ||
296 | devm_iounmap(hspi->dev, hspi->addr); | ||
297 | error1: | 295 | error1: |
298 | clk_put(clk); | 296 | clk_put(clk); |
299 | error0: | 297 | error0: |
@@ -310,7 +308,6 @@ static int __devexit hspi_remove(struct platform_device *pdev) | |||
310 | 308 | ||
311 | clk_put(hspi->clk); | 309 | clk_put(hspi->clk); |
312 | spi_unregister_master(hspi->master); | 310 | spi_unregister_master(hspi->master); |
313 | devm_iounmap(hspi->dev, hspi->addr); | ||
314 | 311 | ||
315 | return 0; | 312 | return 0; |
316 | } | 313 | } |
diff --git a/drivers/spi/spi-stmp.c b/drivers/spi/spi-stmp.c index 58e385285323..911e904b3c84 100644 --- a/drivers/spi/spi-stmp.c +++ b/drivers/spi/spi-stmp.c | |||
@@ -594,9 +594,7 @@ static int __devexit stmp_spi_remove(struct platform_device *dev) | |||
594 | struct stmp_spi *ss; | 594 | struct stmp_spi *ss; |
595 | struct spi_master *master; | 595 | struct spi_master *master; |
596 | 596 | ||
597 | master = platform_get_drvdata(dev); | 597 | master = spi_master_get(platform_get_drvdata(dev)); |
598 | if (master == NULL) | ||
599 | goto out0; | ||
600 | ss = spi_master_get_devdata(master); | 598 | ss = spi_master_get_devdata(master); |
601 | 599 | ||
602 | spi_unregister_master(master); | 600 | spi_unregister_master(master); |
@@ -609,8 +607,6 @@ static int __devexit stmp_spi_remove(struct platform_device *dev) | |||
609 | destroy_workqueue(ss->workqueue); | 607 | destroy_workqueue(ss->workqueue); |
610 | iounmap(ss->regs); | 608 | iounmap(ss->regs); |
611 | spi_master_put(master); | 609 | spi_master_put(master); |
612 | platform_set_drvdata(dev, NULL); | ||
613 | out0: | ||
614 | return 0; | 610 | return 0; |
615 | } | 611 | } |
616 | 612 | ||
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c deleted file mode 100644 index 488d9b6e9cbe..000000000000 --- a/drivers/spi/spi-tegra.c +++ /dev/null | |||
@@ -1,647 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for Nvidia TEGRA spi controller. | ||
3 | * | ||
4 | * Copyright (C) 2010 Google, Inc. | ||
5 | * | ||
6 | * Author: | ||
7 | * Erik Gilling <konkers@android.com> | ||
8 | * | ||
9 | * This software is licensed under the terms of the GNU General Public | ||
10 | * License version 2, as published by the Free Software Foundation, and | ||
11 | * may be copied, distributed, and modified under those terms. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | #include <linux/dmapool.h> | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/delay.h> | ||
31 | |||
32 | #include <linux/spi/spi.h> | ||
33 | #include <linux/dmaengine.h> | ||
34 | |||
35 | #include <mach/dma.h> | ||
36 | |||
37 | #define SLINK_COMMAND 0x000 | ||
38 | #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) | ||
39 | #define SLINK_WORD_SIZE(x) (((x) & 0x1f) << 5) | ||
40 | #define SLINK_BOTH_EN (1 << 10) | ||
41 | #define SLINK_CS_SW (1 << 11) | ||
42 | #define SLINK_CS_VALUE (1 << 12) | ||
43 | #define SLINK_CS_POLARITY (1 << 13) | ||
44 | #define SLINK_IDLE_SDA_DRIVE_LOW (0 << 16) | ||
45 | #define SLINK_IDLE_SDA_DRIVE_HIGH (1 << 16) | ||
46 | #define SLINK_IDLE_SDA_PULL_LOW (2 << 16) | ||
47 | #define SLINK_IDLE_SDA_PULL_HIGH (3 << 16) | ||
48 | #define SLINK_IDLE_SDA_MASK (3 << 16) | ||
49 | #define SLINK_CS_POLARITY1 (1 << 20) | ||
50 | #define SLINK_CK_SDA (1 << 21) | ||
51 | #define SLINK_CS_POLARITY2 (1 << 22) | ||
52 | #define SLINK_CS_POLARITY3 (1 << 23) | ||
53 | #define SLINK_IDLE_SCLK_DRIVE_LOW (0 << 24) | ||
54 | #define SLINK_IDLE_SCLK_DRIVE_HIGH (1 << 24) | ||
55 | #define SLINK_IDLE_SCLK_PULL_LOW (2 << 24) | ||
56 | #define SLINK_IDLE_SCLK_PULL_HIGH (3 << 24) | ||
57 | #define SLINK_IDLE_SCLK_MASK (3 << 24) | ||
58 | #define SLINK_M_S (1 << 28) | ||
59 | #define SLINK_WAIT (1 << 29) | ||
60 | #define SLINK_GO (1 << 30) | ||
61 | #define SLINK_ENB (1 << 31) | ||
62 | |||
63 | #define SLINK_COMMAND2 0x004 | ||
64 | #define SLINK_LSBFE (1 << 0) | ||
65 | #define SLINK_SSOE (1 << 1) | ||
66 | #define SLINK_SPIE (1 << 4) | ||
67 | #define SLINK_BIDIROE (1 << 6) | ||
68 | #define SLINK_MODFEN (1 << 7) | ||
69 | #define SLINK_INT_SIZE(x) (((x) & 0x1f) << 8) | ||
70 | #define SLINK_CS_ACTIVE_BETWEEN (1 << 17) | ||
71 | #define SLINK_SS_EN_CS(x) (((x) & 0x3) << 18) | ||
72 | #define SLINK_SS_SETUP(x) (((x) & 0x3) << 20) | ||
73 | #define SLINK_FIFO_REFILLS_0 (0 << 22) | ||
74 | #define SLINK_FIFO_REFILLS_1 (1 << 22) | ||
75 | #define SLINK_FIFO_REFILLS_2 (2 << 22) | ||
76 | #define SLINK_FIFO_REFILLS_3 (3 << 22) | ||
77 | #define SLINK_FIFO_REFILLS_MASK (3 << 22) | ||
78 | #define SLINK_WAIT_PACK_INT(x) (((x) & 0x7) << 26) | ||
79 | #define SLINK_SPC0 (1 << 29) | ||
80 | #define SLINK_TXEN (1 << 30) | ||
81 | #define SLINK_RXEN (1 << 31) | ||
82 | |||
83 | #define SLINK_STATUS 0x008 | ||
84 | #define SLINK_COUNT(val) (((val) >> 0) & 0x1f) | ||
85 | #define SLINK_WORD(val) (((val) >> 5) & 0x1f) | ||
86 | #define SLINK_BLK_CNT(val) (((val) >> 0) & 0xffff) | ||
87 | #define SLINK_MODF (1 << 16) | ||
88 | #define SLINK_RX_UNF (1 << 18) | ||
89 | #define SLINK_TX_OVF (1 << 19) | ||
90 | #define SLINK_TX_FULL (1 << 20) | ||
91 | #define SLINK_TX_EMPTY (1 << 21) | ||
92 | #define SLINK_RX_FULL (1 << 22) | ||
93 | #define SLINK_RX_EMPTY (1 << 23) | ||
94 | #define SLINK_TX_UNF (1 << 24) | ||
95 | #define SLINK_RX_OVF (1 << 25) | ||
96 | #define SLINK_TX_FLUSH (1 << 26) | ||
97 | #define SLINK_RX_FLUSH (1 << 27) | ||
98 | #define SLINK_SCLK (1 << 28) | ||
99 | #define SLINK_ERR (1 << 29) | ||
100 | #define SLINK_RDY (1 << 30) | ||
101 | #define SLINK_BSY (1 << 31) | ||
102 | |||
103 | #define SLINK_MAS_DATA 0x010 | ||
104 | #define SLINK_SLAVE_DATA 0x014 | ||
105 | |||
106 | #define SLINK_DMA_CTL 0x018 | ||
107 | #define SLINK_DMA_BLOCK_SIZE(x) (((x) & 0xffff) << 0) | ||
108 | #define SLINK_TX_TRIG_1 (0 << 16) | ||
109 | #define SLINK_TX_TRIG_4 (1 << 16) | ||
110 | #define SLINK_TX_TRIG_8 (2 << 16) | ||
111 | #define SLINK_TX_TRIG_16 (3 << 16) | ||
112 | #define SLINK_TX_TRIG_MASK (3 << 16) | ||
113 | #define SLINK_RX_TRIG_1 (0 << 18) | ||
114 | #define SLINK_RX_TRIG_4 (1 << 18) | ||
115 | #define SLINK_RX_TRIG_8 (2 << 18) | ||
116 | #define SLINK_RX_TRIG_16 (3 << 18) | ||
117 | #define SLINK_RX_TRIG_MASK (3 << 18) | ||
118 | #define SLINK_PACKED (1 << 20) | ||
119 | #define SLINK_PACK_SIZE_4 (0 << 21) | ||
120 | #define SLINK_PACK_SIZE_8 (1 << 21) | ||
121 | #define SLINK_PACK_SIZE_16 (2 << 21) | ||
122 | #define SLINK_PACK_SIZE_32 (3 << 21) | ||
123 | #define SLINK_PACK_SIZE_MASK (3 << 21) | ||
124 | #define SLINK_IE_TXC (1 << 26) | ||
125 | #define SLINK_IE_RXC (1 << 27) | ||
126 | #define SLINK_DMA_EN (1 << 31) | ||
127 | |||
128 | #define SLINK_STATUS2 0x01c | ||
129 | #define SLINK_TX_FIFO_EMPTY_COUNT(val) (((val) & 0x3f) >> 0) | ||
130 | #define SLINK_RX_FIFO_FULL_COUNT(val) (((val) & 0x3f) >> 16) | ||
131 | |||
132 | #define SLINK_TX_FIFO 0x100 | ||
133 | #define SLINK_RX_FIFO 0x180 | ||
134 | |||
135 | static const unsigned long spi_tegra_req_sels[] = { | ||
136 | TEGRA_DMA_REQ_SEL_SL2B1, | ||
137 | TEGRA_DMA_REQ_SEL_SL2B2, | ||
138 | TEGRA_DMA_REQ_SEL_SL2B3, | ||
139 | TEGRA_DMA_REQ_SEL_SL2B4, | ||
140 | }; | ||
141 | |||
142 | #define BB_LEN 32 | ||
143 | |||
144 | struct spi_tegra_data { | ||
145 | struct spi_master *master; | ||
146 | struct platform_device *pdev; | ||
147 | spinlock_t lock; | ||
148 | |||
149 | struct clk *clk; | ||
150 | void __iomem *base; | ||
151 | unsigned long phys; | ||
152 | |||
153 | u32 cur_speed; | ||
154 | |||
155 | struct list_head queue; | ||
156 | struct spi_transfer *cur; | ||
157 | unsigned cur_pos; | ||
158 | unsigned cur_len; | ||
159 | unsigned cur_bytes_per_word; | ||
160 | |||
161 | /* The tegra spi controller has a bug which causes the first word | ||
162 | * in PIO transactions to be garbage. Since packed DMA transactions | ||
163 | * require transfers to be 4 byte aligned we need a bounce buffer | ||
164 | * for the generic case. | ||
165 | */ | ||
166 | int dma_req_len; | ||
167 | struct dma_chan *rx_dma; | ||
168 | struct dma_slave_config sconfig; | ||
169 | struct dma_async_tx_descriptor *rx_dma_desc; | ||
170 | dma_cookie_t rx_cookie; | ||
171 | u32 *rx_bb; | ||
172 | dma_addr_t rx_bb_phys; | ||
173 | }; | ||
174 | |||
175 | static void tegra_spi_rx_dma_complete(void *args); | ||
176 | static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, | ||
177 | unsigned long reg) | ||
178 | { | ||
179 | return readl(tspi->base + reg); | ||
180 | } | ||
181 | |||
182 | static inline void spi_tegra_writel(struct spi_tegra_data *tspi, | ||
183 | unsigned long val, | ||
184 | unsigned long reg) | ||
185 | { | ||
186 | writel(val, tspi->base + reg); | ||
187 | } | ||
188 | |||
189 | static void spi_tegra_go(struct spi_tegra_data *tspi) | ||
190 | { | ||
191 | unsigned long val; | ||
192 | |||
193 | wmb(); | ||
194 | |||
195 | val = spi_tegra_readl(tspi, SLINK_DMA_CTL); | ||
196 | val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; | ||
197 | val |= SLINK_DMA_BLOCK_SIZE(tspi->dma_req_len / 4 - 1); | ||
198 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | ||
199 | tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma, | ||
200 | tspi->rx_bb_phys, tspi->dma_req_len, | ||
201 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); | ||
202 | if (!tspi->rx_dma_desc) { | ||
203 | dev_err(&tspi->pdev->dev, "dmaengine slave prep failed\n"); | ||
204 | return; | ||
205 | } | ||
206 | tspi->rx_dma_desc->callback = tegra_spi_rx_dma_complete; | ||
207 | tspi->rx_dma_desc->callback_param = tspi; | ||
208 | tspi->rx_cookie = dmaengine_submit(tspi->rx_dma_desc); | ||
209 | dma_async_issue_pending(tspi->rx_dma); | ||
210 | |||
211 | val |= SLINK_DMA_EN; | ||
212 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | ||
213 | } | ||
214 | |||
215 | static unsigned spi_tegra_fill_tx_fifo(struct spi_tegra_data *tspi, | ||
216 | struct spi_transfer *t) | ||
217 | { | ||
218 | unsigned len = min(t->len - tspi->cur_pos, BB_LEN * | ||
219 | tspi->cur_bytes_per_word); | ||
220 | u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_pos; | ||
221 | int i, j; | ||
222 | unsigned long val; | ||
223 | |||
224 | val = spi_tegra_readl(tspi, SLINK_COMMAND); | ||
225 | val &= ~SLINK_WORD_SIZE(~0); | ||
226 | val |= SLINK_WORD_SIZE(len / tspi->cur_bytes_per_word - 1); | ||
227 | spi_tegra_writel(tspi, val, SLINK_COMMAND); | ||
228 | |||
229 | for (i = 0; i < len; i += tspi->cur_bytes_per_word) { | ||
230 | val = 0; | ||
231 | for (j = 0; j < tspi->cur_bytes_per_word; j++) | ||
232 | val |= tx_buf[i + j] << j * 8; | ||
233 | |||
234 | spi_tegra_writel(tspi, val, SLINK_TX_FIFO); | ||
235 | } | ||
236 | |||
237 | tspi->dma_req_len = len / tspi->cur_bytes_per_word * 4; | ||
238 | |||
239 | return len; | ||
240 | } | ||
241 | |||
242 | static unsigned spi_tegra_drain_rx_fifo(struct spi_tegra_data *tspi, | ||
243 | struct spi_transfer *t) | ||
244 | { | ||
245 | unsigned len = tspi->cur_len; | ||
246 | u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_pos; | ||
247 | int i, j; | ||
248 | unsigned long val; | ||
249 | |||
250 | for (i = 0; i < len; i += tspi->cur_bytes_per_word) { | ||
251 | val = tspi->rx_bb[i / tspi->cur_bytes_per_word]; | ||
252 | for (j = 0; j < tspi->cur_bytes_per_word; j++) | ||
253 | rx_buf[i + j] = (val >> (j * 8)) & 0xff; | ||
254 | } | ||
255 | |||
256 | return len; | ||
257 | } | ||
258 | |||
259 | static void spi_tegra_start_transfer(struct spi_device *spi, | ||
260 | struct spi_transfer *t) | ||
261 | { | ||
262 | struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); | ||
263 | u32 speed; | ||
264 | u8 bits_per_word; | ||
265 | unsigned long val; | ||
266 | |||
267 | speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz; | ||
268 | bits_per_word = t->bits_per_word ? t->bits_per_word : | ||
269 | spi->bits_per_word; | ||
270 | |||
271 | tspi->cur_bytes_per_word = (bits_per_word - 1) / 8 + 1; | ||
272 | |||
273 | if (speed != tspi->cur_speed) | ||
274 | clk_set_rate(tspi->clk, speed); | ||
275 | |||
276 | if (tspi->cur_speed == 0) | ||
277 | clk_prepare_enable(tspi->clk); | ||
278 | |||
279 | tspi->cur_speed = speed; | ||
280 | |||
281 | val = spi_tegra_readl(tspi, SLINK_COMMAND2); | ||
282 | val &= ~SLINK_SS_EN_CS(~0) | SLINK_RXEN | SLINK_TXEN; | ||
283 | if (t->rx_buf) | ||
284 | val |= SLINK_RXEN; | ||
285 | if (t->tx_buf) | ||
286 | val |= SLINK_TXEN; | ||
287 | val |= SLINK_SS_EN_CS(spi->chip_select); | ||
288 | val |= SLINK_SPIE; | ||
289 | spi_tegra_writel(tspi, val, SLINK_COMMAND2); | ||
290 | |||
291 | val = spi_tegra_readl(tspi, SLINK_COMMAND); | ||
292 | val &= ~SLINK_BIT_LENGTH(~0); | ||
293 | val |= SLINK_BIT_LENGTH(bits_per_word - 1); | ||
294 | |||
295 | /* FIXME: should probably control CS manually so that we can be sure | ||
296 | * it does not go low between transfer and to support delay_usecs | ||
297 | * correctly. | ||
298 | */ | ||
299 | val &= ~SLINK_IDLE_SCLK_MASK & ~SLINK_CK_SDA & ~SLINK_CS_SW; | ||
300 | |||
301 | if (spi->mode & SPI_CPHA) | ||
302 | val |= SLINK_CK_SDA; | ||
303 | |||
304 | if (spi->mode & SPI_CPOL) | ||
305 | val |= SLINK_IDLE_SCLK_DRIVE_HIGH; | ||
306 | else | ||
307 | val |= SLINK_IDLE_SCLK_DRIVE_LOW; | ||
308 | |||
309 | val |= SLINK_M_S; | ||
310 | |||
311 | spi_tegra_writel(tspi, val, SLINK_COMMAND); | ||
312 | |||
313 | spi_tegra_writel(tspi, SLINK_RX_FLUSH | SLINK_TX_FLUSH, SLINK_STATUS); | ||
314 | |||
315 | tspi->cur = t; | ||
316 | tspi->cur_pos = 0; | ||
317 | tspi->cur_len = spi_tegra_fill_tx_fifo(tspi, t); | ||
318 | |||
319 | spi_tegra_go(tspi); | ||
320 | } | ||
321 | |||
322 | static void spi_tegra_start_message(struct spi_device *spi, | ||
323 | struct spi_message *m) | ||
324 | { | ||
325 | struct spi_transfer *t; | ||
326 | |||
327 | m->actual_length = 0; | ||
328 | m->status = 0; | ||
329 | |||
330 | t = list_first_entry(&m->transfers, struct spi_transfer, transfer_list); | ||
331 | spi_tegra_start_transfer(spi, t); | ||
332 | } | ||
333 | |||
334 | static void handle_spi_rx_dma_complete(struct spi_tegra_data *tspi) | ||
335 | { | ||
336 | unsigned long flags; | ||
337 | struct spi_message *m; | ||
338 | struct spi_device *spi; | ||
339 | int timeout = 0; | ||
340 | unsigned long val; | ||
341 | |||
342 | /* the SPI controller may come back with both the BSY and RDY bits | ||
343 | * set. In this case we need to wait for the BSY bit to clear so | ||
344 | * that we are sure the DMA is finished. 1000 reads was empirically | ||
345 | * determined to be long enough. | ||
346 | */ | ||
347 | while (timeout++ < 1000) { | ||
348 | if (!(spi_tegra_readl(tspi, SLINK_STATUS) & SLINK_BSY)) | ||
349 | break; | ||
350 | } | ||
351 | |||
352 | spin_lock_irqsave(&tspi->lock, flags); | ||
353 | |||
354 | val = spi_tegra_readl(tspi, SLINK_STATUS); | ||
355 | val |= SLINK_RDY; | ||
356 | spi_tegra_writel(tspi, val, SLINK_STATUS); | ||
357 | |||
358 | m = list_first_entry(&tspi->queue, struct spi_message, queue); | ||
359 | |||
360 | if (timeout >= 1000) | ||
361 | m->status = -EIO; | ||
362 | |||
363 | spi = m->state; | ||
364 | |||
365 | tspi->cur_pos += spi_tegra_drain_rx_fifo(tspi, tspi->cur); | ||
366 | m->actual_length += tspi->cur_pos; | ||
367 | |||
368 | if (tspi->cur_pos < tspi->cur->len) { | ||
369 | tspi->cur_len = spi_tegra_fill_tx_fifo(tspi, tspi->cur); | ||
370 | spi_tegra_go(tspi); | ||
371 | } else if (!list_is_last(&tspi->cur->transfer_list, | ||
372 | &m->transfers)) { | ||
373 | tspi->cur = list_first_entry(&tspi->cur->transfer_list, | ||
374 | struct spi_transfer, | ||
375 | transfer_list); | ||
376 | spi_tegra_start_transfer(spi, tspi->cur); | ||
377 | } else { | ||
378 | list_del(&m->queue); | ||
379 | |||
380 | m->complete(m->context); | ||
381 | |||
382 | if (!list_empty(&tspi->queue)) { | ||
383 | m = list_first_entry(&tspi->queue, struct spi_message, | ||
384 | queue); | ||
385 | spi = m->state; | ||
386 | spi_tegra_start_message(spi, m); | ||
387 | } else { | ||
388 | clk_disable_unprepare(tspi->clk); | ||
389 | tspi->cur_speed = 0; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | spin_unlock_irqrestore(&tspi->lock, flags); | ||
394 | } | ||
395 | |||
396 | static void tegra_spi_rx_dma_complete(void *args) | ||
397 | { | ||
398 | struct spi_tegra_data *tspi = args; | ||
399 | handle_spi_rx_dma_complete(tspi); | ||
400 | } | ||
401 | |||
402 | static int spi_tegra_setup(struct spi_device *spi) | ||
403 | { | ||
404 | struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); | ||
405 | unsigned long cs_bit; | ||
406 | unsigned long val; | ||
407 | unsigned long flags; | ||
408 | |||
409 | dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n", | ||
410 | spi->bits_per_word, | ||
411 | spi->mode & SPI_CPOL ? "" : "~", | ||
412 | spi->mode & SPI_CPHA ? "" : "~", | ||
413 | spi->max_speed_hz); | ||
414 | |||
415 | |||
416 | switch (spi->chip_select) { | ||
417 | case 0: | ||
418 | cs_bit = SLINK_CS_POLARITY; | ||
419 | break; | ||
420 | |||
421 | case 1: | ||
422 | cs_bit = SLINK_CS_POLARITY1; | ||
423 | break; | ||
424 | |||
425 | case 2: | ||
426 | cs_bit = SLINK_CS_POLARITY2; | ||
427 | break; | ||
428 | |||
429 | case 4: | ||
430 | cs_bit = SLINK_CS_POLARITY3; | ||
431 | break; | ||
432 | |||
433 | default: | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | spin_lock_irqsave(&tspi->lock, flags); | ||
438 | |||
439 | val = spi_tegra_readl(tspi, SLINK_COMMAND); | ||
440 | if (spi->mode & SPI_CS_HIGH) | ||
441 | val |= cs_bit; | ||
442 | else | ||
443 | val &= ~cs_bit; | ||
444 | spi_tegra_writel(tspi, val, SLINK_COMMAND); | ||
445 | |||
446 | spin_unlock_irqrestore(&tspi->lock, flags); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int spi_tegra_transfer(struct spi_device *spi, struct spi_message *m) | ||
452 | { | ||
453 | struct spi_tegra_data *tspi = spi_master_get_devdata(spi->master); | ||
454 | struct spi_transfer *t; | ||
455 | unsigned long flags; | ||
456 | int was_empty; | ||
457 | |||
458 | if (list_empty(&m->transfers) || !m->complete) | ||
459 | return -EINVAL; | ||
460 | |||
461 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
462 | if (t->bits_per_word < 0 || t->bits_per_word > 32) | ||
463 | return -EINVAL; | ||
464 | |||
465 | if (t->len == 0) | ||
466 | return -EINVAL; | ||
467 | |||
468 | if (!t->rx_buf && !t->tx_buf) | ||
469 | return -EINVAL; | ||
470 | } | ||
471 | |||
472 | m->state = spi; | ||
473 | |||
474 | spin_lock_irqsave(&tspi->lock, flags); | ||
475 | was_empty = list_empty(&tspi->queue); | ||
476 | list_add_tail(&m->queue, &tspi->queue); | ||
477 | |||
478 | if (was_empty) | ||
479 | spi_tegra_start_message(spi, m); | ||
480 | |||
481 | spin_unlock_irqrestore(&tspi->lock, flags); | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int __devinit spi_tegra_probe(struct platform_device *pdev) | ||
487 | { | ||
488 | struct spi_master *master; | ||
489 | struct spi_tegra_data *tspi; | ||
490 | struct resource *r; | ||
491 | int ret; | ||
492 | dma_cap_mask_t mask; | ||
493 | |||
494 | master = spi_alloc_master(&pdev->dev, sizeof *tspi); | ||
495 | if (master == NULL) { | ||
496 | dev_err(&pdev->dev, "master allocation failed\n"); | ||
497 | return -ENOMEM; | ||
498 | } | ||
499 | |||
500 | /* the spi->mode bits understood by this driver: */ | ||
501 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | ||
502 | |||
503 | master->bus_num = pdev->id; | ||
504 | |||
505 | master->setup = spi_tegra_setup; | ||
506 | master->transfer = spi_tegra_transfer; | ||
507 | master->num_chipselect = 4; | ||
508 | |||
509 | dev_set_drvdata(&pdev->dev, master); | ||
510 | tspi = spi_master_get_devdata(master); | ||
511 | tspi->master = master; | ||
512 | tspi->pdev = pdev; | ||
513 | spin_lock_init(&tspi->lock); | ||
514 | |||
515 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
516 | if (r == NULL) { | ||
517 | ret = -ENODEV; | ||
518 | goto err0; | ||
519 | } | ||
520 | |||
521 | if (!request_mem_region(r->start, resource_size(r), | ||
522 | dev_name(&pdev->dev))) { | ||
523 | ret = -EBUSY; | ||
524 | goto err0; | ||
525 | } | ||
526 | |||
527 | tspi->phys = r->start; | ||
528 | tspi->base = ioremap(r->start, resource_size(r)); | ||
529 | if (!tspi->base) { | ||
530 | dev_err(&pdev->dev, "can't ioremap iomem\n"); | ||
531 | ret = -ENOMEM; | ||
532 | goto err1; | ||
533 | } | ||
534 | |||
535 | tspi->clk = clk_get(&pdev->dev, NULL); | ||
536 | if (IS_ERR(tspi->clk)) { | ||
537 | dev_err(&pdev->dev, "can not get clock\n"); | ||
538 | ret = PTR_ERR(tspi->clk); | ||
539 | goto err2; | ||
540 | } | ||
541 | |||
542 | INIT_LIST_HEAD(&tspi->queue); | ||
543 | |||
544 | dma_cap_zero(mask); | ||
545 | dma_cap_set(DMA_SLAVE, mask); | ||
546 | tspi->rx_dma = dma_request_channel(mask, NULL, NULL); | ||
547 | if (!tspi->rx_dma) { | ||
548 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); | ||
549 | ret = -ENODEV; | ||
550 | goto err3; | ||
551 | } | ||
552 | |||
553 | tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | ||
554 | &tspi->rx_bb_phys, GFP_KERNEL); | ||
555 | if (!tspi->rx_bb) { | ||
556 | dev_err(&pdev->dev, "can not allocate rx bounce buffer\n"); | ||
557 | ret = -ENOMEM; | ||
558 | goto err4; | ||
559 | } | ||
560 | |||
561 | /* Dmaengine Dma slave config */ | ||
562 | tspi->sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; | ||
563 | tspi->sconfig.dst_addr = tspi->phys + SLINK_RX_FIFO; | ||
564 | tspi->sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
565 | tspi->sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
566 | tspi->sconfig.slave_id = spi_tegra_req_sels[pdev->id]; | ||
567 | tspi->sconfig.src_maxburst = 1; | ||
568 | tspi->sconfig.dst_maxburst = 1; | ||
569 | ret = dmaengine_device_control(tspi->rx_dma, | ||
570 | DMA_SLAVE_CONFIG, (unsigned long) &tspi->sconfig); | ||
571 | if (ret < 0) { | ||
572 | dev_err(&pdev->dev, "can not do slave configure for dma %d\n", | ||
573 | ret); | ||
574 | goto err4; | ||
575 | } | ||
576 | |||
577 | master->dev.of_node = pdev->dev.of_node; | ||
578 | ret = spi_register_master(master); | ||
579 | |||
580 | if (ret < 0) | ||
581 | goto err5; | ||
582 | |||
583 | return ret; | ||
584 | |||
585 | err5: | ||
586 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | ||
587 | tspi->rx_bb, tspi->rx_bb_phys); | ||
588 | err4: | ||
589 | dma_release_channel(tspi->rx_dma); | ||
590 | err3: | ||
591 | clk_put(tspi->clk); | ||
592 | err2: | ||
593 | iounmap(tspi->base); | ||
594 | err1: | ||
595 | release_mem_region(r->start, resource_size(r)); | ||
596 | err0: | ||
597 | spi_master_put(master); | ||
598 | return ret; | ||
599 | } | ||
600 | |||
601 | static int __devexit spi_tegra_remove(struct platform_device *pdev) | ||
602 | { | ||
603 | struct spi_master *master; | ||
604 | struct spi_tegra_data *tspi; | ||
605 | struct resource *r; | ||
606 | |||
607 | master = dev_get_drvdata(&pdev->dev); | ||
608 | tspi = spi_master_get_devdata(master); | ||
609 | |||
610 | spi_unregister_master(master); | ||
611 | dma_release_channel(tspi->rx_dma); | ||
612 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | ||
613 | tspi->rx_bb, tspi->rx_bb_phys); | ||
614 | |||
615 | clk_put(tspi->clk); | ||
616 | iounmap(tspi->base); | ||
617 | |||
618 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
619 | release_mem_region(r->start, resource_size(r)); | ||
620 | |||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | MODULE_ALIAS("platform:spi_tegra"); | ||
625 | |||
626 | #ifdef CONFIG_OF | ||
627 | static struct of_device_id spi_tegra_of_match_table[] __devinitdata = { | ||
628 | { .compatible = "nvidia,tegra20-spi", }, | ||
629 | {} | ||
630 | }; | ||
631 | MODULE_DEVICE_TABLE(of, spi_tegra_of_match_table); | ||
632 | #else /* CONFIG_OF */ | ||
633 | #define spi_tegra_of_match_table NULL | ||
634 | #endif /* CONFIG_OF */ | ||
635 | |||
636 | static struct platform_driver spi_tegra_driver = { | ||
637 | .driver = { | ||
638 | .name = "spi_tegra", | ||
639 | .owner = THIS_MODULE, | ||
640 | .of_match_table = spi_tegra_of_match_table, | ||
641 | }, | ||
642 | .probe = spi_tegra_probe, | ||
643 | .remove = __devexit_p(spi_tegra_remove), | ||
644 | }; | ||
645 | module_platform_driver(spi_tegra_driver); | ||
646 | |||
647 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c index 0ce5c12aab55..24421024deaf 100644 --- a/drivers/spi/spi-tle62x0.c +++ b/drivers/spi/spi-tle62x0.c | |||
@@ -316,18 +316,7 @@ static struct spi_driver tle62x0_driver = { | |||
316 | .remove = __devexit_p(tle62x0_remove), | 316 | .remove = __devexit_p(tle62x0_remove), |
317 | }; | 317 | }; |
318 | 318 | ||
319 | static __init int tle62x0_init(void) | 319 | module_spi_driver(tle62x0_driver); |
320 | { | ||
321 | return spi_register_driver(&tle62x0_driver); | ||
322 | } | ||
323 | |||
324 | static __exit void tle62x0_exit(void) | ||
325 | { | ||
326 | spi_unregister_driver(&tle62x0_driver); | ||
327 | } | ||
328 | |||
329 | module_init(tle62x0_init); | ||
330 | module_exit(tle62x0_exit); | ||
331 | 320 | ||
332 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 321 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
333 | MODULE_DESCRIPTION("TLE62x0 SPI driver"); | 322 | MODULE_DESCRIPTION("TLE62x0 SPI driver"); |
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 1284c9b74653..135f7406f4bf 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c | |||
@@ -1536,8 +1536,6 @@ static int __devexit pch_spi_pd_remove(struct platform_device *plat_dev) | |||
1536 | 1536 | ||
1537 | pci_iounmap(board_dat->pdev, data->io_remap_addr); | 1537 | pci_iounmap(board_dat->pdev, data->io_remap_addr); |
1538 | spi_unregister_master(data->master); | 1538 | spi_unregister_master(data->master); |
1539 | spi_master_put(data->master); | ||
1540 | platform_set_drvdata(plat_dev, NULL); | ||
1541 | 1539 | ||
1542 | return 0; | 1540 | return 0; |
1543 | } | 1541 | } |
diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index fe1d7b283cb6..854b7294f6c6 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h | |||
@@ -244,6 +244,7 @@ struct dma_chan; | |||
244 | * indicates no delay and the device will be suspended immediately. | 244 | * indicates no delay and the device will be suspended immediately. |
245 | * @rt: indicates the controller should run the message pump with realtime | 245 | * @rt: indicates the controller should run the message pump with realtime |
246 | * priority to minimise the transfer latency on the bus. | 246 | * priority to minimise the transfer latency on the bus. |
247 | * @chipselects: list of <num_chipselects> chip select gpios | ||
247 | */ | 248 | */ |
248 | struct pl022_ssp_controller { | 249 | struct pl022_ssp_controller { |
249 | u16 bus_id; | 250 | u16 bus_id; |
@@ -254,6 +255,7 @@ struct pl022_ssp_controller { | |||
254 | void *dma_tx_param; | 255 | void *dma_tx_param; |
255 | int autosuspend_delay; | 256 | int autosuspend_delay; |
256 | bool rt; | 257 | bool rt; |
258 | int *chipselects; | ||
257 | }; | 259 | }; |
258 | 260 | ||
259 | /** | 261 | /** |
diff --git a/include/linux/platform_data/sc18is602.h b/include/linux/platform_data/sc18is602.h new file mode 100644 index 000000000000..997b06634152 --- /dev/null +++ b/include/linux/platform_data/sc18is602.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Platform data for NXP SC18IS602/603 | ||
3 | * | ||
4 | * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * For further information, see the Documentation/spi/sc18is602 file. | ||
11 | */ | ||
12 | |||
13 | /** | ||
14 | * struct sc18is602_platform_data - sc18is602 info | ||
15 | * @clock_frequency SC18IS603 oscillator frequency | ||
16 | */ | ||
17 | struct sc18is602_platform_data { | ||
18 | u32 clock_frequency; | ||
19 | }; | ||
diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h new file mode 100644 index 000000000000..61ae1306db23 --- /dev/null +++ b/include/linux/spi/mxs-spi.h | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * include/linux/spi/mxs-spi.h | ||
3 | * | ||
4 | * Freescale i.MX233/i.MX28 SPI controller register definition | ||
5 | * | ||
6 | * Copyright 2008 Embedded Alley Solutions, Inc. | ||
7 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef __LINUX_SPI_MXS_SPI_H__ | ||
25 | #define __LINUX_SPI_MXS_SPI_H__ | ||
26 | |||
27 | #include <linux/fsl/mxs-dma.h> | ||
28 | |||
29 | #define ssp_is_old(host) ((host)->devid == IMX23_SSP) | ||
30 | |||
31 | /* SSP registers */ | ||
32 | #define HW_SSP_CTRL0 0x000 | ||
33 | #define BM_SSP_CTRL0_RUN (1 << 29) | ||
34 | #define BM_SSP_CTRL0_SDIO_IRQ_CHECK (1 << 28) | ||
35 | #define BM_SSP_CTRL0_LOCK_CS (1 << 27) | ||
36 | #define BM_SSP_CTRL0_IGNORE_CRC (1 << 26) | ||
37 | #define BM_SSP_CTRL0_READ (1 << 25) | ||
38 | #define BM_SSP_CTRL0_DATA_XFER (1 << 24) | ||
39 | #define BP_SSP_CTRL0_BUS_WIDTH 22 | ||
40 | #define BM_SSP_CTRL0_BUS_WIDTH (0x3 << 22) | ||
41 | #define BM_SSP_CTRL0_WAIT_FOR_IRQ (1 << 21) | ||
42 | #define BM_SSP_CTRL0_WAIT_FOR_CMD (1 << 20) | ||
43 | #define BM_SSP_CTRL0_LONG_RESP (1 << 19) | ||
44 | #define BM_SSP_CTRL0_GET_RESP (1 << 17) | ||
45 | #define BM_SSP_CTRL0_ENABLE (1 << 16) | ||
46 | #define BP_SSP_CTRL0_XFER_COUNT 0 | ||
47 | #define BM_SSP_CTRL0_XFER_COUNT 0xffff | ||
48 | #define HW_SSP_CMD0 0x010 | ||
49 | #define BM_SSP_CMD0_DBL_DATA_RATE_EN (1 << 25) | ||
50 | #define BM_SSP_CMD0_SLOW_CLKING_EN (1 << 22) | ||
51 | #define BM_SSP_CMD0_CONT_CLKING_EN (1 << 21) | ||
52 | #define BM_SSP_CMD0_APPEND_8CYC (1 << 20) | ||
53 | #define BP_SSP_CMD0_BLOCK_SIZE 16 | ||
54 | #define BM_SSP_CMD0_BLOCK_SIZE (0xf << 16) | ||
55 | #define BP_SSP_CMD0_BLOCK_COUNT 8 | ||
56 | #define BM_SSP_CMD0_BLOCK_COUNT (0xff << 8) | ||
57 | #define BP_SSP_CMD0_CMD 0 | ||
58 | #define BM_SSP_CMD0_CMD 0xff | ||
59 | #define HW_SSP_CMD1 0x020 | ||
60 | #define HW_SSP_XFER_SIZE 0x030 | ||
61 | #define HW_SSP_BLOCK_SIZE 0x040 | ||
62 | #define BP_SSP_BLOCK_SIZE_BLOCK_COUNT 4 | ||
63 | #define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) | ||
64 | #define BP_SSP_BLOCK_SIZE_BLOCK_SIZE 0 | ||
65 | #define BM_SSP_BLOCK_SIZE_BLOCK_SIZE 0xf | ||
66 | #define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070) | ||
67 | #define BP_SSP_TIMING_TIMEOUT 16 | ||
68 | #define BM_SSP_TIMING_TIMEOUT (0xffff << 16) | ||
69 | #define BP_SSP_TIMING_CLOCK_DIVIDE 8 | ||
70 | #define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) | ||
71 | #define BF_SSP_TIMING_CLOCK_DIVIDE(v) \ | ||
72 | (((v) << 8) & BM_SSP_TIMING_CLOCK_DIVIDE) | ||
73 | #define BP_SSP_TIMING_CLOCK_RATE 0 | ||
74 | #define BM_SSP_TIMING_CLOCK_RATE 0xff | ||
75 | #define BF_SSP_TIMING_CLOCK_RATE(v) \ | ||
76 | (((v) << 0) & BM_SSP_TIMING_CLOCK_RATE) | ||
77 | #define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080) | ||
78 | #define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) | ||
79 | #define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) | ||
80 | #define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) | ||
81 | #define BM_SSP_CTRL1_RESP_ERR_IRQ_EN (1 << 28) | ||
82 | #define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ (1 << 27) | ||
83 | #define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN (1 << 26) | ||
84 | #define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ (1 << 25) | ||
85 | #define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN (1 << 24) | ||
86 | #define BM_SSP_CTRL1_DATA_CRC_IRQ (1 << 23) | ||
87 | #define BM_SSP_CTRL1_DATA_CRC_IRQ_EN (1 << 22) | ||
88 | #define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ (1 << 21) | ||
89 | #define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ_EN (1 << 20) | ||
90 | #define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ (1 << 17) | ||
91 | #define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN (1 << 16) | ||
92 | #define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ (1 << 15) | ||
93 | #define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN (1 << 14) | ||
94 | #define BM_SSP_CTRL1_DMA_ENABLE (1 << 13) | ||
95 | #define BM_SSP_CTRL1_PHASE (1 << 10) | ||
96 | #define BM_SSP_CTRL1_POLARITY (1 << 9) | ||
97 | #define BP_SSP_CTRL1_WORD_LENGTH 4 | ||
98 | #define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) | ||
99 | #define BF_SSP_CTRL1_WORD_LENGTH(v) \ | ||
100 | (((v) << 4) & BM_SSP_CTRL1_WORD_LENGTH) | ||
101 | #define BV_SSP_CTRL1_WORD_LENGTH__FOUR_BITS 0x3 | ||
102 | #define BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS 0x7 | ||
103 | #define BV_SSP_CTRL1_WORD_LENGTH__SIXTEEN_BITS 0xF | ||
104 | #define BP_SSP_CTRL1_SSP_MODE 0 | ||
105 | #define BM_SSP_CTRL1_SSP_MODE 0xf | ||
106 | #define BF_SSP_CTRL1_SSP_MODE(v) \ | ||
107 | (((v) << 0) & BM_SSP_CTRL1_SSP_MODE) | ||
108 | #define BV_SSP_CTRL1_SSP_MODE__SPI 0x0 | ||
109 | #define BV_SSP_CTRL1_SSP_MODE__SSI 0x1 | ||
110 | #define BV_SSP_CTRL1_SSP_MODE__SD_MMC 0x3 | ||
111 | #define BV_SSP_CTRL1_SSP_MODE__MS 0x4 | ||
112 | |||
113 | #define HW_SSP_DATA(h) (ssp_is_old(h) ? 0x070 : 0x090) | ||
114 | |||
115 | #define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0) | ||
116 | #define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0) | ||
117 | #define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0) | ||
118 | #define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0) | ||
119 | #define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100) | ||
120 | #define BM_SSP_STATUS_CARD_DETECT (1 << 28) | ||
121 | #define BM_SSP_STATUS_SDIO_IRQ (1 << 17) | ||
122 | #define BM_SSP_STATUS_FIFO_EMPTY (1 << 5) | ||
123 | |||
124 | #define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field) | ||
125 | |||
126 | #define SSP_PIO_NUM 3 | ||
127 | |||
128 | enum mxs_ssp_id { | ||
129 | IMX23_SSP, | ||
130 | IMX28_SSP, | ||
131 | }; | ||
132 | |||
133 | struct mxs_ssp { | ||
134 | struct device *dev; | ||
135 | void __iomem *base; | ||
136 | struct clk *clk; | ||
137 | unsigned int clk_rate; | ||
138 | enum mxs_ssp_id devid; | ||
139 | |||
140 | int dma_channel; | ||
141 | struct dma_chan *dmach; | ||
142 | struct mxs_dma_data dma_data; | ||
143 | unsigned int dma_dir; | ||
144 | enum dma_transfer_direction slave_dirn; | ||
145 | u32 ssp_pio_words[SSP_PIO_NUM]; | ||
146 | }; | ||
147 | |||
148 | void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate); | ||
149 | |||
150 | #endif /* __LINUX_SPI_MXS_SPI_H__ */ | ||