mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
gpio fixes for v6.19-rc8
- don't call into pinctrl when setting direction in gpio-rockchip as it's
not needed and may trigger locking context errors
- change spinlock to raw_spinlock in gpio-sprd
- fix a use-after-free bug in gpio-virtuser
- don't register a driver from another driver's probe() in gpio-omap
- fix int width problems in GPIO ACPI code
- fix interrupt-to-pin mapping in gpio-brcmstb
- mask interrupts in irq shutdown in gpio-pca953x
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEkeUTLeW1Rh17omX8BZ0uy/82hMMFAml8lz4ACgkQBZ0uy/82
hMN1KQ/+Imlv9lyge+IFUqX5lH1frlrNNKRIHKY9Mo5c1T0/HyqSHR/kD7TQbC8P
RP/N4lSx1bt0Myfo6KyCqfQPH/UwgM1Opt2debU+TxtW8Bep+FPS/WzdU6yKCENA
r71VW7rzDb3LcZ8irDzir6gYq3hTogaQ9POVHThMJAtZ/o/IlBjDe4YGW3cU2Brc
XVu5vyjeCQjg+Qs4/1/fATSlSK0eWqUZd/sitFhZynIdoDX6tWTkQnmDrJ4N10zc
XF78DXa+x5jI3qPoSJnOH0q8BMcU0TORVEpMx8zI1uhp88mMQjEvD97Zc0SHLytQ
p9xgke845n7IFCywHAOc/TmuRHLHi98QsY6PW1rbm2HsO8X3GRyuCgpMWLSzNNeb
rldlVFPFJpzFzzhxoWPh6mTItlFUSVO6M7JYzJxMMuYeM/2WOXeTN1S11AeqJqiF
bfKETHOLH/0EK5bokIo6BEaHmUgCm7LQ5dzLyDt1s3AsCEXWJFiM+nqkpXz6FkbB
up+GFnADfQMPQ/5EYJgv5Pz7qpXuzoxVy8ra06k70USpdgr/EILtRLbjlZZqtP8w
qHqmqH0fcXue8uHH2Pe2tgIatOEuYlGOJ20bTfT2q1g8zCIYl46eyimoLy/wRZhS
GRBB0mDGqIECEy5L3LHaMMiLeoaxVqTCMdMuDE0hvjP0LaWeNqo=
=KCJE
-----END PGP SIGNATURE-----
Merge tag 'gpio-fixes-for-v6.19-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio fixes from Bartosz Golaszewski:
"Over the last week I received quite an unexpected (for rc7) number of
fixes but they are all pretty small and mostly limited to drivers:
- don't call into pinctrl when setting direction in gpio-rockchip as
it's not needed and may trigger locking context errors
- change spinlock to raw_spinlock in gpio-sprd
- fix a use-after-free bug in gpio-virtuser
- don't register a driver from another driver's probe() in gpio-omap
- fix int width problems in GPIO ACPI code
- fix interrupt-to-pin mapping in gpio-brcmstb
- mask interrupts in irq shutdown in gpio-pca953x"
* tag 'gpio-fixes-for-v6.19-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
gpiolib: acpi: Fix potential out-of-boundary left shift
gpio: brcmstb: correct hwirq to bank map
gpio: omap: do not register driver in probe()
gpio: pca953x: mask interrupts in irq shutdown
gpio: virtuser: fix UAF in configfs release path
gpiolib: acpi: use BIT_ULL() for u64 mask in address space handler
gpio: sprd: Change sprd_gpio lock to raw_spin_lock
gpio: rockchip: Stop calling pinctrl for set_direction
This commit is contained in:
commit
d941a3f656
|
|
@ -301,12 +301,10 @@ static struct brcmstb_gpio_bank *brcmstb_gpio_hwirq_to_bank(
|
|||
struct brcmstb_gpio_priv *priv, irq_hw_number_t hwirq)
|
||||
{
|
||||
struct brcmstb_gpio_bank *bank;
|
||||
int i = 0;
|
||||
|
||||
/* banks are in descending order */
|
||||
list_for_each_entry_reverse(bank, &priv->bank_list, node) {
|
||||
i += bank->chip.gc.ngpio;
|
||||
if (hwirq < i)
|
||||
list_for_each_entry(bank, &priv->bank_list, node) {
|
||||
if (hwirq >= bank->chip.gc.offset &&
|
||||
hwirq < (bank->chip.gc.offset + bank->chip.gc.ngpio))
|
||||
return bank;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -799,10 +799,13 @@ static struct platform_device omap_mpuio_device = {
|
|||
|
||||
static inline void omap_mpuio_init(struct gpio_bank *bank)
|
||||
{
|
||||
platform_set_drvdata(&omap_mpuio_device, bank);
|
||||
static bool registered;
|
||||
|
||||
if (platform_driver_register(&omap_mpuio_driver) == 0)
|
||||
(void) platform_device_register(&omap_mpuio_device);
|
||||
platform_set_drvdata(&omap_mpuio_device, bank);
|
||||
if (!registered) {
|
||||
(void)platform_device_register(&omap_mpuio_device);
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
|
@ -1575,13 +1578,24 @@ static struct platform_driver omap_gpio_driver = {
|
|||
*/
|
||||
static int __init omap_gpio_drv_reg(void)
|
||||
{
|
||||
return platform_driver_register(&omap_gpio_driver);
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&omap_mpuio_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = platform_driver_register(&omap_gpio_driver);
|
||||
if (ret)
|
||||
platform_driver_unregister(&omap_mpuio_driver);
|
||||
|
||||
return ret;
|
||||
}
|
||||
postcore_initcall(omap_gpio_drv_reg);
|
||||
|
||||
static void __exit omap_gpio_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&omap_gpio_driver);
|
||||
platform_driver_unregister(&omap_mpuio_driver);
|
||||
}
|
||||
module_exit(omap_gpio_exit);
|
||||
|
||||
|
|
|
|||
|
|
@ -914,6 +914,8 @@ static void pca953x_irq_shutdown(struct irq_data *d)
|
|||
clear_bit(hwirq, chip->irq_trig_fall);
|
||||
clear_bit(hwirq, chip->irq_trig_level_low);
|
||||
clear_bit(hwirq, chip->irq_trig_level_high);
|
||||
|
||||
pca953x_irq_mask(d);
|
||||
}
|
||||
|
||||
static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
|
@ -164,12 +163,6 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
|
|||
unsigned long flags;
|
||||
u32 data = input ? 0 : 1;
|
||||
|
||||
|
||||
if (input)
|
||||
pinctrl_gpio_direction_input(chip, offset);
|
||||
else
|
||||
pinctrl_gpio_direction_output(chip, offset);
|
||||
|
||||
raw_spin_lock_irqsave(&bank->slock, flags);
|
||||
rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
|
||||
raw_spin_unlock_irqrestore(&bank->slock, flags);
|
||||
|
|
@ -593,7 +586,6 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
|
|||
gc->ngpio = bank->nr_pins;
|
||||
gc->label = bank->name;
|
||||
gc->parent = bank->dev;
|
||||
gc->can_sleep = true;
|
||||
|
||||
ret = gpiochip_add_data(gc, bank);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
struct sprd_gpio {
|
||||
struct gpio_chip chip;
|
||||
void __iomem *base;
|
||||
spinlock_t lock;
|
||||
raw_spinlock_t lock;
|
||||
int irq;
|
||||
};
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset,
|
|||
unsigned long flags;
|
||||
u32 tmp;
|
||||
|
||||
spin_lock_irqsave(&sprd_gpio->lock, flags);
|
||||
raw_spin_lock_irqsave(&sprd_gpio->lock, flags);
|
||||
tmp = readl_relaxed(base + reg);
|
||||
|
||||
if (val)
|
||||
|
|
@ -63,7 +63,7 @@ static void sprd_gpio_update(struct gpio_chip *chip, unsigned int offset,
|
|||
tmp &= ~BIT(SPRD_GPIO_BIT(offset));
|
||||
|
||||
writel_relaxed(tmp, base + reg);
|
||||
spin_unlock_irqrestore(&sprd_gpio->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&sprd_gpio->lock, flags);
|
||||
}
|
||||
|
||||
static int sprd_gpio_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
|
||||
|
|
@ -236,7 +236,7 @@ static int sprd_gpio_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(sprd_gpio->base))
|
||||
return PTR_ERR(sprd_gpio->base);
|
||||
|
||||
spin_lock_init(&sprd_gpio->lock);
|
||||
raw_spin_lock_init(&sprd_gpio->lock);
|
||||
|
||||
sprd_gpio->chip.label = dev_name(&pdev->dev);
|
||||
sprd_gpio->chip.ngpio = SPRD_GPIO_NR;
|
||||
|
|
|
|||
|
|
@ -1682,10 +1682,10 @@ static void gpio_virtuser_device_config_group_release(struct config_item *item)
|
|||
{
|
||||
struct gpio_virtuser_device *dev = to_gpio_virtuser_device(item);
|
||||
|
||||
guard(mutex)(&dev->lock);
|
||||
|
||||
if (gpio_virtuser_device_is_live(dev))
|
||||
gpio_virtuser_device_deactivate(dev);
|
||||
scoped_guard(mutex, &dev->lock) {
|
||||
if (gpio_virtuser_device_is_live(dev))
|
||||
gpio_virtuser_device_deactivate(dev);
|
||||
}
|
||||
|
||||
mutex_destroy(&dev->lock);
|
||||
ida_free(&gpio_virtuser_ida, dev->id);
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
|||
unsigned int pin = agpio->pin_table[i];
|
||||
struct acpi_gpio_connection *conn;
|
||||
struct gpio_desc *desc;
|
||||
u16 word, shift;
|
||||
bool found;
|
||||
|
||||
mutex_lock(&achip->conn_lock);
|
||||
|
|
@ -1158,10 +1159,22 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
|||
|
||||
mutex_unlock(&achip->conn_lock);
|
||||
|
||||
if (function == ACPI_WRITE)
|
||||
gpiod_set_raw_value_cansleep(desc, !!(*value & BIT(i)));
|
||||
else
|
||||
*value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
|
||||
/*
|
||||
* For the cases when OperationRegion() consists of more than
|
||||
* 64 bits calculate the word and bit shift to use that one to
|
||||
* access the value.
|
||||
*/
|
||||
word = i / 64;
|
||||
shift = i % 64;
|
||||
|
||||
if (function == ACPI_WRITE) {
|
||||
gpiod_set_raw_value_cansleep(desc, value[word] & BIT_ULL(shift));
|
||||
} else {
|
||||
if (gpiod_get_raw_value_cansleep(desc))
|
||||
value[word] |= BIT_ULL(shift);
|
||||
else
|
||||
value[word] &= ~BIT_ULL(shift);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -3545,10 +3545,9 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned offset,
|
||||
bool input)
|
||||
static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct rockchip_pin_bank *bank;
|
||||
|
|
@ -3562,7 +3561,7 @@ static const struct pinmux_ops rockchip_pmx_ops = {
|
|||
.get_function_name = rockchip_pmx_get_func_name,
|
||||
.get_function_groups = rockchip_pmx_get_groups,
|
||||
.set_mux = rockchip_pmx_set,
|
||||
.gpio_set_direction = rockchip_pmx_gpio_set_direction,
|
||||
.gpio_request_enable = rockchip_pmx_gpio_request_enable,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user