Skip to content

Commit 659eaa0

Browse files
committed
Merge tag 'pinctrl-v6.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control fixes from Linus Walleij: - Concurrent register updates in the Qualcomm LPASS pin controller gets a proper lock. - revert a mutex fix that was causing problems: contention on the mutex or something of the sort lead to probe reordering and MMC block devices start to register in a different order, which unsuspecting userspace is not ready to handle * tag 'pinctrl-v6.6-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: Revert "pinctrl: avoid unsafe code pattern in find_pinctrl()" pinctrl: qcom: lpass-lpi: fix concurrent register updates
2 parents f617647 + 62140a1 commit 659eaa0

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

drivers/pinctrl/core.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,20 +1022,17 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev,
10221022

10231023
static struct pinctrl *find_pinctrl(struct device *dev)
10241024
{
1025-
struct pinctrl *entry, *p = NULL;
1025+
struct pinctrl *p;
10261026

10271027
mutex_lock(&pinctrl_list_mutex);
1028-
1029-
list_for_each_entry(entry, &pinctrl_list, node) {
1030-
if (entry->dev == dev) {
1031-
p = entry;
1032-
kref_get(&p->users);
1033-
break;
1028+
list_for_each_entry(p, &pinctrl_list, node)
1029+
if (p->dev == dev) {
1030+
mutex_unlock(&pinctrl_list_mutex);
1031+
return p;
10341032
}
1035-
}
10361033

10371034
mutex_unlock(&pinctrl_list_mutex);
1038-
return p;
1035+
return NULL;
10391036
}
10401037

10411038
static void pinctrl_free(struct pinctrl *p, bool inlist);
@@ -1143,6 +1140,7 @@ struct pinctrl *pinctrl_get(struct device *dev)
11431140
p = find_pinctrl(dev);
11441141
if (p) {
11451142
dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
1143+
kref_get(&p->users);
11461144
return p;
11471145
}
11481146

drivers/pinctrl/qcom/pinctrl-lpass-lpi.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ struct lpi_pinctrl {
3232
char __iomem *tlmm_base;
3333
char __iomem *slew_base;
3434
struct clk_bulk_data clks[MAX_LPI_NUM_CLKS];
35-
struct mutex slew_access_lock;
35+
/* Protects from concurrent register updates */
36+
struct mutex lock;
3637
DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
3738
const struct lpi_pinctrl_variant_data *data;
3839
};
@@ -103,6 +104,7 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
103104
if (WARN_ON(i == g->nfuncs))
104105
return -EINVAL;
105106

107+
mutex_lock(&pctrl->lock);
106108
val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG);
107109

108110
/*
@@ -128,6 +130,7 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
128130

129131
u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK);
130132
lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val);
133+
mutex_unlock(&pctrl->lock);
131134

132135
return 0;
133136
}
@@ -233,14 +236,14 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
233236
if (slew_offset == LPI_NO_SLEW)
234237
break;
235238

236-
mutex_lock(&pctrl->slew_access_lock);
239+
mutex_lock(&pctrl->lock);
237240

238241
sval = ioread32(pctrl->slew_base + LPI_SLEW_RATE_CTL_REG);
239242
sval &= ~(LPI_SLEW_RATE_MASK << slew_offset);
240243
sval |= arg << slew_offset;
241244
iowrite32(sval, pctrl->slew_base + LPI_SLEW_RATE_CTL_REG);
242245

243-
mutex_unlock(&pctrl->slew_access_lock);
246+
mutex_unlock(&pctrl->lock);
244247
break;
245248
default:
246249
return -EINVAL;
@@ -256,6 +259,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
256259
lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val);
257260
}
258261

262+
mutex_lock(&pctrl->lock);
259263
val = lpi_gpio_read(pctrl, group, LPI_GPIO_CFG_REG);
260264

261265
u32p_replace_bits(&val, pullup, LPI_GPIO_PULL_MASK);
@@ -264,6 +268,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
264268
u32p_replace_bits(&val, output_enabled, LPI_GPIO_OE_MASK);
265269

266270
lpi_gpio_write(pctrl, group, LPI_GPIO_CFG_REG, val);
271+
mutex_unlock(&pctrl->lock);
267272

268273
return 0;
269274
}
@@ -461,7 +466,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
461466
pctrl->chip.label = dev_name(dev);
462467
pctrl->chip.can_sleep = false;
463468

464-
mutex_init(&pctrl->slew_access_lock);
469+
mutex_init(&pctrl->lock);
465470

466471
pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl);
467472
if (IS_ERR(pctrl->ctrl)) {
@@ -483,7 +488,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
483488
return 0;
484489

485490
err_pinctrl:
486-
mutex_destroy(&pctrl->slew_access_lock);
491+
mutex_destroy(&pctrl->lock);
487492
clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
488493

489494
return ret;
@@ -495,7 +500,7 @@ int lpi_pinctrl_remove(struct platform_device *pdev)
495500
struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev);
496501
int i;
497502

498-
mutex_destroy(&pctrl->slew_access_lock);
503+
mutex_destroy(&pctrl->lock);
499504
clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
500505

501506
for (i = 0; i < pctrl->data->npins; i++)

0 commit comments

Comments
 (0)