Late pin control fixes for the v6.6 kernel cycle:
- Concurrent register updates in the Qualcomm LPASS pin controller gets a proper lock. - We 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. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmUy1N8ACgkQQRCzN7AZ XXM2RA/+IiRmsEc2zvyTRr2EYOe6oAxC9f515YYJnoRolt+FUbijWMvB8oB6zeJy dDByXxCercuX4y0nivRkL1G0B5QMi4OTfKPte26LxRFv6zm7brObHuK17HKnwIP7 sfLK+FT3jatl8PwwsUwc9ildXhdQ+JCD5yHarqDCqVVCiiqxINPu3GRWoDQHlDts lwyOPE2s0l6m29ms3NFM2lX13j/C7vwX+QMDWF2BZ8S0WEC7l7TYugvnBmt4zJ/6 +1h1E2nywBMd8YVCtMFRyoOhdxTxnuMSnotpHAqXH/NZ1f2c8SMilv6YLte9r6Yh BdjAFejRGF/L4uNgk65X4+3DTZbsiMWYkZXNO8zis4jAKCOo7giCvt5R45p0smul j1lAAJU5SwxUDP5Lm5IVdrSJtGj7ZcpsEJAyBRsbS1Yepqfb4S+J3F6xwz4TEp0K TCB4epS/G1Y2100PYzTdVZCrq/mbJCEYLtdmy8dFlIMh/EjZmPVNZw3VofdLgoyv VwpOtK0R8NMfxeuAQLrLs4WjxWEzf2DhbIBo8MmTI8SzdqbKHL8EwsXR5Cis09hB G2nnPpIJzTl8fKA9oGwiCCDpgxpXnmr5qh2VslCu9GpC3x2znbFxzFt8/1QU0QtT V7LnsJ3Xuy28bKscAHFNM1zPjBf8YZXLNyWVEHLUK4i///0JoFY= =CPHT -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
659eaa0015
@ -1022,20 +1022,17 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev,
|
||||
|
||||
static struct pinctrl *find_pinctrl(struct device *dev)
|
||||
{
|
||||
struct pinctrl *entry, *p = NULL;
|
||||
struct pinctrl *p;
|
||||
|
||||
mutex_lock(&pinctrl_list_mutex);
|
||||
|
||||
list_for_each_entry(entry, &pinctrl_list, node) {
|
||||
if (entry->dev == dev) {
|
||||
p = entry;
|
||||
kref_get(&p->users);
|
||||
break;
|
||||
list_for_each_entry(p, &pinctrl_list, node)
|
||||
if (p->dev == dev) {
|
||||
mutex_unlock(&pinctrl_list_mutex);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pinctrl_list_mutex);
|
||||
return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void pinctrl_free(struct pinctrl *p, bool inlist);
|
||||
@ -1143,6 +1140,7 @@ struct pinctrl *pinctrl_get(struct device *dev)
|
||||
p = find_pinctrl(dev);
|
||||
if (p) {
|
||||
dev_dbg(dev, "obtain a copy of previously claimed pinctrl\n");
|
||||
kref_get(&p->users);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,8 @@ struct lpi_pinctrl {
|
||||
char __iomem *tlmm_base;
|
||||
char __iomem *slew_base;
|
||||
struct clk_bulk_data clks[MAX_LPI_NUM_CLKS];
|
||||
struct mutex slew_access_lock;
|
||||
/* Protects from concurrent register updates */
|
||||
struct mutex lock;
|
||||
DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
|
||||
const struct lpi_pinctrl_variant_data *data;
|
||||
};
|
||||
@ -103,6 +104,7 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
|
||||
if (WARN_ON(i == g->nfuncs))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pctrl->lock);
|
||||
val = lpi_gpio_read(pctrl, pin, LPI_GPIO_CFG_REG);
|
||||
|
||||
/*
|
||||
@ -128,6 +130,7 @@ static int lpi_gpio_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
|
||||
|
||||
u32p_replace_bits(&val, i, LPI_GPIO_FUNCTION_MASK);
|
||||
lpi_gpio_write(pctrl, pin, LPI_GPIO_CFG_REG, val);
|
||||
mutex_unlock(&pctrl->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -233,14 +236,14 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
|
||||
if (slew_offset == LPI_NO_SLEW)
|
||||
break;
|
||||
|
||||
mutex_lock(&pctrl->slew_access_lock);
|
||||
mutex_lock(&pctrl->lock);
|
||||
|
||||
sval = ioread32(pctrl->slew_base + LPI_SLEW_RATE_CTL_REG);
|
||||
sval &= ~(LPI_SLEW_RATE_MASK << slew_offset);
|
||||
sval |= arg << slew_offset;
|
||||
iowrite32(sval, pctrl->slew_base + LPI_SLEW_RATE_CTL_REG);
|
||||
|
||||
mutex_unlock(&pctrl->slew_access_lock);
|
||||
mutex_unlock(&pctrl->lock);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -256,6 +259,7 @@ static int lpi_config_set(struct pinctrl_dev *pctldev, unsigned int group,
|
||||
lpi_gpio_write(pctrl, group, LPI_GPIO_VALUE_REG, val);
|
||||
}
|
||||
|
||||
mutex_lock(&pctrl->lock);
|
||||
val = lpi_gpio_read(pctrl, group, LPI_GPIO_CFG_REG);
|
||||
|
||||
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,
|
||||
u32p_replace_bits(&val, output_enabled, LPI_GPIO_OE_MASK);
|
||||
|
||||
lpi_gpio_write(pctrl, group, LPI_GPIO_CFG_REG, val);
|
||||
mutex_unlock(&pctrl->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -461,7 +466,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
|
||||
pctrl->chip.label = dev_name(dev);
|
||||
pctrl->chip.can_sleep = false;
|
||||
|
||||
mutex_init(&pctrl->slew_access_lock);
|
||||
mutex_init(&pctrl->lock);
|
||||
|
||||
pctrl->ctrl = devm_pinctrl_register(dev, &pctrl->desc, pctrl);
|
||||
if (IS_ERR(pctrl->ctrl)) {
|
||||
@ -483,7 +488,7 @@ int lpi_pinctrl_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
err_pinctrl:
|
||||
mutex_destroy(&pctrl->slew_access_lock);
|
||||
mutex_destroy(&pctrl->lock);
|
||||
clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
|
||||
|
||||
return ret;
|
||||
@ -495,7 +500,7 @@ int lpi_pinctrl_remove(struct platform_device *pdev)
|
||||
struct lpi_pinctrl *pctrl = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
mutex_destroy(&pctrl->slew_access_lock);
|
||||
mutex_destroy(&pctrl->lock);
|
||||
clk_bulk_disable_unprepare(MAX_LPI_NUM_CLKS, pctrl->clks);
|
||||
|
||||
for (i = 0; i < pctrl->data->npins; i++)
|
||||
|
Loading…
Reference in New Issue
Block a user