summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/intel/pinctrl-baytrail.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 18:50:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 18:50:03 +0000
commit01a69402cf9d38ff180345d55c2ee51c7e89fbc7 (patch)
treeb406c5242a088c4f59c6e4b719b783f43aca6ae9 /drivers/pinctrl/intel/pinctrl-baytrail.c
parentAdding upstream version 6.7.12. (diff)
downloadlinux-01a69402cf9d38ff180345d55c2ee51c7e89fbc7.tar.xz
linux-01a69402cf9d38ff180345d55c2ee51c7e89fbc7.zip
Adding upstream version 6.8.9.upstream/6.8.9
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/pinctrl/intel/pinctrl-baytrail.c')
-rw-r--r--drivers/pinctrl/intel/pinctrl-baytrail.c237
1 files changed, 95 insertions, 142 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index f1af21dbd5..ac97724c59 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -9,6 +9,7 @@
#include <linux/acpi.h>
#include <linux/array_size.h>
#include <linux/bitops.h>
+#include <linux/cleanup.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -587,10 +588,9 @@ static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
const struct intel_pingroup group,
unsigned int func)
{
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
for (i = 0; i < group.grp.npins; i++) {
void __iomem *padcfg0;
@@ -608,18 +608,15 @@ static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
value |= func;
writel(value, padcfg0);
}
-
- raw_spin_unlock_irqrestore(&byt_lock, flags);
}
static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
const struct intel_pingroup group,
const unsigned int *func)
{
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
for (i = 0; i < group.grp.npins; i++) {
void __iomem *padcfg0;
@@ -637,8 +634,6 @@ static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
value |= func[i];
writel(value, padcfg0);
}
-
- raw_spin_unlock_irqrestore(&byt_lock, flags);
}
static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
@@ -676,10 +671,10 @@ static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
{
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
- unsigned long flags;
u32 value;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
+
value = readl(reg);
/* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
@@ -687,7 +682,6 @@ static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int off
value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
writel(value, reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
}
static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
@@ -697,9 +691,8 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
u32 value, gpio_mux;
- unsigned long flags;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
/*
* In most cases, func pin mux 000 means GPIO function.
@@ -712,15 +705,14 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
*/
value = readl(reg) & BYT_PIN_MUX;
gpio_mux = byt_get_gpio_mux(vg, offset);
- if (gpio_mux != value) {
- value = readl(reg) & ~BYT_PIN_MUX;
- value |= gpio_mux;
- writel(value, reg);
+ if (gpio_mux == value)
+ return 0;
- dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset);
- }
+ value = readl(reg) & ~BYT_PIN_MUX;
+ value |= gpio_mux;
+ writel(value, reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
+ dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset);
return 0;
}
@@ -758,10 +750,9 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
{
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- unsigned long flags;
u32 value;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
value = readl(val_reg);
value &= ~BYT_DIR_MASK;
@@ -772,8 +763,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
writel(value, val_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
-
return 0;
}
@@ -810,6 +799,7 @@ static int byt_set_pull_strength(u32 *reg, u16 strength)
*reg &= ~BYT_PULL_STR_MASK;
switch (strength) {
+ case 1: /* Set default strength value in case none is given */
case 2000:
*reg |= BYT_PULL_STR_2K;
break;
@@ -829,6 +819,24 @@ static int byt_set_pull_strength(u32 *reg, u16 strength)
return 0;
}
+static void byt_gpio_force_input_mode(struct intel_pinctrl *vg, unsigned int offset)
+{
+ void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+ u32 value;
+
+ value = readl(reg);
+ if (!(value & BYT_INPUT_EN))
+ return;
+
+ /*
+ * Pull assignment is only applicable in input mode. If
+ * chip is not in input mode, set it and warn about it.
+ */
+ value &= ~BYT_INPUT_EN;
+ writel(value, reg);
+ dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
+}
+
static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
unsigned long *config)
{
@@ -837,15 +845,15 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
- unsigned long flags;
u32 conf, pull, val, debounce;
u16 arg = 0;
- raw_spin_lock_irqsave(&byt_lock, flags);
- conf = readl(conf_reg);
+ scoped_guard(raw_spinlock_irqsave, &byt_lock) {
+ conf = readl(conf_reg);
+ val = readl(val_reg);
+ }
+
pull = conf & BYT_PULL_ASSIGN_MASK;
- val = readl(val_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
@@ -872,9 +880,8 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
if (!(conf & BYT_DEBOUNCE_EN))
return -EINVAL;
- raw_spin_lock_irqsave(&byt_lock, flags);
- debounce = readl(db_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &byt_lock)
+ debounce = readl(db_reg);
switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
case BYT_DEBOUNCE_PULSE_375US:
@@ -919,18 +926,15 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
{
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
- void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
- u32 conf, val, db_pulse, debounce;
+ u32 conf, db_pulse, debounce;
enum pin_config_param param;
- unsigned long flags;
- int i, ret = 0;
+ int i, ret;
u32 arg;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
conf = readl(conf_reg);
- val = readl(val_reg);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
@@ -941,59 +945,30 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
conf &= ~BYT_PULL_ASSIGN_MASK;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- /* Set default strength value in case none is given */
- if (arg == 1)
- arg = 2000;
-
- /*
- * Pull assignment is only applicable in input mode. If
- * chip is not in input mode, set it and warn about it.
- */
- if (val & BYT_INPUT_EN) {
- val &= ~BYT_INPUT_EN;
- writel(val, val_reg);
- dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
- }
+ byt_gpio_force_input_mode(vg, offset);
conf &= ~BYT_PULL_ASSIGN_MASK;
conf |= BYT_PULL_ASSIGN_DOWN;
ret = byt_set_pull_strength(&conf, arg);
+ if (ret)
+ return ret;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- /* Set default strength value in case none is given */
- if (arg == 1)
- arg = 2000;
-
- /*
- * Pull assignment is only applicable in input mode. If
- * chip is not in input mode, set it and warn about it.
- */
- if (val & BYT_INPUT_EN) {
- val &= ~BYT_INPUT_EN;
- writel(val, val_reg);
- dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
- }
+ byt_gpio_force_input_mode(vg, offset);
conf &= ~BYT_PULL_ASSIGN_MASK;
conf |= BYT_PULL_ASSIGN_UP;
ret = byt_set_pull_strength(&conf, arg);
+ if (ret)
+ return ret;
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
- if (arg) {
- conf |= BYT_DEBOUNCE_EN;
- } else {
- conf &= ~BYT_DEBOUNCE_EN;
-
- /*
- * No need to update the pulse value.
- * Debounce is going to be disabled.
- */
- break;
- }
-
switch (arg) {
+ case 0:
+ db_pulse = 0;
+ break;
case 375:
db_pulse = BYT_DEBOUNCE_PULSE_375US;
break;
@@ -1016,33 +991,28 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
db_pulse = BYT_DEBOUNCE_PULSE_24MS;
break;
default:
- if (arg)
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
- if (ret)
- break;
+ if (db_pulse) {
+ debounce = readl(db_reg);
+ debounce = (debounce & ~BYT_DEBOUNCE_PULSE_MASK) | db_pulse;
+ writel(debounce, db_reg);
- debounce = readl(db_reg);
- debounce = (debounce & ~BYT_DEBOUNCE_PULSE_MASK) | db_pulse;
- writel(debounce, db_reg);
+ conf |= BYT_DEBOUNCE_EN;
+ } else {
+ conf &= ~BYT_DEBOUNCE_EN;
+ }
break;
default:
- ret = -ENOTSUPP;
+ return -ENOTSUPP;
}
-
- if (ret)
- break;
}
- if (!ret)
- writel(conf, conf_reg);
+ writel(conf, conf_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
-
- return ret;
+ return 0;
}
static const struct pinconf_ops byt_pinconf_ops = {
@@ -1062,12 +1032,10 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct intel_pinctrl *vg = gpiochip_get_data(chip);
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- unsigned long flags;
u32 val;
- raw_spin_lock_irqsave(&byt_lock, flags);
- val = readl(reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &byt_lock)
+ val = readl(reg);
return !!(val & BYT_LEVEL);
}
@@ -1075,35 +1043,34 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct intel_pinctrl *vg = gpiochip_get_data(chip);
- void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- unsigned long flags;
+ void __iomem *reg;
u32 old_val;
+ reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
if (!reg)
return;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
+
old_val = readl(reg);
if (value)
writel(old_val | BYT_LEVEL, reg);
else
writel(old_val & ~BYT_LEVEL, reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
}
static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
struct intel_pinctrl *vg = gpiochip_get_data(chip);
- void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- unsigned long flags;
+ void __iomem *reg;
u32 value;
+ reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
if (!reg)
return -EINVAL;
- raw_spin_lock_irqsave(&byt_lock, flags);
- value = readl(reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &byt_lock)
+ value = readl(reg);
if (!(value & BYT_OUTPUT_EN))
return GPIO_LINE_DIRECTION_OUT;
@@ -1117,17 +1084,15 @@ static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{
struct intel_pinctrl *vg = gpiochip_get_data(chip);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- unsigned long flags;
u32 reg;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
reg = readl(val_reg);
reg &= ~BYT_DIR_MASK;
reg |= BYT_OUTPUT_EN;
writel(reg, val_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0;
}
@@ -1142,10 +1107,9 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
{
struct intel_pinctrl *vg = gpiochip_get_data(chip);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- unsigned long flags;
u32 reg;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
byt_gpio_direct_irq_check(vg, offset);
@@ -1158,7 +1122,6 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
writel(reg, val_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0;
}
@@ -1173,8 +1136,6 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
void __iomem *conf_reg, *val_reg;
const char *pull_str = NULL;
const char *pull = NULL;
- unsigned long flags;
- const char *label;
unsigned int pin;
pin = vg->soc->pins[i].number;
@@ -1191,19 +1152,20 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
continue;
}
- raw_spin_lock_irqsave(&byt_lock, flags);
- conf0 = readl(conf_reg);
- val = readl(val_reg);
- raw_spin_unlock_irqrestore(&byt_lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &byt_lock) {
+ conf0 = readl(conf_reg);
+ val = readl(val_reg);
+ }
comm = intel_get_community(vg, pin);
if (!comm) {
seq_printf(s, "Pin %i: can't retrieve community\n", pin);
continue;
}
- label = gpiochip_is_requested(chip, i);
- if (!label)
- label = "Unrequested";
+
+ char *label __free(kfree) = gpiochip_dup_line_label(chip, i);
+ if (IS_ERR(label))
+ continue;
switch (conf0 & BYT_PULL_ASSIGN_MASK) {
case BYT_PULL_ASSIGN_UP:
@@ -1232,7 +1194,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
seq_printf(s,
" gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
pin,
- label,
+ label ?: "Unrequested",
val & BYT_INPUT_EN ? " " : "in",
val & BYT_OUTPUT_EN ? " " : "out",
str_hi_lo(val & BYT_LEVEL),
@@ -1278,9 +1240,9 @@ static void byt_irq_ack(struct irq_data *d)
if (!reg)
return;
- raw_spin_lock(&byt_lock);
+ guard(raw_spinlock)(&byt_lock);
+
writel(BIT(hwirq % 32), reg);
- raw_spin_unlock(&byt_lock);
}
static void byt_irq_mask(struct irq_data *d)
@@ -1298,7 +1260,6 @@ static void byt_irq_unmask(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_pinctrl *vg = gpiochip_get_data(gc);
irq_hw_number_t hwirq = irqd_to_hwirq(d);
- unsigned long flags;
void __iomem *reg;
u32 value;
@@ -1308,7 +1269,8 @@ static void byt_irq_unmask(struct irq_data *d)
if (!reg)
return;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
+
value = readl(reg);
switch (irqd_get_trigger_type(d)) {
@@ -1330,23 +1292,21 @@ static void byt_irq_unmask(struct irq_data *d)
}
writel(value, reg);
-
- raw_spin_unlock_irqrestore(&byt_lock, flags);
}
static int byt_irq_type(struct irq_data *d, unsigned int type)
{
struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
irq_hw_number_t hwirq = irqd_to_hwirq(d);
- u32 value;
- unsigned long flags;
void __iomem *reg;
+ u32 value;
reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
if (!reg)
return -EINVAL;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
+
value = readl(reg);
WARN(value & BYT_DIRECT_IRQ_EN,
@@ -1368,8 +1328,6 @@ static int byt_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(&byt_lock, flags);
-
return 0;
}
@@ -1401,9 +1359,8 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
continue;
}
- raw_spin_lock(&byt_lock);
- pending = readl(reg);
- raw_spin_unlock(&byt_lock);
+ scoped_guard(raw_spinlock, &byt_lock)
+ pending = readl(reg);
for_each_set_bit(pin, &pending, 32)
generic_handle_domain_irq(vg->chip.irq.domain, base + pin);
}
@@ -1666,10 +1623,9 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
static int byt_gpio_suspend(struct device *dev)
{
struct intel_pinctrl *vg = dev_get_drvdata(dev);
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
for (i = 0; i < vg->soc->npins; i++) {
void __iomem *reg;
@@ -1693,17 +1649,15 @@ static int byt_gpio_suspend(struct device *dev)
vg->context.pads[i].val = value;
}
- raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0;
}
static int byt_gpio_resume(struct device *dev)
{
struct intel_pinctrl *vg = dev_get_drvdata(dev);
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(&byt_lock, flags);
+ guard(raw_spinlock_irqsave)(&byt_lock);
for (i = 0; i < vg->soc->npins; i++) {
void __iomem *reg;
@@ -1743,7 +1697,6 @@ static int byt_gpio_resume(struct device *dev)
}
}
- raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0;
}