static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state) { int i; /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */ for (i = 0; i < pxa_last_gpio; i++) { if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && (GPDR(i) & GPIO_bit(i))) { if (GPLR(i) & GPIO_bit(i)) PGSR(i) |= GPIO_bit(i); else PGSR(i) &= ~GPIO_bit(i); } } for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { saved_gafr[0][i] = GAFR_L(i); saved_gafr[1][i] = GAFR_U(i); saved_gpdr[i] = GPDR(i * 32); saved_pgsr[i] = PGSR(i); GPDR(i * 32) = gpdr_lpm[i]; } return 0; }
static void pxa2xx_mfp_resume(void) { int i; for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { GAFR_L(i) = saved_gafr[0][i]; GAFR_U(i) = saved_gafr[1][i]; GPDR(i * 32) = saved_gpdr[i]; PGSR(i) = saved_pgsr[i]; } PSSR = PSSR_RDH | PSSR_PH; }
static int pxa2xx_mfp_resume(struct sys_device *d) { int i; for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { GAFR_L(i) = saved_gafr[0][i]; GAFR_U(i) = saved_gafr[1][i]; GPDR(i * 32) = saved_gpdr[i]; PGSR(i) = saved_pgsr[i]; } PSSR = PSSR_RDH | PSSR_PH; return 0; }
static int pxa2xx_mfp_suspend(void) { int i; /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */ for (i = 0; i < pxa_last_gpio; i++) { if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && (GPDR(i) & GPIO_bit(i))) { if (GPLR(i) & GPIO_bit(i)) PGSR(gpio_to_bank(i)) |= GPIO_bit(i); else PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i); } } for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { saved_gafr[0][i] = GAFR_L(i); saved_gafr[1][i] = GAFR_U(i); saved_gpdr[i] = GPDR(i * 32); saved_gplr[i] = GPLR(i * 32); saved_pgsr[i] = PGSR(i); GPSR(i * 32) = PGSR(i); GPCR(i * 32) = ~PGSR(i); } /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */ for (i = 0; i < pxa_last_gpio; i++) { if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) || ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i)))) GPDR(i) |= GPIO_bit(i); else GPDR(i) &= ~GPIO_bit(i); } return 0; }
static int __mfp_config_gpio(unsigned gpio, unsigned long c) { unsigned long gafr, mask = GPIO_bit(gpio); int bank = gpio_to_bank(gpio); int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */ int shft = (gpio & 0xf) << 1; int fn = MFP_AF(c); int is_out = (c & MFP_DIR_OUT) ? 1 : 0; if (fn > 3) return -EINVAL; /* alternate function and direction at run-time */ gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank); gafr = (gafr & ~(0x3 << shft)) | (fn << shft); if (uorl == 0) GAFR_L(bank) = gafr; else GAFR_U(bank) = gafr; if (is_out ^ gpio_desc[gpio].dir_inverted) GPDR(gpio) |= mask; else GPDR(gpio) &= ~mask; /* alternate function and direction at low power mode */ switch (c & MFP_LPM_STATE_MASK) { case MFP_LPM_DRIVE_HIGH: PGSR(bank) |= mask; is_out = 1; break; case MFP_LPM_DRIVE_LOW: PGSR(bank) &= ~mask; is_out = 1; break; case MFP_LPM_INPUT: case MFP_LPM_DEFAULT: break; default: /* warning and fall through, treat as MFP_LPM_DEFAULT */ pr_warning("%s: GPIO%d: unsupported low power mode\n", __func__, gpio); break; } if (is_out ^ gpio_desc[gpio].dir_inverted) gpdr_lpm[bank] |= mask; else gpdr_lpm[bank] &= ~mask; /* give early warning if MFP_LPM_CAN_WAKEUP is set on the * configurations of those pins not able to wakeup */ if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) { pr_warning("%s: GPIO%d unable to wakeup\n", __func__, gpio); return -EINVAL; } if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { pr_warning("%s: output GPIO%d unable to wakeup\n", __func__, gpio); return -EINVAL; } return 0; }
static int __mfp_config_gpio(unsigned gpio, unsigned long c) { unsigned long gafr, mask = GPIO_bit(gpio); int bank = gpio_to_bank(gpio); int uorl = !!(gpio & 0x10); int shft = (gpio & 0xf) << 1; int fn = MFP_AF(c); int is_out = (c & MFP_DIR_OUT) ? 1 : 0; if (fn > 3) return -EINVAL; gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank); gafr = (gafr & ~(0x3 << shft)) | (fn << shft); if (uorl == 0) GAFR_L(bank) = gafr; else GAFR_U(bank) = gafr; if (is_out ^ gpio_desc[gpio].dir_inverted) GPDR(gpio) |= mask; else GPDR(gpio) &= ~mask; switch (c & MFP_LPM_STATE_MASK) { case MFP_LPM_DRIVE_HIGH: PGSR(bank) |= mask; is_out = 1; break; case MFP_LPM_DRIVE_LOW: PGSR(bank) &= ~mask; is_out = 1; break; case MFP_LPM_INPUT: case MFP_LPM_DEFAULT: break; default: pr_warning("%s: GPIO%d: unsupported low power mode\n", __func__, gpio); break; } if (is_out ^ gpio_desc[gpio].dir_inverted) gpdr_lpm[bank] |= mask; else gpdr_lpm[bank] &= ~mask; if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) { pr_warning("%s: GPIO%d unable to wakeup\n", __func__, gpio); return -EINVAL; } if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { pr_warning("%s: output GPIO%d unable to wakeup\n", __func__, gpio); return -EINVAL; } return 0; }