Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Blackfin: bf538: pull gpio/port logic out of core hibernate paths

Re-architect how we save/restore the gpio/port logic that only pertains
to bf538/bf539 parts by pulling it out of the core code paths and pushing
it out to bf538-specific locations.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>

+65 -36
+4
arch/blackfin/include/asm/gpio.h
··· 119 119 #ifdef BFIN_SPECIAL_GPIO_BANKS 120 120 void bfin_special_gpio_free(unsigned gpio); 121 121 int bfin_special_gpio_request(unsigned gpio, const char *label); 122 + # ifdef CONFIG_PM 123 + void bfin_special_gpio_pm_hibernate_restore(void); 124 + void bfin_special_gpio_pm_hibernate_suspend(void); 125 + # endif 122 126 #endif 123 127 124 128 #ifdef CONFIG_PM
+22
arch/blackfin/kernel/bfin_gpio.c
··· 118 118 119 119 #if defined(CONFIG_PM) 120 120 static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; 121 + # ifdef BF538_FAMILY 122 + static unsigned short port_fer_saved[3]; 123 + # endif 121 124 #endif 122 125 123 126 static void gpio_error(unsigned gpio) ··· 607 604 { 608 605 int i, bank; 609 606 607 + #ifdef BF538_FAMILY 608 + for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i) 609 + port_fer_saved[i] = *port_fer[i]; 610 + #endif 611 + 610 612 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { 611 613 bank = gpio_bank(i); 612 614 ··· 633 625 gpio_bank_saved[bank].maska = gpio_array[bank]->maska; 634 626 } 635 627 628 + #ifdef BFIN_SPECIAL_GPIO_BANKS 629 + bfin_special_gpio_pm_hibernate_suspend(); 630 + #endif 631 + 636 632 AWA_DUMMY_READ(maska); 637 633 } 638 634 639 635 void bfin_gpio_pm_hibernate_restore(void) 640 636 { 641 637 int i, bank; 638 + 639 + #ifdef BF538_FAMILY 640 + for (i = 0; i < ARRAY_SIZE(port_fer_saved); ++i) 641 + *port_fer[i] = port_fer_saved[i]; 642 + #endif 642 643 643 644 for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { 644 645 bank = gpio_bank(i); ··· 670 653 gpio_array[bank]->both = gpio_bank_saved[bank].both; 671 654 gpio_array[bank]->maska = gpio_bank_saved[bank].maska; 672 655 } 656 + 657 + #ifdef BFIN_SPECIAL_GPIO_BANKS 658 + bfin_special_gpio_pm_hibernate_restore(); 659 + #endif 660 + 673 661 AWA_DUMMY_READ(maska); 674 662 } 675 663
+36 -1
arch/blackfin/mach-bf538/ext-gpio.c
··· 1 1 /* 2 2 * GPIOLIB interface for BF538/9 PORT C, D, and E GPIOs 3 3 * 4 - * Copyright 2009 Analog Devices Inc. 4 + * Copyright 2009-2011 Analog Devices Inc. 5 5 * 6 6 * Licensed under the GPL-2 or later. 7 7 */ ··· 121 121 gpiochip_add(&bf538_porte_chip); 122 122 } 123 123 arch_initcall(bf538_extgpio_setup); 124 + 125 + #ifdef CONFIG_PM 126 + static struct { 127 + u16 data, dir, inen; 128 + } gpio_bank_saved[3]; 129 + 130 + static void __iomem * const port_bases[3] = { 131 + (void *)PORTCIO, 132 + (void *)PORTDIO, 133 + (void *)PORTEIO, 134 + }; 135 + 136 + void bfin_special_gpio_pm_hibernate_suspend(void) 137 + { 138 + int i; 139 + 140 + for (i = 0; i < ARRAY_SIZE(port_bases); ++i) { 141 + gpio_bank_saved[i].data = read_PORTIO(port_bases[i]); 142 + gpio_bank_saved[i].inen = read_PORTIO_INEN(port_bases[i]); 143 + gpio_bank_saved[i].dir = read_PORTIO_DIR(port_bases[i]); 144 + } 145 + } 146 + 147 + void bfin_special_gpio_pm_hibernate_restore(void) 148 + { 149 + int i; 150 + 151 + for (i = 0; i < ARRAY_SIZE(port_bases); ++i) { 152 + write_PORTIO_INEN(port_bases[i], gpio_bank_saved[i].inen); 153 + write_PORTIO_SET(port_bases[i], 154 + gpio_bank_saved[i].data & gpio_bank_saved[i].dir); 155 + write_PORTIO_DIR(port_bases[i], gpio_bank_saved[i].dir); 156 + } 157 + } 158 + #endif
+3
arch/blackfin/mach-bf538/include/mach/gpio.h
··· 8 8 #define _MACH_GPIO_H_ 9 9 10 10 #define MAX_BLACKFIN_GPIOS 16 11 + #ifdef CONFIG_GPIOLIB 12 + /* We only use the special logic with GPIOLIB devices */ 11 13 #define BFIN_SPECIAL_GPIO_BANKS 3 14 + #endif 12 15 13 16 #define GPIO_PF0 0 /* PF */ 14 17 #define GPIO_PF1 1
-35
arch/blackfin/mach-common/dpmc_modes.S
··· 459 459 PM_PUSH_SYNC(9) 460 460 #endif 461 461 462 - #ifdef PORTCIO_FER 463 - /* 16bit loads can only be done with dregs */ 464 - PM_SYS_PUSH16(0, PORTCIO_DIR) 465 - PM_SYS_PUSH16(1, PORTCIO_INEN) 466 - PM_SYS_PUSH16(2, PORTCIO) 467 - PM_SYS_PUSH16(3, PORTCIO_FER) 468 - PM_SYS_PUSH16(4, PORTDIO_DIR) 469 - PM_SYS_PUSH16(5, PORTDIO_INEN) 470 - PM_SYS_PUSH16(6, PORTDIO) 471 - PM_SYS_PUSH16(7, PORTDIO_FER) 472 - PM_PUSH_SYNC(7) 473 - PM_SYS_PUSH16(0, PORTEIO_DIR) 474 - PM_SYS_PUSH16(1, PORTEIO_INEN) 475 - PM_SYS_PUSH16(2, PORTEIO) 476 - PM_SYS_PUSH16(3, PORTEIO_FER) 477 - PM_PUSH_SYNC(3) 478 - #endif 479 - 480 462 /* Save Core MMRs */ 481 463 I0.H = hi(COREMMR_BASE); 482 464 I0.L = lo(COREMMR_BASE); ··· 758 776 /* Restore System MMRs */ 759 777 FP.H = hi(SYSMMR_BASE); 760 778 FP.L = lo(SYSMMR_BASE); 761 - 762 - #ifdef PORTCIO_FER 763 - PM_POP_SYNC(3) 764 - PM_SYS_POP16(3, PORTEIO_FER) 765 - PM_SYS_POP16(2, PORTEIO) 766 - PM_SYS_POP16(1, PORTEIO_INEN) 767 - PM_SYS_POP16(0, PORTEIO_DIR) 768 - PM_POP_SYNC(7) 769 - PM_SYS_POP16(7, PORTDIO_FER) 770 - PM_SYS_POP16(6, PORTDIO) 771 - PM_SYS_POP16(5, PORTDIO_INEN) 772 - PM_SYS_POP16(4, PORTDIO_DIR) 773 - PM_SYS_POP16(3, PORTCIO_FER) 774 - PM_SYS_POP16(2, PORTCIO) 775 - PM_SYS_POP16(1, PORTCIO_INEN) 776 - PM_SYS_POP16(0, PORTCIO_DIR) 777 - #endif 778 779 779 780 #ifdef EBIU_FCTL 780 781 PM_POP_SYNC(12)