diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2007-10-10 04:58:49 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-10-10 04:58:49 -0400 |
commit | 2b39331a282c3a03415653d4e188910a11c9db8a (patch) | |
tree | 821b5cfd939eede49cb33f9d115fb986b93a3c48 /arch/blackfin/kernel/bfin_gpio.c | |
parent | 337d390b3a9c1ce92a12bdb77b9ae6ded6273b12 (diff) |
Blackfin arch: Comply with revised Anomaly Workarounds for BF533 05000311 and BF561 05000323
Comply with revised Anomaly Workarounds for BF533 05000311 and BF561 05000323
accoring to BF533 anomaly sheet Rev. A 09/04/07
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 177 |
1 files changed, 107 insertions, 70 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index b58b0de3c90..3fe0cd49e8d 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -88,6 +88,36 @@ | |||
88 | #include <asm/portmux.h> | 88 | #include <asm/portmux.h> |
89 | #include <linux/irq.h> | 89 | #include <linux/irq.h> |
90 | 90 | ||
91 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
92 | enum { | ||
93 | AWA_data = SYSCR, | ||
94 | AWA_data_clear = SYSCR, | ||
95 | AWA_data_set = SYSCR, | ||
96 | AWA_toggle = SYSCR, | ||
97 | AWA_maska = UART_SCR, | ||
98 | AWA_maska_clear = UART_SCR, | ||
99 | AWA_maska_set = UART_SCR, | ||
100 | AWA_maska_toggle = UART_SCR, | ||
101 | AWA_maskb = UART_GCTL, | ||
102 | AWA_maskb_clear = UART_GCTL, | ||
103 | AWA_maskb_set = UART_GCTL, | ||
104 | AWA_maskb_toggle = UART_GCTL, | ||
105 | AWA_dir = SPORT1_STAT, | ||
106 | AWA_polar = SPORT1_STAT, | ||
107 | AWA_edge = SPORT1_STAT, | ||
108 | AWA_both = SPORT1_STAT, | ||
109 | #if ANOMALY_05000311 | ||
110 | AWA_inen = TIMER_ENABLE, | ||
111 | #elif ANOMALY_05000323 | ||
112 | AWA_inen = DMA1_1_CONFIG, | ||
113 | #endif | ||
114 | }; | ||
115 | /* Anomaly Workaround */ | ||
116 | #define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name) | ||
117 | #else | ||
118 | #define AWA_DUMMY_READ(...) do { } while (0) | ||
119 | #endif | ||
120 | |||
91 | #ifdef BF533_FAMILY | 121 | #ifdef BF533_FAMILY |
92 | static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { | 122 | static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { |
93 | (struct gpio_port_t *) FIO_FLAG_D, | 123 | (struct gpio_port_t *) FIO_FLAG_D, |
@@ -332,10 +362,13 @@ inline u16 get_portmux(unsigned short portno) | |||
332 | static void default_gpio(unsigned short gpio) | 362 | static void default_gpio(unsigned short gpio) |
333 | { | 363 | { |
334 | unsigned short bank, bitmask; | 364 | unsigned short bank, bitmask; |
365 | unsigned long flags; | ||
335 | 366 | ||
336 | bank = gpio_bank(gpio); | 367 | bank = gpio_bank(gpio); |
337 | bitmask = gpio_bit(gpio); | 368 | bitmask = gpio_bit(gpio); |
338 | 369 | ||
370 | local_irq_save(flags); | ||
371 | |||
339 | gpio_bankb[bank]->maska_clear = bitmask; | 372 | gpio_bankb[bank]->maska_clear = bitmask; |
340 | gpio_bankb[bank]->maskb_clear = bitmask; | 373 | gpio_bankb[bank]->maskb_clear = bitmask; |
341 | SSYNC(); | 374 | SSYNC(); |
@@ -344,6 +377,9 @@ static void default_gpio(unsigned short gpio) | |||
344 | gpio_bankb[bank]->polar &= ~bitmask; | 377 | gpio_bankb[bank]->polar &= ~bitmask; |
345 | gpio_bankb[bank]->both &= ~bitmask; | 378 | gpio_bankb[bank]->both &= ~bitmask; |
346 | gpio_bankb[bank]->edge &= ~bitmask; | 379 | gpio_bankb[bank]->edge &= ~bitmask; |
380 | AWA_DUMMY_READ(edge); | ||
381 | local_irq_restore(flags); | ||
382 | |||
347 | } | 383 | } |
348 | #else | 384 | #else |
349 | # define default_gpio(...) do { } while (0) | 385 | # define default_gpio(...) do { } while (0) |
@@ -396,6 +432,7 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | |||
396 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ | 432 | gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ |
397 | else \ | 433 | else \ |
398 | gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ | 434 | gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ |
435 | AWA_DUMMY_READ(name); \ | ||
399 | local_irq_restore(flags); \ | 436 | local_irq_restore(flags); \ |
400 | } \ | 437 | } \ |
401 | EXPORT_SYMBOL(set_gpio_ ## name); | 438 | EXPORT_SYMBOL(set_gpio_ ## name); |
@@ -407,6 +444,22 @@ SET_GPIO(edge) | |||
407 | SET_GPIO(both) | 444 | SET_GPIO(both) |
408 | 445 | ||
409 | 446 | ||
447 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
448 | #define SET_GPIO_SC(name) \ | ||
449 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | ||
450 | { \ | ||
451 | unsigned long flags; \ | ||
452 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ | ||
453 | local_irq_save(flags); \ | ||
454 | if (arg) \ | ||
455 | gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ | ||
456 | else \ | ||
457 | gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ | ||
458 | AWA_DUMMY_READ(name); \ | ||
459 | local_irq_restore(flags); \ | ||
460 | } \ | ||
461 | EXPORT_SYMBOL(set_gpio_ ## name); | ||
462 | #else | ||
410 | #define SET_GPIO_SC(name) \ | 463 | #define SET_GPIO_SC(name) \ |
411 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | 464 | void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ |
412 | { \ | 465 | { \ |
@@ -417,37 +470,20 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ | |||
417 | gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ | 470 | gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ |
418 | } \ | 471 | } \ |
419 | EXPORT_SYMBOL(set_gpio_ ## name); | 472 | EXPORT_SYMBOL(set_gpio_ ## name); |
473 | #endif | ||
420 | 474 | ||
421 | SET_GPIO_SC(maska) | 475 | SET_GPIO_SC(maska) |
422 | SET_GPIO_SC(maskb) | 476 | SET_GPIO_SC(maskb) |
423 | |||
424 | #if ANOMALY_05000311 | ||
425 | void set_gpio_data(unsigned short gpio, unsigned short arg) | ||
426 | { | ||
427 | unsigned long flags; | ||
428 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | ||
429 | local_irq_save(flags); | ||
430 | if (arg) | ||
431 | gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); | ||
432 | else | ||
433 | gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); | ||
434 | bfin_read_CHIPID(); | ||
435 | local_irq_restore(flags); | ||
436 | } | ||
437 | EXPORT_SYMBOL(set_gpio_data); | ||
438 | #else | ||
439 | SET_GPIO_SC(data) | 477 | SET_GPIO_SC(data) |
440 | #endif | ||
441 | |||
442 | 478 | ||
443 | #if ANOMALY_05000311 | 479 | #if ANOMALY_05000311 || ANOMALY_05000323 |
444 | void set_gpio_toggle(unsigned short gpio) | 480 | void set_gpio_toggle(unsigned short gpio) |
445 | { | 481 | { |
446 | unsigned long flags; | 482 | unsigned long flags; |
447 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | 483 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); |
448 | local_irq_save(flags); | 484 | local_irq_save(flags); |
449 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); | 485 | gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); |
450 | bfin_read_CHIPID(); | 486 | AWA_DUMMY_READ(toggle); |
451 | local_irq_restore(flags); | 487 | local_irq_restore(flags); |
452 | } | 488 | } |
453 | #else | 489 | #else |
@@ -462,13 +498,27 @@ EXPORT_SYMBOL(set_gpio_toggle); | |||
462 | 498 | ||
463 | /*Set current PORT date (16-bit word)*/ | 499 | /*Set current PORT date (16-bit word)*/ |
464 | 500 | ||
501 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
465 | #define SET_GPIO_P(name) \ | 502 | #define SET_GPIO_P(name) \ |
466 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | 503 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ |
467 | { \ | 504 | { \ |
505 | unsigned long flags; \ | ||
506 | local_irq_save(flags); \ | ||
468 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | 507 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ |
508 | AWA_DUMMY_READ(name); \ | ||
509 | local_irq_restore(flags); \ | ||
469 | } \ | 510 | } \ |
470 | EXPORT_SYMBOL(set_gpiop_ ## name); | 511 | EXPORT_SYMBOL(set_gpiop_ ## name); |
512 | #else | ||
513 | #define SET_GPIO_P(name) \ | ||
514 | void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ | ||
515 | { \ | ||
516 | gpio_bankb[gpio_bank(gpio)]->name = arg; \ | ||
517 | } \ | ||
518 | EXPORT_SYMBOL(set_gpiop_ ## name); | ||
519 | #endif | ||
471 | 520 | ||
521 | SET_GPIO_P(data) | ||
472 | SET_GPIO_P(dir) | 522 | SET_GPIO_P(dir) |
473 | SET_GPIO_P(inen) | 523 | SET_GPIO_P(inen) |
474 | SET_GPIO_P(polar) | 524 | SET_GPIO_P(polar) |
@@ -478,31 +528,30 @@ SET_GPIO_P(maska) | |||
478 | SET_GPIO_P(maskb) | 528 | SET_GPIO_P(maskb) |
479 | 529 | ||
480 | 530 | ||
481 | #if ANOMALY_05000311 | ||
482 | void set_gpiop_data(unsigned short gpio, unsigned short arg) | ||
483 | { | ||
484 | unsigned long flags; | ||
485 | local_irq_save(flags); | ||
486 | gpio_bankb[gpio_bank(gpio)]->data = arg; | ||
487 | bfin_read_CHIPID(); | ||
488 | local_irq_restore(flags); | ||
489 | } | ||
490 | EXPORT_SYMBOL(set_gpiop_data); | ||
491 | #else | ||
492 | SET_GPIO_P(data) | ||
493 | #endif | ||
494 | |||
495 | |||
496 | |||
497 | /* Get a specific bit */ | 531 | /* Get a specific bit */ |
498 | 532 | #if ANOMALY_05000311 || ANOMALY_05000323 | |
533 | #define GET_GPIO(name) \ | ||
534 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | ||
535 | { \ | ||
536 | unsigned long flags; \ | ||
537 | unsigned short ret; \ | ||
538 | local_irq_save(flags); \ | ||
539 | ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ | ||
540 | AWA_DUMMY_READ(name); \ | ||
541 | local_irq_restore(flags); \ | ||
542 | return ret; \ | ||
543 | } \ | ||
544 | EXPORT_SYMBOL(get_gpio_ ## name); | ||
545 | #else | ||
499 | #define GET_GPIO(name) \ | 546 | #define GET_GPIO(name) \ |
500 | unsigned short get_gpio_ ## name(unsigned short gpio) \ | 547 | unsigned short get_gpio_ ## name(unsigned short gpio) \ |
501 | { \ | 548 | { \ |
502 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ | 549 | return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ |
503 | } \ | 550 | } \ |
504 | EXPORT_SYMBOL(get_gpio_ ## name); | 551 | EXPORT_SYMBOL(get_gpio_ ## name); |
552 | #endif | ||
505 | 553 | ||
554 | GET_GPIO(data) | ||
506 | GET_GPIO(dir) | 555 | GET_GPIO(dir) |
507 | GET_GPIO(inen) | 556 | GET_GPIO(inen) |
508 | GET_GPIO(polar) | 557 | GET_GPIO(polar) |
@@ -511,33 +560,31 @@ GET_GPIO(both) | |||
511 | GET_GPIO(maska) | 560 | GET_GPIO(maska) |
512 | GET_GPIO(maskb) | 561 | GET_GPIO(maskb) |
513 | 562 | ||
514 | |||
515 | #if ANOMALY_05000311 | ||
516 | unsigned short get_gpio_data(unsigned short gpio) | ||
517 | { | ||
518 | unsigned long flags; | ||
519 | unsigned short ret; | ||
520 | BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); | ||
521 | local_irq_save(flags); | ||
522 | ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); | ||
523 | bfin_read_CHIPID(); | ||
524 | local_irq_restore(flags); | ||
525 | return ret; | ||
526 | } | ||
527 | EXPORT_SYMBOL(get_gpio_data); | ||
528 | #else | ||
529 | GET_GPIO(data) | ||
530 | #endif | ||
531 | |||
532 | /*Get current PORT date (16-bit word)*/ | 563 | /*Get current PORT date (16-bit word)*/ |
533 | 564 | ||
565 | #if ANOMALY_05000311 || ANOMALY_05000323 | ||
566 | #define GET_GPIO_P(name) \ | ||
567 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | ||
568 | { \ | ||
569 | unsigned long flags; \ | ||
570 | unsigned short ret; \ | ||
571 | local_irq_save(flags); \ | ||
572 | ret = (gpio_bankb[gpio_bank(gpio)]->name); \ | ||
573 | AWA_DUMMY_READ(name); \ | ||
574 | local_irq_restore(flags); \ | ||
575 | return ret; \ | ||
576 | } \ | ||
577 | EXPORT_SYMBOL(get_gpiop_ ## name); | ||
578 | #else | ||
534 | #define GET_GPIO_P(name) \ | 579 | #define GET_GPIO_P(name) \ |
535 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ | 580 | unsigned short get_gpiop_ ## name(unsigned short gpio) \ |
536 | { \ | 581 | { \ |
537 | return (gpio_bankb[gpio_bank(gpio)]->name);\ | 582 | return (gpio_bankb[gpio_bank(gpio)]->name);\ |
538 | } \ | 583 | } \ |
539 | EXPORT_SYMBOL(get_gpiop_ ## name); | 584 | EXPORT_SYMBOL(get_gpiop_ ## name); |
585 | #endif | ||
540 | 586 | ||
587 | GET_GPIO_P(data) | ||
541 | GET_GPIO_P(dir) | 588 | GET_GPIO_P(dir) |
542 | GET_GPIO_P(inen) | 589 | GET_GPIO_P(inen) |
543 | GET_GPIO_P(polar) | 590 | GET_GPIO_P(polar) |
@@ -546,21 +593,6 @@ GET_GPIO_P(both) | |||
546 | GET_GPIO_P(maska) | 593 | GET_GPIO_P(maska) |
547 | GET_GPIO_P(maskb) | 594 | GET_GPIO_P(maskb) |
548 | 595 | ||
549 | #if ANOMALY_05000311 | ||
550 | unsigned short get_gpiop_data(unsigned short gpio) | ||
551 | { | ||
552 | unsigned long flags; | ||
553 | unsigned short ret; | ||
554 | local_irq_save(flags); | ||
555 | ret = gpio_bankb[gpio_bank(gpio)]->data; | ||
556 | bfin_read_CHIPID(); | ||
557 | local_irq_restore(flags); | ||
558 | return ret; | ||
559 | } | ||
560 | EXPORT_SYMBOL(get_gpiop_data); | ||
561 | #else | ||
562 | GET_GPIO_P(data) | ||
563 | #endif | ||
564 | 596 | ||
565 | #ifdef CONFIG_PM | 597 | #ifdef CONFIG_PM |
566 | /*********************************************************** | 598 | /*********************************************************** |
@@ -684,6 +716,8 @@ u32 gpio_pm_setup(void) | |||
684 | } | 716 | } |
685 | } | 717 | } |
686 | 718 | ||
719 | AWA_DUMMY_READ(maskb_set); | ||
720 | |||
687 | if (sic_iwr) | 721 | if (sic_iwr) |
688 | return sic_iwr; | 722 | return sic_iwr; |
689 | else | 723 | else |
@@ -715,6 +749,7 @@ void gpio_pm_restore(void) | |||
715 | 749 | ||
716 | gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; | 750 | gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; |
717 | } | 751 | } |
752 | AWA_DUMMY_READ(maskb); | ||
718 | } | 753 | } |
719 | 754 | ||
720 | #endif | 755 | #endif |
@@ -1089,6 +1124,7 @@ void gpio_direction_input(unsigned short gpio) | |||
1089 | local_irq_save(flags); | 1124 | local_irq_save(flags); |
1090 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); | 1125 | gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); |
1091 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); | 1126 | gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); |
1127 | AWA_DUMMY_READ(inen); | ||
1092 | local_irq_restore(flags); | 1128 | local_irq_restore(flags); |
1093 | } | 1129 | } |
1094 | EXPORT_SYMBOL(gpio_direction_input); | 1130 | EXPORT_SYMBOL(gpio_direction_input); |
@@ -1102,6 +1138,7 @@ void gpio_direction_output(unsigned short gpio) | |||
1102 | local_irq_save(flags); | 1138 | local_irq_save(flags); |
1103 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); | 1139 | gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); |
1104 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); | 1140 | gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); |
1141 | AWA_DUMMY_READ(dir); | ||
1105 | local_irq_restore(flags); | 1142 | local_irq_restore(flags); |
1106 | } | 1143 | } |
1107 | EXPORT_SYMBOL(gpio_direction_output); | 1144 | EXPORT_SYMBOL(gpio_direction_output); |