diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-08 04:35:30 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-08 04:35:30 -0400 |
commit | 5ea472a77f8e4811ceee3f44a9deda6ad6e8b789 (patch) | |
tree | a9ec5019e2b666a19874fc344ffb0dd5da6bce94 /drivers/spi | |
parent | 6c009ecef8cca28c7c09eb16d0802e37915a76e1 (diff) | |
parent | 577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff) |
Merge commit 'v2.6.30-rc1' into perfcounters/core
Conflicts:
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/unistd.h
include/linux/init_task.h
Merge reason: the conflicts are non-trivial: PowerPC placement
of sys_perf_counter_open has to be mixed with the
new preadv/pwrite syscalls.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/pxa2xx_spi.c | 98 | ||||
-rw-r--r-- | drivers/spi/spi_bfin5xx.c | 645 | ||||
-rw-r--r-- | drivers/spi/spi_imx.c | 5 |
3 files changed, 422 insertions, 326 deletions
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 33fcef3150d4..c1688c71f052 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/gpio.h> | ||
31 | 32 | ||
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
@@ -53,6 +54,7 @@ MODULE_ALIAS("platform:pxa2xx-spi"); | |||
53 | #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) | 54 | #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) |
54 | #define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0) | 55 | #define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0) |
55 | #define MAX_DMA_LEN 8191 | 56 | #define MAX_DMA_LEN 8191 |
57 | #define DMA_ALIGNMENT 8 | ||
56 | 58 | ||
57 | /* | 59 | /* |
58 | * for testing SSCR1 changes that require SSP restart, basically | 60 | * for testing SSCR1 changes that require SSP restart, basically |
@@ -166,6 +168,8 @@ struct chip_data { | |||
166 | u8 enable_dma; | 168 | u8 enable_dma; |
167 | u8 bits_per_word; | 169 | u8 bits_per_word; |
168 | u32 speed_hz; | 170 | u32 speed_hz; |
171 | int gpio_cs; | ||
172 | int gpio_cs_inverted; | ||
169 | int (*write)(struct driver_data *drv_data); | 173 | int (*write)(struct driver_data *drv_data); |
170 | int (*read)(struct driver_data *drv_data); | 174 | int (*read)(struct driver_data *drv_data); |
171 | void (*cs_control)(u32 command); | 175 | void (*cs_control)(u32 command); |
@@ -173,6 +177,32 @@ struct chip_data { | |||
173 | 177 | ||
174 | static void pump_messages(struct work_struct *work); | 178 | static void pump_messages(struct work_struct *work); |
175 | 179 | ||
180 | static void cs_assert(struct driver_data *drv_data) | ||
181 | { | ||
182 | struct chip_data *chip = drv_data->cur_chip; | ||
183 | |||
184 | if (chip->cs_control) { | ||
185 | chip->cs_control(PXA2XX_CS_ASSERT); | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | if (gpio_is_valid(chip->gpio_cs)) | ||
190 | gpio_set_value(chip->gpio_cs, chip->gpio_cs_inverted); | ||
191 | } | ||
192 | |||
193 | static void cs_deassert(struct driver_data *drv_data) | ||
194 | { | ||
195 | struct chip_data *chip = drv_data->cur_chip; | ||
196 | |||
197 | if (chip->cs_control) { | ||
198 | chip->cs_control(PXA2XX_CS_ASSERT); | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | if (gpio_is_valid(chip->gpio_cs)) | ||
203 | gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); | ||
204 | } | ||
205 | |||
176 | static int flush(struct driver_data *drv_data) | 206 | static int flush(struct driver_data *drv_data) |
177 | { | 207 | { |
178 | unsigned long limit = loops_per_jiffy << 1; | 208 | unsigned long limit = loops_per_jiffy << 1; |
@@ -189,10 +219,6 @@ static int flush(struct driver_data *drv_data) | |||
189 | return limit; | 219 | return limit; |
190 | } | 220 | } |
191 | 221 | ||
192 | static void null_cs_control(u32 command) | ||
193 | { | ||
194 | } | ||
195 | |||
196 | static int null_writer(struct driver_data *drv_data) | 222 | static int null_writer(struct driver_data *drv_data) |
197 | { | 223 | { |
198 | void __iomem *reg = drv_data->ioaddr; | 224 | void __iomem *reg = drv_data->ioaddr; |
@@ -400,7 +426,6 @@ static void giveback(struct driver_data *drv_data) | |||
400 | msg = drv_data->cur_msg; | 426 | msg = drv_data->cur_msg; |
401 | drv_data->cur_msg = NULL; | 427 | drv_data->cur_msg = NULL; |
402 | drv_data->cur_transfer = NULL; | 428 | drv_data->cur_transfer = NULL; |
403 | drv_data->cur_chip = NULL; | ||
404 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | 429 | queue_work(drv_data->workqueue, &drv_data->pump_messages); |
405 | spin_unlock_irqrestore(&drv_data->lock, flags); | 430 | spin_unlock_irqrestore(&drv_data->lock, flags); |
406 | 431 | ||
@@ -416,7 +441,7 @@ static void giveback(struct driver_data *drv_data) | |||
416 | * a message with an error, or next message is for another chip | 441 | * a message with an error, or next message is for another chip |
417 | */ | 442 | */ |
418 | if (!last_transfer->cs_change) | 443 | if (!last_transfer->cs_change) |
419 | drv_data->cs_control(PXA2XX_CS_DEASSERT); | 444 | cs_deassert(drv_data); |
420 | else { | 445 | else { |
421 | struct spi_message *next_msg; | 446 | struct spi_message *next_msg; |
422 | 447 | ||
@@ -445,12 +470,14 @@ static void giveback(struct driver_data *drv_data) | |||
445 | if (next_msg && next_msg->spi != msg->spi) | 470 | if (next_msg && next_msg->spi != msg->spi) |
446 | next_msg = NULL; | 471 | next_msg = NULL; |
447 | if (!next_msg || msg->state == ERROR_STATE) | 472 | if (!next_msg || msg->state == ERROR_STATE) |
448 | drv_data->cs_control(PXA2XX_CS_DEASSERT); | 473 | cs_deassert(drv_data); |
449 | } | 474 | } |
450 | 475 | ||
451 | msg->state = NULL; | 476 | msg->state = NULL; |
452 | if (msg->complete) | 477 | if (msg->complete) |
453 | msg->complete(msg->context); | 478 | msg->complete(msg->context); |
479 | |||
480 | drv_data->cur_chip = NULL; | ||
454 | } | 481 | } |
455 | 482 | ||
456 | static int wait_ssp_rx_stall(void const __iomem *ioaddr) | 483 | static int wait_ssp_rx_stall(void const __iomem *ioaddr) |
@@ -887,7 +914,7 @@ static void pump_transfers(unsigned long data) | |||
887 | 914 | ||
888 | /* Drop chip select only if cs_change is requested */ | 915 | /* Drop chip select only if cs_change is requested */ |
889 | if (previous->cs_change) | 916 | if (previous->cs_change) |
890 | drv_data->cs_control(PXA2XX_CS_DEASSERT); | 917 | cs_deassert(drv_data); |
891 | } | 918 | } |
892 | 919 | ||
893 | /* Check for transfers that need multiple DMA segments */ | 920 | /* Check for transfers that need multiple DMA segments */ |
@@ -922,7 +949,6 @@ static void pump_transfers(unsigned long data) | |||
922 | } | 949 | } |
923 | drv_data->n_bytes = chip->n_bytes; | 950 | drv_data->n_bytes = chip->n_bytes; |
924 | drv_data->dma_width = chip->dma_width; | 951 | drv_data->dma_width = chip->dma_width; |
925 | drv_data->cs_control = chip->cs_control; | ||
926 | drv_data->tx = (void *)transfer->tx_buf; | 952 | drv_data->tx = (void *)transfer->tx_buf; |
927 | drv_data->tx_end = drv_data->tx + transfer->len; | 953 | drv_data->tx_end = drv_data->tx + transfer->len; |
928 | drv_data->rx = transfer->rx_buf; | 954 | drv_data->rx = transfer->rx_buf; |
@@ -1084,11 +1110,7 @@ static void pump_transfers(unsigned long data) | |||
1084 | write_SSTO(chip->timeout, reg); | 1110 | write_SSTO(chip->timeout, reg); |
1085 | } | 1111 | } |
1086 | 1112 | ||
1087 | /* FIXME, need to handle cs polarity, | 1113 | cs_assert(drv_data); |
1088 | * this driver uses struct pxa2xx_spi_chip.cs_control to | ||
1089 | * specify a CS handling function, and it ignores most | ||
1090 | * struct spi_device.mode[s], including SPI_CS_HIGH */ | ||
1091 | drv_data->cs_control(PXA2XX_CS_ASSERT); | ||
1092 | 1114 | ||
1093 | /* after chip select, release the data by enabling service | 1115 | /* after chip select, release the data by enabling service |
1094 | * requests and interrupts, without changing any mode bits */ | 1116 | * requests and interrupts, without changing any mode bits */ |
@@ -1166,6 +1188,44 @@ static int transfer(struct spi_device *spi, struct spi_message *msg) | |||
1166 | /* the spi->mode bits understood by this driver: */ | 1188 | /* the spi->mode bits understood by this driver: */ |
1167 | #define MODEBITS (SPI_CPOL | SPI_CPHA) | 1189 | #define MODEBITS (SPI_CPOL | SPI_CPHA) |
1168 | 1190 | ||
1191 | static int setup_cs(struct spi_device *spi, struct chip_data *chip, | ||
1192 | struct pxa2xx_spi_chip *chip_info) | ||
1193 | { | ||
1194 | int err = 0; | ||
1195 | |||
1196 | if (chip == NULL || chip_info == NULL) | ||
1197 | return 0; | ||
1198 | |||
1199 | /* NOTE: setup() can be called multiple times, possibly with | ||
1200 | * different chip_info, release previously requested GPIO | ||
1201 | */ | ||
1202 | if (gpio_is_valid(chip->gpio_cs)) | ||
1203 | gpio_free(chip->gpio_cs); | ||
1204 | |||
1205 | /* If (*cs_control) is provided, ignore GPIO chip select */ | ||
1206 | if (chip_info->cs_control) { | ||
1207 | chip->cs_control = chip_info->cs_control; | ||
1208 | return 0; | ||
1209 | } | ||
1210 | |||
1211 | if (gpio_is_valid(chip_info->gpio_cs)) { | ||
1212 | err = gpio_request(chip_info->gpio_cs, "SPI_CS"); | ||
1213 | if (err) { | ||
1214 | dev_err(&spi->dev, "failed to request chip select " | ||
1215 | "GPIO%d\n", chip_info->gpio_cs); | ||
1216 | return err; | ||
1217 | } | ||
1218 | |||
1219 | chip->gpio_cs = chip_info->gpio_cs; | ||
1220 | chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; | ||
1221 | |||
1222 | err = gpio_direction_output(chip->gpio_cs, | ||
1223 | !chip->gpio_cs_inverted); | ||
1224 | } | ||
1225 | |||
1226 | return err; | ||
1227 | } | ||
1228 | |||
1169 | static int setup(struct spi_device *spi) | 1229 | static int setup(struct spi_device *spi) |
1170 | { | 1230 | { |
1171 | struct pxa2xx_spi_chip *chip_info = NULL; | 1231 | struct pxa2xx_spi_chip *chip_info = NULL; |
@@ -1211,7 +1271,7 @@ static int setup(struct spi_device *spi) | |||
1211 | return -ENOMEM; | 1271 | return -ENOMEM; |
1212 | } | 1272 | } |
1213 | 1273 | ||
1214 | chip->cs_control = null_cs_control; | 1274 | chip->gpio_cs = -1; |
1215 | chip->enable_dma = 0; | 1275 | chip->enable_dma = 0; |
1216 | chip->timeout = TIMOUT_DFLT; | 1276 | chip->timeout = TIMOUT_DFLT; |
1217 | chip->dma_burst_size = drv_data->master_info->enable_dma ? | 1277 | chip->dma_burst_size = drv_data->master_info->enable_dma ? |
@@ -1225,8 +1285,6 @@ static int setup(struct spi_device *spi) | |||
1225 | /* chip_info isn't always needed */ | 1285 | /* chip_info isn't always needed */ |
1226 | chip->cr1 = 0; | 1286 | chip->cr1 = 0; |
1227 | if (chip_info) { | 1287 | if (chip_info) { |
1228 | if (chip_info->cs_control) | ||
1229 | chip->cs_control = chip_info->cs_control; | ||
1230 | if (chip_info->timeout) | 1288 | if (chip_info->timeout) |
1231 | chip->timeout = chip_info->timeout; | 1289 | chip->timeout = chip_info->timeout; |
1232 | if (chip_info->tx_threshold) | 1290 | if (chip_info->tx_threshold) |
@@ -1308,13 +1366,16 @@ static int setup(struct spi_device *spi) | |||
1308 | 1366 | ||
1309 | spi_set_ctldata(spi, chip); | 1367 | spi_set_ctldata(spi, chip); |
1310 | 1368 | ||
1311 | return 0; | 1369 | return setup_cs(spi, chip, chip_info); |
1312 | } | 1370 | } |
1313 | 1371 | ||
1314 | static void cleanup(struct spi_device *spi) | 1372 | static void cleanup(struct spi_device *spi) |
1315 | { | 1373 | { |
1316 | struct chip_data *chip = spi_get_ctldata(spi); | 1374 | struct chip_data *chip = spi_get_ctldata(spi); |
1317 | 1375 | ||
1376 | if (gpio_is_valid(chip->gpio_cs)) | ||
1377 | gpio_free(chip->gpio_cs); | ||
1378 | |||
1318 | kfree(chip); | 1379 | kfree(chip); |
1319 | } | 1380 | } |
1320 | 1381 | ||
@@ -1438,6 +1499,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1438 | 1499 | ||
1439 | master->bus_num = pdev->id; | 1500 | master->bus_num = pdev->id; |
1440 | master->num_chipselect = platform_info->num_chipselect; | 1501 | master->num_chipselect = platform_info->num_chipselect; |
1502 | master->dma_alignment = DMA_ALIGNMENT; | ||
1441 | master->cleanup = cleanup; | 1503 | master->cleanup = cleanup; |
1442 | master->setup = setup; | 1504 | master->setup = setup; |
1443 | master->transfer = transfer; | 1505 | master->transfer = transfer; |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 3410b0c55ed2..f014cc21e813 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -25,18 +25,17 @@ | |||
25 | #include <asm/dma.h> | 25 | #include <asm/dma.h> |
26 | #include <asm/portmux.h> | 26 | #include <asm/portmux.h> |
27 | #include <asm/bfin5xx_spi.h> | 27 | #include <asm/bfin5xx_spi.h> |
28 | #include <asm/cacheflush.h> | ||
28 | 29 | ||
29 | #define DRV_NAME "bfin-spi" | 30 | #define DRV_NAME "bfin-spi" |
30 | #define DRV_AUTHOR "Bryan Wu, Luke Yang" | 31 | #define DRV_AUTHOR "Bryan Wu, Luke Yang" |
31 | #define DRV_DESC "Blackfin BF5xx on-chip SPI Controller Driver" | 32 | #define DRV_DESC "Blackfin on-chip SPI Controller Driver" |
32 | #define DRV_VERSION "1.0" | 33 | #define DRV_VERSION "1.0" |
33 | 34 | ||
34 | MODULE_AUTHOR(DRV_AUTHOR); | 35 | MODULE_AUTHOR(DRV_AUTHOR); |
35 | MODULE_DESCRIPTION(DRV_DESC); | 36 | MODULE_DESCRIPTION(DRV_DESC); |
36 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
37 | 38 | ||
38 | #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07) == 0) | ||
39 | |||
40 | #define START_STATE ((void *)0) | 39 | #define START_STATE ((void *)0) |
41 | #define RUNNING_STATE ((void *)1) | 40 | #define RUNNING_STATE ((void *)1) |
42 | #define DONE_STATE ((void *)2) | 41 | #define DONE_STATE ((void *)2) |
@@ -44,6 +43,9 @@ MODULE_LICENSE("GPL"); | |||
44 | #define QUEUE_RUNNING 0 | 43 | #define QUEUE_RUNNING 0 |
45 | #define QUEUE_STOPPED 1 | 44 | #define QUEUE_STOPPED 1 |
46 | 45 | ||
46 | /* Value to send if no TX value is supplied */ | ||
47 | #define SPI_IDLE_TXVAL 0x0000 | ||
48 | |||
47 | struct driver_data { | 49 | struct driver_data { |
48 | /* Driver model hookup */ | 50 | /* Driver model hookup */ |
49 | struct platform_device *pdev; | 51 | struct platform_device *pdev; |
@@ -110,6 +112,8 @@ struct chip_data { | |||
110 | u8 bits_per_word; /* 8 or 16 */ | 112 | u8 bits_per_word; /* 8 or 16 */ |
111 | u8 cs_change_per_word; | 113 | u8 cs_change_per_word; |
112 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ | 114 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ |
115 | u32 cs_gpio; | ||
116 | u16 idle_tx_val; | ||
113 | void (*write) (struct driver_data *); | 117 | void (*write) (struct driver_data *); |
114 | void (*read) (struct driver_data *); | 118 | void (*read) (struct driver_data *); |
115 | void (*duplex) (struct driver_data *); | 119 | void (*duplex) (struct driver_data *); |
@@ -154,10 +158,13 @@ static u16 hz_to_spi_baud(u32 speed_hz) | |||
154 | if ((sclk % (2 * speed_hz)) > 0) | 158 | if ((sclk % (2 * speed_hz)) > 0) |
155 | spi_baud++; | 159 | spi_baud++; |
156 | 160 | ||
161 | if (spi_baud < MIN_SPI_BAUD_VAL) | ||
162 | spi_baud = MIN_SPI_BAUD_VAL; | ||
163 | |||
157 | return spi_baud; | 164 | return spi_baud; |
158 | } | 165 | } |
159 | 166 | ||
160 | static int flush(struct driver_data *drv_data) | 167 | static int bfin_spi_flush(struct driver_data *drv_data) |
161 | { | 168 | { |
162 | unsigned long limit = loops_per_jiffy << 1; | 169 | unsigned long limit = loops_per_jiffy << 1; |
163 | 170 | ||
@@ -171,33 +178,40 @@ static int flush(struct driver_data *drv_data) | |||
171 | } | 178 | } |
172 | 179 | ||
173 | /* Chip select operation functions for cs_change flag */ | 180 | /* Chip select operation functions for cs_change flag */ |
174 | static void cs_active(struct driver_data *drv_data, struct chip_data *chip) | 181 | static void bfin_spi_cs_active(struct driver_data *drv_data, struct chip_data *chip) |
175 | { | 182 | { |
176 | u16 flag = read_FLAG(drv_data); | 183 | if (likely(chip->chip_select_num)) { |
184 | u16 flag = read_FLAG(drv_data); | ||
177 | 185 | ||
178 | flag |= chip->flag; | 186 | flag |= chip->flag; |
179 | flag &= ~(chip->flag << 8); | 187 | flag &= ~(chip->flag << 8); |
180 | 188 | ||
181 | write_FLAG(drv_data, flag); | 189 | write_FLAG(drv_data, flag); |
190 | } else { | ||
191 | gpio_set_value(chip->cs_gpio, 0); | ||
192 | } | ||
182 | } | 193 | } |
183 | 194 | ||
184 | static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip) | 195 | static void bfin_spi_cs_deactive(struct driver_data *drv_data, struct chip_data *chip) |
185 | { | 196 | { |
186 | u16 flag = read_FLAG(drv_data); | 197 | if (likely(chip->chip_select_num)) { |
198 | u16 flag = read_FLAG(drv_data); | ||
187 | 199 | ||
188 | flag |= (chip->flag << 8); | 200 | flag &= ~chip->flag; |
201 | flag |= (chip->flag << 8); | ||
189 | 202 | ||
190 | write_FLAG(drv_data, flag); | 203 | write_FLAG(drv_data, flag); |
204 | } else { | ||
205 | gpio_set_value(chip->cs_gpio, 1); | ||
206 | } | ||
191 | 207 | ||
192 | /* Move delay here for consistency */ | 208 | /* Move delay here for consistency */ |
193 | if (chip->cs_chg_udelay) | 209 | if (chip->cs_chg_udelay) |
194 | udelay(chip->cs_chg_udelay); | 210 | udelay(chip->cs_chg_udelay); |
195 | } | 211 | } |
196 | 212 | ||
197 | #define MAX_SPI_SSEL 7 | ||
198 | |||
199 | /* stop controller and re-config current chip*/ | 213 | /* stop controller and re-config current chip*/ |
200 | static void restore_state(struct driver_data *drv_data) | 214 | static void bfin_spi_restore_state(struct driver_data *drv_data) |
201 | { | 215 | { |
202 | struct chip_data *chip = drv_data->cur_chip; | 216 | struct chip_data *chip = drv_data->cur_chip; |
203 | 217 | ||
@@ -211,294 +225,256 @@ static void restore_state(struct driver_data *drv_data) | |||
211 | write_BAUD(drv_data, chip->baud); | 225 | write_BAUD(drv_data, chip->baud); |
212 | 226 | ||
213 | bfin_spi_enable(drv_data); | 227 | bfin_spi_enable(drv_data); |
214 | cs_active(drv_data, chip); | 228 | bfin_spi_cs_active(drv_data, chip); |
215 | } | 229 | } |
216 | 230 | ||
217 | /* used to kick off transfer in rx mode */ | 231 | /* used to kick off transfer in rx mode and read unwanted RX data */ |
218 | static unsigned short dummy_read(struct driver_data *drv_data) | 232 | static inline void bfin_spi_dummy_read(struct driver_data *drv_data) |
219 | { | 233 | { |
220 | unsigned short tmp; | 234 | (void) read_RDBR(drv_data); |
221 | tmp = read_RDBR(drv_data); | ||
222 | return tmp; | ||
223 | } | 235 | } |
224 | 236 | ||
225 | static void null_writer(struct driver_data *drv_data) | 237 | static void bfin_spi_null_writer(struct driver_data *drv_data) |
226 | { | 238 | { |
227 | u8 n_bytes = drv_data->n_bytes; | 239 | u8 n_bytes = drv_data->n_bytes; |
240 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
241 | |||
242 | /* clear RXS (we check for RXS inside the loop) */ | ||
243 | bfin_spi_dummy_read(drv_data); | ||
228 | 244 | ||
229 | while (drv_data->tx < drv_data->tx_end) { | 245 | while (drv_data->tx < drv_data->tx_end) { |
230 | write_TDBR(drv_data, 0); | 246 | write_TDBR(drv_data, tx_val); |
231 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | ||
232 | cpu_relax(); | ||
233 | drv_data->tx += n_bytes; | 247 | drv_data->tx += n_bytes; |
248 | /* wait until transfer finished. | ||
249 | checking SPIF or TXS may not guarantee transfer completion */ | ||
250 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
251 | cpu_relax(); | ||
252 | /* discard RX data and clear RXS */ | ||
253 | bfin_spi_dummy_read(drv_data); | ||
234 | } | 254 | } |
235 | } | 255 | } |
236 | 256 | ||
237 | static void null_reader(struct driver_data *drv_data) | 257 | static void bfin_spi_null_reader(struct driver_data *drv_data) |
238 | { | 258 | { |
239 | u8 n_bytes = drv_data->n_bytes; | 259 | u8 n_bytes = drv_data->n_bytes; |
240 | dummy_read(drv_data); | 260 | u16 tx_val = drv_data->cur_chip->idle_tx_val; |
261 | |||
262 | /* discard old RX data and clear RXS */ | ||
263 | bfin_spi_dummy_read(drv_data); | ||
241 | 264 | ||
242 | while (drv_data->rx < drv_data->rx_end) { | 265 | while (drv_data->rx < drv_data->rx_end) { |
266 | write_TDBR(drv_data, tx_val); | ||
267 | drv_data->rx += n_bytes; | ||
243 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 268 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
244 | cpu_relax(); | 269 | cpu_relax(); |
245 | dummy_read(drv_data); | 270 | bfin_spi_dummy_read(drv_data); |
246 | drv_data->rx += n_bytes; | ||
247 | } | 271 | } |
248 | } | 272 | } |
249 | 273 | ||
250 | static void u8_writer(struct driver_data *drv_data) | 274 | static void bfin_spi_u8_writer(struct driver_data *drv_data) |
251 | { | 275 | { |
252 | dev_dbg(&drv_data->pdev->dev, | 276 | /* clear RXS (we check for RXS inside the loop) */ |
253 | "cr8-s is 0x%x\n", read_STAT(drv_data)); | 277 | bfin_spi_dummy_read(drv_data); |
254 | 278 | ||
255 | while (drv_data->tx < drv_data->tx_end) { | 279 | while (drv_data->tx < drv_data->tx_end) { |
256 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 280 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); |
257 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 281 | /* wait until transfer finished. |
282 | checking SPIF or TXS may not guarantee transfer completion */ | ||
283 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
258 | cpu_relax(); | 284 | cpu_relax(); |
259 | ++drv_data->tx; | 285 | /* discard RX data and clear RXS */ |
286 | bfin_spi_dummy_read(drv_data); | ||
260 | } | 287 | } |
261 | |||
262 | /* poll for SPI completion before return */ | ||
263 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
264 | cpu_relax(); | ||
265 | } | 288 | } |
266 | 289 | ||
267 | static void u8_cs_chg_writer(struct driver_data *drv_data) | 290 | static void bfin_spi_u8_cs_chg_writer(struct driver_data *drv_data) |
268 | { | 291 | { |
269 | struct chip_data *chip = drv_data->cur_chip; | 292 | struct chip_data *chip = drv_data->cur_chip; |
270 | 293 | ||
271 | while (drv_data->tx < drv_data->tx_end) { | 294 | /* clear RXS (we check for RXS inside the loop) */ |
272 | cs_active(drv_data, chip); | 295 | bfin_spi_dummy_read(drv_data); |
273 | 296 | ||
274 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 297 | while (drv_data->tx < drv_data->tx_end) { |
275 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 298 | bfin_spi_cs_active(drv_data, chip); |
276 | cpu_relax(); | 299 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); |
277 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 300 | /* make sure transfer finished before deactiving CS */ |
301 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
278 | cpu_relax(); | 302 | cpu_relax(); |
279 | 303 | bfin_spi_dummy_read(drv_data); | |
280 | cs_deactive(drv_data, chip); | 304 | bfin_spi_cs_deactive(drv_data, chip); |
281 | |||
282 | ++drv_data->tx; | ||
283 | } | 305 | } |
284 | } | 306 | } |
285 | 307 | ||
286 | static void u8_reader(struct driver_data *drv_data) | 308 | static void bfin_spi_u8_reader(struct driver_data *drv_data) |
287 | { | 309 | { |
288 | dev_dbg(&drv_data->pdev->dev, | 310 | u16 tx_val = drv_data->cur_chip->idle_tx_val; |
289 | "cr-8 is 0x%x\n", read_STAT(drv_data)); | ||
290 | |||
291 | /* poll for SPI completion before start */ | ||
292 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
293 | cpu_relax(); | ||
294 | 311 | ||
295 | /* clear TDBR buffer before read(else it will be shifted out) */ | 312 | /* discard old RX data and clear RXS */ |
296 | write_TDBR(drv_data, 0xFFFF); | 313 | bfin_spi_dummy_read(drv_data); |
297 | 314 | ||
298 | dummy_read(drv_data); | 315 | while (drv_data->rx < drv_data->rx_end) { |
299 | 316 | write_TDBR(drv_data, tx_val); | |
300 | while (drv_data->rx < drv_data->rx_end - 1) { | ||
301 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 317 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
302 | cpu_relax(); | 318 | cpu_relax(); |
303 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 319 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
304 | ++drv_data->rx; | ||
305 | } | 320 | } |
306 | |||
307 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
308 | cpu_relax(); | ||
309 | *(u8 *) (drv_data->rx) = read_SHAW(drv_data); | ||
310 | ++drv_data->rx; | ||
311 | } | 321 | } |
312 | 322 | ||
313 | static void u8_cs_chg_reader(struct driver_data *drv_data) | 323 | static void bfin_spi_u8_cs_chg_reader(struct driver_data *drv_data) |
314 | { | 324 | { |
315 | struct chip_data *chip = drv_data->cur_chip; | 325 | struct chip_data *chip = drv_data->cur_chip; |
326 | u16 tx_val = chip->idle_tx_val; | ||
316 | 327 | ||
317 | while (drv_data->rx < drv_data->rx_end) { | 328 | /* discard old RX data and clear RXS */ |
318 | cs_active(drv_data, chip); | 329 | bfin_spi_dummy_read(drv_data); |
319 | read_RDBR(drv_data); /* kick off */ | ||
320 | 330 | ||
331 | while (drv_data->rx < drv_data->rx_end) { | ||
332 | bfin_spi_cs_active(drv_data, chip); | ||
333 | write_TDBR(drv_data, tx_val); | ||
321 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 334 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
322 | cpu_relax(); | 335 | cpu_relax(); |
323 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 336 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
324 | cpu_relax(); | 337 | bfin_spi_cs_deactive(drv_data, chip); |
325 | |||
326 | *(u8 *) (drv_data->rx) = read_SHAW(drv_data); | ||
327 | cs_deactive(drv_data, chip); | ||
328 | |||
329 | ++drv_data->rx; | ||
330 | } | 338 | } |
331 | } | 339 | } |
332 | 340 | ||
333 | static void u8_duplex(struct driver_data *drv_data) | 341 | static void bfin_spi_u8_duplex(struct driver_data *drv_data) |
334 | { | 342 | { |
335 | /* in duplex mode, clk is triggered by writing of TDBR */ | 343 | /* discard old RX data and clear RXS */ |
344 | bfin_spi_dummy_read(drv_data); | ||
345 | |||
336 | while (drv_data->rx < drv_data->rx_end) { | 346 | while (drv_data->rx < drv_data->rx_end) { |
337 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 347 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); |
338 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
339 | cpu_relax(); | ||
340 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 348 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
341 | cpu_relax(); | 349 | cpu_relax(); |
342 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 350 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
343 | ++drv_data->rx; | ||
344 | ++drv_data->tx; | ||
345 | } | 351 | } |
346 | } | 352 | } |
347 | 353 | ||
348 | static void u8_cs_chg_duplex(struct driver_data *drv_data) | 354 | static void bfin_spi_u8_cs_chg_duplex(struct driver_data *drv_data) |
349 | { | 355 | { |
350 | struct chip_data *chip = drv_data->cur_chip; | 356 | struct chip_data *chip = drv_data->cur_chip; |
351 | 357 | ||
352 | while (drv_data->rx < drv_data->rx_end) { | 358 | /* discard old RX data and clear RXS */ |
353 | cs_active(drv_data, chip); | 359 | bfin_spi_dummy_read(drv_data); |
354 | |||
355 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | ||
356 | 360 | ||
357 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 361 | while (drv_data->rx < drv_data->rx_end) { |
358 | cpu_relax(); | 362 | bfin_spi_cs_active(drv_data, chip); |
363 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx++))); | ||
359 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 364 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
360 | cpu_relax(); | 365 | cpu_relax(); |
361 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | 366 | *(u8 *) (drv_data->rx++) = read_RDBR(drv_data); |
362 | 367 | bfin_spi_cs_deactive(drv_data, chip); | |
363 | cs_deactive(drv_data, chip); | ||
364 | |||
365 | ++drv_data->rx; | ||
366 | ++drv_data->tx; | ||
367 | } | 368 | } |
368 | } | 369 | } |
369 | 370 | ||
370 | static void u16_writer(struct driver_data *drv_data) | 371 | static void bfin_spi_u16_writer(struct driver_data *drv_data) |
371 | { | 372 | { |
372 | dev_dbg(&drv_data->pdev->dev, | 373 | /* clear RXS (we check for RXS inside the loop) */ |
373 | "cr16 is 0x%x\n", read_STAT(drv_data)); | 374 | bfin_spi_dummy_read(drv_data); |
374 | 375 | ||
375 | while (drv_data->tx < drv_data->tx_end) { | 376 | while (drv_data->tx < drv_data->tx_end) { |
376 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 377 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
377 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | ||
378 | cpu_relax(); | ||
379 | drv_data->tx += 2; | 378 | drv_data->tx += 2; |
379 | /* wait until transfer finished. | ||
380 | checking SPIF or TXS may not guarantee transfer completion */ | ||
381 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
382 | cpu_relax(); | ||
383 | /* discard RX data and clear RXS */ | ||
384 | bfin_spi_dummy_read(drv_data); | ||
380 | } | 385 | } |
381 | |||
382 | /* poll for SPI completion before return */ | ||
383 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
384 | cpu_relax(); | ||
385 | } | 386 | } |
386 | 387 | ||
387 | static void u16_cs_chg_writer(struct driver_data *drv_data) | 388 | static void bfin_spi_u16_cs_chg_writer(struct driver_data *drv_data) |
388 | { | 389 | { |
389 | struct chip_data *chip = drv_data->cur_chip; | 390 | struct chip_data *chip = drv_data->cur_chip; |
390 | 391 | ||
391 | while (drv_data->tx < drv_data->tx_end) { | 392 | /* clear RXS (we check for RXS inside the loop) */ |
392 | cs_active(drv_data, chip); | 393 | bfin_spi_dummy_read(drv_data); |
393 | 394 | ||
395 | while (drv_data->tx < drv_data->tx_end) { | ||
396 | bfin_spi_cs_active(drv_data, chip); | ||
394 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 397 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
395 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | ||
396 | cpu_relax(); | ||
397 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
398 | cpu_relax(); | ||
399 | |||
400 | cs_deactive(drv_data, chip); | ||
401 | |||
402 | drv_data->tx += 2; | 398 | drv_data->tx += 2; |
399 | /* make sure transfer finished before deactiving CS */ | ||
400 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
401 | cpu_relax(); | ||
402 | bfin_spi_dummy_read(drv_data); | ||
403 | bfin_spi_cs_deactive(drv_data, chip); | ||
403 | } | 404 | } |
404 | } | 405 | } |
405 | 406 | ||
406 | static void u16_reader(struct driver_data *drv_data) | 407 | static void bfin_spi_u16_reader(struct driver_data *drv_data) |
407 | { | 408 | { |
408 | dev_dbg(&drv_data->pdev->dev, | 409 | u16 tx_val = drv_data->cur_chip->idle_tx_val; |
409 | "cr-16 is 0x%x\n", read_STAT(drv_data)); | ||
410 | |||
411 | /* poll for SPI completion before start */ | ||
412 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
413 | cpu_relax(); | ||
414 | |||
415 | /* clear TDBR buffer before read(else it will be shifted out) */ | ||
416 | write_TDBR(drv_data, 0xFFFF); | ||
417 | 410 | ||
418 | dummy_read(drv_data); | 411 | /* discard old RX data and clear RXS */ |
412 | bfin_spi_dummy_read(drv_data); | ||
419 | 413 | ||
420 | while (drv_data->rx < (drv_data->rx_end - 2)) { | 414 | while (drv_data->rx < drv_data->rx_end) { |
415 | write_TDBR(drv_data, tx_val); | ||
421 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 416 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
422 | cpu_relax(); | 417 | cpu_relax(); |
423 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 418 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
424 | drv_data->rx += 2; | 419 | drv_data->rx += 2; |
425 | } | 420 | } |
426 | |||
427 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
428 | cpu_relax(); | ||
429 | *(u16 *) (drv_data->rx) = read_SHAW(drv_data); | ||
430 | drv_data->rx += 2; | ||
431 | } | 421 | } |
432 | 422 | ||
433 | static void u16_cs_chg_reader(struct driver_data *drv_data) | 423 | static void bfin_spi_u16_cs_chg_reader(struct driver_data *drv_data) |
434 | { | 424 | { |
435 | struct chip_data *chip = drv_data->cur_chip; | 425 | struct chip_data *chip = drv_data->cur_chip; |
426 | u16 tx_val = chip->idle_tx_val; | ||
436 | 427 | ||
437 | /* poll for SPI completion before start */ | 428 | /* discard old RX data and clear RXS */ |
438 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 429 | bfin_spi_dummy_read(drv_data); |
439 | cpu_relax(); | ||
440 | |||
441 | /* clear TDBR buffer before read(else it will be shifted out) */ | ||
442 | write_TDBR(drv_data, 0xFFFF); | ||
443 | |||
444 | cs_active(drv_data, chip); | ||
445 | dummy_read(drv_data); | ||
446 | |||
447 | while (drv_data->rx < drv_data->rx_end - 2) { | ||
448 | cs_deactive(drv_data, chip); | ||
449 | 430 | ||
431 | while (drv_data->rx < drv_data->rx_end) { | ||
432 | bfin_spi_cs_active(drv_data, chip); | ||
433 | write_TDBR(drv_data, tx_val); | ||
450 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 434 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
451 | cpu_relax(); | 435 | cpu_relax(); |
452 | cs_active(drv_data, chip); | ||
453 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 436 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
454 | drv_data->rx += 2; | 437 | drv_data->rx += 2; |
438 | bfin_spi_cs_deactive(drv_data, chip); | ||
455 | } | 439 | } |
456 | cs_deactive(drv_data, chip); | ||
457 | |||
458 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
459 | cpu_relax(); | ||
460 | *(u16 *) (drv_data->rx) = read_SHAW(drv_data); | ||
461 | drv_data->rx += 2; | ||
462 | } | 440 | } |
463 | 441 | ||
464 | static void u16_duplex(struct driver_data *drv_data) | 442 | static void bfin_spi_u16_duplex(struct driver_data *drv_data) |
465 | { | 443 | { |
466 | /* in duplex mode, clk is triggered by writing of TDBR */ | 444 | /* discard old RX data and clear RXS */ |
467 | while (drv_data->tx < drv_data->tx_end) { | 445 | bfin_spi_dummy_read(drv_data); |
446 | |||
447 | while (drv_data->rx < drv_data->rx_end) { | ||
468 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 448 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
469 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 449 | drv_data->tx += 2; |
470 | cpu_relax(); | ||
471 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 450 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
472 | cpu_relax(); | 451 | cpu_relax(); |
473 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 452 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
474 | drv_data->rx += 2; | 453 | drv_data->rx += 2; |
475 | drv_data->tx += 2; | ||
476 | } | 454 | } |
477 | } | 455 | } |
478 | 456 | ||
479 | static void u16_cs_chg_duplex(struct driver_data *drv_data) | 457 | static void bfin_spi_u16_cs_chg_duplex(struct driver_data *drv_data) |
480 | { | 458 | { |
481 | struct chip_data *chip = drv_data->cur_chip; | 459 | struct chip_data *chip = drv_data->cur_chip; |
482 | 460 | ||
483 | while (drv_data->tx < drv_data->tx_end) { | 461 | /* discard old RX data and clear RXS */ |
484 | cs_active(drv_data, chip); | 462 | bfin_spi_dummy_read(drv_data); |
485 | 463 | ||
464 | while (drv_data->rx < drv_data->rx_end) { | ||
465 | bfin_spi_cs_active(drv_data, chip); | ||
486 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 466 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
487 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 467 | drv_data->tx += 2; |
488 | cpu_relax(); | ||
489 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 468 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
490 | cpu_relax(); | 469 | cpu_relax(); |
491 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); | 470 | *(u16 *) (drv_data->rx) = read_RDBR(drv_data); |
492 | |||
493 | cs_deactive(drv_data, chip); | ||
494 | |||
495 | drv_data->rx += 2; | 471 | drv_data->rx += 2; |
496 | drv_data->tx += 2; | 472 | bfin_spi_cs_deactive(drv_data, chip); |
497 | } | 473 | } |
498 | } | 474 | } |
499 | 475 | ||
500 | /* test if ther is more transfer to be done */ | 476 | /* test if ther is more transfer to be done */ |
501 | static void *next_transfer(struct driver_data *drv_data) | 477 | static void *bfin_spi_next_transfer(struct driver_data *drv_data) |
502 | { | 478 | { |
503 | struct spi_message *msg = drv_data->cur_msg; | 479 | struct spi_message *msg = drv_data->cur_msg; |
504 | struct spi_transfer *trans = drv_data->cur_transfer; | 480 | struct spi_transfer *trans = drv_data->cur_transfer; |
@@ -517,7 +493,7 @@ static void *next_transfer(struct driver_data *drv_data) | |||
517 | * caller already set message->status; | 493 | * caller already set message->status; |
518 | * dma and pio irqs are blocked give finished message back | 494 | * dma and pio irqs are blocked give finished message back |
519 | */ | 495 | */ |
520 | static void giveback(struct driver_data *drv_data) | 496 | static void bfin_spi_giveback(struct driver_data *drv_data) |
521 | { | 497 | { |
522 | struct chip_data *chip = drv_data->cur_chip; | 498 | struct chip_data *chip = drv_data->cur_chip; |
523 | struct spi_transfer *last_transfer; | 499 | struct spi_transfer *last_transfer; |
@@ -537,26 +513,30 @@ static void giveback(struct driver_data *drv_data) | |||
537 | 513 | ||
538 | msg->state = NULL; | 514 | msg->state = NULL; |
539 | 515 | ||
540 | /* disable chip select signal. And not stop spi in autobuffer mode */ | ||
541 | if (drv_data->tx_dma != 0xFFFF) { | ||
542 | cs_deactive(drv_data, chip); | ||
543 | bfin_spi_disable(drv_data); | ||
544 | } | ||
545 | |||
546 | if (!drv_data->cs_change) | 516 | if (!drv_data->cs_change) |
547 | cs_deactive(drv_data, chip); | 517 | bfin_spi_cs_deactive(drv_data, chip); |
518 | |||
519 | /* Not stop spi in autobuffer mode */ | ||
520 | if (drv_data->tx_dma != 0xFFFF) | ||
521 | bfin_spi_disable(drv_data); | ||
548 | 522 | ||
549 | if (msg->complete) | 523 | if (msg->complete) |
550 | msg->complete(msg->context); | 524 | msg->complete(msg->context); |
551 | } | 525 | } |
552 | 526 | ||
553 | static irqreturn_t dma_irq_handler(int irq, void *dev_id) | 527 | static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id) |
554 | { | 528 | { |
555 | struct driver_data *drv_data = dev_id; | 529 | struct driver_data *drv_data = dev_id; |
556 | struct chip_data *chip = drv_data->cur_chip; | 530 | struct chip_data *chip = drv_data->cur_chip; |
557 | struct spi_message *msg = drv_data->cur_msg; | 531 | struct spi_message *msg = drv_data->cur_msg; |
532 | unsigned long timeout; | ||
533 | unsigned short dmastat = get_dma_curr_irqstat(drv_data->dma_channel); | ||
534 | u16 spistat = read_STAT(drv_data); | ||
535 | |||
536 | dev_dbg(&drv_data->pdev->dev, | ||
537 | "in dma_irq_handler dmastat:0x%x spistat:0x%x\n", | ||
538 | dmastat, spistat); | ||
558 | 539 | ||
559 | dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n"); | ||
560 | clear_dma_irqstat(drv_data->dma_channel); | 540 | clear_dma_irqstat(drv_data->dma_channel); |
561 | 541 | ||
562 | /* Wait for DMA to complete */ | 542 | /* Wait for DMA to complete */ |
@@ -575,16 +555,30 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) | |||
575 | cpu_relax(); | 555 | cpu_relax(); |
576 | } | 556 | } |
577 | 557 | ||
558 | dev_dbg(&drv_data->pdev->dev, | ||
559 | "in dma_irq_handler dmastat:0x%x spistat:0x%x\n", | ||
560 | dmastat, read_STAT(drv_data)); | ||
561 | |||
562 | timeout = jiffies + HZ; | ||
578 | while (!(read_STAT(drv_data) & SPIF)) | 563 | while (!(read_STAT(drv_data) & SPIF)) |
579 | cpu_relax(); | 564 | if (!time_before(jiffies, timeout)) { |
565 | dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF"); | ||
566 | break; | ||
567 | } else | ||
568 | cpu_relax(); | ||
580 | 569 | ||
581 | msg->actual_length += drv_data->len_in_bytes; | 570 | if ((dmastat & DMA_ERR) && (spistat & RBSY)) { |
571 | msg->state = ERROR_STATE; | ||
572 | dev_err(&drv_data->pdev->dev, "dma receive: fifo/buffer overflow\n"); | ||
573 | } else { | ||
574 | msg->actual_length += drv_data->len_in_bytes; | ||
582 | 575 | ||
583 | if (drv_data->cs_change) | 576 | if (drv_data->cs_change) |
584 | cs_deactive(drv_data, chip); | 577 | bfin_spi_cs_deactive(drv_data, chip); |
585 | 578 | ||
586 | /* Move to next transfer */ | 579 | /* Move to next transfer */ |
587 | msg->state = next_transfer(drv_data); | 580 | msg->state = bfin_spi_next_transfer(drv_data); |
581 | } | ||
588 | 582 | ||
589 | /* Schedule transfer tasklet */ | 583 | /* Schedule transfer tasklet */ |
590 | tasklet_schedule(&drv_data->pump_transfers); | 584 | tasklet_schedule(&drv_data->pump_transfers); |
@@ -598,7 +592,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) | |||
598 | return IRQ_HANDLED; | 592 | return IRQ_HANDLED; |
599 | } | 593 | } |
600 | 594 | ||
601 | static void pump_transfers(unsigned long data) | 595 | static void bfin_spi_pump_transfers(unsigned long data) |
602 | { | 596 | { |
603 | struct driver_data *drv_data = (struct driver_data *)data; | 597 | struct driver_data *drv_data = (struct driver_data *)data; |
604 | struct spi_message *message = NULL; | 598 | struct spi_message *message = NULL; |
@@ -621,20 +615,23 @@ static void pump_transfers(unsigned long data) | |||
621 | 615 | ||
622 | /* Handle for abort */ | 616 | /* Handle for abort */ |
623 | if (message->state == ERROR_STATE) { | 617 | if (message->state == ERROR_STATE) { |
618 | dev_dbg(&drv_data->pdev->dev, "transfer: we've hit an error\n"); | ||
624 | message->status = -EIO; | 619 | message->status = -EIO; |
625 | giveback(drv_data); | 620 | bfin_spi_giveback(drv_data); |
626 | return; | 621 | return; |
627 | } | 622 | } |
628 | 623 | ||
629 | /* Handle end of message */ | 624 | /* Handle end of message */ |
630 | if (message->state == DONE_STATE) { | 625 | if (message->state == DONE_STATE) { |
626 | dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n"); | ||
631 | message->status = 0; | 627 | message->status = 0; |
632 | giveback(drv_data); | 628 | bfin_spi_giveback(drv_data); |
633 | return; | 629 | return; |
634 | } | 630 | } |
635 | 631 | ||
636 | /* Delay if requested at end of transfer */ | 632 | /* Delay if requested at end of transfer */ |
637 | if (message->state == RUNNING_STATE) { | 633 | if (message->state == RUNNING_STATE) { |
634 | dev_dbg(&drv_data->pdev->dev, "transfer: still running ...\n"); | ||
638 | previous = list_entry(transfer->transfer_list.prev, | 635 | previous = list_entry(transfer->transfer_list.prev, |
639 | struct spi_transfer, transfer_list); | 636 | struct spi_transfer, transfer_list); |
640 | if (previous->delay_usecs) | 637 | if (previous->delay_usecs) |
@@ -642,13 +639,20 @@ static void pump_transfers(unsigned long data) | |||
642 | } | 639 | } |
643 | 640 | ||
644 | /* Setup the transfer state based on the type of transfer */ | 641 | /* Setup the transfer state based on the type of transfer */ |
645 | if (flush(drv_data) == 0) { | 642 | if (bfin_spi_flush(drv_data) == 0) { |
646 | dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n"); | 643 | dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n"); |
647 | message->status = -EIO; | 644 | message->status = -EIO; |
648 | giveback(drv_data); | 645 | bfin_spi_giveback(drv_data); |
649 | return; | 646 | return; |
650 | } | 647 | } |
651 | 648 | ||
649 | if (transfer->len == 0) { | ||
650 | /* Move to next transfer of this msg */ | ||
651 | message->state = bfin_spi_next_transfer(drv_data); | ||
652 | /* Schedule next transfer tasklet */ | ||
653 | tasklet_schedule(&drv_data->pump_transfers); | ||
654 | } | ||
655 | |||
652 | if (transfer->tx_buf != NULL) { | 656 | if (transfer->tx_buf != NULL) { |
653 | drv_data->tx = (void *)transfer->tx_buf; | 657 | drv_data->tx = (void *)transfer->tx_buf; |
654 | drv_data->tx_end = drv_data->tx + transfer->len; | 658 | drv_data->tx_end = drv_data->tx + transfer->len; |
@@ -679,31 +683,31 @@ static void pump_transfers(unsigned long data) | |||
679 | drv_data->n_bytes = 1; | 683 | drv_data->n_bytes = 1; |
680 | width = CFG_SPI_WORDSIZE8; | 684 | width = CFG_SPI_WORDSIZE8; |
681 | drv_data->read = chip->cs_change_per_word ? | 685 | drv_data->read = chip->cs_change_per_word ? |
682 | u8_cs_chg_reader : u8_reader; | 686 | bfin_spi_u8_cs_chg_reader : bfin_spi_u8_reader; |
683 | drv_data->write = chip->cs_change_per_word ? | 687 | drv_data->write = chip->cs_change_per_word ? |
684 | u8_cs_chg_writer : u8_writer; | 688 | bfin_spi_u8_cs_chg_writer : bfin_spi_u8_writer; |
685 | drv_data->duplex = chip->cs_change_per_word ? | 689 | drv_data->duplex = chip->cs_change_per_word ? |
686 | u8_cs_chg_duplex : u8_duplex; | 690 | bfin_spi_u8_cs_chg_duplex : bfin_spi_u8_duplex; |
687 | break; | 691 | break; |
688 | 692 | ||
689 | case 16: | 693 | case 16: |
690 | drv_data->n_bytes = 2; | 694 | drv_data->n_bytes = 2; |
691 | width = CFG_SPI_WORDSIZE16; | 695 | width = CFG_SPI_WORDSIZE16; |
692 | drv_data->read = chip->cs_change_per_word ? | 696 | drv_data->read = chip->cs_change_per_word ? |
693 | u16_cs_chg_reader : u16_reader; | 697 | bfin_spi_u16_cs_chg_reader : bfin_spi_u16_reader; |
694 | drv_data->write = chip->cs_change_per_word ? | 698 | drv_data->write = chip->cs_change_per_word ? |
695 | u16_cs_chg_writer : u16_writer; | 699 | bfin_spi_u16_cs_chg_writer : bfin_spi_u16_writer; |
696 | drv_data->duplex = chip->cs_change_per_word ? | 700 | drv_data->duplex = chip->cs_change_per_word ? |
697 | u16_cs_chg_duplex : u16_duplex; | 701 | bfin_spi_u16_cs_chg_duplex : bfin_spi_u16_duplex; |
698 | break; | 702 | break; |
699 | 703 | ||
700 | default: | 704 | default: |
701 | /* No change, the same as default setting */ | 705 | /* No change, the same as default setting */ |
702 | drv_data->n_bytes = chip->n_bytes; | 706 | drv_data->n_bytes = chip->n_bytes; |
703 | width = chip->width; | 707 | width = chip->width; |
704 | drv_data->write = drv_data->tx ? chip->write : null_writer; | 708 | drv_data->write = drv_data->tx ? chip->write : bfin_spi_null_writer; |
705 | drv_data->read = drv_data->rx ? chip->read : null_reader; | 709 | drv_data->read = drv_data->rx ? chip->read : bfin_spi_null_reader; |
706 | drv_data->duplex = chip->duplex ? chip->duplex : null_writer; | 710 | drv_data->duplex = chip->duplex ? chip->duplex : bfin_spi_null_writer; |
707 | break; | 711 | break; |
708 | } | 712 | } |
709 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | 713 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); |
@@ -717,7 +721,7 @@ static void pump_transfers(unsigned long data) | |||
717 | } | 721 | } |
718 | dev_dbg(&drv_data->pdev->dev, | 722 | dev_dbg(&drv_data->pdev->dev, |
719 | "transfer: drv_data->write is %p, chip->write is %p, null_wr is %p\n", | 723 | "transfer: drv_data->write is %p, chip->write is %p, null_wr is %p\n", |
720 | drv_data->write, chip->write, null_writer); | 724 | drv_data->write, chip->write, bfin_spi_null_writer); |
721 | 725 | ||
722 | /* speed and width has been set on per message */ | 726 | /* speed and width has been set on per message */ |
723 | message->state = RUNNING_STATE; | 727 | message->state = RUNNING_STATE; |
@@ -731,32 +735,34 @@ static void pump_transfers(unsigned long data) | |||
731 | 735 | ||
732 | write_STAT(drv_data, BIT_STAT_CLR); | 736 | write_STAT(drv_data, BIT_STAT_CLR); |
733 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); | 737 | cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD)); |
734 | cs_active(drv_data, chip); | 738 | if (drv_data->cs_change) |
739 | bfin_spi_cs_active(drv_data, chip); | ||
735 | 740 | ||
736 | dev_dbg(&drv_data->pdev->dev, | 741 | dev_dbg(&drv_data->pdev->dev, |
737 | "now pumping a transfer: width is %d, len is %d\n", | 742 | "now pumping a transfer: width is %d, len is %d\n", |
738 | width, transfer->len); | 743 | width, transfer->len); |
739 | 744 | ||
740 | /* | 745 | /* |
741 | * Try to map dma buffer and do a dma transfer if | 746 | * Try to map dma buffer and do a dma transfer. If successful use, |
742 | * successful use different way to r/w according to | 747 | * different way to r/w according to the enable_dma settings and if |
743 | * drv_data->cur_chip->enable_dma | 748 | * we are not doing a full duplex transfer (since the hardware does |
749 | * not support full duplex DMA transfers). | ||
744 | */ | 750 | */ |
745 | if (!full_duplex && drv_data->cur_chip->enable_dma | 751 | if (!full_duplex && drv_data->cur_chip->enable_dma |
746 | && drv_data->len > 6) { | 752 | && drv_data->len > 6) { |
747 | 753 | ||
754 | unsigned long dma_start_addr, flags; | ||
755 | |||
748 | disable_dma(drv_data->dma_channel); | 756 | disable_dma(drv_data->dma_channel); |
749 | clear_dma_irqstat(drv_data->dma_channel); | 757 | clear_dma_irqstat(drv_data->dma_channel); |
750 | bfin_spi_disable(drv_data); | ||
751 | 758 | ||
752 | /* config dma channel */ | 759 | /* config dma channel */ |
753 | dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n"); | 760 | dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n"); |
761 | set_dma_x_count(drv_data->dma_channel, drv_data->len); | ||
754 | if (width == CFG_SPI_WORDSIZE16) { | 762 | if (width == CFG_SPI_WORDSIZE16) { |
755 | set_dma_x_count(drv_data->dma_channel, drv_data->len); | ||
756 | set_dma_x_modify(drv_data->dma_channel, 2); | 763 | set_dma_x_modify(drv_data->dma_channel, 2); |
757 | dma_width = WDSIZE_16; | 764 | dma_width = WDSIZE_16; |
758 | } else { | 765 | } else { |
759 | set_dma_x_count(drv_data->dma_channel, drv_data->len); | ||
760 | set_dma_x_modify(drv_data->dma_channel, 1); | 766 | set_dma_x_modify(drv_data->dma_channel, 1); |
761 | dma_width = WDSIZE_8; | 767 | dma_width = WDSIZE_8; |
762 | } | 768 | } |
@@ -779,58 +785,75 @@ static void pump_transfers(unsigned long data) | |||
779 | enable_dma(drv_data->dma_channel); | 785 | enable_dma(drv_data->dma_channel); |
780 | 786 | ||
781 | /* start SPI transfer */ | 787 | /* start SPI transfer */ |
782 | write_CTRL(drv_data, | 788 | write_CTRL(drv_data, cr | BIT_CTL_TIMOD_DMA_TX); |
783 | (cr | CFG_SPI_DMAWRITE | BIT_CTL_ENABLE)); | ||
784 | 789 | ||
785 | /* just return here, there can only be one transfer | 790 | /* just return here, there can only be one transfer |
786 | * in this mode | 791 | * in this mode |
787 | */ | 792 | */ |
788 | message->status = 0; | 793 | message->status = 0; |
789 | giveback(drv_data); | 794 | bfin_spi_giveback(drv_data); |
790 | return; | 795 | return; |
791 | } | 796 | } |
792 | 797 | ||
793 | /* In dma mode, rx or tx must be NULL in one transfer */ | 798 | /* In dma mode, rx or tx must be NULL in one transfer */ |
799 | dma_config = (RESTART | dma_width | DI_EN); | ||
794 | if (drv_data->rx != NULL) { | 800 | if (drv_data->rx != NULL) { |
795 | /* set transfer mode, and enable SPI */ | 801 | /* set transfer mode, and enable SPI */ |
796 | dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n"); | 802 | dev_dbg(&drv_data->pdev->dev, "doing DMA in to %p (size %zx)\n", |
803 | drv_data->rx, drv_data->len_in_bytes); | ||
797 | 804 | ||
798 | /* clear tx reg soformer data is not shifted out */ | 805 | /* invalidate caches, if needed */ |
799 | write_TDBR(drv_data, 0xFFFF); | 806 | if (bfin_addr_dcachable((unsigned long) drv_data->rx)) |
807 | invalidate_dcache_range((unsigned long) drv_data->rx, | ||
808 | (unsigned long) (drv_data->rx + | ||
809 | drv_data->len_in_bytes)); | ||
800 | 810 | ||
801 | set_dma_x_count(drv_data->dma_channel, drv_data->len); | 811 | dma_config |= WNR; |
802 | 812 | dma_start_addr = (unsigned long)drv_data->rx; | |
803 | /* start dma */ | 813 | cr |= BIT_CTL_TIMOD_DMA_RX | BIT_CTL_SENDOPT; |
804 | dma_enable_irq(drv_data->dma_channel); | ||
805 | dma_config = (WNR | RESTART | dma_width | DI_EN); | ||
806 | set_dma_config(drv_data->dma_channel, dma_config); | ||
807 | set_dma_start_addr(drv_data->dma_channel, | ||
808 | (unsigned long)drv_data->rx); | ||
809 | enable_dma(drv_data->dma_channel); | ||
810 | |||
811 | /* start SPI transfer */ | ||
812 | write_CTRL(drv_data, | ||
813 | (cr | CFG_SPI_DMAREAD | BIT_CTL_ENABLE)); | ||
814 | 814 | ||
815 | } else if (drv_data->tx != NULL) { | 815 | } else if (drv_data->tx != NULL) { |
816 | dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n"); | 816 | dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n"); |
817 | 817 | ||
818 | /* start dma */ | 818 | /* flush caches, if needed */ |
819 | dma_enable_irq(drv_data->dma_channel); | 819 | if (bfin_addr_dcachable((unsigned long) drv_data->tx)) |
820 | dma_config = (RESTART | dma_width | DI_EN); | 820 | flush_dcache_range((unsigned long) drv_data->tx, |
821 | set_dma_config(drv_data->dma_channel, dma_config); | 821 | (unsigned long) (drv_data->tx + |
822 | set_dma_start_addr(drv_data->dma_channel, | 822 | drv_data->len_in_bytes)); |
823 | (unsigned long)drv_data->tx); | 823 | |
824 | enable_dma(drv_data->dma_channel); | 824 | dma_start_addr = (unsigned long)drv_data->tx; |
825 | cr |= BIT_CTL_TIMOD_DMA_TX; | ||
826 | |||
827 | } else | ||
828 | BUG(); | ||
829 | |||
830 | /* oh man, here there be monsters ... and i dont mean the | ||
831 | * fluffy cute ones from pixar, i mean the kind that'll eat | ||
832 | * your data, kick your dog, and love it all. do *not* try | ||
833 | * and change these lines unless you (1) heavily test DMA | ||
834 | * with SPI flashes on a loaded system (e.g. ping floods), | ||
835 | * (2) know just how broken the DMA engine interaction with | ||
836 | * the SPI peripheral is, and (3) have someone else to blame | ||
837 | * when you screw it all up anyways. | ||
838 | */ | ||
839 | set_dma_start_addr(drv_data->dma_channel, dma_start_addr); | ||
840 | set_dma_config(drv_data->dma_channel, dma_config); | ||
841 | local_irq_save(flags); | ||
842 | SSYNC(); | ||
843 | write_CTRL(drv_data, cr); | ||
844 | enable_dma(drv_data->dma_channel); | ||
845 | dma_enable_irq(drv_data->dma_channel); | ||
846 | local_irq_restore(flags); | ||
825 | 847 | ||
826 | /* start SPI transfer */ | ||
827 | write_CTRL(drv_data, | ||
828 | (cr | CFG_SPI_DMAWRITE | BIT_CTL_ENABLE)); | ||
829 | } | ||
830 | } else { | 848 | } else { |
831 | /* IO mode write then read */ | 849 | /* IO mode write then read */ |
832 | dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); | 850 | dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); |
833 | 851 | ||
852 | /* we always use SPI_WRITE mode. SPI_READ mode | ||
853 | seems to have problems with setting up the | ||
854 | output value in TDBR prior to the transfer. */ | ||
855 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
856 | |||
834 | if (full_duplex) { | 857 | if (full_duplex) { |
835 | /* full duplex mode */ | 858 | /* full duplex mode */ |
836 | BUG_ON((drv_data->tx_end - drv_data->tx) != | 859 | BUG_ON((drv_data->tx_end - drv_data->tx) != |
@@ -838,9 +861,6 @@ static void pump_transfers(unsigned long data) | |||
838 | dev_dbg(&drv_data->pdev->dev, | 861 | dev_dbg(&drv_data->pdev->dev, |
839 | "IO duplex: cr is 0x%x\n", cr); | 862 | "IO duplex: cr is 0x%x\n", cr); |
840 | 863 | ||
841 | /* set SPI transfer mode */ | ||
842 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
843 | |||
844 | drv_data->duplex(drv_data); | 864 | drv_data->duplex(drv_data); |
845 | 865 | ||
846 | if (drv_data->tx != drv_data->tx_end) | 866 | if (drv_data->tx != drv_data->tx_end) |
@@ -850,9 +870,6 @@ static void pump_transfers(unsigned long data) | |||
850 | dev_dbg(&drv_data->pdev->dev, | 870 | dev_dbg(&drv_data->pdev->dev, |
851 | "IO write: cr is 0x%x\n", cr); | 871 | "IO write: cr is 0x%x\n", cr); |
852 | 872 | ||
853 | /* set SPI transfer mode */ | ||
854 | write_CTRL(drv_data, (cr | CFG_SPI_WRITE)); | ||
855 | |||
856 | drv_data->write(drv_data); | 873 | drv_data->write(drv_data); |
857 | 874 | ||
858 | if (drv_data->tx != drv_data->tx_end) | 875 | if (drv_data->tx != drv_data->tx_end) |
@@ -862,9 +879,6 @@ static void pump_transfers(unsigned long data) | |||
862 | dev_dbg(&drv_data->pdev->dev, | 879 | dev_dbg(&drv_data->pdev->dev, |
863 | "IO read: cr is 0x%x\n", cr); | 880 | "IO read: cr is 0x%x\n", cr); |
864 | 881 | ||
865 | /* set SPI transfer mode */ | ||
866 | write_CTRL(drv_data, (cr | CFG_SPI_READ)); | ||
867 | |||
868 | drv_data->read(drv_data); | 882 | drv_data->read(drv_data); |
869 | if (drv_data->rx != drv_data->rx_end) | 883 | if (drv_data->rx != drv_data->rx_end) |
870 | tranf_success = 0; | 884 | tranf_success = 0; |
@@ -876,20 +890,19 @@ static void pump_transfers(unsigned long data) | |||
876 | message->state = ERROR_STATE; | 890 | message->state = ERROR_STATE; |
877 | } else { | 891 | } else { |
878 | /* Update total byte transfered */ | 892 | /* Update total byte transfered */ |
879 | message->actual_length += drv_data->len; | 893 | message->actual_length += drv_data->len_in_bytes; |
880 | |||
881 | /* Move to next transfer of this msg */ | 894 | /* Move to next transfer of this msg */ |
882 | message->state = next_transfer(drv_data); | 895 | message->state = bfin_spi_next_transfer(drv_data); |
896 | if (drv_data->cs_change) | ||
897 | bfin_spi_cs_deactive(drv_data, chip); | ||
883 | } | 898 | } |
884 | |||
885 | /* Schedule next transfer tasklet */ | 899 | /* Schedule next transfer tasklet */ |
886 | tasklet_schedule(&drv_data->pump_transfers); | 900 | tasklet_schedule(&drv_data->pump_transfers); |
887 | |||
888 | } | 901 | } |
889 | } | 902 | } |
890 | 903 | ||
891 | /* pop a msg from queue and kick off real transfer */ | 904 | /* pop a msg from queue and kick off real transfer */ |
892 | static void pump_messages(struct work_struct *work) | 905 | static void bfin_spi_pump_messages(struct work_struct *work) |
893 | { | 906 | { |
894 | struct driver_data *drv_data; | 907 | struct driver_data *drv_data; |
895 | unsigned long flags; | 908 | unsigned long flags; |
@@ -917,7 +930,7 @@ static void pump_messages(struct work_struct *work) | |||
917 | 930 | ||
918 | /* Setup the SSP using the per chip configuration */ | 931 | /* Setup the SSP using the per chip configuration */ |
919 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); | 932 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); |
920 | restore_state(drv_data); | 933 | bfin_spi_restore_state(drv_data); |
921 | 934 | ||
922 | list_del_init(&drv_data->cur_msg->queue); | 935 | list_del_init(&drv_data->cur_msg->queue); |
923 | 936 | ||
@@ -946,7 +959,7 @@ static void pump_messages(struct work_struct *work) | |||
946 | * got a msg to transfer, queue it in drv_data->queue. | 959 | * got a msg to transfer, queue it in drv_data->queue. |
947 | * And kick off message pumper | 960 | * And kick off message pumper |
948 | */ | 961 | */ |
949 | static int transfer(struct spi_device *spi, struct spi_message *msg) | 962 | static int bfin_spi_transfer(struct spi_device *spi, struct spi_message *msg) |
950 | { | 963 | { |
951 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | 964 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); |
952 | unsigned long flags; | 965 | unsigned long flags; |
@@ -975,7 +988,7 @@ static int transfer(struct spi_device *spi, struct spi_message *msg) | |||
975 | 988 | ||
976 | #define MAX_SPI_SSEL 7 | 989 | #define MAX_SPI_SSEL 7 |
977 | 990 | ||
978 | static u16 ssel[3][MAX_SPI_SSEL] = { | 991 | static u16 ssel[][MAX_SPI_SSEL] = { |
979 | {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3, | 992 | {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3, |
980 | P_SPI0_SSEL4, P_SPI0_SSEL5, | 993 | P_SPI0_SSEL4, P_SPI0_SSEL5, |
981 | P_SPI0_SSEL6, P_SPI0_SSEL7}, | 994 | P_SPI0_SSEL6, P_SPI0_SSEL7}, |
@@ -990,12 +1003,12 @@ static u16 ssel[3][MAX_SPI_SSEL] = { | |||
990 | }; | 1003 | }; |
991 | 1004 | ||
992 | /* first setup for new devices */ | 1005 | /* first setup for new devices */ |
993 | static int setup(struct spi_device *spi) | 1006 | static int bfin_spi_setup(struct spi_device *spi) |
994 | { | 1007 | { |
995 | struct bfin5xx_spi_chip *chip_info = NULL; | 1008 | struct bfin5xx_spi_chip *chip_info = NULL; |
996 | struct chip_data *chip; | 1009 | struct chip_data *chip; |
997 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | 1010 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); |
998 | u8 spi_flg; | 1011 | int ret; |
999 | 1012 | ||
1000 | /* Abort device setup if requested features are not supported */ | 1013 | /* Abort device setup if requested features are not supported */ |
1001 | if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) { | 1014 | if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) { |
@@ -1041,6 +1054,8 @@ static int setup(struct spi_device *spi) | |||
1041 | chip->bits_per_word = chip_info->bits_per_word; | 1054 | chip->bits_per_word = chip_info->bits_per_word; |
1042 | chip->cs_change_per_word = chip_info->cs_change_per_word; | 1055 | chip->cs_change_per_word = chip_info->cs_change_per_word; |
1043 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; | 1056 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; |
1057 | chip->cs_gpio = chip_info->cs_gpio; | ||
1058 | chip->idle_tx_val = chip_info->idle_tx_val; | ||
1044 | } | 1059 | } |
1045 | 1060 | ||
1046 | /* translate common spi framework into our register */ | 1061 | /* translate common spi framework into our register */ |
@@ -1059,13 +1074,13 @@ static int setup(struct spi_device *spi) | |||
1059 | */ | 1074 | */ |
1060 | if (chip->enable_dma && !drv_data->dma_requested) { | 1075 | if (chip->enable_dma && !drv_data->dma_requested) { |
1061 | /* register dma irq handler */ | 1076 | /* register dma irq handler */ |
1062 | if (request_dma(drv_data->dma_channel, "BF53x_SPI_DMA") < 0) { | 1077 | if (request_dma(drv_data->dma_channel, "BFIN_SPI_DMA") < 0) { |
1063 | dev_dbg(&spi->dev, | 1078 | dev_dbg(&spi->dev, |
1064 | "Unable to request BlackFin SPI DMA channel\n"); | 1079 | "Unable to request BlackFin SPI DMA channel\n"); |
1065 | return -ENODEV; | 1080 | return -ENODEV; |
1066 | } | 1081 | } |
1067 | if (set_dma_callback(drv_data->dma_channel, | 1082 | if (set_dma_callback(drv_data->dma_channel, |
1068 | (void *)dma_irq_handler, drv_data) < 0) { | 1083 | bfin_spi_dma_irq_handler, drv_data) < 0) { |
1069 | dev_dbg(&spi->dev, "Unable to set dma callback\n"); | 1084 | dev_dbg(&spi->dev, "Unable to set dma callback\n"); |
1070 | return -EPERM; | 1085 | return -EPERM; |
1071 | } | 1086 | } |
@@ -1078,37 +1093,47 @@ static int setup(struct spi_device *spi) | |||
1078 | * SPI_BAUD, not the real baudrate | 1093 | * SPI_BAUD, not the real baudrate |
1079 | */ | 1094 | */ |
1080 | chip->baud = hz_to_spi_baud(spi->max_speed_hz); | 1095 | chip->baud = hz_to_spi_baud(spi->max_speed_hz); |
1081 | spi_flg = ~(1 << (spi->chip_select)); | 1096 | chip->flag = 1 << (spi->chip_select); |
1082 | chip->flag = ((u16) spi_flg << 8) | (1 << (spi->chip_select)); | ||
1083 | chip->chip_select_num = spi->chip_select; | 1097 | chip->chip_select_num = spi->chip_select; |
1084 | 1098 | ||
1099 | if (chip->chip_select_num == 0) { | ||
1100 | ret = gpio_request(chip->cs_gpio, spi->modalias); | ||
1101 | if (ret) { | ||
1102 | if (drv_data->dma_requested) | ||
1103 | free_dma(drv_data->dma_channel); | ||
1104 | return ret; | ||
1105 | } | ||
1106 | gpio_direction_output(chip->cs_gpio, 1); | ||
1107 | } | ||
1108 | |||
1085 | switch (chip->bits_per_word) { | 1109 | switch (chip->bits_per_word) { |
1086 | case 8: | 1110 | case 8: |
1087 | chip->n_bytes = 1; | 1111 | chip->n_bytes = 1; |
1088 | chip->width = CFG_SPI_WORDSIZE8; | 1112 | chip->width = CFG_SPI_WORDSIZE8; |
1089 | chip->read = chip->cs_change_per_word ? | 1113 | chip->read = chip->cs_change_per_word ? |
1090 | u8_cs_chg_reader : u8_reader; | 1114 | bfin_spi_u8_cs_chg_reader : bfin_spi_u8_reader; |
1091 | chip->write = chip->cs_change_per_word ? | 1115 | chip->write = chip->cs_change_per_word ? |
1092 | u8_cs_chg_writer : u8_writer; | 1116 | bfin_spi_u8_cs_chg_writer : bfin_spi_u8_writer; |
1093 | chip->duplex = chip->cs_change_per_word ? | 1117 | chip->duplex = chip->cs_change_per_word ? |
1094 | u8_cs_chg_duplex : u8_duplex; | 1118 | bfin_spi_u8_cs_chg_duplex : bfin_spi_u8_duplex; |
1095 | break; | 1119 | break; |
1096 | 1120 | ||
1097 | case 16: | 1121 | case 16: |
1098 | chip->n_bytes = 2; | 1122 | chip->n_bytes = 2; |
1099 | chip->width = CFG_SPI_WORDSIZE16; | 1123 | chip->width = CFG_SPI_WORDSIZE16; |
1100 | chip->read = chip->cs_change_per_word ? | 1124 | chip->read = chip->cs_change_per_word ? |
1101 | u16_cs_chg_reader : u16_reader; | 1125 | bfin_spi_u16_cs_chg_reader : bfin_spi_u16_reader; |
1102 | chip->write = chip->cs_change_per_word ? | 1126 | chip->write = chip->cs_change_per_word ? |
1103 | u16_cs_chg_writer : u16_writer; | 1127 | bfin_spi_u16_cs_chg_writer : bfin_spi_u16_writer; |
1104 | chip->duplex = chip->cs_change_per_word ? | 1128 | chip->duplex = chip->cs_change_per_word ? |
1105 | u16_cs_chg_duplex : u16_duplex; | 1129 | bfin_spi_u16_cs_chg_duplex : bfin_spi_u16_duplex; |
1106 | break; | 1130 | break; |
1107 | 1131 | ||
1108 | default: | 1132 | default: |
1109 | dev_err(&spi->dev, "%d bits_per_word is not supported\n", | 1133 | dev_err(&spi->dev, "%d bits_per_word is not supported\n", |
1110 | chip->bits_per_word); | 1134 | chip->bits_per_word); |
1111 | kfree(chip); | 1135 | if (chip_info) |
1136 | kfree(chip); | ||
1112 | return -ENODEV; | 1137 | return -ENODEV; |
1113 | } | 1138 | } |
1114 | 1139 | ||
@@ -1125,7 +1150,7 @@ static int setup(struct spi_device *spi) | |||
1125 | peripheral_request(ssel[spi->master->bus_num] | 1150 | peripheral_request(ssel[spi->master->bus_num] |
1126 | [chip->chip_select_num-1], spi->modalias); | 1151 | [chip->chip_select_num-1], spi->modalias); |
1127 | 1152 | ||
1128 | cs_deactive(drv_data, chip); | 1153 | bfin_spi_cs_deactive(drv_data, chip); |
1129 | 1154 | ||
1130 | return 0; | 1155 | return 0; |
1131 | } | 1156 | } |
@@ -1134,19 +1159,25 @@ static int setup(struct spi_device *spi) | |||
1134 | * callback for spi framework. | 1159 | * callback for spi framework. |
1135 | * clean driver specific data | 1160 | * clean driver specific data |
1136 | */ | 1161 | */ |
1137 | static void cleanup(struct spi_device *spi) | 1162 | static void bfin_spi_cleanup(struct spi_device *spi) |
1138 | { | 1163 | { |
1139 | struct chip_data *chip = spi_get_ctldata(spi); | 1164 | struct chip_data *chip = spi_get_ctldata(spi); |
1140 | 1165 | ||
1166 | if (!chip) | ||
1167 | return; | ||
1168 | |||
1141 | if ((chip->chip_select_num > 0) | 1169 | if ((chip->chip_select_num > 0) |
1142 | && (chip->chip_select_num <= spi->master->num_chipselect)) | 1170 | && (chip->chip_select_num <= spi->master->num_chipselect)) |
1143 | peripheral_free(ssel[spi->master->bus_num] | 1171 | peripheral_free(ssel[spi->master->bus_num] |
1144 | [chip->chip_select_num-1]); | 1172 | [chip->chip_select_num-1]); |
1145 | 1173 | ||
1174 | if (chip->chip_select_num == 0) | ||
1175 | gpio_free(chip->cs_gpio); | ||
1176 | |||
1146 | kfree(chip); | 1177 | kfree(chip); |
1147 | } | 1178 | } |
1148 | 1179 | ||
1149 | static inline int init_queue(struct driver_data *drv_data) | 1180 | static inline int bfin_spi_init_queue(struct driver_data *drv_data) |
1150 | { | 1181 | { |
1151 | INIT_LIST_HEAD(&drv_data->queue); | 1182 | INIT_LIST_HEAD(&drv_data->queue); |
1152 | spin_lock_init(&drv_data->lock); | 1183 | spin_lock_init(&drv_data->lock); |
@@ -1156,10 +1187,10 @@ static inline int init_queue(struct driver_data *drv_data) | |||
1156 | 1187 | ||
1157 | /* init transfer tasklet */ | 1188 | /* init transfer tasklet */ |
1158 | tasklet_init(&drv_data->pump_transfers, | 1189 | tasklet_init(&drv_data->pump_transfers, |
1159 | pump_transfers, (unsigned long)drv_data); | 1190 | bfin_spi_pump_transfers, (unsigned long)drv_data); |
1160 | 1191 | ||
1161 | /* init messages workqueue */ | 1192 | /* init messages workqueue */ |
1162 | INIT_WORK(&drv_data->pump_messages, pump_messages); | 1193 | INIT_WORK(&drv_data->pump_messages, bfin_spi_pump_messages); |
1163 | drv_data->workqueue = create_singlethread_workqueue( | 1194 | drv_data->workqueue = create_singlethread_workqueue( |
1164 | dev_name(drv_data->master->dev.parent)); | 1195 | dev_name(drv_data->master->dev.parent)); |
1165 | if (drv_data->workqueue == NULL) | 1196 | if (drv_data->workqueue == NULL) |
@@ -1168,7 +1199,7 @@ static inline int init_queue(struct driver_data *drv_data) | |||
1168 | return 0; | 1199 | return 0; |
1169 | } | 1200 | } |
1170 | 1201 | ||
1171 | static inline int start_queue(struct driver_data *drv_data) | 1202 | static inline int bfin_spi_start_queue(struct driver_data *drv_data) |
1172 | { | 1203 | { |
1173 | unsigned long flags; | 1204 | unsigned long flags; |
1174 | 1205 | ||
@@ -1190,7 +1221,7 @@ static inline int start_queue(struct driver_data *drv_data) | |||
1190 | return 0; | 1221 | return 0; |
1191 | } | 1222 | } |
1192 | 1223 | ||
1193 | static inline int stop_queue(struct driver_data *drv_data) | 1224 | static inline int bfin_spi_stop_queue(struct driver_data *drv_data) |
1194 | { | 1225 | { |
1195 | unsigned long flags; | 1226 | unsigned long flags; |
1196 | unsigned limit = 500; | 1227 | unsigned limit = 500; |
@@ -1219,11 +1250,11 @@ static inline int stop_queue(struct driver_data *drv_data) | |||
1219 | return status; | 1250 | return status; |
1220 | } | 1251 | } |
1221 | 1252 | ||
1222 | static inline int destroy_queue(struct driver_data *drv_data) | 1253 | static inline int bfin_spi_destroy_queue(struct driver_data *drv_data) |
1223 | { | 1254 | { |
1224 | int status; | 1255 | int status; |
1225 | 1256 | ||
1226 | status = stop_queue(drv_data); | 1257 | status = bfin_spi_stop_queue(drv_data); |
1227 | if (status != 0) | 1258 | if (status != 0) |
1228 | return status; | 1259 | return status; |
1229 | 1260 | ||
@@ -1232,7 +1263,7 @@ static inline int destroy_queue(struct driver_data *drv_data) | |||
1232 | return 0; | 1263 | return 0; |
1233 | } | 1264 | } |
1234 | 1265 | ||
1235 | static int __init bfin5xx_spi_probe(struct platform_device *pdev) | 1266 | static int __init bfin_spi_probe(struct platform_device *pdev) |
1236 | { | 1267 | { |
1237 | struct device *dev = &pdev->dev; | 1268 | struct device *dev = &pdev->dev; |
1238 | struct bfin5xx_spi_master *platform_info; | 1269 | struct bfin5xx_spi_master *platform_info; |
@@ -1258,9 +1289,9 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev) | |||
1258 | 1289 | ||
1259 | master->bus_num = pdev->id; | 1290 | master->bus_num = pdev->id; |
1260 | master->num_chipselect = platform_info->num_chipselect; | 1291 | master->num_chipselect = platform_info->num_chipselect; |
1261 | master->cleanup = cleanup; | 1292 | master->cleanup = bfin_spi_cleanup; |
1262 | master->setup = setup; | 1293 | master->setup = bfin_spi_setup; |
1263 | master->transfer = transfer; | 1294 | master->transfer = bfin_spi_transfer; |
1264 | 1295 | ||
1265 | /* Find and map our resources */ | 1296 | /* Find and map our resources */ |
1266 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1297 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1285,13 +1316,13 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev) | |||
1285 | } | 1316 | } |
1286 | 1317 | ||
1287 | /* Initial and start queue */ | 1318 | /* Initial and start queue */ |
1288 | status = init_queue(drv_data); | 1319 | status = bfin_spi_init_queue(drv_data); |
1289 | if (status != 0) { | 1320 | if (status != 0) { |
1290 | dev_err(dev, "problem initializing queue\n"); | 1321 | dev_err(dev, "problem initializing queue\n"); |
1291 | goto out_error_queue_alloc; | 1322 | goto out_error_queue_alloc; |
1292 | } | 1323 | } |
1293 | 1324 | ||
1294 | status = start_queue(drv_data); | 1325 | status = bfin_spi_start_queue(drv_data); |
1295 | if (status != 0) { | 1326 | if (status != 0) { |
1296 | dev_err(dev, "problem starting queue\n"); | 1327 | dev_err(dev, "problem starting queue\n"); |
1297 | goto out_error_queue_alloc; | 1328 | goto out_error_queue_alloc; |
@@ -1317,7 +1348,7 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev) | |||
1317 | return status; | 1348 | return status; |
1318 | 1349 | ||
1319 | out_error_queue_alloc: | 1350 | out_error_queue_alloc: |
1320 | destroy_queue(drv_data); | 1351 | bfin_spi_destroy_queue(drv_data); |
1321 | out_error_no_dma_ch: | 1352 | out_error_no_dma_ch: |
1322 | iounmap((void *) drv_data->regs_base); | 1353 | iounmap((void *) drv_data->regs_base); |
1323 | out_error_ioremap: | 1354 | out_error_ioremap: |
@@ -1328,7 +1359,7 @@ out_error_get_res: | |||
1328 | } | 1359 | } |
1329 | 1360 | ||
1330 | /* stop hardware and remove the driver */ | 1361 | /* stop hardware and remove the driver */ |
1331 | static int __devexit bfin5xx_spi_remove(struct platform_device *pdev) | 1362 | static int __devexit bfin_spi_remove(struct platform_device *pdev) |
1332 | { | 1363 | { |
1333 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1364 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1334 | int status = 0; | 1365 | int status = 0; |
@@ -1337,7 +1368,7 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev) | |||
1337 | return 0; | 1368 | return 0; |
1338 | 1369 | ||
1339 | /* Remove the queue */ | 1370 | /* Remove the queue */ |
1340 | status = destroy_queue(drv_data); | 1371 | status = bfin_spi_destroy_queue(drv_data); |
1341 | if (status != 0) | 1372 | if (status != 0) |
1342 | return status; | 1373 | return status; |
1343 | 1374 | ||
@@ -1362,12 +1393,12 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev) | |||
1362 | } | 1393 | } |
1363 | 1394 | ||
1364 | #ifdef CONFIG_PM | 1395 | #ifdef CONFIG_PM |
1365 | static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | 1396 | static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state) |
1366 | { | 1397 | { |
1367 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1398 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1368 | int status = 0; | 1399 | int status = 0; |
1369 | 1400 | ||
1370 | status = stop_queue(drv_data); | 1401 | status = bfin_spi_stop_queue(drv_data); |
1371 | if (status != 0) | 1402 | if (status != 0) |
1372 | return status; | 1403 | return status; |
1373 | 1404 | ||
@@ -1377,7 +1408,7 @@ static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | |||
1377 | return 0; | 1408 | return 0; |
1378 | } | 1409 | } |
1379 | 1410 | ||
1380 | static int bfin5xx_spi_resume(struct platform_device *pdev) | 1411 | static int bfin_spi_resume(struct platform_device *pdev) |
1381 | { | 1412 | { |
1382 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1413 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1383 | int status = 0; | 1414 | int status = 0; |
@@ -1386,7 +1417,7 @@ static int bfin5xx_spi_resume(struct platform_device *pdev) | |||
1386 | bfin_spi_enable(drv_data); | 1417 | bfin_spi_enable(drv_data); |
1387 | 1418 | ||
1388 | /* Start the queue running */ | 1419 | /* Start the queue running */ |
1389 | status = start_queue(drv_data); | 1420 | status = bfin_spi_start_queue(drv_data); |
1390 | if (status != 0) { | 1421 | if (status != 0) { |
1391 | dev_err(&pdev->dev, "problem starting queue (%d)\n", status); | 1422 | dev_err(&pdev->dev, "problem starting queue (%d)\n", status); |
1392 | return status; | 1423 | return status; |
@@ -1395,29 +1426,29 @@ static int bfin5xx_spi_resume(struct platform_device *pdev) | |||
1395 | return 0; | 1426 | return 0; |
1396 | } | 1427 | } |
1397 | #else | 1428 | #else |
1398 | #define bfin5xx_spi_suspend NULL | 1429 | #define bfin_spi_suspend NULL |
1399 | #define bfin5xx_spi_resume NULL | 1430 | #define bfin_spi_resume NULL |
1400 | #endif /* CONFIG_PM */ | 1431 | #endif /* CONFIG_PM */ |
1401 | 1432 | ||
1402 | MODULE_ALIAS("platform:bfin-spi"); | 1433 | MODULE_ALIAS("platform:bfin-spi"); |
1403 | static struct platform_driver bfin5xx_spi_driver = { | 1434 | static struct platform_driver bfin_spi_driver = { |
1404 | .driver = { | 1435 | .driver = { |
1405 | .name = DRV_NAME, | 1436 | .name = DRV_NAME, |
1406 | .owner = THIS_MODULE, | 1437 | .owner = THIS_MODULE, |
1407 | }, | 1438 | }, |
1408 | .suspend = bfin5xx_spi_suspend, | 1439 | .suspend = bfin_spi_suspend, |
1409 | .resume = bfin5xx_spi_resume, | 1440 | .resume = bfin_spi_resume, |
1410 | .remove = __devexit_p(bfin5xx_spi_remove), | 1441 | .remove = __devexit_p(bfin_spi_remove), |
1411 | }; | 1442 | }; |
1412 | 1443 | ||
1413 | static int __init bfin5xx_spi_init(void) | 1444 | static int __init bfin_spi_init(void) |
1414 | { | 1445 | { |
1415 | return platform_driver_probe(&bfin5xx_spi_driver, bfin5xx_spi_probe); | 1446 | return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe); |
1416 | } | 1447 | } |
1417 | module_init(bfin5xx_spi_init); | 1448 | module_init(bfin_spi_init); |
1418 | 1449 | ||
1419 | static void __exit bfin5xx_spi_exit(void) | 1450 | static void __exit bfin_spi_exit(void) |
1420 | { | 1451 | { |
1421 | platform_driver_unregister(&bfin5xx_spi_driver); | 1452 | platform_driver_unregister(&bfin_spi_driver); |
1422 | } | 1453 | } |
1423 | module_exit(bfin5xx_spi_exit); | 1454 | module_exit(bfin_spi_exit); |
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 0480d8bb19d3..0671aeef5792 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -186,6 +186,7 @@ | |||
186 | #define QUEUE_STOPPED (1) | 186 | #define QUEUE_STOPPED (1) |
187 | 187 | ||
188 | #define IS_DMA_ALIGNED(x) (((u32)(x) & 0x03) == 0) | 188 | #define IS_DMA_ALIGNED(x) (((u32)(x) & 0x03) == 0) |
189 | #define DMA_ALIGNMENT 4 | ||
189 | /*-------------------------------------------------------------------------*/ | 190 | /*-------------------------------------------------------------------------*/ |
190 | 191 | ||
191 | 192 | ||
@@ -779,7 +780,8 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) | |||
779 | 780 | ||
780 | /* Read trailing bytes */ | 781 | /* Read trailing bytes */ |
781 | limit = loops_per_jiffy << 1; | 782 | limit = loops_per_jiffy << 1; |
782 | while ((read(drv_data) == 0) && limit--); | 783 | while ((read(drv_data) == 0) && --limit) |
784 | cpu_relax(); | ||
783 | 785 | ||
784 | if (limit == 0) | 786 | if (limit == 0) |
785 | dev_err(&drv_data->pdev->dev, | 787 | dev_err(&drv_data->pdev->dev, |
@@ -1481,6 +1483,7 @@ static int __init spi_imx_probe(struct platform_device *pdev) | |||
1481 | 1483 | ||
1482 | master->bus_num = pdev->id; | 1484 | master->bus_num = pdev->id; |
1483 | master->num_chipselect = platform_info->num_chipselect; | 1485 | master->num_chipselect = platform_info->num_chipselect; |
1486 | master->dma_alignment = DMA_ALIGNMENT; | ||
1484 | master->cleanup = cleanup; | 1487 | master->cleanup = cleanup; |
1485 | master->setup = setup; | 1488 | master->setup = setup; |
1486 | master->transfer = transfer; | 1489 | master->transfer = transfer; |