diff options
Diffstat (limited to 'drivers/pinctrl/intel/pinctrl-intel.c')
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index cc3aaba24188..c7a71c49df0a 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -81,13 +81,16 @@ #define PADCFG1_TERM_MASK GENMASK(12, 10) #define PADCFG1_TERM_20K BIT(2) #define PADCFG1_TERM_5K BIT(1) +#define PADCFG1_TERM_4K (BIT(2) | BIT(1)) #define PADCFG1_TERM_1K BIT(0) +#define PADCFG1_TERM_952 (BIT(2) | BIT(0)) #define PADCFG1_TERM_833 (BIT(1) | BIT(0)) +#define PADCFG1_TERM_800 (BIT(2) | BIT(1) | BIT(0)) #define PADCFG2 0x008 -#define PADCFG2_DEBEN BIT(0) #define PADCFG2_DEBOUNCE_SHIFT 1 #define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1) +#define PADCFG2_DEBEN BIT(0) #define DEBOUNCE_PERIOD_NSEC 31250 @@ -369,7 +372,7 @@ static const char *intel_get_function_name(struct pinctrl_dev *pctldev, { struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->soc->functions[function].name; + return pctrl->soc->functions[function].func.name; } static int intel_get_function_groups(struct pinctrl_dev *pctldev, @@ -379,8 +382,8 @@ static int intel_get_function_groups(struct pinctrl_dev *pctldev, { struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - *groups = pctrl->soc->functions[function].groups; - *ngroups = pctrl->soc->functions[function].ngroups; + *groups = pctrl->soc->functions[function].func.groups; + *ngroups = pctrl->soc->functions[function].func.ngroups; return 0; } @@ -574,6 +577,9 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, case PADCFG1_TERM_1K: *arg = 1000; break; + case PADCFG1_TERM_4K: + *arg = 4000; + break; case PADCFG1_TERM_5K: *arg = 5000; break; @@ -599,6 +605,9 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, return -EINVAL; *arg = 1000; break; + case PADCFG1_TERM_4K: + *arg = 4000; + break; case PADCFG1_TERM_5K: *arg = 5000; break; @@ -691,21 +700,17 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, raw_spin_lock_irqsave(&pctrl->lock, flags); value = readl(padcfg1); + value &= ~(PADCFG1_TERM_MASK | PADCFG1_TERM_UP); + + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 5000; switch (param) { case PIN_CONFIG_BIAS_DISABLE: - value &= ~(PADCFG1_TERM_MASK | PADCFG1_TERM_UP); break; case PIN_CONFIG_BIAS_PULL_UP: - value &= ~PADCFG1_TERM_MASK; - - value |= PADCFG1_TERM_UP; - - /* Set default strength value in case none is given */ - if (arg == 1) - arg = 5000; - switch (arg) { case 20000: value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT; @@ -713,6 +718,9 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, case 5000: value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT; break; + case 4000: + value |= PADCFG1_TERM_4K << PADCFG1_TERM_SHIFT; + break; case 1000: value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT; break; @@ -721,17 +729,13 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, break; default: ret = -EINVAL; + break; } + value |= PADCFG1_TERM_UP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK); - - /* Set default strength value in case none is given */ - if (arg == 1) - arg = 5000; - switch (arg) { case 20000: value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT; @@ -739,6 +743,9 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, case 5000: value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT; break; + case 4000: + value |= PADCFG1_TERM_4K << PADCFG1_TERM_SHIFT; + break; case 1000: if (!(community->features & PINCTRL_FEATURE_1K_PD)) { ret = -EINVAL; @@ -755,9 +762,14 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, break; default: ret = -EINVAL; + break; } break; + + default: + ret = -EINVAL; + break; } if (!ret) @@ -1215,13 +1227,8 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, /* Only interrupts that are enabled */ pending &= enabled; - for_each_set_bit(gpp_offset, &pending, padgrp->size) { - unsigned int irq; - - irq = irq_find_mapping(gc->irq.domain, - padgrp->gpio_base + gpp_offset); - generic_handle_irq(irq); - } + for_each_set_bit(gpp_offset, &pending, padgrp->size) + generic_handle_domain_irq(gc->irq.domain, padgrp->gpio_base + gpp_offset); ret += pending ? 1 : 0; } @@ -1399,7 +1406,7 @@ static int intel_pinctrl_add_padgroups_by_gpps(struct intel_pinctrl *pctrl, for (i = 0; i < ngpps; i++) { gpps[i] = community->gpps[i]; - if (gpps[i].size > 32) + if (gpps[i].size > INTEL_PINCTRL_MAX_GPP_SIZE) return -EINVAL; /* Special treatment for GPIO base */ @@ -1417,7 +1424,7 @@ static int intel_pinctrl_add_padgroups_by_gpps(struct intel_pinctrl *pctrl, } gpps[i].padown_num = padown_num; - padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32); + padown_num += DIV_ROUND_UP(gpps[i].size * 4, INTEL_PINCTRL_MAX_GPP_SIZE); } community->gpps = gpps; @@ -1433,7 +1440,7 @@ static int intel_pinctrl_add_padgroups_by_size(struct intel_pinctrl *pctrl, unsigned int padown_num = 0; size_t i, ngpps = DIV_ROUND_UP(npins, community->gpp_size); - if (community->gpp_size > 32) + if (community->gpp_size > INTEL_PINCTRL_MAX_GPP_SIZE) return -EINVAL; gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL); @@ -1451,14 +1458,7 @@ static int intel_pinctrl_add_padgroups_by_size(struct intel_pinctrl *pctrl, gpps[i].gpio_base = gpps[i].base; gpps[i].padown_num = padown_num; - /* - * In older hardware the number of padown registers per - * group is fixed regardless of the group size. - */ - if (community->gpp_num_padown_regs) - padown_num += community->gpp_num_padown_regs; - else - padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32); + padown_num += community->gpp_num_padown_regs; } community->ngpps = ngpps; @@ -1709,6 +1709,12 @@ const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_ EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data); #ifdef CONFIG_PM_SLEEP +static bool __intel_gpio_is_direct_irq(u32 value) +{ + return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && + (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO); +} + static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) { const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); @@ -1742,8 +1748,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int * See https://bugzilla.kernel.org/show_bug.cgi?id=214749. */ value = readl(intel_get_padcfg(pctrl, pin, PADCFG0)); - if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && - (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO)) + if (__intel_gpio_is_direct_irq(value)) return true; return false; @@ -1873,7 +1878,12 @@ int intel_pinctrl_resume_noirq(struct device *dev) for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; - if (!intel_pinctrl_should_save(pctrl, desc->number)) + if (!(intel_pinctrl_should_save(pctrl, desc->number) || + /* + * If the firmware mangled the register contents too much, + * check the saved value for the Direct IRQ mode. + */ + __intel_gpio_is_direct_irq(pads[i].padcfg0))) continue; intel_restore_padcfg(pctrl, desc->number, PADCFG0, pads[i].padcfg0); |