aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorBryan Wu <bryan.wu@analog.com>2007-12-05 02:45:13 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-12-05 12:21:19 -0500
commit5fec5b5a4ec0d6d8b41c56e3cc7de41063cd4736 (patch)
tree3705b4a2000d9a2ae912a3412b4912358b850840 /drivers/spi
parentcc2f81a695640dd1c0cf12b35ee303460fa6d0bc (diff)
spi: spi_bfin cleanups, error handling
Cleanup and error handling - add error handling in SPI bus driver with selecting clients - use proper defines to access Blackfin MMRs - remove useless SSYNCs - cleaner use of portmux calls Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi_bfin5xx.c111
1 files changed, 47 insertions, 64 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 759a6fc9b4d4..803c5b25db50 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -59,10 +59,9 @@ MODULE_LICENSE("GPL");
59 59
60#define DEFINE_SPI_REG(reg, off) \ 60#define DEFINE_SPI_REG(reg, off) \
61static inline u16 read_##reg(void) \ 61static inline u16 read_##reg(void) \
62 { return *(volatile unsigned short*)(SPI0_REGBASE + off); } \ 62 { return bfin_read16(SPI0_REGBASE + off); } \
63static inline void write_##reg(u16 v) \ 63static inline void write_##reg(u16 v) \
64 {*(volatile unsigned short*)(SPI0_REGBASE + off) = v;\ 64 {bfin_write16(SPI0_REGBASE + off, v); }
65 SSYNC();}
66 65
67DEFINE_SPI_REG(CTRL, 0x00) 66DEFINE_SPI_REG(CTRL, 0x00)
68DEFINE_SPI_REG(FLAG, 0x04) 67DEFINE_SPI_REG(FLAG, 0x04)
@@ -145,7 +144,6 @@ static void bfin_spi_enable(struct driver_data *drv_data)
145 144
146 cr = read_CTRL(); 145 cr = read_CTRL();
147 write_CTRL(cr | BIT_CTL_ENABLE); 146 write_CTRL(cr | BIT_CTL_ENABLE);
148 SSYNC();
149} 147}
150 148
151static void bfin_spi_disable(struct driver_data *drv_data) 149static void bfin_spi_disable(struct driver_data *drv_data)
@@ -154,7 +152,6 @@ static void bfin_spi_disable(struct driver_data *drv_data)
154 152
155 cr = read_CTRL(); 153 cr = read_CTRL();
156 write_CTRL(cr & (~BIT_CTL_ENABLE)); 154 write_CTRL(cr & (~BIT_CTL_ENABLE));
157 SSYNC();
158} 155}
159 156
160/* Caculate the SPI_BAUD register value based on input HZ */ 157/* Caculate the SPI_BAUD register value based on input HZ */
@@ -182,52 +179,44 @@ static int flush(struct driver_data *drv_data)
182 return limit; 179 return limit;
183} 180}
184 181
182#define MAX_SPI0_SSEL 7
183
185/* stop controller and re-config current chip*/ 184/* stop controller and re-config current chip*/
186static void restore_state(struct driver_data *drv_data) 185static int restore_state(struct driver_data *drv_data)
187{ 186{
188 struct chip_data *chip = drv_data->cur_chip; 187 struct chip_data *chip = drv_data->cur_chip;
188 int ret = 0;
189 u16 ssel[MAX_SPI0_SSEL] = {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
190 P_SPI0_SSEL4, P_SPI0_SSEL5,
191 P_SPI0_SSEL6, P_SPI0_SSEL7,};
189 192
190 /* Clear status and disable clock */ 193 /* Clear status and disable clock */
191 write_STAT(BIT_STAT_CLR); 194 write_STAT(BIT_STAT_CLR);
192 bfin_spi_disable(drv_data); 195 bfin_spi_disable(drv_data);
193 dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n"); 196 dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");
194 197
198 /* Load the registers */
199 write_CTRL(chip->ctl_reg);
200 write_BAUD(chip->baud);
201 write_FLAG(chip->flag);
202
195 if (!chip->chip_select_requested) { 203 if (!chip->chip_select_requested) {
204 int i = chip->chip_select_num;
196 205
197 dev_dbg(&drv_data->pdev->dev, 206 dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
198 "chip select number is %d\n", chip->chip_select_num); 207
199 208 if ((i > 0) && (i <= MAX_SPI0_SSEL))
200 switch (chip->chip_select_num) { 209 ret = peripheral_request(ssel[i-1], DRV_NAME);
201 case 1:
202 peripheral_request(P_SPI0_SSEL1, DRV_NAME);
203 break;
204 case 2:
205 peripheral_request(P_SPI0_SSEL2, DRV_NAME);
206 break;
207 case 3:
208 peripheral_request(P_SPI0_SSEL3, DRV_NAME);
209 break;
210 case 4:
211 peripheral_request(P_SPI0_SSEL4, DRV_NAME);
212 break;
213 case 5:
214 peripheral_request(P_SPI0_SSEL5, DRV_NAME);
215 break;
216 case 6:
217 peripheral_request(P_SPI0_SSEL6, DRV_NAME);
218 break;
219 case 7:
220 peripheral_request(P_SPI0_SSEL7, DRV_NAME);
221 break;
222 }
223 210
224 chip->chip_select_requested = 1; 211 chip->chip_select_requested = 1;
225 } 212 }
226 213
227 /* Load the registers */ 214 if (ret)
228 write_CTRL(chip->ctl_reg); 215 dev_dbg(&drv_data->pdev->dev,
229 write_BAUD(chip->baud); 216 ": request chip select number %d failed\n",
230 write_FLAG(chip->flag); 217 chip->chip_select_num);
218
219 return ret;
231} 220}
232 221
233/* used to kick off transfer in rx mode */ 222/* used to kick off transfer in rx mode */
@@ -285,7 +274,6 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
285 274
286 while (drv_data->tx < drv_data->tx_end) { 275 while (drv_data->tx < drv_data->tx_end) {
287 write_FLAG(chip->flag); 276 write_FLAG(chip->flag);
288 SSYNC();
289 277
290 write_TDBR(*(u8 *) (drv_data->tx)); 278 write_TDBR(*(u8 *) (drv_data->tx));
291 while (read_STAT() & BIT_STAT_TXS) 279 while (read_STAT() & BIT_STAT_TXS)
@@ -293,13 +281,13 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
293 while (!(read_STAT() & BIT_STAT_SPIF)) 281 while (!(read_STAT() & BIT_STAT_SPIF))
294 continue; 282 continue;
295 write_FLAG(0xFF00 | chip->flag); 283 write_FLAG(0xFF00 | chip->flag);
296 SSYNC(); 284
297 if (chip->cs_chg_udelay) 285 if (chip->cs_chg_udelay)
298 udelay(chip->cs_chg_udelay); 286 udelay(chip->cs_chg_udelay);
299 ++drv_data->tx; 287 ++drv_data->tx;
300 } 288 }
301 write_FLAG(0xFF00); 289 write_FLAG(0xFF00);
302 SSYNC(); 290
303} 291}
304 292
305static void u8_reader(struct driver_data *drv_data) 293static void u8_reader(struct driver_data *drv_data)
@@ -331,7 +319,6 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
331 319
332 while (drv_data->rx < drv_data->rx_end) { 320 while (drv_data->rx < drv_data->rx_end) {
333 write_FLAG(chip->flag); 321 write_FLAG(chip->flag);
334 SSYNC();
335 322
336 read_RDBR(); /* kick off */ 323 read_RDBR(); /* kick off */
337 while (!(read_STAT() & BIT_STAT_RXS)) 324 while (!(read_STAT() & BIT_STAT_RXS))
@@ -340,13 +327,13 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
340 continue; 327 continue;
341 *(u8 *) (drv_data->rx) = read_SHAW(); 328 *(u8 *) (drv_data->rx) = read_SHAW();
342 write_FLAG(0xFF00 | chip->flag); 329 write_FLAG(0xFF00 | chip->flag);
343 SSYNC(); 330
344 if (chip->cs_chg_udelay) 331 if (chip->cs_chg_udelay)
345 udelay(chip->cs_chg_udelay); 332 udelay(chip->cs_chg_udelay);
346 ++drv_data->rx; 333 ++drv_data->rx;
347 } 334 }
348 write_FLAG(0xFF00); 335 write_FLAG(0xFF00);
349 SSYNC(); 336
350} 337}
351 338
352static void u8_duplex(struct driver_data *drv_data) 339static void u8_duplex(struct driver_data *drv_data)
@@ -370,7 +357,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
370 357
371 while (drv_data->rx < drv_data->rx_end) { 358 while (drv_data->rx < drv_data->rx_end) {
372 write_FLAG(chip->flag); 359 write_FLAG(chip->flag);
373 SSYNC(); 360
374 361
375 write_TDBR(*(u8 *) (drv_data->tx)); 362 write_TDBR(*(u8 *) (drv_data->tx));
376 while (!(read_STAT() & BIT_STAT_SPIF)) 363 while (!(read_STAT() & BIT_STAT_SPIF))
@@ -379,14 +366,14 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
379 continue; 366 continue;
380 *(u8 *) (drv_data->rx) = read_RDBR(); 367 *(u8 *) (drv_data->rx) = read_RDBR();
381 write_FLAG(0xFF00 | chip->flag); 368 write_FLAG(0xFF00 | chip->flag);
382 SSYNC(); 369
383 if (chip->cs_chg_udelay) 370 if (chip->cs_chg_udelay)
384 udelay(chip->cs_chg_udelay); 371 udelay(chip->cs_chg_udelay);
385 ++drv_data->rx; 372 ++drv_data->rx;
386 ++drv_data->tx; 373 ++drv_data->tx;
387 } 374 }
388 write_FLAG(0xFF00); 375 write_FLAG(0xFF00);
389 SSYNC(); 376
390} 377}
391 378
392static void u16_writer(struct driver_data *drv_data) 379static void u16_writer(struct driver_data *drv_data)
@@ -412,7 +399,6 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
412 399
413 while (drv_data->tx < drv_data->tx_end) { 400 while (drv_data->tx < drv_data->tx_end) {
414 write_FLAG(chip->flag); 401 write_FLAG(chip->flag);
415 SSYNC();
416 402
417 write_TDBR(*(u16 *) (drv_data->tx)); 403 write_TDBR(*(u16 *) (drv_data->tx));
418 while ((read_STAT() & BIT_STAT_TXS)) 404 while ((read_STAT() & BIT_STAT_TXS))
@@ -420,13 +406,12 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
420 while (!(read_STAT() & BIT_STAT_SPIF)) 406 while (!(read_STAT() & BIT_STAT_SPIF))
421 continue; 407 continue;
422 write_FLAG(0xFF00 | chip->flag); 408 write_FLAG(0xFF00 | chip->flag);
423 SSYNC(); 409
424 if (chip->cs_chg_udelay) 410 if (chip->cs_chg_udelay)
425 udelay(chip->cs_chg_udelay); 411 udelay(chip->cs_chg_udelay);
426 drv_data->tx += 2; 412 drv_data->tx += 2;
427 } 413 }
428 write_FLAG(0xFF00); 414 write_FLAG(0xFF00);
429 SSYNC();
430} 415}
431 416
432static void u16_reader(struct driver_data *drv_data) 417static void u16_reader(struct driver_data *drv_data)
@@ -454,7 +439,6 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
454 439
455 while (drv_data->rx < drv_data->rx_end) { 440 while (drv_data->rx < drv_data->rx_end) {
456 write_FLAG(chip->flag); 441 write_FLAG(chip->flag);
457 SSYNC();
458 442
459 read_RDBR(); /* kick off */ 443 read_RDBR(); /* kick off */
460 while (!(read_STAT() & BIT_STAT_RXS)) 444 while (!(read_STAT() & BIT_STAT_RXS))
@@ -463,13 +447,12 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
463 continue; 447 continue;
464 *(u16 *) (drv_data->rx) = read_SHAW(); 448 *(u16 *) (drv_data->rx) = read_SHAW();
465 write_FLAG(0xFF00 | chip->flag); 449 write_FLAG(0xFF00 | chip->flag);
466 SSYNC(); 450
467 if (chip->cs_chg_udelay) 451 if (chip->cs_chg_udelay)
468 udelay(chip->cs_chg_udelay); 452 udelay(chip->cs_chg_udelay);
469 drv_data->rx += 2; 453 drv_data->rx += 2;
470 } 454 }
471 write_FLAG(0xFF00); 455 write_FLAG(0xFF00);
472 SSYNC();
473} 456}
474 457
475static void u16_duplex(struct driver_data *drv_data) 458static void u16_duplex(struct driver_data *drv_data)
@@ -493,7 +476,6 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
493 476
494 while (drv_data->tx < drv_data->tx_end) { 477 while (drv_data->tx < drv_data->tx_end) {
495 write_FLAG(chip->flag); 478 write_FLAG(chip->flag);
496 SSYNC();
497 479
498 write_TDBR(*(u16 *) (drv_data->tx)); 480 write_TDBR(*(u16 *) (drv_data->tx));
499 while (!(read_STAT() & BIT_STAT_SPIF)) 481 while (!(read_STAT() & BIT_STAT_SPIF))
@@ -502,14 +484,13 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
502 continue; 484 continue;
503 *(u16 *) (drv_data->rx) = read_RDBR(); 485 *(u16 *) (drv_data->rx) = read_RDBR();
504 write_FLAG(0xFF00 | chip->flag); 486 write_FLAG(0xFF00 | chip->flag);
505 SSYNC(); 487
506 if (chip->cs_chg_udelay) 488 if (chip->cs_chg_udelay)
507 udelay(chip->cs_chg_udelay); 489 udelay(chip->cs_chg_udelay);
508 drv_data->rx += 2; 490 drv_data->rx += 2;
509 drv_data->tx += 2; 491 drv_data->tx += 2;
510 } 492 }
511 write_FLAG(0xFF00); 493 write_FLAG(0xFF00);
512 SSYNC();
513} 494}
514 495
515/* test if ther is more transfer to be done */ 496/* test if ther is more transfer to be done */
@@ -811,7 +792,6 @@ static void pump_transfers(unsigned long data)
811 "IO duplex: cr is 0x%x\n", cr); 792 "IO duplex: cr is 0x%x\n", cr);
812 793
813 write_CTRL(cr); 794 write_CTRL(cr);
814 SSYNC();
815 795
816 drv_data->duplex(drv_data); 796 drv_data->duplex(drv_data);
817 797
@@ -826,7 +806,6 @@ static void pump_transfers(unsigned long data)
826 "IO write: cr is 0x%x\n", cr); 806 "IO write: cr is 0x%x\n", cr);
827 807
828 write_CTRL(cr); 808 write_CTRL(cr);
829 SSYNC();
830 809
831 drv_data->write(drv_data); 810 drv_data->write(drv_data);
832 811
@@ -841,7 +820,6 @@ static void pump_transfers(unsigned long data)
841 "IO read: cr is 0x%x\n", cr); 820 "IO read: cr is 0x%x\n", cr);
842 821
843 write_CTRL(cr); 822 write_CTRL(cr);
844 SSYNC();
845 823
846 drv_data->read(drv_data); 824 drv_data->read(drv_data);
847 if (drv_data->rx != drv_data->rx_end) 825 if (drv_data->rx != drv_data->rx_end)
@@ -892,6 +870,14 @@ static void pump_messages(struct work_struct *work)
892 /* Extract head of queue */ 870 /* Extract head of queue */
893 drv_data->cur_msg = list_entry(drv_data->queue.next, 871 drv_data->cur_msg = list_entry(drv_data->queue.next,
894 struct spi_message, queue); 872 struct spi_message, queue);
873
874 /* Setup the SSP using the per chip configuration */
875 drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
876 if (restore_state(drv_data)) {
877 spin_unlock_irqrestore(&drv_data->lock, flags);
878 return;
879 };
880
895 list_del_init(&drv_data->cur_msg->queue); 881 list_del_init(&drv_data->cur_msg->queue);
896 882
897 /* Initial message state */ 883 /* Initial message state */
@@ -899,13 +885,10 @@ static void pump_messages(struct work_struct *work)
899 drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, 885 drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
900 struct spi_transfer, transfer_list); 886 struct spi_transfer, transfer_list);
901 887
902 /* Setup the SSP using the per chip configuration */ 888 dev_dbg(&drv_data->pdev->dev, "got a message to pump, "
903 drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); 889 "state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
904 restore_state(drv_data); 890 drv_data->cur_chip->baud, drv_data->cur_chip->flag,
905 dev_dbg(&drv_data->pdev->dev, 891 drv_data->cur_chip->ctl_reg);
906 "got a message to pump, state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
907 drv_data->cur_chip->baud, drv_data->cur_chip->flag,
908 drv_data->cur_chip->ctl_reg);
909 892
910 dev_dbg(&drv_data->pdev->dev, 893 dev_dbg(&drv_data->pdev->dev,
911 "the first transfer len is %d\n", 894 "the first transfer len is %d\n",