Commit 7d6709a20866a885916214590b7c394a21be9e25
1 parent
dad2f2fb0f
Exists in
master
and in
7 other branches
powerpc: Fix build of some FSL platforms
Commit 87ec0e98cfdd8b68da6a7f9e70142ffc0e404fbb in kumar's next branch broke one of my test configs since it looks like Anton forgot about that mpc832x_rdb platform which still uses the old style probing for the SPI stuff. I'll let them do a cleaner fix that probably involves changing the probing method and getting rid of the platform device but for now this will do to fix it. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Showing 3 changed files with 6 additions and 6 deletions Inline Diff
arch/powerpc/platforms/83xx/mpc832x_rdb.c
1 | /* | 1 | /* |
2 | * arch/powerpc/platforms/83xx/mpc832x_rdb.c | 2 | * arch/powerpc/platforms/83xx/mpc832x_rdb.c |
3 | * | 3 | * |
4 | * Copyright (C) Freescale Semiconductor, Inc. 2007. All rights reserved. | 4 | * Copyright (C) Freescale Semiconductor, Inc. 2007. All rights reserved. |
5 | * | 5 | * |
6 | * Description: | 6 | * Description: |
7 | * MPC832x RDB board specific routines. | 7 | * MPC832x RDB board specific routines. |
8 | * This file is based on mpc832x_mds.c and mpc8313_rdb.c | 8 | * This file is based on mpc832x_mds.c and mpc8313_rdb.c |
9 | * Author: Michael Barkowski <michael.barkowski@freescale.com> | 9 | * Author: Michael Barkowski <michael.barkowski@freescale.com> |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
13 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * Free Software Foundation; either version 2 of the License, or (at your |
14 | * option) any later version. | 14 | * option) any later version. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
20 | #include <linux/spi/mmc_spi.h> | 20 | #include <linux/spi/mmc_spi.h> |
21 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/fsl_devices.h> | 23 | #include <linux/fsl_devices.h> |
24 | 24 | ||
25 | #include <asm/time.h> | 25 | #include <asm/time.h> |
26 | #include <asm/ipic.h> | 26 | #include <asm/ipic.h> |
27 | #include <asm/udbg.h> | 27 | #include <asm/udbg.h> |
28 | #include <asm/qe.h> | 28 | #include <asm/qe.h> |
29 | #include <asm/qe_ic.h> | 29 | #include <asm/qe_ic.h> |
30 | #include <sysdev/fsl_soc.h> | 30 | #include <sysdev/fsl_soc.h> |
31 | #include <sysdev/fsl_pci.h> | 31 | #include <sysdev/fsl_pci.h> |
32 | 32 | ||
33 | #include "mpc83xx.h" | 33 | #include "mpc83xx.h" |
34 | 34 | ||
35 | #undef DEBUG | 35 | #undef DEBUG |
36 | #ifdef DEBUG | 36 | #ifdef DEBUG |
37 | #define DBG(fmt...) udbg_printf(fmt) | 37 | #define DBG(fmt...) udbg_printf(fmt) |
38 | #else | 38 | #else |
39 | #define DBG(fmt...) | 39 | #define DBG(fmt...) |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #ifdef CONFIG_QUICC_ENGINE | 42 | #ifdef CONFIG_QUICC_ENGINE |
43 | static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, | 43 | static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, |
44 | struct spi_board_info *board_infos, | 44 | struct spi_board_info *board_infos, |
45 | unsigned int num_board_infos, | 45 | unsigned int num_board_infos, |
46 | void (*cs_control)(struct spi_device *dev, | 46 | void (*cs_control)(struct spi_device *dev, |
47 | bool on)) | 47 | bool on)) |
48 | { | 48 | { |
49 | struct device_node *np; | 49 | struct device_node *np; |
50 | unsigned int i = 0; | 50 | unsigned int i = 0; |
51 | 51 | ||
52 | for_each_compatible_node(np, type, compatible) { | 52 | for_each_compatible_node(np, type, compatible) { |
53 | int ret; | 53 | int ret; |
54 | unsigned int j; | 54 | unsigned int j; |
55 | const void *prop; | 55 | const void *prop; |
56 | struct resource res[2]; | 56 | struct resource res[2]; |
57 | struct platform_device *pdev; | 57 | struct platform_device *pdev; |
58 | struct fsl_spi_platform_data pdata = { | 58 | struct fsl_spi_platform_data pdata = { |
59 | .cs_control = cs_control, | 59 | .cs_control = cs_control, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | memset(res, 0, sizeof(res)); | 62 | memset(res, 0, sizeof(res)); |
63 | 63 | ||
64 | pdata.sysclk = sysclk; | 64 | pdata.sysclk = sysclk; |
65 | 65 | ||
66 | prop = of_get_property(np, "reg", NULL); | 66 | prop = of_get_property(np, "reg", NULL); |
67 | if (!prop) | 67 | if (!prop) |
68 | goto err; | 68 | goto err; |
69 | pdata.bus_num = *(u32 *)prop; | 69 | pdata.bus_num = *(u32 *)prop; |
70 | 70 | ||
71 | prop = of_get_property(np, "cell-index", NULL); | 71 | prop = of_get_property(np, "cell-index", NULL); |
72 | if (prop) | 72 | if (prop) |
73 | i = *(u32 *)prop; | 73 | i = *(u32 *)prop; |
74 | 74 | ||
75 | prop = of_get_property(np, "mode", NULL); | 75 | prop = of_get_property(np, "mode", NULL); |
76 | if (prop && !strcmp(prop, "cpu-qe")) | 76 | if (prop && !strcmp(prop, "cpu-qe")) |
77 | pdata.qe_mode = 1; | 77 | pdata.flags = SPI_QE_CPU_MODE; |
78 | 78 | ||
79 | for (j = 0; j < num_board_infos; j++) { | 79 | for (j = 0; j < num_board_infos; j++) { |
80 | if (board_infos[j].bus_num == pdata.bus_num) | 80 | if (board_infos[j].bus_num == pdata.bus_num) |
81 | pdata.max_chipselect++; | 81 | pdata.max_chipselect++; |
82 | } | 82 | } |
83 | 83 | ||
84 | if (!pdata.max_chipselect) | 84 | if (!pdata.max_chipselect) |
85 | continue; | 85 | continue; |
86 | 86 | ||
87 | ret = of_address_to_resource(np, 0, &res[0]); | 87 | ret = of_address_to_resource(np, 0, &res[0]); |
88 | if (ret) | 88 | if (ret) |
89 | goto err; | 89 | goto err; |
90 | 90 | ||
91 | ret = of_irq_to_resource(np, 0, &res[1]); | 91 | ret = of_irq_to_resource(np, 0, &res[1]); |
92 | if (ret == NO_IRQ) | 92 | if (ret == NO_IRQ) |
93 | goto err; | 93 | goto err; |
94 | 94 | ||
95 | pdev = platform_device_alloc("mpc83xx_spi", i); | 95 | pdev = platform_device_alloc("mpc83xx_spi", i); |
96 | if (!pdev) | 96 | if (!pdev) |
97 | goto err; | 97 | goto err; |
98 | 98 | ||
99 | ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); | 99 | ret = platform_device_add_data(pdev, &pdata, sizeof(pdata)); |
100 | if (ret) | 100 | if (ret) |
101 | goto unreg; | 101 | goto unreg; |
102 | 102 | ||
103 | ret = platform_device_add_resources(pdev, res, | 103 | ret = platform_device_add_resources(pdev, res, |
104 | ARRAY_SIZE(res)); | 104 | ARRAY_SIZE(res)); |
105 | if (ret) | 105 | if (ret) |
106 | goto unreg; | 106 | goto unreg; |
107 | 107 | ||
108 | ret = platform_device_add(pdev); | 108 | ret = platform_device_add(pdev); |
109 | if (ret) | 109 | if (ret) |
110 | goto unreg; | 110 | goto unreg; |
111 | 111 | ||
112 | goto next; | 112 | goto next; |
113 | unreg: | 113 | unreg: |
114 | platform_device_del(pdev); | 114 | platform_device_del(pdev); |
115 | err: | 115 | err: |
116 | pr_err("%s: registration failed\n", np->full_name); | 116 | pr_err("%s: registration failed\n", np->full_name); |
117 | next: | 117 | next: |
118 | i++; | 118 | i++; |
119 | } | 119 | } |
120 | 120 | ||
121 | return i; | 121 | return i; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int __init fsl_spi_init(struct spi_board_info *board_infos, | 124 | static int __init fsl_spi_init(struct spi_board_info *board_infos, |
125 | unsigned int num_board_infos, | 125 | unsigned int num_board_infos, |
126 | void (*cs_control)(struct spi_device *spi, | 126 | void (*cs_control)(struct spi_device *spi, |
127 | bool on)) | 127 | bool on)) |
128 | { | 128 | { |
129 | u32 sysclk = -1; | 129 | u32 sysclk = -1; |
130 | int ret; | 130 | int ret; |
131 | 131 | ||
132 | /* SPI controller is either clocked from QE or SoC clock */ | 132 | /* SPI controller is either clocked from QE or SoC clock */ |
133 | sysclk = get_brgfreq(); | 133 | sysclk = get_brgfreq(); |
134 | if (sysclk == -1) { | 134 | if (sysclk == -1) { |
135 | sysclk = fsl_get_sys_freq(); | 135 | sysclk = fsl_get_sys_freq(); |
136 | if (sysclk == -1) | 136 | if (sysclk == -1) |
137 | return -ENODEV; | 137 | return -ENODEV; |
138 | } | 138 | } |
139 | 139 | ||
140 | ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, | 140 | ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, |
141 | num_board_infos, cs_control); | 141 | num_board_infos, cs_control); |
142 | if (!ret) | 142 | if (!ret) |
143 | of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, | 143 | of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos, |
144 | num_board_infos, cs_control); | 144 | num_board_infos, cs_control); |
145 | 145 | ||
146 | return spi_register_board_info(board_infos, num_board_infos); | 146 | return spi_register_board_info(board_infos, num_board_infos); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) | 149 | static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on) |
150 | { | 150 | { |
151 | pr_debug("%s %d %d\n", __func__, spi->chip_select, on); | 151 | pr_debug("%s %d %d\n", __func__, spi->chip_select, on); |
152 | par_io_data_set(3, 13, on); | 152 | par_io_data_set(3, 13, on); |
153 | } | 153 | } |
154 | 154 | ||
155 | static struct mmc_spi_platform_data mpc832x_mmc_pdata = { | 155 | static struct mmc_spi_platform_data mpc832x_mmc_pdata = { |
156 | .ocr_mask = MMC_VDD_33_34, | 156 | .ocr_mask = MMC_VDD_33_34, |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static struct spi_board_info mpc832x_spi_boardinfo = { | 159 | static struct spi_board_info mpc832x_spi_boardinfo = { |
160 | .bus_num = 0x4c0, | 160 | .bus_num = 0x4c0, |
161 | .chip_select = 0, | 161 | .chip_select = 0, |
162 | .max_speed_hz = 50000000, | 162 | .max_speed_hz = 50000000, |
163 | .modalias = "mmc_spi", | 163 | .modalias = "mmc_spi", |
164 | .platform_data = &mpc832x_mmc_pdata, | 164 | .platform_data = &mpc832x_mmc_pdata, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static int __init mpc832x_spi_init(void) | 167 | static int __init mpc832x_spi_init(void) |
168 | { | 168 | { |
169 | par_io_config_pin(3, 0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */ | 169 | par_io_config_pin(3, 0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */ |
170 | par_io_config_pin(3, 1, 3, 0, 1, 0); /* SPI1 MISO, I/O */ | 170 | par_io_config_pin(3, 1, 3, 0, 1, 0); /* SPI1 MISO, I/O */ |
171 | par_io_config_pin(3, 2, 3, 0, 1, 0); /* SPI1 CLK, I/O */ | 171 | par_io_config_pin(3, 2, 3, 0, 1, 0); /* SPI1 CLK, I/O */ |
172 | par_io_config_pin(3, 3, 2, 0, 1, 0); /* SPI1 SEL, I */ | 172 | par_io_config_pin(3, 3, 2, 0, 1, 0); /* SPI1 SEL, I */ |
173 | 173 | ||
174 | par_io_config_pin(3, 13, 1, 0, 0, 0); /* !SD_CS, O */ | 174 | par_io_config_pin(3, 13, 1, 0, 0, 0); /* !SD_CS, O */ |
175 | par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */ | 175 | par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */ |
176 | par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */ | 176 | par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */ |
177 | 177 | ||
178 | /* | 178 | /* |
179 | * Don't bother with legacy stuff when device tree contains | 179 | * Don't bother with legacy stuff when device tree contains |
180 | * mmc-spi-slot node. | 180 | * mmc-spi-slot node. |
181 | */ | 181 | */ |
182 | if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot")) | 182 | if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot")) |
183 | return 0; | 183 | return 0; |
184 | return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control); | 184 | return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control); |
185 | } | 185 | } |
186 | machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); | 186 | machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); |
187 | #endif /* CONFIG_QUICC_ENGINE */ | 187 | #endif /* CONFIG_QUICC_ENGINE */ |
188 | 188 | ||
189 | /* ************************************************************************ | 189 | /* ************************************************************************ |
190 | * | 190 | * |
191 | * Setup the architecture | 191 | * Setup the architecture |
192 | * | 192 | * |
193 | */ | 193 | */ |
194 | static void __init mpc832x_rdb_setup_arch(void) | 194 | static void __init mpc832x_rdb_setup_arch(void) |
195 | { | 195 | { |
196 | #if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE) | 196 | #if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE) |
197 | struct device_node *np; | 197 | struct device_node *np; |
198 | #endif | 198 | #endif |
199 | 199 | ||
200 | if (ppc_md.progress) | 200 | if (ppc_md.progress) |
201 | ppc_md.progress("mpc832x_rdb_setup_arch()", 0); | 201 | ppc_md.progress("mpc832x_rdb_setup_arch()", 0); |
202 | 202 | ||
203 | #ifdef CONFIG_PCI | 203 | #ifdef CONFIG_PCI |
204 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | 204 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") |
205 | mpc83xx_add_bridge(np); | 205 | mpc83xx_add_bridge(np); |
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | #ifdef CONFIG_QUICC_ENGINE | 208 | #ifdef CONFIG_QUICC_ENGINE |
209 | qe_reset(); | 209 | qe_reset(); |
210 | 210 | ||
211 | if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { | 211 | if ((np = of_find_node_by_name(NULL, "par_io")) != NULL) { |
212 | par_io_init(np); | 212 | par_io_init(np); |
213 | of_node_put(np); | 213 | of_node_put(np); |
214 | 214 | ||
215 | for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) | 215 | for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) |
216 | par_io_of_config(np); | 216 | par_io_of_config(np); |
217 | } | 217 | } |
218 | #endif /* CONFIG_QUICC_ENGINE */ | 218 | #endif /* CONFIG_QUICC_ENGINE */ |
219 | } | 219 | } |
220 | 220 | ||
221 | static struct of_device_id mpc832x_ids[] = { | 221 | static struct of_device_id mpc832x_ids[] = { |
222 | { .type = "soc", }, | 222 | { .type = "soc", }, |
223 | { .compatible = "soc", }, | 223 | { .compatible = "soc", }, |
224 | { .compatible = "simple-bus", }, | 224 | { .compatible = "simple-bus", }, |
225 | { .type = "qe", }, | 225 | { .type = "qe", }, |
226 | { .compatible = "fsl,qe", }, | 226 | { .compatible = "fsl,qe", }, |
227 | {}, | 227 | {}, |
228 | }; | 228 | }; |
229 | 229 | ||
230 | static int __init mpc832x_declare_of_platform_devices(void) | 230 | static int __init mpc832x_declare_of_platform_devices(void) |
231 | { | 231 | { |
232 | /* Publish the QE devices */ | 232 | /* Publish the QE devices */ |
233 | of_platform_bus_probe(NULL, mpc832x_ids, NULL); | 233 | of_platform_bus_probe(NULL, mpc832x_ids, NULL); |
234 | 234 | ||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices); | 237 | machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices); |
238 | 238 | ||
239 | static void __init mpc832x_rdb_init_IRQ(void) | 239 | static void __init mpc832x_rdb_init_IRQ(void) |
240 | { | 240 | { |
241 | 241 | ||
242 | struct device_node *np; | 242 | struct device_node *np; |
243 | 243 | ||
244 | np = of_find_node_by_type(NULL, "ipic"); | 244 | np = of_find_node_by_type(NULL, "ipic"); |
245 | if (!np) | 245 | if (!np) |
246 | return; | 246 | return; |
247 | 247 | ||
248 | ipic_init(np, 0); | 248 | ipic_init(np, 0); |
249 | 249 | ||
250 | /* Initialize the default interrupt mapping priorities, | 250 | /* Initialize the default interrupt mapping priorities, |
251 | * in case the boot rom changed something on us. | 251 | * in case the boot rom changed something on us. |
252 | */ | 252 | */ |
253 | ipic_set_default_priority(); | 253 | ipic_set_default_priority(); |
254 | of_node_put(np); | 254 | of_node_put(np); |
255 | 255 | ||
256 | #ifdef CONFIG_QUICC_ENGINE | 256 | #ifdef CONFIG_QUICC_ENGINE |
257 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | 257 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); |
258 | if (!np) { | 258 | if (!np) { |
259 | np = of_find_node_by_type(NULL, "qeic"); | 259 | np = of_find_node_by_type(NULL, "qeic"); |
260 | if (!np) | 260 | if (!np) |
261 | return; | 261 | return; |
262 | } | 262 | } |
263 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | 263 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); |
264 | of_node_put(np); | 264 | of_node_put(np); |
265 | #endif /* CONFIG_QUICC_ENGINE */ | 265 | #endif /* CONFIG_QUICC_ENGINE */ |
266 | } | 266 | } |
267 | 267 | ||
268 | /* | 268 | /* |
269 | * Called very early, MMU is off, device-tree isn't unflattened | 269 | * Called very early, MMU is off, device-tree isn't unflattened |
270 | */ | 270 | */ |
271 | static int __init mpc832x_rdb_probe(void) | 271 | static int __init mpc832x_rdb_probe(void) |
272 | { | 272 | { |
273 | unsigned long root = of_get_flat_dt_root(); | 273 | unsigned long root = of_get_flat_dt_root(); |
274 | 274 | ||
275 | return of_flat_dt_is_compatible(root, "MPC832xRDB"); | 275 | return of_flat_dt_is_compatible(root, "MPC832xRDB"); |
276 | } | 276 | } |
277 | 277 | ||
278 | define_machine(mpc832x_rdb) { | 278 | define_machine(mpc832x_rdb) { |
279 | .name = "MPC832x RDB", | 279 | .name = "MPC832x RDB", |
280 | .probe = mpc832x_rdb_probe, | 280 | .probe = mpc832x_rdb_probe, |
281 | .setup_arch = mpc832x_rdb_setup_arch, | 281 | .setup_arch = mpc832x_rdb_setup_arch, |
282 | .init_IRQ = mpc832x_rdb_init_IRQ, | 282 | .init_IRQ = mpc832x_rdb_init_IRQ, |
283 | .get_irq = ipic_get_irq, | 283 | .get_irq = ipic_get_irq, |
284 | .restart = mpc83xx_restart, | 284 | .restart = mpc83xx_restart, |
285 | .time_init = mpc83xx_time_init, | 285 | .time_init = mpc83xx_time_init, |
286 | .calibrate_decr = generic_calibrate_decr, | 286 | .calibrate_decr = generic_calibrate_decr, |
287 | .progress = udbg_progress, | 287 | .progress = udbg_progress, |
288 | }; | 288 | }; |
289 | 289 |
drivers/spi/spi_mpc8xxx.c
1 | /* | 1 | /* |
2 | * MPC8xxx SPI controller driver. | 2 | * MPC8xxx SPI controller driver. |
3 | * | 3 | * |
4 | * Maintainer: Kumar Gala | 4 | * Maintainer: Kumar Gala |
5 | * | 5 | * |
6 | * Copyright (C) 2006 Polycom, Inc. | 6 | * Copyright (C) 2006 Polycom, Inc. |
7 | * | 7 | * |
8 | * CPM SPI and QE buffer descriptors mode support: | 8 | * CPM SPI and QE buffer descriptors mode support: |
9 | * Copyright (c) 2009 MontaVista Software, Inc. | 9 | * Copyright (c) 2009 MontaVista Software, Inc. |
10 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | 10 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify it | 12 | * This program is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 13 | * under the terms of the GNU General Public License as published by the |
14 | * Free Software Foundation; either version 2 of the License, or (at your | 14 | * Free Software Foundation; either version 2 of the License, or (at your |
15 | * option) any later version. | 15 | * option) any later version. |
16 | */ | 16 | */ |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/bug.h> | 21 | #include <linux/bug.h> |
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/completion.h> | 25 | #include <linux/completion.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/spi/spi.h> | 30 | #include <linux/spi/spi.h> |
31 | #include <linux/spi/spi_bitbang.h> | 31 | #include <linux/spi/spi_bitbang.h> |
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <linux/fsl_devices.h> | 33 | #include <linux/fsl_devices.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/of.h> | 37 | #include <linux/of.h> |
38 | #include <linux/of_platform.h> | 38 | #include <linux/of_platform.h> |
39 | #include <linux/gpio.h> | 39 | #include <linux/gpio.h> |
40 | #include <linux/of_gpio.h> | 40 | #include <linux/of_gpio.h> |
41 | #include <linux/of_spi.h> | 41 | #include <linux/of_spi.h> |
42 | 42 | ||
43 | #include <sysdev/fsl_soc.h> | 43 | #include <sysdev/fsl_soc.h> |
44 | #include <asm/cpm.h> | 44 | #include <asm/cpm.h> |
45 | #include <asm/qe.h> | 45 | #include <asm/qe.h> |
46 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
47 | 47 | ||
48 | /* CPM1 and CPM2 are mutually exclusive. */ | 48 | /* CPM1 and CPM2 are mutually exclusive. */ |
49 | #ifdef CONFIG_CPM1 | 49 | #ifdef CONFIG_CPM1 |
50 | #include <asm/cpm1.h> | 50 | #include <asm/cpm1.h> |
51 | #define CPM_SPI_CMD mk_cr_cmd(CPM_CR_CH_SPI, 0) | 51 | #define CPM_SPI_CMD mk_cr_cmd(CPM_CR_CH_SPI, 0) |
52 | #else | 52 | #else |
53 | #include <asm/cpm2.h> | 53 | #include <asm/cpm2.h> |
54 | #define CPM_SPI_CMD mk_cr_cmd(CPM_CR_SPI_PAGE, CPM_CR_SPI_SBLOCK, 0, 0) | 54 | #define CPM_SPI_CMD mk_cr_cmd(CPM_CR_SPI_PAGE, CPM_CR_SPI_SBLOCK, 0, 0) |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | /* SPI Controller registers */ | 57 | /* SPI Controller registers */ |
58 | struct mpc8xxx_spi_reg { | 58 | struct mpc8xxx_spi_reg { |
59 | u8 res1[0x20]; | 59 | u8 res1[0x20]; |
60 | __be32 mode; | 60 | __be32 mode; |
61 | __be32 event; | 61 | __be32 event; |
62 | __be32 mask; | 62 | __be32 mask; |
63 | __be32 command; | 63 | __be32 command; |
64 | __be32 transmit; | 64 | __be32 transmit; |
65 | __be32 receive; | 65 | __be32 receive; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* SPI Parameter RAM */ | 68 | /* SPI Parameter RAM */ |
69 | struct spi_pram { | 69 | struct spi_pram { |
70 | __be16 rbase; /* Rx Buffer descriptor base address */ | 70 | __be16 rbase; /* Rx Buffer descriptor base address */ |
71 | __be16 tbase; /* Tx Buffer descriptor base address */ | 71 | __be16 tbase; /* Tx Buffer descriptor base address */ |
72 | u8 rfcr; /* Rx function code */ | 72 | u8 rfcr; /* Rx function code */ |
73 | u8 tfcr; /* Tx function code */ | 73 | u8 tfcr; /* Tx function code */ |
74 | __be16 mrblr; /* Max receive buffer length */ | 74 | __be16 mrblr; /* Max receive buffer length */ |
75 | __be32 rstate; /* Internal */ | 75 | __be32 rstate; /* Internal */ |
76 | __be32 rdp; /* Internal */ | 76 | __be32 rdp; /* Internal */ |
77 | __be16 rbptr; /* Internal */ | 77 | __be16 rbptr; /* Internal */ |
78 | __be16 rbc; /* Internal */ | 78 | __be16 rbc; /* Internal */ |
79 | __be32 rxtmp; /* Internal */ | 79 | __be32 rxtmp; /* Internal */ |
80 | __be32 tstate; /* Internal */ | 80 | __be32 tstate; /* Internal */ |
81 | __be32 tdp; /* Internal */ | 81 | __be32 tdp; /* Internal */ |
82 | __be16 tbptr; /* Internal */ | 82 | __be16 tbptr; /* Internal */ |
83 | __be16 tbc; /* Internal */ | 83 | __be16 tbc; /* Internal */ |
84 | __be32 txtmp; /* Internal */ | 84 | __be32 txtmp; /* Internal */ |
85 | __be32 res; /* Tx temp. */ | 85 | __be32 res; /* Tx temp. */ |
86 | __be16 rpbase; /* Relocation pointer (CPM1 only) */ | 86 | __be16 rpbase; /* Relocation pointer (CPM1 only) */ |
87 | __be16 res1; /* Reserved */ | 87 | __be16 res1; /* Reserved */ |
88 | }; | 88 | }; |
89 | 89 | ||
90 | /* SPI Controller mode register definitions */ | 90 | /* SPI Controller mode register definitions */ |
91 | #define SPMODE_LOOP (1 << 30) | 91 | #define SPMODE_LOOP (1 << 30) |
92 | #define SPMODE_CI_INACTIVEHIGH (1 << 29) | 92 | #define SPMODE_CI_INACTIVEHIGH (1 << 29) |
93 | #define SPMODE_CP_BEGIN_EDGECLK (1 << 28) | 93 | #define SPMODE_CP_BEGIN_EDGECLK (1 << 28) |
94 | #define SPMODE_DIV16 (1 << 27) | 94 | #define SPMODE_DIV16 (1 << 27) |
95 | #define SPMODE_REV (1 << 26) | 95 | #define SPMODE_REV (1 << 26) |
96 | #define SPMODE_MS (1 << 25) | 96 | #define SPMODE_MS (1 << 25) |
97 | #define SPMODE_ENABLE (1 << 24) | 97 | #define SPMODE_ENABLE (1 << 24) |
98 | #define SPMODE_LEN(x) ((x) << 20) | 98 | #define SPMODE_LEN(x) ((x) << 20) |
99 | #define SPMODE_PM(x) ((x) << 16) | 99 | #define SPMODE_PM(x) ((x) << 16) |
100 | #define SPMODE_OP (1 << 14) | 100 | #define SPMODE_OP (1 << 14) |
101 | #define SPMODE_CG(x) ((x) << 7) | 101 | #define SPMODE_CG(x) ((x) << 7) |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * Default for SPI Mode: | 104 | * Default for SPI Mode: |
105 | * SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk | 105 | * SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk |
106 | */ | 106 | */ |
107 | #define SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \ | 107 | #define SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \ |
108 | SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf)) | 108 | SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf)) |
109 | 109 | ||
110 | /* SPIE register values */ | 110 | /* SPIE register values */ |
111 | #define SPIE_NE 0x00000200 /* Not empty */ | 111 | #define SPIE_NE 0x00000200 /* Not empty */ |
112 | #define SPIE_NF 0x00000100 /* Not full */ | 112 | #define SPIE_NF 0x00000100 /* Not full */ |
113 | 113 | ||
114 | /* SPIM register values */ | 114 | /* SPIM register values */ |
115 | #define SPIM_NE 0x00000200 /* Not empty */ | 115 | #define SPIM_NE 0x00000200 /* Not empty */ |
116 | #define SPIM_NF 0x00000100 /* Not full */ | 116 | #define SPIM_NF 0x00000100 /* Not full */ |
117 | 117 | ||
118 | #define SPIE_TXB 0x00000200 /* Last char is written to tx fifo */ | 118 | #define SPIE_TXB 0x00000200 /* Last char is written to tx fifo */ |
119 | #define SPIE_RXB 0x00000100 /* Last char is written to rx buf */ | 119 | #define SPIE_RXB 0x00000100 /* Last char is written to rx buf */ |
120 | 120 | ||
121 | /* SPCOM register values */ | 121 | /* SPCOM register values */ |
122 | #define SPCOM_STR (1 << 23) /* Start transmit */ | 122 | #define SPCOM_STR (1 << 23) /* Start transmit */ |
123 | 123 | ||
124 | #define SPI_PRAM_SIZE 0x100 | 124 | #define SPI_PRAM_SIZE 0x100 |
125 | #define SPI_MRBLR ((unsigned int)PAGE_SIZE) | 125 | #define SPI_MRBLR ((unsigned int)PAGE_SIZE) |
126 | 126 | ||
127 | /* SPI Controller driver's private data. */ | 127 | /* SPI Controller driver's private data. */ |
128 | struct mpc8xxx_spi { | 128 | struct mpc8xxx_spi { |
129 | struct device *dev; | 129 | struct device *dev; |
130 | struct mpc8xxx_spi_reg __iomem *base; | 130 | struct mpc8xxx_spi_reg __iomem *base; |
131 | 131 | ||
132 | /* rx & tx bufs from the spi_transfer */ | 132 | /* rx & tx bufs from the spi_transfer */ |
133 | const void *tx; | 133 | const void *tx; |
134 | void *rx; | 134 | void *rx; |
135 | 135 | ||
136 | int subblock; | 136 | int subblock; |
137 | struct spi_pram __iomem *pram; | 137 | struct spi_pram __iomem *pram; |
138 | struct cpm_buf_desc __iomem *tx_bd; | 138 | struct cpm_buf_desc __iomem *tx_bd; |
139 | struct cpm_buf_desc __iomem *rx_bd; | 139 | struct cpm_buf_desc __iomem *rx_bd; |
140 | 140 | ||
141 | struct spi_transfer *xfer_in_progress; | 141 | struct spi_transfer *xfer_in_progress; |
142 | 142 | ||
143 | /* dma addresses for CPM transfers */ | 143 | /* dma addresses for CPM transfers */ |
144 | dma_addr_t tx_dma; | 144 | dma_addr_t tx_dma; |
145 | dma_addr_t rx_dma; | 145 | dma_addr_t rx_dma; |
146 | bool map_tx_dma; | 146 | bool map_tx_dma; |
147 | bool map_rx_dma; | 147 | bool map_rx_dma; |
148 | 148 | ||
149 | dma_addr_t dma_dummy_tx; | 149 | dma_addr_t dma_dummy_tx; |
150 | dma_addr_t dma_dummy_rx; | 150 | dma_addr_t dma_dummy_rx; |
151 | 151 | ||
152 | /* functions to deal with different sized buffers */ | 152 | /* functions to deal with different sized buffers */ |
153 | void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *); | 153 | void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *); |
154 | u32(*get_tx) (struct mpc8xxx_spi *); | 154 | u32(*get_tx) (struct mpc8xxx_spi *); |
155 | 155 | ||
156 | unsigned int count; | 156 | unsigned int count; |
157 | unsigned int irq; | 157 | unsigned int irq; |
158 | 158 | ||
159 | unsigned nsecs; /* (clock cycle time)/2 */ | 159 | unsigned nsecs; /* (clock cycle time)/2 */ |
160 | 160 | ||
161 | u32 spibrg; /* SPIBRG input clock */ | 161 | u32 spibrg; /* SPIBRG input clock */ |
162 | u32 rx_shift; /* RX data reg shift when in qe mode */ | 162 | u32 rx_shift; /* RX data reg shift when in qe mode */ |
163 | u32 tx_shift; /* TX data reg shift when in qe mode */ | 163 | u32 tx_shift; /* TX data reg shift when in qe mode */ |
164 | 164 | ||
165 | unsigned int flags; | 165 | unsigned int flags; |
166 | #define SPI_QE_CPU_MODE (1 << 0) /* QE CPU ("PIO") mode */ | ||
167 | #define SPI_CPM_MODE (1 << 1) /* CPM/QE ("DMA") mode */ | ||
168 | #define SPI_CPM1 (1 << 2) /* SPI unit is in CPM1 block */ | ||
169 | #define SPI_CPM2 (1 << 3) /* SPI unit is in CPM2 block */ | ||
170 | #define SPI_QE (1 << 4) /* SPI unit is in QE block */ | ||
171 | 166 | ||
172 | struct workqueue_struct *workqueue; | 167 | struct workqueue_struct *workqueue; |
173 | struct work_struct work; | 168 | struct work_struct work; |
174 | 169 | ||
175 | struct list_head queue; | 170 | struct list_head queue; |
176 | spinlock_t lock; | 171 | spinlock_t lock; |
177 | 172 | ||
178 | struct completion done; | 173 | struct completion done; |
179 | }; | 174 | }; |
180 | 175 | ||
181 | static void *mpc8xxx_dummy_rx; | 176 | static void *mpc8xxx_dummy_rx; |
182 | static DEFINE_MUTEX(mpc8xxx_dummy_rx_lock); | 177 | static DEFINE_MUTEX(mpc8xxx_dummy_rx_lock); |
183 | static int mpc8xxx_dummy_rx_refcnt; | 178 | static int mpc8xxx_dummy_rx_refcnt; |
184 | 179 | ||
185 | struct spi_mpc8xxx_cs { | 180 | struct spi_mpc8xxx_cs { |
186 | /* functions to deal with different sized buffers */ | 181 | /* functions to deal with different sized buffers */ |
187 | void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *); | 182 | void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *); |
188 | u32 (*get_tx) (struct mpc8xxx_spi *); | 183 | u32 (*get_tx) (struct mpc8xxx_spi *); |
189 | u32 rx_shift; /* RX data reg shift when in qe mode */ | 184 | u32 rx_shift; /* RX data reg shift when in qe mode */ |
190 | u32 tx_shift; /* TX data reg shift when in qe mode */ | 185 | u32 tx_shift; /* TX data reg shift when in qe mode */ |
191 | u32 hw_mode; /* Holds HW mode register settings */ | 186 | u32 hw_mode; /* Holds HW mode register settings */ |
192 | }; | 187 | }; |
193 | 188 | ||
194 | static inline void mpc8xxx_spi_write_reg(__be32 __iomem *reg, u32 val) | 189 | static inline void mpc8xxx_spi_write_reg(__be32 __iomem *reg, u32 val) |
195 | { | 190 | { |
196 | out_be32(reg, val); | 191 | out_be32(reg, val); |
197 | } | 192 | } |
198 | 193 | ||
199 | static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg) | 194 | static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg) |
200 | { | 195 | { |
201 | return in_be32(reg); | 196 | return in_be32(reg); |
202 | } | 197 | } |
203 | 198 | ||
204 | #define MPC83XX_SPI_RX_BUF(type) \ | 199 | #define MPC83XX_SPI_RX_BUF(type) \ |
205 | static \ | 200 | static \ |
206 | void mpc8xxx_spi_rx_buf_##type(u32 data, struct mpc8xxx_spi *mpc8xxx_spi) \ | 201 | void mpc8xxx_spi_rx_buf_##type(u32 data, struct mpc8xxx_spi *mpc8xxx_spi) \ |
207 | { \ | 202 | { \ |
208 | type *rx = mpc8xxx_spi->rx; \ | 203 | type *rx = mpc8xxx_spi->rx; \ |
209 | *rx++ = (type)(data >> mpc8xxx_spi->rx_shift); \ | 204 | *rx++ = (type)(data >> mpc8xxx_spi->rx_shift); \ |
210 | mpc8xxx_spi->rx = rx; \ | 205 | mpc8xxx_spi->rx = rx; \ |
211 | } | 206 | } |
212 | 207 | ||
213 | #define MPC83XX_SPI_TX_BUF(type) \ | 208 | #define MPC83XX_SPI_TX_BUF(type) \ |
214 | static \ | 209 | static \ |
215 | u32 mpc8xxx_spi_tx_buf_##type(struct mpc8xxx_spi *mpc8xxx_spi) \ | 210 | u32 mpc8xxx_spi_tx_buf_##type(struct mpc8xxx_spi *mpc8xxx_spi) \ |
216 | { \ | 211 | { \ |
217 | u32 data; \ | 212 | u32 data; \ |
218 | const type *tx = mpc8xxx_spi->tx; \ | 213 | const type *tx = mpc8xxx_spi->tx; \ |
219 | if (!tx) \ | 214 | if (!tx) \ |
220 | return 0; \ | 215 | return 0; \ |
221 | data = *tx++ << mpc8xxx_spi->tx_shift; \ | 216 | data = *tx++ << mpc8xxx_spi->tx_shift; \ |
222 | mpc8xxx_spi->tx = tx; \ | 217 | mpc8xxx_spi->tx = tx; \ |
223 | return data; \ | 218 | return data; \ |
224 | } | 219 | } |
225 | 220 | ||
226 | MPC83XX_SPI_RX_BUF(u8) | 221 | MPC83XX_SPI_RX_BUF(u8) |
227 | MPC83XX_SPI_RX_BUF(u16) | 222 | MPC83XX_SPI_RX_BUF(u16) |
228 | MPC83XX_SPI_RX_BUF(u32) | 223 | MPC83XX_SPI_RX_BUF(u32) |
229 | MPC83XX_SPI_TX_BUF(u8) | 224 | MPC83XX_SPI_TX_BUF(u8) |
230 | MPC83XX_SPI_TX_BUF(u16) | 225 | MPC83XX_SPI_TX_BUF(u16) |
231 | MPC83XX_SPI_TX_BUF(u32) | 226 | MPC83XX_SPI_TX_BUF(u32) |
232 | 227 | ||
233 | static void mpc8xxx_spi_change_mode(struct spi_device *spi) | 228 | static void mpc8xxx_spi_change_mode(struct spi_device *spi) |
234 | { | 229 | { |
235 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); | 230 | struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); |
236 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 231 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
237 | __be32 __iomem *mode = &mspi->base->mode; | 232 | __be32 __iomem *mode = &mspi->base->mode; |
238 | unsigned long flags; | 233 | unsigned long flags; |
239 | 234 | ||
240 | if (cs->hw_mode == mpc8xxx_spi_read_reg(mode)) | 235 | if (cs->hw_mode == mpc8xxx_spi_read_reg(mode)) |
241 | return; | 236 | return; |
242 | 237 | ||
243 | /* Turn off IRQs locally to minimize time that SPI is disabled. */ | 238 | /* Turn off IRQs locally to minimize time that SPI is disabled. */ |
244 | local_irq_save(flags); | 239 | local_irq_save(flags); |
245 | 240 | ||
246 | /* Turn off SPI unit prior changing mode */ | 241 | /* Turn off SPI unit prior changing mode */ |
247 | mpc8xxx_spi_write_reg(mode, cs->hw_mode & ~SPMODE_ENABLE); | 242 | mpc8xxx_spi_write_reg(mode, cs->hw_mode & ~SPMODE_ENABLE); |
248 | mpc8xxx_spi_write_reg(mode, cs->hw_mode); | 243 | mpc8xxx_spi_write_reg(mode, cs->hw_mode); |
249 | 244 | ||
250 | /* When in CPM mode, we need to reinit tx and rx. */ | 245 | /* When in CPM mode, we need to reinit tx and rx. */ |
251 | if (mspi->flags & SPI_CPM_MODE) { | 246 | if (mspi->flags & SPI_CPM_MODE) { |
252 | if (mspi->flags & SPI_QE) { | 247 | if (mspi->flags & SPI_QE) { |
253 | qe_issue_cmd(QE_INIT_TX_RX, mspi->subblock, | 248 | qe_issue_cmd(QE_INIT_TX_RX, mspi->subblock, |
254 | QE_CR_PROTOCOL_UNSPECIFIED, 0); | 249 | QE_CR_PROTOCOL_UNSPECIFIED, 0); |
255 | } else { | 250 | } else { |
256 | cpm_command(CPM_SPI_CMD, CPM_CR_INIT_TRX); | 251 | cpm_command(CPM_SPI_CMD, CPM_CR_INIT_TRX); |
257 | if (mspi->flags & SPI_CPM1) { | 252 | if (mspi->flags & SPI_CPM1) { |
258 | out_be16(&mspi->pram->rbptr, | 253 | out_be16(&mspi->pram->rbptr, |
259 | in_be16(&mspi->pram->rbase)); | 254 | in_be16(&mspi->pram->rbase)); |
260 | out_be16(&mspi->pram->tbptr, | 255 | out_be16(&mspi->pram->tbptr, |
261 | in_be16(&mspi->pram->tbase)); | 256 | in_be16(&mspi->pram->tbase)); |
262 | } | 257 | } |
263 | } | 258 | } |
264 | } | 259 | } |
265 | 260 | ||
266 | local_irq_restore(flags); | 261 | local_irq_restore(flags); |
267 | } | 262 | } |
268 | 263 | ||
269 | static void mpc8xxx_spi_chipselect(struct spi_device *spi, int value) | 264 | static void mpc8xxx_spi_chipselect(struct spi_device *spi, int value) |
270 | { | 265 | { |
271 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 266 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
272 | struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; | 267 | struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; |
273 | bool pol = spi->mode & SPI_CS_HIGH; | 268 | bool pol = spi->mode & SPI_CS_HIGH; |
274 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 269 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
275 | 270 | ||
276 | if (value == BITBANG_CS_INACTIVE) { | 271 | if (value == BITBANG_CS_INACTIVE) { |
277 | if (pdata->cs_control) | 272 | if (pdata->cs_control) |
278 | pdata->cs_control(spi, !pol); | 273 | pdata->cs_control(spi, !pol); |
279 | } | 274 | } |
280 | 275 | ||
281 | if (value == BITBANG_CS_ACTIVE) { | 276 | if (value == BITBANG_CS_ACTIVE) { |
282 | mpc8xxx_spi->rx_shift = cs->rx_shift; | 277 | mpc8xxx_spi->rx_shift = cs->rx_shift; |
283 | mpc8xxx_spi->tx_shift = cs->tx_shift; | 278 | mpc8xxx_spi->tx_shift = cs->tx_shift; |
284 | mpc8xxx_spi->get_rx = cs->get_rx; | 279 | mpc8xxx_spi->get_rx = cs->get_rx; |
285 | mpc8xxx_spi->get_tx = cs->get_tx; | 280 | mpc8xxx_spi->get_tx = cs->get_tx; |
286 | 281 | ||
287 | mpc8xxx_spi_change_mode(spi); | 282 | mpc8xxx_spi_change_mode(spi); |
288 | 283 | ||
289 | if (pdata->cs_control) | 284 | if (pdata->cs_control) |
290 | pdata->cs_control(spi, pol); | 285 | pdata->cs_control(spi, pol); |
291 | } | 286 | } |
292 | } | 287 | } |
293 | 288 | ||
294 | static | 289 | static |
295 | int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | 290 | int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) |
296 | { | 291 | { |
297 | struct mpc8xxx_spi *mpc8xxx_spi; | 292 | struct mpc8xxx_spi *mpc8xxx_spi; |
298 | u8 bits_per_word, pm; | 293 | u8 bits_per_word, pm; |
299 | u32 hz; | 294 | u32 hz; |
300 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 295 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
301 | 296 | ||
302 | mpc8xxx_spi = spi_master_get_devdata(spi->master); | 297 | mpc8xxx_spi = spi_master_get_devdata(spi->master); |
303 | 298 | ||
304 | if (t) { | 299 | if (t) { |
305 | bits_per_word = t->bits_per_word; | 300 | bits_per_word = t->bits_per_word; |
306 | hz = t->speed_hz; | 301 | hz = t->speed_hz; |
307 | } else { | 302 | } else { |
308 | bits_per_word = 0; | 303 | bits_per_word = 0; |
309 | hz = 0; | 304 | hz = 0; |
310 | } | 305 | } |
311 | 306 | ||
312 | /* spi_transfer level calls that work per-word */ | 307 | /* spi_transfer level calls that work per-word */ |
313 | if (!bits_per_word) | 308 | if (!bits_per_word) |
314 | bits_per_word = spi->bits_per_word; | 309 | bits_per_word = spi->bits_per_word; |
315 | 310 | ||
316 | /* Make sure its a bit width we support [4..16, 32] */ | 311 | /* Make sure its a bit width we support [4..16, 32] */ |
317 | if ((bits_per_word < 4) | 312 | if ((bits_per_word < 4) |
318 | || ((bits_per_word > 16) && (bits_per_word != 32))) | 313 | || ((bits_per_word > 16) && (bits_per_word != 32))) |
319 | return -EINVAL; | 314 | return -EINVAL; |
320 | 315 | ||
321 | if (!hz) | 316 | if (!hz) |
322 | hz = spi->max_speed_hz; | 317 | hz = spi->max_speed_hz; |
323 | 318 | ||
324 | cs->rx_shift = 0; | 319 | cs->rx_shift = 0; |
325 | cs->tx_shift = 0; | 320 | cs->tx_shift = 0; |
326 | if (bits_per_word <= 8) { | 321 | if (bits_per_word <= 8) { |
327 | cs->get_rx = mpc8xxx_spi_rx_buf_u8; | 322 | cs->get_rx = mpc8xxx_spi_rx_buf_u8; |
328 | cs->get_tx = mpc8xxx_spi_tx_buf_u8; | 323 | cs->get_tx = mpc8xxx_spi_tx_buf_u8; |
329 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { | 324 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { |
330 | cs->rx_shift = 16; | 325 | cs->rx_shift = 16; |
331 | cs->tx_shift = 24; | 326 | cs->tx_shift = 24; |
332 | } | 327 | } |
333 | } else if (bits_per_word <= 16) { | 328 | } else if (bits_per_word <= 16) { |
334 | cs->get_rx = mpc8xxx_spi_rx_buf_u16; | 329 | cs->get_rx = mpc8xxx_spi_rx_buf_u16; |
335 | cs->get_tx = mpc8xxx_spi_tx_buf_u16; | 330 | cs->get_tx = mpc8xxx_spi_tx_buf_u16; |
336 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { | 331 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { |
337 | cs->rx_shift = 16; | 332 | cs->rx_shift = 16; |
338 | cs->tx_shift = 16; | 333 | cs->tx_shift = 16; |
339 | } | 334 | } |
340 | } else if (bits_per_word <= 32) { | 335 | } else if (bits_per_word <= 32) { |
341 | cs->get_rx = mpc8xxx_spi_rx_buf_u32; | 336 | cs->get_rx = mpc8xxx_spi_rx_buf_u32; |
342 | cs->get_tx = mpc8xxx_spi_tx_buf_u32; | 337 | cs->get_tx = mpc8xxx_spi_tx_buf_u32; |
343 | } else | 338 | } else |
344 | return -EINVAL; | 339 | return -EINVAL; |
345 | 340 | ||
346 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE && | 341 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE && |
347 | spi->mode & SPI_LSB_FIRST) { | 342 | spi->mode & SPI_LSB_FIRST) { |
348 | cs->tx_shift = 0; | 343 | cs->tx_shift = 0; |
349 | if (bits_per_word <= 8) | 344 | if (bits_per_word <= 8) |
350 | cs->rx_shift = 8; | 345 | cs->rx_shift = 8; |
351 | else | 346 | else |
352 | cs->rx_shift = 0; | 347 | cs->rx_shift = 0; |
353 | } | 348 | } |
354 | 349 | ||
355 | mpc8xxx_spi->rx_shift = cs->rx_shift; | 350 | mpc8xxx_spi->rx_shift = cs->rx_shift; |
356 | mpc8xxx_spi->tx_shift = cs->tx_shift; | 351 | mpc8xxx_spi->tx_shift = cs->tx_shift; |
357 | mpc8xxx_spi->get_rx = cs->get_rx; | 352 | mpc8xxx_spi->get_rx = cs->get_rx; |
358 | mpc8xxx_spi->get_tx = cs->get_tx; | 353 | mpc8xxx_spi->get_tx = cs->get_tx; |
359 | 354 | ||
360 | if (bits_per_word == 32) | 355 | if (bits_per_word == 32) |
361 | bits_per_word = 0; | 356 | bits_per_word = 0; |
362 | else | 357 | else |
363 | bits_per_word = bits_per_word - 1; | 358 | bits_per_word = bits_per_word - 1; |
364 | 359 | ||
365 | /* mask out bits we are going to set */ | 360 | /* mask out bits we are going to set */ |
366 | cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16 | 361 | cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16 |
367 | | SPMODE_PM(0xF)); | 362 | | SPMODE_PM(0xF)); |
368 | 363 | ||
369 | cs->hw_mode |= SPMODE_LEN(bits_per_word); | 364 | cs->hw_mode |= SPMODE_LEN(bits_per_word); |
370 | 365 | ||
371 | if ((mpc8xxx_spi->spibrg / hz) > 64) { | 366 | if ((mpc8xxx_spi->spibrg / hz) > 64) { |
372 | cs->hw_mode |= SPMODE_DIV16; | 367 | cs->hw_mode |= SPMODE_DIV16; |
373 | pm = mpc8xxx_spi->spibrg / (hz * 64); | 368 | pm = mpc8xxx_spi->spibrg / (hz * 64); |
374 | 369 | ||
375 | WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. " | 370 | WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. " |
376 | "Will use %d Hz instead.\n", dev_name(&spi->dev), | 371 | "Will use %d Hz instead.\n", dev_name(&spi->dev), |
377 | hz, mpc8xxx_spi->spibrg / 1024); | 372 | hz, mpc8xxx_spi->spibrg / 1024); |
378 | if (pm > 16) | 373 | if (pm > 16) |
379 | pm = 16; | 374 | pm = 16; |
380 | } else | 375 | } else |
381 | pm = mpc8xxx_spi->spibrg / (hz * 4); | 376 | pm = mpc8xxx_spi->spibrg / (hz * 4); |
382 | if (pm) | 377 | if (pm) |
383 | pm--; | 378 | pm--; |
384 | 379 | ||
385 | cs->hw_mode |= SPMODE_PM(pm); | 380 | cs->hw_mode |= SPMODE_PM(pm); |
386 | 381 | ||
387 | mpc8xxx_spi_change_mode(spi); | 382 | mpc8xxx_spi_change_mode(spi); |
388 | return 0; | 383 | return 0; |
389 | } | 384 | } |
390 | 385 | ||
391 | static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi) | 386 | static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi) |
392 | { | 387 | { |
393 | struct cpm_buf_desc __iomem *tx_bd = mspi->tx_bd; | 388 | struct cpm_buf_desc __iomem *tx_bd = mspi->tx_bd; |
394 | struct cpm_buf_desc __iomem *rx_bd = mspi->rx_bd; | 389 | struct cpm_buf_desc __iomem *rx_bd = mspi->rx_bd; |
395 | unsigned int xfer_len = min(mspi->count, SPI_MRBLR); | 390 | unsigned int xfer_len = min(mspi->count, SPI_MRBLR); |
396 | unsigned int xfer_ofs; | 391 | unsigned int xfer_ofs; |
397 | 392 | ||
398 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; | 393 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; |
399 | 394 | ||
400 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | 395 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); |
401 | out_be16(&rx_bd->cbd_datlen, 0); | 396 | out_be16(&rx_bd->cbd_datlen, 0); |
402 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); | 397 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); |
403 | 398 | ||
404 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | 399 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); |
405 | out_be16(&tx_bd->cbd_datlen, xfer_len); | 400 | out_be16(&tx_bd->cbd_datlen, xfer_len); |
406 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | | 401 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | |
407 | BD_SC_LAST); | 402 | BD_SC_LAST); |
408 | 403 | ||
409 | /* start transfer */ | 404 | /* start transfer */ |
410 | mpc8xxx_spi_write_reg(&mspi->base->command, SPCOM_STR); | 405 | mpc8xxx_spi_write_reg(&mspi->base->command, SPCOM_STR); |
411 | } | 406 | } |
412 | 407 | ||
413 | static int mpc8xxx_spi_cpm_bufs(struct mpc8xxx_spi *mspi, | 408 | static int mpc8xxx_spi_cpm_bufs(struct mpc8xxx_spi *mspi, |
414 | struct spi_transfer *t, bool is_dma_mapped) | 409 | struct spi_transfer *t, bool is_dma_mapped) |
415 | { | 410 | { |
416 | struct device *dev = mspi->dev; | 411 | struct device *dev = mspi->dev; |
417 | 412 | ||
418 | if (is_dma_mapped) { | 413 | if (is_dma_mapped) { |
419 | mspi->map_tx_dma = 0; | 414 | mspi->map_tx_dma = 0; |
420 | mspi->map_rx_dma = 0; | 415 | mspi->map_rx_dma = 0; |
421 | } else { | 416 | } else { |
422 | mspi->map_tx_dma = 1; | 417 | mspi->map_tx_dma = 1; |
423 | mspi->map_rx_dma = 1; | 418 | mspi->map_rx_dma = 1; |
424 | } | 419 | } |
425 | 420 | ||
426 | if (!t->tx_buf) { | 421 | if (!t->tx_buf) { |
427 | mspi->tx_dma = mspi->dma_dummy_tx; | 422 | mspi->tx_dma = mspi->dma_dummy_tx; |
428 | mspi->map_tx_dma = 0; | 423 | mspi->map_tx_dma = 0; |
429 | } | 424 | } |
430 | 425 | ||
431 | if (!t->rx_buf) { | 426 | if (!t->rx_buf) { |
432 | mspi->rx_dma = mspi->dma_dummy_rx; | 427 | mspi->rx_dma = mspi->dma_dummy_rx; |
433 | mspi->map_rx_dma = 0; | 428 | mspi->map_rx_dma = 0; |
434 | } | 429 | } |
435 | 430 | ||
436 | if (mspi->map_tx_dma) { | 431 | if (mspi->map_tx_dma) { |
437 | void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */ | 432 | void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */ |
438 | 433 | ||
439 | mspi->tx_dma = dma_map_single(dev, nonconst_tx, t->len, | 434 | mspi->tx_dma = dma_map_single(dev, nonconst_tx, t->len, |
440 | DMA_TO_DEVICE); | 435 | DMA_TO_DEVICE); |
441 | if (dma_mapping_error(dev, mspi->tx_dma)) { | 436 | if (dma_mapping_error(dev, mspi->tx_dma)) { |
442 | dev_err(dev, "unable to map tx dma\n"); | 437 | dev_err(dev, "unable to map tx dma\n"); |
443 | return -ENOMEM; | 438 | return -ENOMEM; |
444 | } | 439 | } |
445 | } else { | 440 | } else { |
446 | mspi->tx_dma = t->tx_dma; | 441 | mspi->tx_dma = t->tx_dma; |
447 | } | 442 | } |
448 | 443 | ||
449 | if (mspi->map_rx_dma) { | 444 | if (mspi->map_rx_dma) { |
450 | mspi->rx_dma = dma_map_single(dev, mspi->rx, t->len, | 445 | mspi->rx_dma = dma_map_single(dev, mspi->rx, t->len, |
451 | DMA_FROM_DEVICE); | 446 | DMA_FROM_DEVICE); |
452 | if (dma_mapping_error(dev, mspi->rx_dma)) { | 447 | if (dma_mapping_error(dev, mspi->rx_dma)) { |
453 | dev_err(dev, "unable to map rx dma\n"); | 448 | dev_err(dev, "unable to map rx dma\n"); |
454 | goto err_rx_dma; | 449 | goto err_rx_dma; |
455 | } | 450 | } |
456 | } else { | 451 | } else { |
457 | mspi->rx_dma = t->rx_dma; | 452 | mspi->rx_dma = t->rx_dma; |
458 | } | 453 | } |
459 | 454 | ||
460 | /* enable rx ints */ | 455 | /* enable rx ints */ |
461 | mpc8xxx_spi_write_reg(&mspi->base->mask, SPIE_RXB); | 456 | mpc8xxx_spi_write_reg(&mspi->base->mask, SPIE_RXB); |
462 | 457 | ||
463 | mspi->xfer_in_progress = t; | 458 | mspi->xfer_in_progress = t; |
464 | mspi->count = t->len; | 459 | mspi->count = t->len; |
465 | 460 | ||
466 | /* start CPM transfers */ | 461 | /* start CPM transfers */ |
467 | mpc8xxx_spi_cpm_bufs_start(mspi); | 462 | mpc8xxx_spi_cpm_bufs_start(mspi); |
468 | 463 | ||
469 | return 0; | 464 | return 0; |
470 | 465 | ||
471 | err_rx_dma: | 466 | err_rx_dma: |
472 | if (mspi->map_tx_dma) | 467 | if (mspi->map_tx_dma) |
473 | dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE); | 468 | dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE); |
474 | return -ENOMEM; | 469 | return -ENOMEM; |
475 | } | 470 | } |
476 | 471 | ||
477 | static void mpc8xxx_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi) | 472 | static void mpc8xxx_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi) |
478 | { | 473 | { |
479 | struct device *dev = mspi->dev; | 474 | struct device *dev = mspi->dev; |
480 | struct spi_transfer *t = mspi->xfer_in_progress; | 475 | struct spi_transfer *t = mspi->xfer_in_progress; |
481 | 476 | ||
482 | if (mspi->map_tx_dma) | 477 | if (mspi->map_tx_dma) |
483 | dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE); | 478 | dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE); |
484 | if (mspi->map_tx_dma) | 479 | if (mspi->map_tx_dma) |
485 | dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE); | 480 | dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE); |
486 | mspi->xfer_in_progress = NULL; | 481 | mspi->xfer_in_progress = NULL; |
487 | } | 482 | } |
488 | 483 | ||
489 | static int mpc8xxx_spi_cpu_bufs(struct mpc8xxx_spi *mspi, | 484 | static int mpc8xxx_spi_cpu_bufs(struct mpc8xxx_spi *mspi, |
490 | struct spi_transfer *t, unsigned int len) | 485 | struct spi_transfer *t, unsigned int len) |
491 | { | 486 | { |
492 | u32 word; | 487 | u32 word; |
493 | 488 | ||
494 | mspi->count = len; | 489 | mspi->count = len; |
495 | 490 | ||
496 | /* enable rx ints */ | 491 | /* enable rx ints */ |
497 | mpc8xxx_spi_write_reg(&mspi->base->mask, SPIM_NE); | 492 | mpc8xxx_spi_write_reg(&mspi->base->mask, SPIM_NE); |
498 | 493 | ||
499 | /* transmit word */ | 494 | /* transmit word */ |
500 | word = mspi->get_tx(mspi); | 495 | word = mspi->get_tx(mspi); |
501 | mpc8xxx_spi_write_reg(&mspi->base->transmit, word); | 496 | mpc8xxx_spi_write_reg(&mspi->base->transmit, word); |
502 | 497 | ||
503 | return 0; | 498 | return 0; |
504 | } | 499 | } |
505 | 500 | ||
506 | static int mpc8xxx_spi_bufs(struct spi_device *spi, struct spi_transfer *t, | 501 | static int mpc8xxx_spi_bufs(struct spi_device *spi, struct spi_transfer *t, |
507 | bool is_dma_mapped) | 502 | bool is_dma_mapped) |
508 | { | 503 | { |
509 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 504 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
510 | unsigned int len = t->len; | 505 | unsigned int len = t->len; |
511 | u8 bits_per_word; | 506 | u8 bits_per_word; |
512 | int ret; | 507 | int ret; |
513 | 508 | ||
514 | bits_per_word = spi->bits_per_word; | 509 | bits_per_word = spi->bits_per_word; |
515 | if (t->bits_per_word) | 510 | if (t->bits_per_word) |
516 | bits_per_word = t->bits_per_word; | 511 | bits_per_word = t->bits_per_word; |
517 | 512 | ||
518 | if (bits_per_word > 8) { | 513 | if (bits_per_word > 8) { |
519 | /* invalid length? */ | 514 | /* invalid length? */ |
520 | if (len & 1) | 515 | if (len & 1) |
521 | return -EINVAL; | 516 | return -EINVAL; |
522 | len /= 2; | 517 | len /= 2; |
523 | } | 518 | } |
524 | if (bits_per_word > 16) { | 519 | if (bits_per_word > 16) { |
525 | /* invalid length? */ | 520 | /* invalid length? */ |
526 | if (len & 1) | 521 | if (len & 1) |
527 | return -EINVAL; | 522 | return -EINVAL; |
528 | len /= 2; | 523 | len /= 2; |
529 | } | 524 | } |
530 | 525 | ||
531 | mpc8xxx_spi->tx = t->tx_buf; | 526 | mpc8xxx_spi->tx = t->tx_buf; |
532 | mpc8xxx_spi->rx = t->rx_buf; | 527 | mpc8xxx_spi->rx = t->rx_buf; |
533 | 528 | ||
534 | INIT_COMPLETION(mpc8xxx_spi->done); | 529 | INIT_COMPLETION(mpc8xxx_spi->done); |
535 | 530 | ||
536 | if (mpc8xxx_spi->flags & SPI_CPM_MODE) | 531 | if (mpc8xxx_spi->flags & SPI_CPM_MODE) |
537 | ret = mpc8xxx_spi_cpm_bufs(mpc8xxx_spi, t, is_dma_mapped); | 532 | ret = mpc8xxx_spi_cpm_bufs(mpc8xxx_spi, t, is_dma_mapped); |
538 | else | 533 | else |
539 | ret = mpc8xxx_spi_cpu_bufs(mpc8xxx_spi, t, len); | 534 | ret = mpc8xxx_spi_cpu_bufs(mpc8xxx_spi, t, len); |
540 | if (ret) | 535 | if (ret) |
541 | return ret; | 536 | return ret; |
542 | 537 | ||
543 | wait_for_completion(&mpc8xxx_spi->done); | 538 | wait_for_completion(&mpc8xxx_spi->done); |
544 | 539 | ||
545 | /* disable rx ints */ | 540 | /* disable rx ints */ |
546 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0); | 541 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0); |
547 | 542 | ||
548 | if (mpc8xxx_spi->flags & SPI_CPM_MODE) | 543 | if (mpc8xxx_spi->flags & SPI_CPM_MODE) |
549 | mpc8xxx_spi_cpm_bufs_complete(mpc8xxx_spi); | 544 | mpc8xxx_spi_cpm_bufs_complete(mpc8xxx_spi); |
550 | 545 | ||
551 | return mpc8xxx_spi->count; | 546 | return mpc8xxx_spi->count; |
552 | } | 547 | } |
553 | 548 | ||
554 | static void mpc8xxx_spi_do_one_msg(struct spi_message *m) | 549 | static void mpc8xxx_spi_do_one_msg(struct spi_message *m) |
555 | { | 550 | { |
556 | struct spi_device *spi = m->spi; | 551 | struct spi_device *spi = m->spi; |
557 | struct spi_transfer *t; | 552 | struct spi_transfer *t; |
558 | unsigned int cs_change; | 553 | unsigned int cs_change; |
559 | const int nsecs = 50; | 554 | const int nsecs = 50; |
560 | int status; | 555 | int status; |
561 | 556 | ||
562 | cs_change = 1; | 557 | cs_change = 1; |
563 | status = 0; | 558 | status = 0; |
564 | list_for_each_entry(t, &m->transfers, transfer_list) { | 559 | list_for_each_entry(t, &m->transfers, transfer_list) { |
565 | if (t->bits_per_word || t->speed_hz) { | 560 | if (t->bits_per_word || t->speed_hz) { |
566 | /* Don't allow changes if CS is active */ | 561 | /* Don't allow changes if CS is active */ |
567 | status = -EINVAL; | 562 | status = -EINVAL; |
568 | 563 | ||
569 | if (cs_change) | 564 | if (cs_change) |
570 | status = mpc8xxx_spi_setup_transfer(spi, t); | 565 | status = mpc8xxx_spi_setup_transfer(spi, t); |
571 | if (status < 0) | 566 | if (status < 0) |
572 | break; | 567 | break; |
573 | } | 568 | } |
574 | 569 | ||
575 | if (cs_change) { | 570 | if (cs_change) { |
576 | mpc8xxx_spi_chipselect(spi, BITBANG_CS_ACTIVE); | 571 | mpc8xxx_spi_chipselect(spi, BITBANG_CS_ACTIVE); |
577 | ndelay(nsecs); | 572 | ndelay(nsecs); |
578 | } | 573 | } |
579 | cs_change = t->cs_change; | 574 | cs_change = t->cs_change; |
580 | if (t->len) | 575 | if (t->len) |
581 | status = mpc8xxx_spi_bufs(spi, t, m->is_dma_mapped); | 576 | status = mpc8xxx_spi_bufs(spi, t, m->is_dma_mapped); |
582 | if (status) { | 577 | if (status) { |
583 | status = -EMSGSIZE; | 578 | status = -EMSGSIZE; |
584 | break; | 579 | break; |
585 | } | 580 | } |
586 | m->actual_length += t->len; | 581 | m->actual_length += t->len; |
587 | 582 | ||
588 | if (t->delay_usecs) | 583 | if (t->delay_usecs) |
589 | udelay(t->delay_usecs); | 584 | udelay(t->delay_usecs); |
590 | 585 | ||
591 | if (cs_change) { | 586 | if (cs_change) { |
592 | ndelay(nsecs); | 587 | ndelay(nsecs); |
593 | mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE); | 588 | mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE); |
594 | ndelay(nsecs); | 589 | ndelay(nsecs); |
595 | } | 590 | } |
596 | } | 591 | } |
597 | 592 | ||
598 | m->status = status; | 593 | m->status = status; |
599 | m->complete(m->context); | 594 | m->complete(m->context); |
600 | 595 | ||
601 | if (status || !cs_change) { | 596 | if (status || !cs_change) { |
602 | ndelay(nsecs); | 597 | ndelay(nsecs); |
603 | mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE); | 598 | mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE); |
604 | } | 599 | } |
605 | 600 | ||
606 | mpc8xxx_spi_setup_transfer(spi, NULL); | 601 | mpc8xxx_spi_setup_transfer(spi, NULL); |
607 | } | 602 | } |
608 | 603 | ||
609 | static void mpc8xxx_spi_work(struct work_struct *work) | 604 | static void mpc8xxx_spi_work(struct work_struct *work) |
610 | { | 605 | { |
611 | struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi, | 606 | struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi, |
612 | work); | 607 | work); |
613 | 608 | ||
614 | spin_lock_irq(&mpc8xxx_spi->lock); | 609 | spin_lock_irq(&mpc8xxx_spi->lock); |
615 | while (!list_empty(&mpc8xxx_spi->queue)) { | 610 | while (!list_empty(&mpc8xxx_spi->queue)) { |
616 | struct spi_message *m = container_of(mpc8xxx_spi->queue.next, | 611 | struct spi_message *m = container_of(mpc8xxx_spi->queue.next, |
617 | struct spi_message, queue); | 612 | struct spi_message, queue); |
618 | 613 | ||
619 | list_del_init(&m->queue); | 614 | list_del_init(&m->queue); |
620 | spin_unlock_irq(&mpc8xxx_spi->lock); | 615 | spin_unlock_irq(&mpc8xxx_spi->lock); |
621 | 616 | ||
622 | mpc8xxx_spi_do_one_msg(m); | 617 | mpc8xxx_spi_do_one_msg(m); |
623 | 618 | ||
624 | spin_lock_irq(&mpc8xxx_spi->lock); | 619 | spin_lock_irq(&mpc8xxx_spi->lock); |
625 | } | 620 | } |
626 | spin_unlock_irq(&mpc8xxx_spi->lock); | 621 | spin_unlock_irq(&mpc8xxx_spi->lock); |
627 | } | 622 | } |
628 | 623 | ||
629 | static int mpc8xxx_spi_setup(struct spi_device *spi) | 624 | static int mpc8xxx_spi_setup(struct spi_device *spi) |
630 | { | 625 | { |
631 | struct mpc8xxx_spi *mpc8xxx_spi; | 626 | struct mpc8xxx_spi *mpc8xxx_spi; |
632 | int retval; | 627 | int retval; |
633 | u32 hw_mode; | 628 | u32 hw_mode; |
634 | struct spi_mpc8xxx_cs *cs = spi->controller_state; | 629 | struct spi_mpc8xxx_cs *cs = spi->controller_state; |
635 | 630 | ||
636 | if (!spi->max_speed_hz) | 631 | if (!spi->max_speed_hz) |
637 | return -EINVAL; | 632 | return -EINVAL; |
638 | 633 | ||
639 | if (!cs) { | 634 | if (!cs) { |
640 | cs = kzalloc(sizeof *cs, GFP_KERNEL); | 635 | cs = kzalloc(sizeof *cs, GFP_KERNEL); |
641 | if (!cs) | 636 | if (!cs) |
642 | return -ENOMEM; | 637 | return -ENOMEM; |
643 | spi->controller_state = cs; | 638 | spi->controller_state = cs; |
644 | } | 639 | } |
645 | mpc8xxx_spi = spi_master_get_devdata(spi->master); | 640 | mpc8xxx_spi = spi_master_get_devdata(spi->master); |
646 | 641 | ||
647 | hw_mode = cs->hw_mode; /* Save orginal settings */ | 642 | hw_mode = cs->hw_mode; /* Save orginal settings */ |
648 | cs->hw_mode = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode); | 643 | cs->hw_mode = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode); |
649 | /* mask out bits we are going to set */ | 644 | /* mask out bits we are going to set */ |
650 | cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH | 645 | cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH |
651 | | SPMODE_REV | SPMODE_LOOP); | 646 | | SPMODE_REV | SPMODE_LOOP); |
652 | 647 | ||
653 | if (spi->mode & SPI_CPHA) | 648 | if (spi->mode & SPI_CPHA) |
654 | cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; | 649 | cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; |
655 | if (spi->mode & SPI_CPOL) | 650 | if (spi->mode & SPI_CPOL) |
656 | cs->hw_mode |= SPMODE_CI_INACTIVEHIGH; | 651 | cs->hw_mode |= SPMODE_CI_INACTIVEHIGH; |
657 | if (!(spi->mode & SPI_LSB_FIRST)) | 652 | if (!(spi->mode & SPI_LSB_FIRST)) |
658 | cs->hw_mode |= SPMODE_REV; | 653 | cs->hw_mode |= SPMODE_REV; |
659 | if (spi->mode & SPI_LOOP) | 654 | if (spi->mode & SPI_LOOP) |
660 | cs->hw_mode |= SPMODE_LOOP; | 655 | cs->hw_mode |= SPMODE_LOOP; |
661 | 656 | ||
662 | retval = mpc8xxx_spi_setup_transfer(spi, NULL); | 657 | retval = mpc8xxx_spi_setup_transfer(spi, NULL); |
663 | if (retval < 0) { | 658 | if (retval < 0) { |
664 | cs->hw_mode = hw_mode; /* Restore settings */ | 659 | cs->hw_mode = hw_mode; /* Restore settings */ |
665 | return retval; | 660 | return retval; |
666 | } | 661 | } |
667 | return 0; | 662 | return 0; |
668 | } | 663 | } |
669 | 664 | ||
670 | static void mpc8xxx_spi_cpm_irq(struct mpc8xxx_spi *mspi, u32 events) | 665 | static void mpc8xxx_spi_cpm_irq(struct mpc8xxx_spi *mspi, u32 events) |
671 | { | 666 | { |
672 | u16 len; | 667 | u16 len; |
673 | 668 | ||
674 | dev_dbg(mspi->dev, "%s: bd datlen %d, count %d\n", __func__, | 669 | dev_dbg(mspi->dev, "%s: bd datlen %d, count %d\n", __func__, |
675 | in_be16(&mspi->rx_bd->cbd_datlen), mspi->count); | 670 | in_be16(&mspi->rx_bd->cbd_datlen), mspi->count); |
676 | 671 | ||
677 | len = in_be16(&mspi->rx_bd->cbd_datlen); | 672 | len = in_be16(&mspi->rx_bd->cbd_datlen); |
678 | if (len > mspi->count) { | 673 | if (len > mspi->count) { |
679 | WARN_ON(1); | 674 | WARN_ON(1); |
680 | len = mspi->count; | 675 | len = mspi->count; |
681 | } | 676 | } |
682 | 677 | ||
683 | /* Clear the events */ | 678 | /* Clear the events */ |
684 | mpc8xxx_spi_write_reg(&mspi->base->event, events); | 679 | mpc8xxx_spi_write_reg(&mspi->base->event, events); |
685 | 680 | ||
686 | mspi->count -= len; | 681 | mspi->count -= len; |
687 | if (mspi->count) | 682 | if (mspi->count) |
688 | mpc8xxx_spi_cpm_bufs_start(mspi); | 683 | mpc8xxx_spi_cpm_bufs_start(mspi); |
689 | else | 684 | else |
690 | complete(&mspi->done); | 685 | complete(&mspi->done); |
691 | } | 686 | } |
692 | 687 | ||
693 | static void mpc8xxx_spi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | 688 | static void mpc8xxx_spi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) |
694 | { | 689 | { |
695 | /* We need handle RX first */ | 690 | /* We need handle RX first */ |
696 | if (events & SPIE_NE) { | 691 | if (events & SPIE_NE) { |
697 | u32 rx_data = mpc8xxx_spi_read_reg(&mspi->base->receive); | 692 | u32 rx_data = mpc8xxx_spi_read_reg(&mspi->base->receive); |
698 | 693 | ||
699 | if (mspi->rx) | 694 | if (mspi->rx) |
700 | mspi->get_rx(rx_data, mspi); | 695 | mspi->get_rx(rx_data, mspi); |
701 | } | 696 | } |
702 | 697 | ||
703 | if ((events & SPIE_NF) == 0) | 698 | if ((events & SPIE_NF) == 0) |
704 | /* spin until TX is done */ | 699 | /* spin until TX is done */ |
705 | while (((events = | 700 | while (((events = |
706 | mpc8xxx_spi_read_reg(&mspi->base->event)) & | 701 | mpc8xxx_spi_read_reg(&mspi->base->event)) & |
707 | SPIE_NF) == 0) | 702 | SPIE_NF) == 0) |
708 | cpu_relax(); | 703 | cpu_relax(); |
709 | 704 | ||
710 | /* Clear the events */ | 705 | /* Clear the events */ |
711 | mpc8xxx_spi_write_reg(&mspi->base->event, events); | 706 | mpc8xxx_spi_write_reg(&mspi->base->event, events); |
712 | 707 | ||
713 | mspi->count -= 1; | 708 | mspi->count -= 1; |
714 | if (mspi->count) { | 709 | if (mspi->count) { |
715 | u32 word = mspi->get_tx(mspi); | 710 | u32 word = mspi->get_tx(mspi); |
716 | 711 | ||
717 | mpc8xxx_spi_write_reg(&mspi->base->transmit, word); | 712 | mpc8xxx_spi_write_reg(&mspi->base->transmit, word); |
718 | } else { | 713 | } else { |
719 | complete(&mspi->done); | 714 | complete(&mspi->done); |
720 | } | 715 | } |
721 | } | 716 | } |
722 | 717 | ||
723 | static irqreturn_t mpc8xxx_spi_irq(s32 irq, void *context_data) | 718 | static irqreturn_t mpc8xxx_spi_irq(s32 irq, void *context_data) |
724 | { | 719 | { |
725 | struct mpc8xxx_spi *mspi = context_data; | 720 | struct mpc8xxx_spi *mspi = context_data; |
726 | irqreturn_t ret = IRQ_NONE; | 721 | irqreturn_t ret = IRQ_NONE; |
727 | u32 events; | 722 | u32 events; |
728 | 723 | ||
729 | /* Get interrupt events(tx/rx) */ | 724 | /* Get interrupt events(tx/rx) */ |
730 | events = mpc8xxx_spi_read_reg(&mspi->base->event); | 725 | events = mpc8xxx_spi_read_reg(&mspi->base->event); |
731 | if (events) | 726 | if (events) |
732 | ret = IRQ_HANDLED; | 727 | ret = IRQ_HANDLED; |
733 | 728 | ||
734 | dev_dbg(mspi->dev, "%s: events %x\n", __func__, events); | 729 | dev_dbg(mspi->dev, "%s: events %x\n", __func__, events); |
735 | 730 | ||
736 | if (mspi->flags & SPI_CPM_MODE) | 731 | if (mspi->flags & SPI_CPM_MODE) |
737 | mpc8xxx_spi_cpm_irq(mspi, events); | 732 | mpc8xxx_spi_cpm_irq(mspi, events); |
738 | else | 733 | else |
739 | mpc8xxx_spi_cpu_irq(mspi, events); | 734 | mpc8xxx_spi_cpu_irq(mspi, events); |
740 | 735 | ||
741 | return ret; | 736 | return ret; |
742 | } | 737 | } |
743 | 738 | ||
744 | static int mpc8xxx_spi_transfer(struct spi_device *spi, | 739 | static int mpc8xxx_spi_transfer(struct spi_device *spi, |
745 | struct spi_message *m) | 740 | struct spi_message *m) |
746 | { | 741 | { |
747 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); | 742 | struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); |
748 | unsigned long flags; | 743 | unsigned long flags; |
749 | 744 | ||
750 | m->actual_length = 0; | 745 | m->actual_length = 0; |
751 | m->status = -EINPROGRESS; | 746 | m->status = -EINPROGRESS; |
752 | 747 | ||
753 | spin_lock_irqsave(&mpc8xxx_spi->lock, flags); | 748 | spin_lock_irqsave(&mpc8xxx_spi->lock, flags); |
754 | list_add_tail(&m->queue, &mpc8xxx_spi->queue); | 749 | list_add_tail(&m->queue, &mpc8xxx_spi->queue); |
755 | queue_work(mpc8xxx_spi->workqueue, &mpc8xxx_spi->work); | 750 | queue_work(mpc8xxx_spi->workqueue, &mpc8xxx_spi->work); |
756 | spin_unlock_irqrestore(&mpc8xxx_spi->lock, flags); | 751 | spin_unlock_irqrestore(&mpc8xxx_spi->lock, flags); |
757 | 752 | ||
758 | return 0; | 753 | return 0; |
759 | } | 754 | } |
760 | 755 | ||
761 | 756 | ||
762 | static void mpc8xxx_spi_cleanup(struct spi_device *spi) | 757 | static void mpc8xxx_spi_cleanup(struct spi_device *spi) |
763 | { | 758 | { |
764 | kfree(spi->controller_state); | 759 | kfree(spi->controller_state); |
765 | } | 760 | } |
766 | 761 | ||
767 | static void *mpc8xxx_spi_alloc_dummy_rx(void) | 762 | static void *mpc8xxx_spi_alloc_dummy_rx(void) |
768 | { | 763 | { |
769 | mutex_lock(&mpc8xxx_dummy_rx_lock); | 764 | mutex_lock(&mpc8xxx_dummy_rx_lock); |
770 | 765 | ||
771 | if (!mpc8xxx_dummy_rx) | 766 | if (!mpc8xxx_dummy_rx) |
772 | mpc8xxx_dummy_rx = kmalloc(SPI_MRBLR, GFP_KERNEL); | 767 | mpc8xxx_dummy_rx = kmalloc(SPI_MRBLR, GFP_KERNEL); |
773 | if (mpc8xxx_dummy_rx) | 768 | if (mpc8xxx_dummy_rx) |
774 | mpc8xxx_dummy_rx_refcnt++; | 769 | mpc8xxx_dummy_rx_refcnt++; |
775 | 770 | ||
776 | mutex_unlock(&mpc8xxx_dummy_rx_lock); | 771 | mutex_unlock(&mpc8xxx_dummy_rx_lock); |
777 | 772 | ||
778 | return mpc8xxx_dummy_rx; | 773 | return mpc8xxx_dummy_rx; |
779 | } | 774 | } |
780 | 775 | ||
781 | static void mpc8xxx_spi_free_dummy_rx(void) | 776 | static void mpc8xxx_spi_free_dummy_rx(void) |
782 | { | 777 | { |
783 | mutex_lock(&mpc8xxx_dummy_rx_lock); | 778 | mutex_lock(&mpc8xxx_dummy_rx_lock); |
784 | 779 | ||
785 | switch (mpc8xxx_dummy_rx_refcnt) { | 780 | switch (mpc8xxx_dummy_rx_refcnt) { |
786 | case 0: | 781 | case 0: |
787 | WARN_ON(1); | 782 | WARN_ON(1); |
788 | break; | 783 | break; |
789 | case 1: | 784 | case 1: |
790 | kfree(mpc8xxx_dummy_rx); | 785 | kfree(mpc8xxx_dummy_rx); |
791 | mpc8xxx_dummy_rx = NULL; | 786 | mpc8xxx_dummy_rx = NULL; |
792 | /* fall through */ | 787 | /* fall through */ |
793 | default: | 788 | default: |
794 | mpc8xxx_dummy_rx_refcnt--; | 789 | mpc8xxx_dummy_rx_refcnt--; |
795 | break; | 790 | break; |
796 | } | 791 | } |
797 | 792 | ||
798 | mutex_unlock(&mpc8xxx_dummy_rx_lock); | 793 | mutex_unlock(&mpc8xxx_dummy_rx_lock); |
799 | } | 794 | } |
800 | 795 | ||
801 | static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) | 796 | static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) |
802 | { | 797 | { |
803 | struct device *dev = mspi->dev; | 798 | struct device *dev = mspi->dev; |
804 | struct device_node *np = dev_archdata_get_node(&dev->archdata); | 799 | struct device_node *np = dev_archdata_get_node(&dev->archdata); |
805 | const u32 *iprop; | 800 | const u32 *iprop; |
806 | int size; | 801 | int size; |
807 | unsigned long spi_base_ofs; | 802 | unsigned long spi_base_ofs; |
808 | unsigned long pram_ofs = -ENOMEM; | 803 | unsigned long pram_ofs = -ENOMEM; |
809 | 804 | ||
810 | /* Can't use of_address_to_resource(), QE muram isn't at 0. */ | 805 | /* Can't use of_address_to_resource(), QE muram isn't at 0. */ |
811 | iprop = of_get_property(np, "reg", &size); | 806 | iprop = of_get_property(np, "reg", &size); |
812 | 807 | ||
813 | /* QE with a fixed pram location? */ | 808 | /* QE with a fixed pram location? */ |
814 | if (mspi->flags & SPI_QE && iprop && size == sizeof(*iprop) * 4) | 809 | if (mspi->flags & SPI_QE && iprop && size == sizeof(*iprop) * 4) |
815 | return cpm_muram_alloc_fixed(iprop[2], SPI_PRAM_SIZE); | 810 | return cpm_muram_alloc_fixed(iprop[2], SPI_PRAM_SIZE); |
816 | 811 | ||
817 | /* QE but with a dynamic pram location? */ | 812 | /* QE but with a dynamic pram location? */ |
818 | if (mspi->flags & SPI_QE) { | 813 | if (mspi->flags & SPI_QE) { |
819 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); | 814 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); |
820 | qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, mspi->subblock, | 815 | qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, mspi->subblock, |
821 | QE_CR_PROTOCOL_UNSPECIFIED, pram_ofs); | 816 | QE_CR_PROTOCOL_UNSPECIFIED, pram_ofs); |
822 | return pram_ofs; | 817 | return pram_ofs; |
823 | } | 818 | } |
824 | 819 | ||
825 | /* CPM1 and CPM2 pram must be at a fixed addr. */ | 820 | /* CPM1 and CPM2 pram must be at a fixed addr. */ |
826 | if (!iprop || size != sizeof(*iprop) * 4) | 821 | if (!iprop || size != sizeof(*iprop) * 4) |
827 | return -ENOMEM; | 822 | return -ENOMEM; |
828 | 823 | ||
829 | spi_base_ofs = cpm_muram_alloc_fixed(iprop[2], 2); | 824 | spi_base_ofs = cpm_muram_alloc_fixed(iprop[2], 2); |
830 | if (IS_ERR_VALUE(spi_base_ofs)) | 825 | if (IS_ERR_VALUE(spi_base_ofs)) |
831 | return -ENOMEM; | 826 | return -ENOMEM; |
832 | 827 | ||
833 | if (mspi->flags & SPI_CPM2) { | 828 | if (mspi->flags & SPI_CPM2) { |
834 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); | 829 | pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64); |
835 | if (!IS_ERR_VALUE(pram_ofs)) { | 830 | if (!IS_ERR_VALUE(pram_ofs)) { |
836 | u16 __iomem *spi_base = cpm_muram_addr(spi_base_ofs); | 831 | u16 __iomem *spi_base = cpm_muram_addr(spi_base_ofs); |
837 | 832 | ||
838 | out_be16(spi_base, pram_ofs); | 833 | out_be16(spi_base, pram_ofs); |
839 | } | 834 | } |
840 | } else { | 835 | } else { |
841 | struct spi_pram __iomem *pram = cpm_muram_addr(spi_base_ofs); | 836 | struct spi_pram __iomem *pram = cpm_muram_addr(spi_base_ofs); |
842 | u16 rpbase = in_be16(&pram->rpbase); | 837 | u16 rpbase = in_be16(&pram->rpbase); |
843 | 838 | ||
844 | /* Microcode relocation patch applied? */ | 839 | /* Microcode relocation patch applied? */ |
845 | if (rpbase) | 840 | if (rpbase) |
846 | pram_ofs = rpbase; | 841 | pram_ofs = rpbase; |
847 | else | 842 | else |
848 | return spi_base_ofs; | 843 | return spi_base_ofs; |
849 | } | 844 | } |
850 | 845 | ||
851 | cpm_muram_free(spi_base_ofs); | 846 | cpm_muram_free(spi_base_ofs); |
852 | return pram_ofs; | 847 | return pram_ofs; |
853 | } | 848 | } |
854 | 849 | ||
855 | static int mpc8xxx_spi_cpm_init(struct mpc8xxx_spi *mspi) | 850 | static int mpc8xxx_spi_cpm_init(struct mpc8xxx_spi *mspi) |
856 | { | 851 | { |
857 | struct device *dev = mspi->dev; | 852 | struct device *dev = mspi->dev; |
858 | struct device_node *np = dev_archdata_get_node(&dev->archdata); | 853 | struct device_node *np = dev_archdata_get_node(&dev->archdata); |
859 | const u32 *iprop; | 854 | const u32 *iprop; |
860 | int size; | 855 | int size; |
861 | unsigned long pram_ofs; | 856 | unsigned long pram_ofs; |
862 | unsigned long bds_ofs; | 857 | unsigned long bds_ofs; |
863 | 858 | ||
864 | if (!(mspi->flags & SPI_CPM_MODE)) | 859 | if (!(mspi->flags & SPI_CPM_MODE)) |
865 | return 0; | 860 | return 0; |
866 | 861 | ||
867 | if (!mpc8xxx_spi_alloc_dummy_rx()) | 862 | if (!mpc8xxx_spi_alloc_dummy_rx()) |
868 | return -ENOMEM; | 863 | return -ENOMEM; |
869 | 864 | ||
870 | if (mspi->flags & SPI_QE) { | 865 | if (mspi->flags & SPI_QE) { |
871 | iprop = of_get_property(np, "cell-index", &size); | 866 | iprop = of_get_property(np, "cell-index", &size); |
872 | if (iprop && size == sizeof(*iprop)) | 867 | if (iprop && size == sizeof(*iprop)) |
873 | mspi->subblock = *iprop; | 868 | mspi->subblock = *iprop; |
874 | 869 | ||
875 | switch (mspi->subblock) { | 870 | switch (mspi->subblock) { |
876 | default: | 871 | default: |
877 | dev_warn(dev, "cell-index unspecified, assuming SPI1"); | 872 | dev_warn(dev, "cell-index unspecified, assuming SPI1"); |
878 | /* fall through */ | 873 | /* fall through */ |
879 | case 0: | 874 | case 0: |
880 | mspi->subblock = QE_CR_SUBBLOCK_SPI1; | 875 | mspi->subblock = QE_CR_SUBBLOCK_SPI1; |
881 | break; | 876 | break; |
882 | case 1: | 877 | case 1: |
883 | mspi->subblock = QE_CR_SUBBLOCK_SPI2; | 878 | mspi->subblock = QE_CR_SUBBLOCK_SPI2; |
884 | break; | 879 | break; |
885 | } | 880 | } |
886 | } | 881 | } |
887 | 882 | ||
888 | pram_ofs = mpc8xxx_spi_cpm_get_pram(mspi); | 883 | pram_ofs = mpc8xxx_spi_cpm_get_pram(mspi); |
889 | if (IS_ERR_VALUE(pram_ofs)) { | 884 | if (IS_ERR_VALUE(pram_ofs)) { |
890 | dev_err(dev, "can't allocate spi parameter ram\n"); | 885 | dev_err(dev, "can't allocate spi parameter ram\n"); |
891 | goto err_pram; | 886 | goto err_pram; |
892 | } | 887 | } |
893 | 888 | ||
894 | bds_ofs = cpm_muram_alloc(sizeof(*mspi->tx_bd) + | 889 | bds_ofs = cpm_muram_alloc(sizeof(*mspi->tx_bd) + |
895 | sizeof(*mspi->rx_bd), 8); | 890 | sizeof(*mspi->rx_bd), 8); |
896 | if (IS_ERR_VALUE(bds_ofs)) { | 891 | if (IS_ERR_VALUE(bds_ofs)) { |
897 | dev_err(dev, "can't allocate bds\n"); | 892 | dev_err(dev, "can't allocate bds\n"); |
898 | goto err_bds; | 893 | goto err_bds; |
899 | } | 894 | } |
900 | 895 | ||
901 | mspi->dma_dummy_tx = dma_map_single(dev, empty_zero_page, PAGE_SIZE, | 896 | mspi->dma_dummy_tx = dma_map_single(dev, empty_zero_page, PAGE_SIZE, |
902 | DMA_TO_DEVICE); | 897 | DMA_TO_DEVICE); |
903 | if (dma_mapping_error(dev, mspi->dma_dummy_tx)) { | 898 | if (dma_mapping_error(dev, mspi->dma_dummy_tx)) { |
904 | dev_err(dev, "unable to map dummy tx buffer\n"); | 899 | dev_err(dev, "unable to map dummy tx buffer\n"); |
905 | goto err_dummy_tx; | 900 | goto err_dummy_tx; |
906 | } | 901 | } |
907 | 902 | ||
908 | mspi->dma_dummy_rx = dma_map_single(dev, mpc8xxx_dummy_rx, SPI_MRBLR, | 903 | mspi->dma_dummy_rx = dma_map_single(dev, mpc8xxx_dummy_rx, SPI_MRBLR, |
909 | DMA_FROM_DEVICE); | 904 | DMA_FROM_DEVICE); |
910 | if (dma_mapping_error(dev, mspi->dma_dummy_rx)) { | 905 | if (dma_mapping_error(dev, mspi->dma_dummy_rx)) { |
911 | dev_err(dev, "unable to map dummy rx buffer\n"); | 906 | dev_err(dev, "unable to map dummy rx buffer\n"); |
912 | goto err_dummy_rx; | 907 | goto err_dummy_rx; |
913 | } | 908 | } |
914 | 909 | ||
915 | mspi->pram = cpm_muram_addr(pram_ofs); | 910 | mspi->pram = cpm_muram_addr(pram_ofs); |
916 | 911 | ||
917 | mspi->tx_bd = cpm_muram_addr(bds_ofs); | 912 | mspi->tx_bd = cpm_muram_addr(bds_ofs); |
918 | mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); | 913 | mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd)); |
919 | 914 | ||
920 | /* Initialize parameter ram. */ | 915 | /* Initialize parameter ram. */ |
921 | out_be16(&mspi->pram->tbase, cpm_muram_offset(mspi->tx_bd)); | 916 | out_be16(&mspi->pram->tbase, cpm_muram_offset(mspi->tx_bd)); |
922 | out_be16(&mspi->pram->rbase, cpm_muram_offset(mspi->rx_bd)); | 917 | out_be16(&mspi->pram->rbase, cpm_muram_offset(mspi->rx_bd)); |
923 | out_8(&mspi->pram->tfcr, CPMFCR_EB | CPMFCR_GBL); | 918 | out_8(&mspi->pram->tfcr, CPMFCR_EB | CPMFCR_GBL); |
924 | out_8(&mspi->pram->rfcr, CPMFCR_EB | CPMFCR_GBL); | 919 | out_8(&mspi->pram->rfcr, CPMFCR_EB | CPMFCR_GBL); |
925 | out_be16(&mspi->pram->mrblr, SPI_MRBLR); | 920 | out_be16(&mspi->pram->mrblr, SPI_MRBLR); |
926 | out_be32(&mspi->pram->rstate, 0); | 921 | out_be32(&mspi->pram->rstate, 0); |
927 | out_be32(&mspi->pram->rdp, 0); | 922 | out_be32(&mspi->pram->rdp, 0); |
928 | out_be16(&mspi->pram->rbptr, 0); | 923 | out_be16(&mspi->pram->rbptr, 0); |
929 | out_be16(&mspi->pram->rbc, 0); | 924 | out_be16(&mspi->pram->rbc, 0); |
930 | out_be32(&mspi->pram->rxtmp, 0); | 925 | out_be32(&mspi->pram->rxtmp, 0); |
931 | out_be32(&mspi->pram->tstate, 0); | 926 | out_be32(&mspi->pram->tstate, 0); |
932 | out_be32(&mspi->pram->tdp, 0); | 927 | out_be32(&mspi->pram->tdp, 0); |
933 | out_be16(&mspi->pram->tbptr, 0); | 928 | out_be16(&mspi->pram->tbptr, 0); |
934 | out_be16(&mspi->pram->tbc, 0); | 929 | out_be16(&mspi->pram->tbc, 0); |
935 | out_be32(&mspi->pram->txtmp, 0); | 930 | out_be32(&mspi->pram->txtmp, 0); |
936 | 931 | ||
937 | return 0; | 932 | return 0; |
938 | 933 | ||
939 | err_dummy_rx: | 934 | err_dummy_rx: |
940 | dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); | 935 | dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); |
941 | err_dummy_tx: | 936 | err_dummy_tx: |
942 | cpm_muram_free(bds_ofs); | 937 | cpm_muram_free(bds_ofs); |
943 | err_bds: | 938 | err_bds: |
944 | cpm_muram_free(pram_ofs); | 939 | cpm_muram_free(pram_ofs); |
945 | err_pram: | 940 | err_pram: |
946 | mpc8xxx_spi_free_dummy_rx(); | 941 | mpc8xxx_spi_free_dummy_rx(); |
947 | return -ENOMEM; | 942 | return -ENOMEM; |
948 | } | 943 | } |
949 | 944 | ||
950 | static void mpc8xxx_spi_cpm_free(struct mpc8xxx_spi *mspi) | 945 | static void mpc8xxx_spi_cpm_free(struct mpc8xxx_spi *mspi) |
951 | { | 946 | { |
952 | struct device *dev = mspi->dev; | 947 | struct device *dev = mspi->dev; |
953 | 948 | ||
954 | dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE); | 949 | dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE); |
955 | dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); | 950 | dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); |
956 | cpm_muram_free(cpm_muram_offset(mspi->tx_bd)); | 951 | cpm_muram_free(cpm_muram_offset(mspi->tx_bd)); |
957 | cpm_muram_free(cpm_muram_offset(mspi->pram)); | 952 | cpm_muram_free(cpm_muram_offset(mspi->pram)); |
958 | mpc8xxx_spi_free_dummy_rx(); | 953 | mpc8xxx_spi_free_dummy_rx(); |
959 | } | 954 | } |
960 | 955 | ||
961 | static const char *mpc8xxx_spi_strmode(unsigned int flags) | 956 | static const char *mpc8xxx_spi_strmode(unsigned int flags) |
962 | { | 957 | { |
963 | if (flags & SPI_QE_CPU_MODE) { | 958 | if (flags & SPI_QE_CPU_MODE) { |
964 | return "QE CPU"; | 959 | return "QE CPU"; |
965 | } else if (flags & SPI_CPM_MODE) { | 960 | } else if (flags & SPI_CPM_MODE) { |
966 | if (flags & SPI_QE) | 961 | if (flags & SPI_QE) |
967 | return "QE"; | 962 | return "QE"; |
968 | else if (flags & SPI_CPM2) | 963 | else if (flags & SPI_CPM2) |
969 | return "CPM2"; | 964 | return "CPM2"; |
970 | else | 965 | else |
971 | return "CPM1"; | 966 | return "CPM1"; |
972 | } | 967 | } |
973 | return "CPU"; | 968 | return "CPU"; |
974 | } | 969 | } |
975 | 970 | ||
976 | static struct spi_master * __devinit | 971 | static struct spi_master * __devinit |
977 | mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) | 972 | mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) |
978 | { | 973 | { |
979 | struct fsl_spi_platform_data *pdata = dev->platform_data; | 974 | struct fsl_spi_platform_data *pdata = dev->platform_data; |
980 | struct spi_master *master; | 975 | struct spi_master *master; |
981 | struct mpc8xxx_spi *mpc8xxx_spi; | 976 | struct mpc8xxx_spi *mpc8xxx_spi; |
982 | u32 regval; | 977 | u32 regval; |
983 | int ret = 0; | 978 | int ret = 0; |
984 | 979 | ||
985 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); | 980 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); |
986 | if (master == NULL) { | 981 | if (master == NULL) { |
987 | ret = -ENOMEM; | 982 | ret = -ENOMEM; |
988 | goto err; | 983 | goto err; |
989 | } | 984 | } |
990 | 985 | ||
991 | dev_set_drvdata(dev, master); | 986 | dev_set_drvdata(dev, master); |
992 | 987 | ||
993 | /* the spi->mode bits understood by this driver: */ | 988 | /* the spi->mode bits understood by this driver: */ |
994 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | 989 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH |
995 | | SPI_LSB_FIRST | SPI_LOOP; | 990 | | SPI_LSB_FIRST | SPI_LOOP; |
996 | 991 | ||
997 | master->setup = mpc8xxx_spi_setup; | 992 | master->setup = mpc8xxx_spi_setup; |
998 | master->transfer = mpc8xxx_spi_transfer; | 993 | master->transfer = mpc8xxx_spi_transfer; |
999 | master->cleanup = mpc8xxx_spi_cleanup; | 994 | master->cleanup = mpc8xxx_spi_cleanup; |
1000 | 995 | ||
1001 | mpc8xxx_spi = spi_master_get_devdata(master); | 996 | mpc8xxx_spi = spi_master_get_devdata(master); |
1002 | mpc8xxx_spi->dev = dev; | 997 | mpc8xxx_spi->dev = dev; |
1003 | mpc8xxx_spi->get_rx = mpc8xxx_spi_rx_buf_u8; | 998 | mpc8xxx_spi->get_rx = mpc8xxx_spi_rx_buf_u8; |
1004 | mpc8xxx_spi->get_tx = mpc8xxx_spi_tx_buf_u8; | 999 | mpc8xxx_spi->get_tx = mpc8xxx_spi_tx_buf_u8; |
1005 | mpc8xxx_spi->flags = pdata->flags; | 1000 | mpc8xxx_spi->flags = pdata->flags; |
1006 | mpc8xxx_spi->spibrg = pdata->sysclk; | 1001 | mpc8xxx_spi->spibrg = pdata->sysclk; |
1007 | 1002 | ||
1008 | ret = mpc8xxx_spi_cpm_init(mpc8xxx_spi); | 1003 | ret = mpc8xxx_spi_cpm_init(mpc8xxx_spi); |
1009 | if (ret) | 1004 | if (ret) |
1010 | goto err_cpm_init; | 1005 | goto err_cpm_init; |
1011 | 1006 | ||
1012 | mpc8xxx_spi->rx_shift = 0; | 1007 | mpc8xxx_spi->rx_shift = 0; |
1013 | mpc8xxx_spi->tx_shift = 0; | 1008 | mpc8xxx_spi->tx_shift = 0; |
1014 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { | 1009 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { |
1015 | mpc8xxx_spi->rx_shift = 16; | 1010 | mpc8xxx_spi->rx_shift = 16; |
1016 | mpc8xxx_spi->tx_shift = 24; | 1011 | mpc8xxx_spi->tx_shift = 24; |
1017 | } | 1012 | } |
1018 | 1013 | ||
1019 | init_completion(&mpc8xxx_spi->done); | 1014 | init_completion(&mpc8xxx_spi->done); |
1020 | 1015 | ||
1021 | mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); | 1016 | mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); |
1022 | if (mpc8xxx_spi->base == NULL) { | 1017 | if (mpc8xxx_spi->base == NULL) { |
1023 | ret = -ENOMEM; | 1018 | ret = -ENOMEM; |
1024 | goto err_ioremap; | 1019 | goto err_ioremap; |
1025 | } | 1020 | } |
1026 | 1021 | ||
1027 | mpc8xxx_spi->irq = irq; | 1022 | mpc8xxx_spi->irq = irq; |
1028 | 1023 | ||
1029 | /* Register for SPI Interrupt */ | 1024 | /* Register for SPI Interrupt */ |
1030 | ret = request_irq(mpc8xxx_spi->irq, mpc8xxx_spi_irq, | 1025 | ret = request_irq(mpc8xxx_spi->irq, mpc8xxx_spi_irq, |
1031 | 0, "mpc8xxx_spi", mpc8xxx_spi); | 1026 | 0, "mpc8xxx_spi", mpc8xxx_spi); |
1032 | 1027 | ||
1033 | if (ret != 0) | 1028 | if (ret != 0) |
1034 | goto unmap_io; | 1029 | goto unmap_io; |
1035 | 1030 | ||
1036 | master->bus_num = pdata->bus_num; | 1031 | master->bus_num = pdata->bus_num; |
1037 | master->num_chipselect = pdata->max_chipselect; | 1032 | master->num_chipselect = pdata->max_chipselect; |
1038 | 1033 | ||
1039 | /* SPI controller initializations */ | 1034 | /* SPI controller initializations */ |
1040 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, 0); | 1035 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, 0); |
1041 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0); | 1036 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0); |
1042 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->command, 0); | 1037 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->command, 0); |
1043 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->event, 0xffffffff); | 1038 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->event, 0xffffffff); |
1044 | 1039 | ||
1045 | /* Enable SPI interface */ | 1040 | /* Enable SPI interface */ |
1046 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | 1041 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; |
1047 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) | 1042 | if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) |
1048 | regval |= SPMODE_OP; | 1043 | regval |= SPMODE_OP; |
1049 | 1044 | ||
1050 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, regval); | 1045 | mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, regval); |
1051 | spin_lock_init(&mpc8xxx_spi->lock); | 1046 | spin_lock_init(&mpc8xxx_spi->lock); |
1052 | init_completion(&mpc8xxx_spi->done); | 1047 | init_completion(&mpc8xxx_spi->done); |
1053 | INIT_WORK(&mpc8xxx_spi->work, mpc8xxx_spi_work); | 1048 | INIT_WORK(&mpc8xxx_spi->work, mpc8xxx_spi_work); |
1054 | INIT_LIST_HEAD(&mpc8xxx_spi->queue); | 1049 | INIT_LIST_HEAD(&mpc8xxx_spi->queue); |
1055 | 1050 | ||
1056 | mpc8xxx_spi->workqueue = create_singlethread_workqueue( | 1051 | mpc8xxx_spi->workqueue = create_singlethread_workqueue( |
1057 | dev_name(master->dev.parent)); | 1052 | dev_name(master->dev.parent)); |
1058 | if (mpc8xxx_spi->workqueue == NULL) { | 1053 | if (mpc8xxx_spi->workqueue == NULL) { |
1059 | ret = -EBUSY; | 1054 | ret = -EBUSY; |
1060 | goto free_irq; | 1055 | goto free_irq; |
1061 | } | 1056 | } |
1062 | 1057 | ||
1063 | ret = spi_register_master(master); | 1058 | ret = spi_register_master(master); |
1064 | if (ret < 0) | 1059 | if (ret < 0) |
1065 | goto unreg_master; | 1060 | goto unreg_master; |
1066 | 1061 | ||
1067 | dev_info(dev, "at 0x%p (irq = %d), %s mode\n", mpc8xxx_spi->base, | 1062 | dev_info(dev, "at 0x%p (irq = %d), %s mode\n", mpc8xxx_spi->base, |
1068 | mpc8xxx_spi->irq, mpc8xxx_spi_strmode(mpc8xxx_spi->flags)); | 1063 | mpc8xxx_spi->irq, mpc8xxx_spi_strmode(mpc8xxx_spi->flags)); |
1069 | 1064 | ||
1070 | return master; | 1065 | return master; |
1071 | 1066 | ||
1072 | unreg_master: | 1067 | unreg_master: |
1073 | destroy_workqueue(mpc8xxx_spi->workqueue); | 1068 | destroy_workqueue(mpc8xxx_spi->workqueue); |
1074 | free_irq: | 1069 | free_irq: |
1075 | free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); | 1070 | free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); |
1076 | unmap_io: | 1071 | unmap_io: |
1077 | iounmap(mpc8xxx_spi->base); | 1072 | iounmap(mpc8xxx_spi->base); |
1078 | err_ioremap: | 1073 | err_ioremap: |
1079 | mpc8xxx_spi_cpm_free(mpc8xxx_spi); | 1074 | mpc8xxx_spi_cpm_free(mpc8xxx_spi); |
1080 | err_cpm_init: | 1075 | err_cpm_init: |
1081 | spi_master_put(master); | 1076 | spi_master_put(master); |
1082 | err: | 1077 | err: |
1083 | return ERR_PTR(ret); | 1078 | return ERR_PTR(ret); |
1084 | } | 1079 | } |
1085 | 1080 | ||
1086 | static int __devexit mpc8xxx_spi_remove(struct device *dev) | 1081 | static int __devexit mpc8xxx_spi_remove(struct device *dev) |
1087 | { | 1082 | { |
1088 | struct mpc8xxx_spi *mpc8xxx_spi; | 1083 | struct mpc8xxx_spi *mpc8xxx_spi; |
1089 | struct spi_master *master; | 1084 | struct spi_master *master; |
1090 | 1085 | ||
1091 | master = dev_get_drvdata(dev); | 1086 | master = dev_get_drvdata(dev); |
1092 | mpc8xxx_spi = spi_master_get_devdata(master); | 1087 | mpc8xxx_spi = spi_master_get_devdata(master); |
1093 | 1088 | ||
1094 | flush_workqueue(mpc8xxx_spi->workqueue); | 1089 | flush_workqueue(mpc8xxx_spi->workqueue); |
1095 | destroy_workqueue(mpc8xxx_spi->workqueue); | 1090 | destroy_workqueue(mpc8xxx_spi->workqueue); |
1096 | spi_unregister_master(master); | 1091 | spi_unregister_master(master); |
1097 | 1092 | ||
1098 | free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); | 1093 | free_irq(mpc8xxx_spi->irq, mpc8xxx_spi); |
1099 | iounmap(mpc8xxx_spi->base); | 1094 | iounmap(mpc8xxx_spi->base); |
1100 | mpc8xxx_spi_cpm_free(mpc8xxx_spi); | 1095 | mpc8xxx_spi_cpm_free(mpc8xxx_spi); |
1101 | 1096 | ||
1102 | return 0; | 1097 | return 0; |
1103 | } | 1098 | } |
1104 | 1099 | ||
1105 | struct mpc8xxx_spi_probe_info { | 1100 | struct mpc8xxx_spi_probe_info { |
1106 | struct fsl_spi_platform_data pdata; | 1101 | struct fsl_spi_platform_data pdata; |
1107 | int *gpios; | 1102 | int *gpios; |
1108 | bool *alow_flags; | 1103 | bool *alow_flags; |
1109 | }; | 1104 | }; |
1110 | 1105 | ||
1111 | static struct mpc8xxx_spi_probe_info * | 1106 | static struct mpc8xxx_spi_probe_info * |
1112 | to_of_pinfo(struct fsl_spi_platform_data *pdata) | 1107 | to_of_pinfo(struct fsl_spi_platform_data *pdata) |
1113 | { | 1108 | { |
1114 | return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata); | 1109 | return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata); |
1115 | } | 1110 | } |
1116 | 1111 | ||
1117 | static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on) | 1112 | static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on) |
1118 | { | 1113 | { |
1119 | struct device *dev = spi->dev.parent; | 1114 | struct device *dev = spi->dev.parent; |
1120 | struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); | 1115 | struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data); |
1121 | u16 cs = spi->chip_select; | 1116 | u16 cs = spi->chip_select; |
1122 | int gpio = pinfo->gpios[cs]; | 1117 | int gpio = pinfo->gpios[cs]; |
1123 | bool alow = pinfo->alow_flags[cs]; | 1118 | bool alow = pinfo->alow_flags[cs]; |
1124 | 1119 | ||
1125 | gpio_set_value(gpio, on ^ alow); | 1120 | gpio_set_value(gpio, on ^ alow); |
1126 | } | 1121 | } |
1127 | 1122 | ||
1128 | static int of_mpc8xxx_spi_get_chipselects(struct device *dev) | 1123 | static int of_mpc8xxx_spi_get_chipselects(struct device *dev) |
1129 | { | 1124 | { |
1130 | struct device_node *np = dev_archdata_get_node(&dev->archdata); | 1125 | struct device_node *np = dev_archdata_get_node(&dev->archdata); |
1131 | struct fsl_spi_platform_data *pdata = dev->platform_data; | 1126 | struct fsl_spi_platform_data *pdata = dev->platform_data; |
1132 | struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); | 1127 | struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); |
1133 | unsigned int ngpios; | 1128 | unsigned int ngpios; |
1134 | int i = 0; | 1129 | int i = 0; |
1135 | int ret; | 1130 | int ret; |
1136 | 1131 | ||
1137 | ngpios = of_gpio_count(np); | 1132 | ngpios = of_gpio_count(np); |
1138 | if (!ngpios) { | 1133 | if (!ngpios) { |
1139 | /* | 1134 | /* |
1140 | * SPI w/o chip-select line. One SPI device is still permitted | 1135 | * SPI w/o chip-select line. One SPI device is still permitted |
1141 | * though. | 1136 | * though. |
1142 | */ | 1137 | */ |
1143 | pdata->max_chipselect = 1; | 1138 | pdata->max_chipselect = 1; |
1144 | return 0; | 1139 | return 0; |
1145 | } | 1140 | } |
1146 | 1141 | ||
1147 | pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL); | 1142 | pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL); |
1148 | if (!pinfo->gpios) | 1143 | if (!pinfo->gpios) |
1149 | return -ENOMEM; | 1144 | return -ENOMEM; |
1150 | memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios)); | 1145 | memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios)); |
1151 | 1146 | ||
1152 | pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags), | 1147 | pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags), |
1153 | GFP_KERNEL); | 1148 | GFP_KERNEL); |
1154 | if (!pinfo->alow_flags) { | 1149 | if (!pinfo->alow_flags) { |
1155 | ret = -ENOMEM; | 1150 | ret = -ENOMEM; |
1156 | goto err_alloc_flags; | 1151 | goto err_alloc_flags; |
1157 | } | 1152 | } |
1158 | 1153 | ||
1159 | for (; i < ngpios; i++) { | 1154 | for (; i < ngpios; i++) { |
1160 | int gpio; | 1155 | int gpio; |
1161 | enum of_gpio_flags flags; | 1156 | enum of_gpio_flags flags; |
1162 | 1157 | ||
1163 | gpio = of_get_gpio_flags(np, i, &flags); | 1158 | gpio = of_get_gpio_flags(np, i, &flags); |
1164 | if (!gpio_is_valid(gpio)) { | 1159 | if (!gpio_is_valid(gpio)) { |
1165 | dev_err(dev, "invalid gpio #%d: %d\n", i, gpio); | 1160 | dev_err(dev, "invalid gpio #%d: %d\n", i, gpio); |
1166 | ret = gpio; | 1161 | ret = gpio; |
1167 | goto err_loop; | 1162 | goto err_loop; |
1168 | } | 1163 | } |
1169 | 1164 | ||
1170 | ret = gpio_request(gpio, dev_name(dev)); | 1165 | ret = gpio_request(gpio, dev_name(dev)); |
1171 | if (ret) { | 1166 | if (ret) { |
1172 | dev_err(dev, "can't request gpio #%d: %d\n", i, ret); | 1167 | dev_err(dev, "can't request gpio #%d: %d\n", i, ret); |
1173 | goto err_loop; | 1168 | goto err_loop; |
1174 | } | 1169 | } |
1175 | 1170 | ||
1176 | pinfo->gpios[i] = gpio; | 1171 | pinfo->gpios[i] = gpio; |
1177 | pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW; | 1172 | pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW; |
1178 | 1173 | ||
1179 | ret = gpio_direction_output(pinfo->gpios[i], | 1174 | ret = gpio_direction_output(pinfo->gpios[i], |
1180 | pinfo->alow_flags[i]); | 1175 | pinfo->alow_flags[i]); |
1181 | if (ret) { | 1176 | if (ret) { |
1182 | dev_err(dev, "can't set output direction for gpio " | 1177 | dev_err(dev, "can't set output direction for gpio " |
1183 | "#%d: %d\n", i, ret); | 1178 | "#%d: %d\n", i, ret); |
1184 | goto err_loop; | 1179 | goto err_loop; |
1185 | } | 1180 | } |
1186 | } | 1181 | } |
1187 | 1182 | ||
1188 | pdata->max_chipselect = ngpios; | 1183 | pdata->max_chipselect = ngpios; |
1189 | pdata->cs_control = mpc8xxx_spi_cs_control; | 1184 | pdata->cs_control = mpc8xxx_spi_cs_control; |
1190 | 1185 | ||
1191 | return 0; | 1186 | return 0; |
1192 | 1187 | ||
1193 | err_loop: | 1188 | err_loop: |
1194 | while (i >= 0) { | 1189 | while (i >= 0) { |
1195 | if (gpio_is_valid(pinfo->gpios[i])) | 1190 | if (gpio_is_valid(pinfo->gpios[i])) |
1196 | gpio_free(pinfo->gpios[i]); | 1191 | gpio_free(pinfo->gpios[i]); |
1197 | i--; | 1192 | i--; |
1198 | } | 1193 | } |
1199 | 1194 | ||
1200 | kfree(pinfo->alow_flags); | 1195 | kfree(pinfo->alow_flags); |
1201 | pinfo->alow_flags = NULL; | 1196 | pinfo->alow_flags = NULL; |
1202 | err_alloc_flags: | 1197 | err_alloc_flags: |
1203 | kfree(pinfo->gpios); | 1198 | kfree(pinfo->gpios); |
1204 | pinfo->gpios = NULL; | 1199 | pinfo->gpios = NULL; |
1205 | return ret; | 1200 | return ret; |
1206 | } | 1201 | } |
1207 | 1202 | ||
1208 | static int of_mpc8xxx_spi_free_chipselects(struct device *dev) | 1203 | static int of_mpc8xxx_spi_free_chipselects(struct device *dev) |
1209 | { | 1204 | { |
1210 | struct fsl_spi_platform_data *pdata = dev->platform_data; | 1205 | struct fsl_spi_platform_data *pdata = dev->platform_data; |
1211 | struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); | 1206 | struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); |
1212 | int i; | 1207 | int i; |
1213 | 1208 | ||
1214 | if (!pinfo->gpios) | 1209 | if (!pinfo->gpios) |
1215 | return 0; | 1210 | return 0; |
1216 | 1211 | ||
1217 | for (i = 0; i < pdata->max_chipselect; i++) { | 1212 | for (i = 0; i < pdata->max_chipselect; i++) { |
1218 | if (gpio_is_valid(pinfo->gpios[i])) | 1213 | if (gpio_is_valid(pinfo->gpios[i])) |
1219 | gpio_free(pinfo->gpios[i]); | 1214 | gpio_free(pinfo->gpios[i]); |
1220 | } | 1215 | } |
1221 | 1216 | ||
1222 | kfree(pinfo->gpios); | 1217 | kfree(pinfo->gpios); |
1223 | kfree(pinfo->alow_flags); | 1218 | kfree(pinfo->alow_flags); |
1224 | return 0; | 1219 | return 0; |
1225 | } | 1220 | } |
1226 | 1221 | ||
1227 | static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, | 1222 | static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, |
1228 | const struct of_device_id *ofid) | 1223 | const struct of_device_id *ofid) |
1229 | { | 1224 | { |
1230 | struct device *dev = &ofdev->dev; | 1225 | struct device *dev = &ofdev->dev; |
1231 | struct device_node *np = ofdev->node; | 1226 | struct device_node *np = ofdev->node; |
1232 | struct mpc8xxx_spi_probe_info *pinfo; | 1227 | struct mpc8xxx_spi_probe_info *pinfo; |
1233 | struct fsl_spi_platform_data *pdata; | 1228 | struct fsl_spi_platform_data *pdata; |
1234 | struct spi_master *master; | 1229 | struct spi_master *master; |
1235 | struct resource mem; | 1230 | struct resource mem; |
1236 | struct resource irq; | 1231 | struct resource irq; |
1237 | const void *prop; | 1232 | const void *prop; |
1238 | int ret = -ENOMEM; | 1233 | int ret = -ENOMEM; |
1239 | 1234 | ||
1240 | pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); | 1235 | pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); |
1241 | if (!pinfo) | 1236 | if (!pinfo) |
1242 | return -ENOMEM; | 1237 | return -ENOMEM; |
1243 | 1238 | ||
1244 | pdata = &pinfo->pdata; | 1239 | pdata = &pinfo->pdata; |
1245 | dev->platform_data = pdata; | 1240 | dev->platform_data = pdata; |
1246 | 1241 | ||
1247 | /* Allocate bus num dynamically. */ | 1242 | /* Allocate bus num dynamically. */ |
1248 | pdata->bus_num = -1; | 1243 | pdata->bus_num = -1; |
1249 | 1244 | ||
1250 | /* SPI controller is either clocked from QE or SoC clock. */ | 1245 | /* SPI controller is either clocked from QE or SoC clock. */ |
1251 | pdata->sysclk = get_brgfreq(); | 1246 | pdata->sysclk = get_brgfreq(); |
1252 | if (pdata->sysclk == -1) { | 1247 | if (pdata->sysclk == -1) { |
1253 | pdata->sysclk = fsl_get_sys_freq(); | 1248 | pdata->sysclk = fsl_get_sys_freq(); |
1254 | if (pdata->sysclk == -1) { | 1249 | if (pdata->sysclk == -1) { |
1255 | ret = -ENODEV; | 1250 | ret = -ENODEV; |
1256 | goto err_clk; | 1251 | goto err_clk; |
1257 | } | 1252 | } |
1258 | } | 1253 | } |
1259 | 1254 | ||
1260 | prop = of_get_property(np, "mode", NULL); | 1255 | prop = of_get_property(np, "mode", NULL); |
1261 | if (prop && !strcmp(prop, "cpu-qe")) | 1256 | if (prop && !strcmp(prop, "cpu-qe")) |
1262 | pdata->flags = SPI_QE_CPU_MODE; | 1257 | pdata->flags = SPI_QE_CPU_MODE; |
1263 | else if (prop && !strcmp(prop, "qe")) | 1258 | else if (prop && !strcmp(prop, "qe")) |
1264 | pdata->flags = SPI_CPM_MODE | SPI_QE; | 1259 | pdata->flags = SPI_CPM_MODE | SPI_QE; |
1265 | else if (of_device_is_compatible(np, "fsl,cpm2-spi")) | 1260 | else if (of_device_is_compatible(np, "fsl,cpm2-spi")) |
1266 | pdata->flags = SPI_CPM_MODE | SPI_CPM2; | 1261 | pdata->flags = SPI_CPM_MODE | SPI_CPM2; |
1267 | else if (of_device_is_compatible(np, "fsl,cpm1-spi")) | 1262 | else if (of_device_is_compatible(np, "fsl,cpm1-spi")) |
1268 | pdata->flags = SPI_CPM_MODE | SPI_CPM1; | 1263 | pdata->flags = SPI_CPM_MODE | SPI_CPM1; |
1269 | 1264 | ||
1270 | ret = of_mpc8xxx_spi_get_chipselects(dev); | 1265 | ret = of_mpc8xxx_spi_get_chipselects(dev); |
1271 | if (ret) | 1266 | if (ret) |
1272 | goto err; | 1267 | goto err; |
1273 | 1268 | ||
1274 | ret = of_address_to_resource(np, 0, &mem); | 1269 | ret = of_address_to_resource(np, 0, &mem); |
1275 | if (ret) | 1270 | if (ret) |
1276 | goto err; | 1271 | goto err; |
1277 | 1272 | ||
1278 | ret = of_irq_to_resource(np, 0, &irq); | 1273 | ret = of_irq_to_resource(np, 0, &irq); |
1279 | if (!ret) { | 1274 | if (!ret) { |
1280 | ret = -EINVAL; | 1275 | ret = -EINVAL; |
1281 | goto err; | 1276 | goto err; |
1282 | } | 1277 | } |
1283 | 1278 | ||
1284 | master = mpc8xxx_spi_probe(dev, &mem, irq.start); | 1279 | master = mpc8xxx_spi_probe(dev, &mem, irq.start); |
1285 | if (IS_ERR(master)) { | 1280 | if (IS_ERR(master)) { |
1286 | ret = PTR_ERR(master); | 1281 | ret = PTR_ERR(master); |
1287 | goto err; | 1282 | goto err; |
1288 | } | 1283 | } |
1289 | 1284 | ||
1290 | of_register_spi_devices(master, np); | 1285 | of_register_spi_devices(master, np); |
1291 | 1286 | ||
1292 | return 0; | 1287 | return 0; |
1293 | 1288 | ||
1294 | err: | 1289 | err: |
1295 | of_mpc8xxx_spi_free_chipselects(dev); | 1290 | of_mpc8xxx_spi_free_chipselects(dev); |
1296 | err_clk: | 1291 | err_clk: |
1297 | kfree(pinfo); | 1292 | kfree(pinfo); |
1298 | return ret; | 1293 | return ret; |
1299 | } | 1294 | } |
1300 | 1295 | ||
1301 | static int __devexit of_mpc8xxx_spi_remove(struct of_device *ofdev) | 1296 | static int __devexit of_mpc8xxx_spi_remove(struct of_device *ofdev) |
1302 | { | 1297 | { |
1303 | int ret; | 1298 | int ret; |
1304 | 1299 | ||
1305 | ret = mpc8xxx_spi_remove(&ofdev->dev); | 1300 | ret = mpc8xxx_spi_remove(&ofdev->dev); |
1306 | if (ret) | 1301 | if (ret) |
1307 | return ret; | 1302 | return ret; |
1308 | of_mpc8xxx_spi_free_chipselects(&ofdev->dev); | 1303 | of_mpc8xxx_spi_free_chipselects(&ofdev->dev); |
1309 | return 0; | 1304 | return 0; |
1310 | } | 1305 | } |
1311 | 1306 | ||
1312 | static const struct of_device_id of_mpc8xxx_spi_match[] = { | 1307 | static const struct of_device_id of_mpc8xxx_spi_match[] = { |
1313 | { .compatible = "fsl,spi" }, | 1308 | { .compatible = "fsl,spi" }, |
1314 | {}, | 1309 | {}, |
1315 | }; | 1310 | }; |
1316 | MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match); | 1311 | MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match); |
1317 | 1312 | ||
1318 | static struct of_platform_driver of_mpc8xxx_spi_driver = { | 1313 | static struct of_platform_driver of_mpc8xxx_spi_driver = { |
1319 | .name = "mpc8xxx_spi", | 1314 | .name = "mpc8xxx_spi", |
1320 | .match_table = of_mpc8xxx_spi_match, | 1315 | .match_table = of_mpc8xxx_spi_match, |
1321 | .probe = of_mpc8xxx_spi_probe, | 1316 | .probe = of_mpc8xxx_spi_probe, |
1322 | .remove = __devexit_p(of_mpc8xxx_spi_remove), | 1317 | .remove = __devexit_p(of_mpc8xxx_spi_remove), |
1323 | }; | 1318 | }; |
1324 | 1319 | ||
1325 | #ifdef CONFIG_MPC832x_RDB | 1320 | #ifdef CONFIG_MPC832x_RDB |
1326 | /* | 1321 | /* |
1327 | * XXX XXX XXX | 1322 | * XXX XXX XXX |
1328 | * This is "legacy" platform driver, was used by the MPC8323E-RDB boards | 1323 | * This is "legacy" platform driver, was used by the MPC8323E-RDB boards |
1329 | * only. The driver should go away soon, since newer MPC8323E-RDB's device | 1324 | * only. The driver should go away soon, since newer MPC8323E-RDB's device |
1330 | * tree can work with OpenFirmware driver. But for now we support old trees | 1325 | * tree can work with OpenFirmware driver. But for now we support old trees |
1331 | * as well. | 1326 | * as well. |
1332 | */ | 1327 | */ |
1333 | static int __devinit plat_mpc8xxx_spi_probe(struct platform_device *pdev) | 1328 | static int __devinit plat_mpc8xxx_spi_probe(struct platform_device *pdev) |
1334 | { | 1329 | { |
1335 | struct resource *mem; | 1330 | struct resource *mem; |
1336 | unsigned int irq; | 1331 | unsigned int irq; |
1337 | struct spi_master *master; | 1332 | struct spi_master *master; |
1338 | 1333 | ||
1339 | if (!pdev->dev.platform_data) | 1334 | if (!pdev->dev.platform_data) |
1340 | return -EINVAL; | 1335 | return -EINVAL; |
1341 | 1336 | ||
1342 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1337 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1343 | if (!mem) | 1338 | if (!mem) |
1344 | return -EINVAL; | 1339 | return -EINVAL; |
1345 | 1340 | ||
1346 | irq = platform_get_irq(pdev, 0); | 1341 | irq = platform_get_irq(pdev, 0); |
1347 | if (!irq) | 1342 | if (!irq) |
1348 | return -EINVAL; | 1343 | return -EINVAL; |
1349 | 1344 | ||
1350 | master = mpc8xxx_spi_probe(&pdev->dev, mem, irq); | 1345 | master = mpc8xxx_spi_probe(&pdev->dev, mem, irq); |
1351 | if (IS_ERR(master)) | 1346 | if (IS_ERR(master)) |
1352 | return PTR_ERR(master); | 1347 | return PTR_ERR(master); |
1353 | return 0; | 1348 | return 0; |
1354 | } | 1349 | } |
1355 | 1350 | ||
1356 | static int __devexit plat_mpc8xxx_spi_remove(struct platform_device *pdev) | 1351 | static int __devexit plat_mpc8xxx_spi_remove(struct platform_device *pdev) |
1357 | { | 1352 | { |
1358 | return mpc8xxx_spi_remove(&pdev->dev); | 1353 | return mpc8xxx_spi_remove(&pdev->dev); |
1359 | } | 1354 | } |
1360 | 1355 | ||
1361 | MODULE_ALIAS("platform:mpc8xxx_spi"); | 1356 | MODULE_ALIAS("platform:mpc8xxx_spi"); |
1362 | static struct platform_driver mpc8xxx_spi_driver = { | 1357 | static struct platform_driver mpc8xxx_spi_driver = { |
1363 | .probe = plat_mpc8xxx_spi_probe, | 1358 | .probe = plat_mpc8xxx_spi_probe, |
1364 | .remove = __exit_p(plat_mpc8xxx_spi_remove), | 1359 | .remove = __exit_p(plat_mpc8xxx_spi_remove), |
1365 | .driver = { | 1360 | .driver = { |
1366 | .name = "mpc8xxx_spi", | 1361 | .name = "mpc8xxx_spi", |
1367 | .owner = THIS_MODULE, | 1362 | .owner = THIS_MODULE, |
1368 | }, | 1363 | }, |
1369 | }; | 1364 | }; |
1370 | 1365 | ||
1371 | static bool legacy_driver_failed; | 1366 | static bool legacy_driver_failed; |
1372 | 1367 | ||
1373 | static void __init legacy_driver_register(void) | 1368 | static void __init legacy_driver_register(void) |
1374 | { | 1369 | { |
1375 | legacy_driver_failed = platform_driver_register(&mpc8xxx_spi_driver); | 1370 | legacy_driver_failed = platform_driver_register(&mpc8xxx_spi_driver); |
1376 | } | 1371 | } |
1377 | 1372 | ||
1378 | static void __exit legacy_driver_unregister(void) | 1373 | static void __exit legacy_driver_unregister(void) |
1379 | { | 1374 | { |
1380 | if (legacy_driver_failed) | 1375 | if (legacy_driver_failed) |
1381 | return; | 1376 | return; |
1382 | platform_driver_unregister(&mpc8xxx_spi_driver); | 1377 | platform_driver_unregister(&mpc8xxx_spi_driver); |
1383 | } | 1378 | } |
1384 | #else | 1379 | #else |
1385 | static void __init legacy_driver_register(void) {} | 1380 | static void __init legacy_driver_register(void) {} |
1386 | static void __exit legacy_driver_unregister(void) {} | 1381 | static void __exit legacy_driver_unregister(void) {} |
1387 | #endif /* CONFIG_MPC832x_RDB */ | 1382 | #endif /* CONFIG_MPC832x_RDB */ |
1388 | 1383 | ||
1389 | static int __init mpc8xxx_spi_init(void) | 1384 | static int __init mpc8xxx_spi_init(void) |
1390 | { | 1385 | { |
1391 | legacy_driver_register(); | 1386 | legacy_driver_register(); |
1392 | return of_register_platform_driver(&of_mpc8xxx_spi_driver); | 1387 | return of_register_platform_driver(&of_mpc8xxx_spi_driver); |
1393 | } | 1388 | } |
1394 | 1389 | ||
1395 | static void __exit mpc8xxx_spi_exit(void) | 1390 | static void __exit mpc8xxx_spi_exit(void) |
1396 | { | 1391 | { |
1397 | of_unregister_platform_driver(&of_mpc8xxx_spi_driver); | 1392 | of_unregister_platform_driver(&of_mpc8xxx_spi_driver); |
1398 | legacy_driver_unregister(); | 1393 | legacy_driver_unregister(); |
1399 | } | 1394 | } |
1400 | 1395 | ||
1401 | module_init(mpc8xxx_spi_init); | 1396 | module_init(mpc8xxx_spi_init); |
1402 | module_exit(mpc8xxx_spi_exit); | 1397 | module_exit(mpc8xxx_spi_exit); |
1403 | 1398 | ||
1404 | MODULE_AUTHOR("Kumar Gala"); | 1399 | MODULE_AUTHOR("Kumar Gala"); |
1405 | MODULE_DESCRIPTION("Simple MPC8xxx SPI Driver"); | 1400 | MODULE_DESCRIPTION("Simple MPC8xxx SPI Driver"); |
1406 | MODULE_LICENSE("GPL"); | 1401 | MODULE_LICENSE("GPL"); |
1407 | 1402 |
include/linux/fsl_devices.h
1 | /* | 1 | /* |
2 | * include/linux/fsl_devices.h | 2 | * include/linux/fsl_devices.h |
3 | * | 3 | * |
4 | * Definitions for any platform device related flags or structures for | 4 | * Definitions for any platform device related flags or structures for |
5 | * Freescale processor devices | 5 | * Freescale processor devices |
6 | * | 6 | * |
7 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | 7 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> |
8 | * | 8 | * |
9 | * Copyright 2004 Freescale Semiconductor, Inc | 9 | * Copyright 2004 Freescale Semiconductor, Inc |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
13 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * Free Software Foundation; either version 2 of the License, or (at your |
14 | * option) any later version. | 14 | * option) any later version. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifndef _FSL_DEVICE_H_ | 17 | #ifndef _FSL_DEVICE_H_ |
18 | #define _FSL_DEVICE_H_ | 18 | #define _FSL_DEVICE_H_ |
19 | 19 | ||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * Some conventions on how we handle peripherals on Freescale chips | 23 | * Some conventions on how we handle peripherals on Freescale chips |
24 | * | 24 | * |
25 | * unique device: a platform_device entry in fsl_plat_devs[] plus | 25 | * unique device: a platform_device entry in fsl_plat_devs[] plus |
26 | * associated device information in its platform_data structure. | 26 | * associated device information in its platform_data structure. |
27 | * | 27 | * |
28 | * A chip is described by a set of unique devices. | 28 | * A chip is described by a set of unique devices. |
29 | * | 29 | * |
30 | * Each sub-arch has its own master list of unique devices and | 30 | * Each sub-arch has its own master list of unique devices and |
31 | * enumerates them by enum fsl_devices in a sub-arch specific header | 31 | * enumerates them by enum fsl_devices in a sub-arch specific header |
32 | * | 32 | * |
33 | * The platform data structure is broken into two parts. The | 33 | * The platform data structure is broken into two parts. The |
34 | * first is device specific information that help identify any | 34 | * first is device specific information that help identify any |
35 | * unique features of a peripheral. The second is any | 35 | * unique features of a peripheral. The second is any |
36 | * information that may be defined by the board or how the device | 36 | * information that may be defined by the board or how the device |
37 | * is connected externally of the chip. | 37 | * is connected externally of the chip. |
38 | * | 38 | * |
39 | * naming conventions: | 39 | * naming conventions: |
40 | * - platform data structures: <driver>_platform_data | 40 | * - platform data structures: <driver>_platform_data |
41 | * - platform data device flags: FSL_<driver>_DEV_<FLAG> | 41 | * - platform data device flags: FSL_<driver>_DEV_<FLAG> |
42 | * - platform data board flags: FSL_<driver>_BRD_<FLAG> | 42 | * - platform data board flags: FSL_<driver>_BRD_<FLAG> |
43 | * | 43 | * |
44 | */ | 44 | */ |
45 | 45 | ||
46 | enum fsl_usb2_operating_modes { | 46 | enum fsl_usb2_operating_modes { |
47 | FSL_USB2_MPH_HOST, | 47 | FSL_USB2_MPH_HOST, |
48 | FSL_USB2_DR_HOST, | 48 | FSL_USB2_DR_HOST, |
49 | FSL_USB2_DR_DEVICE, | 49 | FSL_USB2_DR_DEVICE, |
50 | FSL_USB2_DR_OTG, | 50 | FSL_USB2_DR_OTG, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | enum fsl_usb2_phy_modes { | 53 | enum fsl_usb2_phy_modes { |
54 | FSL_USB2_PHY_NONE, | 54 | FSL_USB2_PHY_NONE, |
55 | FSL_USB2_PHY_ULPI, | 55 | FSL_USB2_PHY_ULPI, |
56 | FSL_USB2_PHY_UTMI, | 56 | FSL_USB2_PHY_UTMI, |
57 | FSL_USB2_PHY_UTMI_WIDE, | 57 | FSL_USB2_PHY_UTMI_WIDE, |
58 | FSL_USB2_PHY_SERIAL, | 58 | FSL_USB2_PHY_SERIAL, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct fsl_usb2_platform_data { | 61 | struct fsl_usb2_platform_data { |
62 | /* board specific information */ | 62 | /* board specific information */ |
63 | enum fsl_usb2_operating_modes operating_mode; | 63 | enum fsl_usb2_operating_modes operating_mode; |
64 | enum fsl_usb2_phy_modes phy_mode; | 64 | enum fsl_usb2_phy_modes phy_mode; |
65 | unsigned int port_enables; | 65 | unsigned int port_enables; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* Flags in fsl_usb2_mph_platform_data */ | 68 | /* Flags in fsl_usb2_mph_platform_data */ |
69 | #define FSL_USB2_PORT0_ENABLED 0x00000001 | 69 | #define FSL_USB2_PORT0_ENABLED 0x00000001 |
70 | #define FSL_USB2_PORT1_ENABLED 0x00000002 | 70 | #define FSL_USB2_PORT1_ENABLED 0x00000002 |
71 | 71 | ||
72 | struct spi_device; | 72 | struct spi_device; |
73 | 73 | ||
74 | struct fsl_spi_platform_data { | 74 | struct fsl_spi_platform_data { |
75 | u32 initial_spmode; /* initial SPMODE value */ | 75 | u32 initial_spmode; /* initial SPMODE value */ |
76 | s16 bus_num; | 76 | s16 bus_num; |
77 | unsigned int flags; | 77 | unsigned int flags; |
78 | #define SPI_QE_CPU_MODE (1 << 0) /* QE CPU ("PIO") mode */ | ||
79 | #define SPI_CPM_MODE (1 << 1) /* CPM/QE ("DMA") mode */ | ||
80 | #define SPI_CPM1 (1 << 2) /* SPI unit is in CPM1 block */ | ||
81 | #define SPI_CPM2 (1 << 3) /* SPI unit is in CPM2 block */ | ||
82 | #define SPI_QE (1 << 4) /* SPI unit is in QE block */ | ||
78 | /* board specific information */ | 83 | /* board specific information */ |
79 | u16 max_chipselect; | 84 | u16 max_chipselect; |
80 | void (*cs_control)(struct spi_device *spi, bool on); | 85 | void (*cs_control)(struct spi_device *spi, bool on); |
81 | u32 sysclk; | 86 | u32 sysclk; |
82 | }; | 87 | }; |
83 | 88 | ||
84 | struct mpc8xx_pcmcia_ops { | 89 | struct mpc8xx_pcmcia_ops { |
85 | void(*hw_ctrl)(int slot, int enable); | 90 | void(*hw_ctrl)(int slot, int enable); |
86 | int(*voltage_set)(int slot, int vcc, int vpp); | 91 | int(*voltage_set)(int slot, int vcc, int vpp); |
87 | }; | 92 | }; |
88 | 93 | ||
89 | /* Returns non-zero if the current suspend operation would | 94 | /* Returns non-zero if the current suspend operation would |
90 | * lead to a deep sleep (i.e. power removed from the core, | 95 | * lead to a deep sleep (i.e. power removed from the core, |
91 | * instead of just the clock). | 96 | * instead of just the clock). |
92 | */ | 97 | */ |
93 | #if defined(CONFIG_PPC_83xx) && defined(CONFIG_SUSPEND) | 98 | #if defined(CONFIG_PPC_83xx) && defined(CONFIG_SUSPEND) |
94 | int fsl_deep_sleep(void); | 99 | int fsl_deep_sleep(void); |
95 | #else | 100 | #else |
96 | static inline int fsl_deep_sleep(void) { return 0; } | 101 | static inline int fsl_deep_sleep(void) { return 0; } |
97 | #endif | 102 | #endif |
98 | 103 | ||
99 | #endif /* _FSL_DEVICE_H_ */ | 104 | #endif /* _FSL_DEVICE_H_ */ |
100 | 105 |