diff options
Diffstat (limited to 'drivers/pinctrl/intel/pinctrl-intel.c')
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-intel.c | 364 |
1 files changed, 209 insertions, 155 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index d6f29e6faab7..527e4b87ae52 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -70,6 +70,12 @@ #define PADCFG0_PMODE_SHIFT 10 #define PADCFG0_PMODE_MASK GENMASK(13, 10) #define PADCFG0_PMODE_GPIO 0 +#define PADCFG0_GPIODIS_SHIFT 8 +#define PADCFG0_GPIODIS_MASK GENMASK(9, 8) +#define PADCFG0_GPIODIS_NONE 0 +#define PADCFG0_GPIODIS_OUTPUT 1 +#define PADCFG0_GPIODIS_INPUT 2 +#define PADCFG0_GPIODIS_FULL 3 #define PADCFG0_GPIORXDIS BIT(9) #define PADCFG0_GPIOTXDIS BIT(8) #define PADCFG0_GPIORXSTATE BIT(1) @@ -79,6 +85,18 @@ #define PADCFG1_TERM_UP BIT(13) #define PADCFG1_TERM_SHIFT 10 #define PADCFG1_TERM_MASK GENMASK(12, 10) +/* + * Bit 0 Bit 1 Bit 2 Value, Ohms + * + * 0 0 0 - + * 0 0 1 20000 + * 0 1 0 5000 + * 0 1 1 ~4000 + * 1 0 0 1000 (if supported) + * 1 0 1 ~952 (if supported) + * 1 1 0 ~833 (if supported) + * 1 1 1 ~800 (if supported) + */ #define PADCFG1_TERM_20K BIT(2) #define PADCFG1_TERM_5K BIT(1) #define PADCFG1_TERM_4K (BIT(2) | BIT(1)) @@ -108,13 +126,30 @@ struct intel_community_context { #define pin_to_padno(c, p) ((p) - (c)->pin_base) #define padgroup_offset(g, p) ((p) - (g)->base) -struct intel_community *intel_get_community(struct intel_pinctrl *pctrl, unsigned int pin) +#define for_each_intel_pin_community(pctrl, community) \ + for (unsigned int __ci = 0; \ + __ci < pctrl->ncommunities && (community = &pctrl->communities[__ci]); \ + __ci++) \ + +#define for_each_intel_community_pad_group(community, grp) \ + for (unsigned int __gi = 0; \ + __gi < community->ngpps && (grp = &community->gpps[__gi]); \ + __gi++) \ + +#define for_each_intel_pad_group(pctrl, community, grp) \ + for_each_intel_pin_community(pctrl, community) \ + for_each_intel_community_pad_group(community, grp) + +#define for_each_intel_gpio_group(pctrl, community, grp) \ + for_each_intel_pad_group(pctrl, community, grp) \ + if (grp->gpio_base == INTEL_GPIO_BASE_NOMAP) {} else + +const struct intel_community *intel_get_community(const struct intel_pinctrl *pctrl, + unsigned int pin) { - struct intel_community *community; - int i; + const struct intel_community *community; - for (i = 0; i < pctrl->ncommunities; i++) { - community = &pctrl->communities[i]; + for_each_intel_pin_community(pctrl, community) { if (pin >= community->pin_base && pin < community->pin_base + community->npins) return community; @@ -123,17 +158,15 @@ struct intel_community *intel_get_community(struct intel_pinctrl *pctrl, unsigne dev_warn(pctrl->dev, "failed to find community for pin %u\n", pin); return NULL; } -EXPORT_SYMBOL_NS_GPL(intel_get_community, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_community, "PINCTRL_INTEL"); static const struct intel_padgroup * intel_community_get_padgroup(const struct intel_community *community, unsigned int pin) { - int i; - - for (i = 0; i < community->ngpps; i++) { - const struct intel_padgroup *padgrp = &community->gpps[i]; + const struct intel_padgroup *padgrp; + for_each_intel_community_pad_group(community, padgrp) { if (pin >= padgrp->base && pin < padgrp->base + padgrp->size) return padgrp; } @@ -161,7 +194,7 @@ static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, return community->pad_regs + reg + padno * nregs * 4; } -static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned int pin) +static bool intel_pad_owned_by_host(const struct intel_pinctrl *pctrl, unsigned int pin) { const struct intel_community *community; const struct intel_padgroup *padgrp; @@ -186,7 +219,7 @@ static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned int pi return !(readl(padown) & PADOWN_MASK(gpp_offset)); } -static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin) +static bool intel_pad_acpi_mode(const struct intel_pinctrl *pctrl, unsigned int pin) { const struct intel_community *community; const struct intel_padgroup *padgrp; @@ -212,7 +245,6 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin) /** * enum - Locking variants of the pad configuration - * * @PAD_UNLOCKED: pad is fully controlled by the configuration registers * @PAD_LOCKED: pad configuration registers, except TX state, are locked * @PAD_LOCKED_TX: pad configuration TX state is locked @@ -229,9 +261,9 @@ enum { PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX, }; -static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin) +static int intel_pad_locked(const struct intel_pinctrl *pctrl, unsigned int pin) { - struct intel_community *community; + const struct intel_community *community; const struct intel_padgroup *padgrp; unsigned int offset, gpp_offset; u32 value; @@ -267,42 +299,42 @@ static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin) return ret; } -static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin) +static bool intel_pad_is_unlocked(const struct intel_pinctrl *pctrl, unsigned int pin) { return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED; } -static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin) +static bool intel_pad_usable(const struct intel_pinctrl *pctrl, unsigned int pin) { return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin); } int intel_get_groups_count(struct pinctrl_dev *pctldev) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->ngroups; } -EXPORT_SYMBOL_NS_GPL(intel_get_groups_count, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_groups_count, "PINCTRL_INTEL"); const char *intel_get_group_name(struct pinctrl_dev *pctldev, unsigned int group) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->groups[group].grp.name; } -EXPORT_SYMBOL_NS_GPL(intel_get_group_name, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_group_name, "PINCTRL_INTEL"); int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, const unsigned int **pins, unsigned int *npins) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); *pins = pctrl->soc->groups[group].grp.pins; *npins = pctrl->soc->groups[group].grp.npins; return 0; } -EXPORT_SYMBOL_NS_GPL(intel_get_group_pins, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_group_pins, "PINCTRL_INTEL"); static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int pin) @@ -364,30 +396,30 @@ static const struct pinctrl_ops intel_pinctrl_ops = { int intel_get_functions_count(struct pinctrl_dev *pctldev) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->nfunctions; } -EXPORT_SYMBOL_NS_GPL(intel_get_functions_count, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_functions_count, "PINCTRL_INTEL"); const char *intel_get_function_name(struct pinctrl_dev *pctldev, unsigned int function) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); return pctrl->soc->functions[function].func.name; } -EXPORT_SYMBOL_NS_GPL(intel_get_function_name, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_function_name, "PINCTRL_INTEL"); int intel_get_function_groups(struct pinctrl_dev *pctldev, unsigned int function, const char * const **groups, unsigned int * const ngroups) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); *groups = pctrl->soc->functions[function].func.groups; *ngroups = pctrl->soc->functions[function].func.ngroups; return 0; } -EXPORT_SYMBOL_NS_GPL(intel_get_function_groups, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_get_function_groups, "PINCTRL_INTEL"); static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, unsigned int group) @@ -429,19 +461,49 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, return 0; } -static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) -{ - u32 value; +/** + * enum - Possible pad physical connections + * @PAD_CONNECT_NONE: pad is fully disconnected + * @PAD_CONNECT_INPUT: pad is in input only mode + * @PAD_CONNECT_OUTPUT: pad is in output only mode + * @PAD_CONNECT_FULL: pad is fully connected + */ +enum { + PAD_CONNECT_NONE = 0, + PAD_CONNECT_INPUT = 1, + PAD_CONNECT_OUTPUT = 2, + PAD_CONNECT_FULL = PAD_CONNECT_INPUT | PAD_CONNECT_OUTPUT, +}; - value = readl(padcfg0); - if (input) { +static int __intel_gpio_get_direction(u32 value) +{ + switch ((value & PADCFG0_GPIODIS_MASK) >> PADCFG0_GPIODIS_SHIFT) { + case PADCFG0_GPIODIS_FULL: + return PAD_CONNECT_NONE; + case PADCFG0_GPIODIS_OUTPUT: + return PAD_CONNECT_INPUT; + case PADCFG0_GPIODIS_INPUT: + return PAD_CONNECT_OUTPUT; + case PADCFG0_GPIODIS_NONE: + return PAD_CONNECT_FULL; + default: + return -ENOTSUPP; + }; +} + +static u32 __intel_gpio_set_direction(u32 value, bool input, bool output) +{ + if (input) value &= ~PADCFG0_GPIORXDIS; - value |= PADCFG0_GPIOTXDIS; - } else { - value &= ~PADCFG0_GPIOTXDIS; + else value |= PADCFG0_GPIORXDIS; - } - writel(value, padcfg0); + + if (output) + value &= ~PADCFG0_GPIOTXDIS; + else + value |= PADCFG0_GPIOTXDIS; + + return value; } static int __intel_gpio_get_gpio_mode(u32 value) @@ -465,8 +527,7 @@ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) value |= PADCFG0_PMODE_GPIO; /* Disable TX buffer and enable RX (this will be input) */ - value &= ~PADCFG0_GPIORXDIS; - value |= PADCFG0_GPIOTXDIS; + value = __intel_gpio_set_direction(value, true, false); /* Disable SCI/SMI/NMI generation */ value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); @@ -512,12 +573,18 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, { struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); void __iomem *padcfg0; + u32 value; padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); guard(raw_spinlock_irqsave)(&pctrl->lock); - __intel_gpio_set_direction(padcfg0, input); + value = readl(padcfg0); + if (input) + value = __intel_gpio_set_direction(value, true, false); + else + value = __intel_gpio_set_direction(value, false, true); + writel(value, padcfg0); return 0; } @@ -612,6 +679,23 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, return 0; } +static int intel_config_get_high_impedance(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) +{ + void __iomem *padcfg0; + u32 value; + + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + + scoped_guard(raw_spinlock_irqsave, &pctrl->lock) + value = readl(padcfg0); + + if (__intel_gpio_get_direction(value) != PAD_CONNECT_NONE) + return -EINVAL; + + return 0; +} + static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin, enum pin_config_param param, u32 *arg) { @@ -655,6 +739,12 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, return ret; break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + ret = intel_config_get_high_impedance(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + case PIN_CONFIG_INPUT_DEBOUNCE: ret = intel_config_get_debounce(pctrl, pin, param, &arg); if (ret) @@ -753,11 +843,34 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, return 0; } +static void intel_gpio_set_high_impedance(struct intel_pinctrl *pctrl, unsigned int pin) +{ + void __iomem *padcfg0; + u32 value; + + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + + guard(raw_spinlock_irqsave)(&pctrl->lock); + + value = readl(padcfg0); + value = __intel_gpio_set_direction(value, false, false); + writel(value, padcfg0); +} + static int intel_config_set_debounce(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int debounce) { void __iomem *padcfg0, *padcfg2; u32 value0, value2; + unsigned long v; + + if (debounce) { + v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); + if (v < 3 || v > 15) + return -EINVAL; + } else { + v = 0; + } padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); if (!padcfg2) @@ -770,21 +883,15 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, value0 = readl(padcfg0); value2 = readl(padcfg2); - /* Disable glitch filter and debouncer */ - value0 &= ~PADCFG0_PREGFRXSEL; - value2 &= ~(PADCFG2_DEBEN | PADCFG2_DEBOUNCE_MASK); - - if (debounce) { - unsigned long v; - - v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); - if (v < 3 || v > 15) - return -EINVAL; - + value2 = (value2 & ~PADCFG2_DEBOUNCE_MASK) | (v << PADCFG2_DEBOUNCE_SHIFT); + if (v) { /* Enable glitch filter and debouncer */ value0 |= PADCFG0_PREGFRXSEL; - value2 |= v << PADCFG2_DEBOUNCE_SHIFT; value2 |= PADCFG2_DEBEN; + } else { + /* Disable glitch filter and debouncer */ + value0 &= ~PADCFG0_PREGFRXSEL; + value2 &= ~PADCFG2_DEBEN; } writel(value0, padcfg0); @@ -812,6 +919,10 @@ static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin, return ret; break; + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + intel_gpio_set_high_impedance(pctrl, pin); + break; + case PIN_CONFIG_INPUT_DEBOUNCE: ret = intel_config_set_debounce(pctrl, pin, pinconf_to_config_argument(configs[i])); @@ -854,34 +965,21 @@ static const struct pinctrl_desc intel_pinctrl_desc = { * Return: a pin number and pointers to the community and pad group, which * the pin belongs to, or negative error code if translation can't be done. */ -static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, +static int intel_gpio_to_pin(const struct intel_pinctrl *pctrl, unsigned int offset, const struct intel_community **community, const struct intel_padgroup **padgrp) { - int i; - - for (i = 0; i < pctrl->ncommunities; i++) { - const struct intel_community *comm = &pctrl->communities[i]; - int j; - - for (j = 0; j < comm->ngpps; j++) { - const struct intel_padgroup *pgrp = &comm->gpps[j]; - - if (pgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) - continue; + const struct intel_community *comm; + const struct intel_padgroup *grp; - if (offset >= pgrp->gpio_base && - offset < pgrp->gpio_base + pgrp->size) { - int pin; + for_each_intel_gpio_group(pctrl, comm, grp) { + if (offset >= grp->gpio_base && offset < grp->gpio_base + grp->size) { + if (community) + *community = comm; + if (padgrp) + *padgrp = grp; - pin = pgrp->base + offset - pgrp->gpio_base; - if (community) - *community = comm; - if (padgrp) - *padgrp = pgrp; - - return pin; - } + return grp->base + offset - grp->gpio_base; } } @@ -897,7 +995,7 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, * * Return: a GPIO offset, or negative error code if translation can't be done. */ -static int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin) +static int intel_pin_to_gpio(const struct intel_pinctrl *pctrl, int pin) { const struct intel_community *community; const struct intel_padgroup *padgrp; @@ -929,7 +1027,7 @@ static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset) return -EINVAL; padcfg0 = readl(reg); - if (!(padcfg0 & PADCFG0_GPIOTXDIS)) + if (__intel_gpio_get_direction(padcfg0) & PAD_CONNECT_OUTPUT) return !!(padcfg0 & PADCFG0_GPIOTXSTATE); return !!(padcfg0 & PADCFG0_GPIORXSTATE); @@ -982,10 +1080,10 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (padcfg0 & PADCFG0_PMODE_MASK) return -EINVAL; - if (padcfg0 & PADCFG0_GPIOTXDIS) - return GPIO_LINE_DIRECTION_IN; + if (__intel_gpio_get_direction(padcfg0) & PAD_CONNECT_OUTPUT) + return GPIO_LINE_DIRECTION_OUT; - return GPIO_LINE_DIRECTION_OUT; + return GPIO_LINE_DIRECTION_IN; } static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) @@ -1171,15 +1269,16 @@ static const struct irq_chip intel_gpio_irq_chip = { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; -static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, - const struct intel_community *community) +static irqreturn_t intel_gpio_irq(int irq, void *data) { - struct gpio_chip *gc = &pctrl->chip; - unsigned int gpp; + const struct intel_community *community; + const struct intel_padgroup *padgrp; + struct intel_pinctrl *pctrl = data; int ret = 0; - for (gpp = 0; gpp < community->ngpps; gpp++) { - const struct intel_padgroup *padgrp = &community->gpps[gpp]; + /* Need to check all communities for pending interrupts */ + for_each_intel_pad_group(pctrl, community, padgrp) { + struct gpio_chip *gc = &pctrl->chip; unsigned long pending, enabled; unsigned int gpp, gpp_offset; void __iomem *reg, *is; @@ -1203,36 +1302,17 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, ret += pending ? 1 : 0; } - return ret; -} - -static irqreturn_t intel_gpio_irq(int irq, void *data) -{ - const struct intel_community *community; - struct intel_pinctrl *pctrl = data; - unsigned int i; - int ret = 0; - - /* Need to check all communities for pending interrupts */ - for (i = 0; i < pctrl->ncommunities; i++) { - community = &pctrl->communities[i]; - ret += intel_gpio_community_irq_handler(pctrl, community); - } - return IRQ_RETVAL(ret); } static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) { - int i; + const struct intel_community *community; - for (i = 0; i < pctrl->ncommunities; i++) { - const struct intel_community *community; + for_each_intel_pin_community(pctrl, community) { void __iomem *reg, *is; unsigned int gpp; - community = &pctrl->communities[i]; - for (gpp = 0; gpp < community->ngpps; gpp++) { reg = community->regs + community->ie_offset + gpp * 4; is = community->regs + community->is_offset + gpp * 4; @@ -1257,36 +1337,17 @@ static int intel_gpio_irq_init_hw(struct gpio_chip *gc) return 0; } -static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl, - const struct intel_community *community) -{ - int ret = 0, i; - - for (i = 0; i < community->ngpps; i++) { - const struct intel_padgroup *gpp = &community->gpps[i]; - - if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP) - continue; - - ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), - gpp->gpio_base, gpp->base, - gpp->size); - if (ret) - return ret; - } - - return ret; -} - static int intel_gpio_add_pin_ranges(struct gpio_chip *gc) { struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - int ret, i; - - for (i = 0; i < pctrl->ncommunities; i++) { - struct intel_community *community = &pctrl->communities[i]; + const struct intel_community *community; + const struct intel_padgroup *grp; + int ret; - ret = intel_gpio_add_community_ranges(pctrl, community); + for_each_intel_gpio_group(pctrl, community, grp) { + ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), + grp->gpio_base, grp->base, + grp->size); if (ret) { dev_err(pctrl->dev, "failed to add GPIO pin range\n"); return ret; @@ -1299,20 +1360,12 @@ static int intel_gpio_add_pin_ranges(struct gpio_chip *gc) static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl) { const struct intel_community *community; + const struct intel_padgroup *grp; unsigned int ngpio = 0; - int i, j; - for (i = 0; i < pctrl->ncommunities; i++) { - community = &pctrl->communities[i]; - for (j = 0; j < community->ngpps; j++) { - const struct intel_padgroup *gpp = &community->gpps[j]; - - if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP) - continue; - - if (gpp->gpio_base + gpp->size > ngpio) - ngpio = gpp->gpio_base + gpp->size; - } + for_each_intel_gpio_group(pctrl, community, grp) { + if (grp->gpio_base + grp->size > ngpio) + ngpio = grp->gpio_base + grp->size; } return ngpio; @@ -1492,7 +1545,7 @@ static int intel_pinctrl_probe_pwm(struct intel_pinctrl *pctrl, .base_unit_bits = 22, .bypass = true, }; - struct pwm_lpss_chip *pwm; + struct pwm_chip *chip; if (!(community->features & PINCTRL_FEATURE_PWM)) return 0; @@ -1500,8 +1553,8 @@ static int intel_pinctrl_probe_pwm(struct intel_pinctrl *pctrl, if (!IS_REACHABLE(CONFIG_PWM_LPSS)) return 0; - pwm = devm_pwm_lpss_probe(pctrl->dev, community->regs + PWMC, &info); - return PTR_ERR_OR_ZERO(pwm); + chip = devm_pwm_lpss_probe(pctrl->dev, community->regs + PWMC, &info); + return PTR_ERR_OR_ZERO(chip); } int intel_pinctrl_probe(struct platform_device *pdev, @@ -1623,7 +1676,7 @@ int intel_pinctrl_probe(struct platform_device *pdev, return 0; } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe, "PINCTRL_INTEL"); int intel_pinctrl_probe_by_hid(struct platform_device *pdev) { @@ -1635,7 +1688,7 @@ int intel_pinctrl_probe_by_hid(struct platform_device *pdev) return intel_pinctrl_probe(pdev, data); } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_hid, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_hid, "PINCTRL_INTEL"); int intel_pinctrl_probe_by_uid(struct platform_device *pdev) { @@ -1647,7 +1700,7 @@ int intel_pinctrl_probe_by_uid(struct platform_device *pdev) return intel_pinctrl_probe(pdev, data); } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_uid, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_probe_by_uid, "PINCTRL_INTEL"); const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev) { @@ -1678,11 +1731,12 @@ const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_ return data ?: ERR_PTR(-ENODATA); } -EXPORT_SYMBOL_NS_GPL(intel_pinctrl_get_soc_data, PINCTRL_INTEL); +EXPORT_SYMBOL_NS_GPL(intel_pinctrl_get_soc_data, "PINCTRL_INTEL"); static bool __intel_gpio_is_direct_irq(u32 value) { - return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && + return (value & PADCFG0_GPIROUTIOXAPIC) && + (__intel_gpio_get_direction(value) == PAD_CONNECT_INPUT) && (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO); } |