summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/intel/pinctrl-intel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/intel/pinctrl-intel.c')
-rw-r--r--drivers/pinctrl/intel/pinctrl-intel.c194
1 files changed, 81 insertions, 113 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
index 999f453344d2..b19527a8728e 100644
--- a/drivers/pinctrl/intel/pinctrl-intel.c
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
@@ -8,6 +8,7 @@
*/
#include <linux/acpi.h>
+#include <linux/cleanup.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/log2.h>
@@ -393,20 +394,17 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev,
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
const struct intel_pingroup *grp = &pctrl->soc->groups[group];
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
/*
* All pins in the groups needs to be accessible and writable
* before we can enable the mux for this group.
*/
for (i = 0; i < grp->grp.npins; i++) {
- if (!intel_pad_usable(pctrl, grp->grp.pins[i])) {
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ if (!intel_pad_usable(pctrl, grp->grp.pins[i]))
return -EBUSY;
- }
}
/* Now enable the mux setting for each pin in the group */
@@ -428,8 +426,6 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev,
writel(value, padcfg0);
}
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
-
return 0;
}
@@ -485,21 +481,16 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg0;
- unsigned long flags;
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
- if (!intel_pad_owned_by_host(pctrl, pin)) {
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ if (!intel_pad_owned_by_host(pctrl, pin))
return -EBUSY;
- }
- if (!intel_pad_is_unlocked(pctrl, pin)) {
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ if (!intel_pad_is_unlocked(pctrl, pin))
return 0;
- }
/*
* If pin is already configured in GPIO mode, we assume that
@@ -507,15 +498,11 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev,
* potential glitches on the pin. Otherwise, for the pin in
* alternative mode, consumer has to supply respective flags.
*/
- if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) {
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO)
return 0;
- }
intel_gpio_set_gpio_mode(padcfg0);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
-
return 0;
}
@@ -525,13 +512,12 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev,
{
struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
void __iomem *padcfg0;
- unsigned long flags;
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
+
__intel_gpio_set_direction(padcfg0, input);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
return 0;
}
@@ -548,17 +534,13 @@ static const struct pinmux_ops intel_pinmux_ops = {
static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
enum pin_config_param param, u32 *arg)
{
- const struct intel_community *community;
void __iomem *padcfg1;
- unsigned long flags;
u32 value, term;
- community = intel_get_community(pctrl, pin);
padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
- raw_spin_lock_irqsave(&pctrl->lock, flags);
- value = readl(padcfg1);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &pctrl->lock)
+ value = readl(padcfg1);
term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT;
@@ -592,7 +574,9 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_DOWN: {
+ const struct intel_community *community = intel_get_community(pctrl, pin);
+
if (!term || value & PADCFG1_TERM_UP)
return -EINVAL;
@@ -619,6 +603,7 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
}
break;
+ }
default:
return -EINVAL;
@@ -631,7 +616,6 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p
enum pin_config_param param, u32 *arg)
{
void __iomem *padcfg2;
- unsigned long flags;
unsigned long v;
u32 value2;
@@ -639,9 +623,9 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p
if (!padcfg2)
return -ENOTSUPP;
- raw_spin_lock_irqsave(&pctrl->lock, flags);
- value2 = readl(padcfg2);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &pctrl->lock)
+ value2 = readl(padcfg2);
+
if (!(value2 & PADCFG2_DEBEN))
return -EINVAL;
@@ -690,19 +674,8 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
{
unsigned int param = pinconf_to_config_param(config);
unsigned int arg = pinconf_to_config_argument(config);
- const struct intel_community *community;
+ u32 term = 0, up = 0, value;
void __iomem *padcfg1;
- unsigned long flags;
- int ret = 0;
- u32 value;
-
- community = intel_get_community(pctrl, pin);
- padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
-
- 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)
@@ -715,78 +688,77 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
case PIN_CONFIG_BIAS_PULL_UP:
switch (arg) {
case 20000:
- value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_20K;
break;
case 5000:
- value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_5K;
break;
case 4000:
- value |= PADCFG1_TERM_4K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_4K;
break;
case 1000:
- value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_1K;
break;
case 833:
- value |= PADCFG1_TERM_833 << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_833;
break;
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
- value |= PADCFG1_TERM_UP;
+ up = PADCFG1_TERM_UP;
break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_DOWN: {
+ const struct intel_community *community = intel_get_community(pctrl, pin);
+
switch (arg) {
case 20000:
- value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_20K;
break;
case 5000:
- value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_5K;
break;
case 4000:
- value |= PADCFG1_TERM_4K << PADCFG1_TERM_SHIFT;
+ term = PADCFG1_TERM_4K;
break;
case 1000:
- if (!(community->features & PINCTRL_FEATURE_1K_PD)) {
- ret = -EINVAL;
- break;
- }
- value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT;
+ if (!(community->features & PINCTRL_FEATURE_1K_PD))
+ return -EINVAL;
+ term = PADCFG1_TERM_1K;
break;
case 833:
- if (!(community->features & PINCTRL_FEATURE_1K_PD)) {
- ret = -EINVAL;
- break;
- }
- value |= PADCFG1_TERM_833 << PADCFG1_TERM_SHIFT;
+ if (!(community->features & PINCTRL_FEATURE_1K_PD))
+ return -EINVAL;
+ term = PADCFG1_TERM_833;
break;
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
break;
+ }
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
- if (!ret)
- writel(value, padcfg1);
+ padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
- return ret;
+ value = readl(padcfg1);
+ value = (value & ~PADCFG1_TERM_MASK) | (term << PADCFG1_TERM_SHIFT);
+ value = (value & ~PADCFG1_TERM_UP) | up;
+ writel(value, padcfg1);
+
+ return 0;
}
static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
unsigned int pin, unsigned int debounce)
{
void __iomem *padcfg0, *padcfg2;
- unsigned long flags;
u32 value0, value2;
padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2);
@@ -795,7 +767,7 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
value0 = readl(padcfg0);
value2 = readl(padcfg2);
@@ -808,10 +780,8 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
unsigned long v;
v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC);
- if (v < 3 || v > 15) {
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ if (v < 3 || v > 15)
return -EINVAL;
- }
/* Enable glitch filter and debouncer */
value0 |= PADCFG0_PREGFRXSEL;
@@ -822,8 +792,6 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
writel(value0, padcfg0);
writel(value2, padcfg2);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
-
return 0;
}
@@ -973,7 +941,6 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
- unsigned long flags;
void __iomem *reg;
u32 padcfg0;
int pin;
@@ -986,20 +953,19 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset,
if (!reg)
return;
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
+
padcfg0 = readl(reg);
if (value)
padcfg0 |= PADCFG0_GPIOTXSTATE;
else
padcfg0 &= ~PADCFG0_GPIOTXSTATE;
writel(padcfg0, reg);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
- unsigned long flags;
void __iomem *reg;
u32 padcfg0;
int pin;
@@ -1012,9 +978,9 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
if (!reg)
return -EINVAL;
- raw_spin_lock_irqsave(&pctrl->lock, flags);
- padcfg0 = readl(reg);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &pctrl->lock)
+ padcfg0 = readl(reg);
+
if (padcfg0 & PADCFG0_PMODE_MASK)
return -EINVAL;
@@ -1058,15 +1024,17 @@ static void intel_gpio_irq_ack(struct irq_data *d)
pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
if (pin >= 0) {
- unsigned int gpp, gpp_offset, is_offset;
+ unsigned int gpp, gpp_offset;
+ void __iomem *is;
gpp = padgrp->reg_num;
gpp_offset = padgroup_offset(padgrp, pin);
- is_offset = community->is_offset + gpp * 4;
- raw_spin_lock(&pctrl->lock);
- writel(BIT(gpp_offset), community->regs + is_offset);
- raw_spin_unlock(&pctrl->lock);
+ is = community->regs + community->is_offset + gpp * 4;
+
+ guard(raw_spinlock)(&pctrl->lock);
+
+ writel(BIT(gpp_offset), is);
}
}
@@ -1080,7 +1048,6 @@ static void intel_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwi
pin = intel_gpio_to_pin(pctrl, hwirq, &community, &padgrp);
if (pin >= 0) {
unsigned int gpp, gpp_offset;
- unsigned long flags;
void __iomem *reg, *is;
u32 value;
@@ -1090,7 +1057,7 @@ static void intel_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwi
reg = community->regs + community->ie_offset + gpp * 4;
is = community->regs + community->is_offset + gpp * 4;
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
/* Clear interrupt status first to avoid unexpected interrupt */
writel(BIT(gpp_offset), is);
@@ -1101,7 +1068,6 @@ static void intel_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwi
else
value |= BIT(gpp_offset);
writel(value, reg);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
}
@@ -1129,7 +1095,6 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL);
u32 rxevcfg, rxinv, value;
- unsigned long flags;
void __iomem *reg;
reg = intel_get_padcfg(pctrl, pin, PADCFG0);
@@ -1163,7 +1128,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
else
rxinv = 0;
- raw_spin_lock_irqsave(&pctrl->lock, flags);
+ guard(raw_spinlock_irqsave)(&pctrl->lock);
intel_gpio_set_gpio_mode(reg);
@@ -1179,8 +1144,6 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
else if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_handler_locked(d, handle_level_irq);
- raw_spin_unlock_irqrestore(&pctrl->lock, flags);
-
return 0;
}
@@ -1219,16 +1182,19 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
for (gpp = 0; gpp < community->ngpps; gpp++) {
const struct intel_padgroup *padgrp = &community->gpps[gpp];
- unsigned long pending, enabled, gpp_offset;
+ unsigned long pending, enabled;
+ unsigned int gpp, gpp_offset;
+ void __iomem *reg, *is;
- raw_spin_lock(&pctrl->lock);
+ gpp = padgrp->reg_num;
- pending = readl(community->regs + community->is_offset +
- padgrp->reg_num * 4);
- enabled = readl(community->regs + community->ie_offset +
- padgrp->reg_num * 4);
+ reg = community->regs + community->ie_offset + gpp * 4;
+ is = community->regs + community->is_offset + gpp * 4;
- raw_spin_unlock(&pctrl->lock);
+ scoped_guard(raw_spinlock, &pctrl->lock) {
+ pending = readl(is);
+ enabled = readl(reg);
+ }
/* Only interrupts that are enabled */
pending &= enabled;
@@ -1264,16 +1230,18 @@ static void intel_gpio_irq_init(struct intel_pinctrl *pctrl)
for (i = 0; i < pctrl->ncommunities; i++) {
const struct intel_community *community;
- void __iomem *base;
+ void __iomem *reg, *is;
unsigned int gpp;
community = &pctrl->communities[i];
- base = community->regs;
for (gpp = 0; gpp < community->ngpps; gpp++) {
+ reg = community->regs + community->ie_offset + gpp * 4;
+ is = community->regs + community->is_offset + gpp * 4;
+
/* Mask and clear all interrupts */
- writel(0, base + community->ie_offset + gpp * 4);
- writel(0xffff, base + community->is_offset + gpp * 4);
+ writel(0, reg);
+ writel(0xffff, is);
}
}
}