mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
gpio fixes for v7.1-rc6
- fix interrupt handling in gpio-mxc - fix scoped_guard() usage in gpio-adnp - don't accept partial writes in gpio-virtuser debugfs interface as they can't really work correctly - fix resource leaks in gpio-rockchip - fix locking issues in remove path in shared GPIO management - undo the vote of a GPIO shared proxy virtual device on GPIO release -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEkeUTLeW1Rh17omX8BZ0uy/82hMMFAmoYQrwACgkQBZ0uy/82 hMOLoA/+L86ir6t3Q5dzKk527gRRZY1xnBj3wVyD/6s3HMpAcbm7NUBLGxNNetJl YxYIQZPHI6NtFH3VpcKQSBx1ECaXhIhBFucWX/qEW7VToQS0+0KV+ys+xR8Tp7fP 4qypSk7v8H1tR4yP0pDnzKUdYm8nA5pDGHwVv+VoV5SdwRVAIjZDL4yRy2/NhtWD qcWL9x0+lWgTt7gXLd3VGfKKbewsNyzDs5FBYaEUsPoYAj/AH4ezFSnNodc/5Ds+ M3bv7bEef3WrYeL2zdSWF4wHy3ABqOtBW/o9F5hYUYVDhRc7ACArYj6ayhPQQRs0 YtyYsnQZkFqu4lFvInQ+5quJfAhxJmWq+fQZbPidXeR+KlDk8N22L4jwWsabEuPj rNI8ijUo88h5VkU7ARstXWCQCZWcxibMS+zPaX0TqV5LhvRZPpuHPbpzACL1HOSr LiFI9npnJNsHkQ7mBhVIrUtbUd+CO549/KIarN7ldX4svwSOGN1lWF3041hRkPXO WGj13ledyw8WdbcqWIqTXKt3po0ILcM/nOfI+vqVqqOLVB2m7sJfdGMR8WQwX2GV g3xdPHAP270LAwkDRbwgYmeAFaiVLLTRV/hag5R6MIdL51pCJC67dB6eUNTqUCmB U2wepAFXRn0HB3XYf9Wmzzh8QbzUTVkqpnjujBq0sVmKvF5zMCE= =hkRD -----END PGP SIGNATURE----- Merge tag 'gpio-fixes-for-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux Pull gpio fixes from Bartosz Golaszewski: - fix interrupt handling in gpio-mxc - fix scoped_guard() usage in gpio-adnp - don't accept partial writes in gpio-virtuser debugfs interface as they can't really work correctly - fix resource leaks in gpio-rockchip - fix locking issues in remove path in shared GPIO management - undo the vote of a GPIO shared proxy virtual device on GPIO release * tag 'gpio-fixes-for-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: gpio: rockchip: teardown bugs and resource leaks gpio: rockchip: convert bank->clk to devm_clk_get_enabled() gpio: virtuser: Fix uninitialized data bug in gpio_virtuser_direction_do_write() gpio: shared: fix lockdep false positive by removing unneeded lock gpio: shared: fix deadlock on shared proxy's parent removal gpio: adnp: fix flow control regression caused by scoped_guard() gpio: shared: undo the vote of the proxy on GPIO free gpio: mxc: fix irq_high handling
This commit is contained in:
commit
b0f908d785
|
|
@ -237,7 +237,9 @@ static irqreturn_t adnp_irq(int irq, void *data)
|
|||
unsigned long pending;
|
||||
int err;
|
||||
|
||||
scoped_guard(mutex, &adnp->i2c_lock) {
|
||||
{
|
||||
guard(mutex)(&adnp->i2c_lock);
|
||||
|
||||
err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
|
||||
if (err < 0)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
|
|||
* the handler is needed only once, but doing it for every port
|
||||
* is more robust and easier.
|
||||
*/
|
||||
port->irq_high = -1;
|
||||
port->irq_high = 0;
|
||||
port->mx_irq_handler = mx2_gpio_irq_handler;
|
||||
} else
|
||||
port->mx_irq_handler = mx3_gpio_irq_handler;
|
||||
|
|
|
|||
|
|
@ -638,10 +638,17 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void rockchip_clk_put(void *data)
|
||||
{
|
||||
struct clk *clk = data;
|
||||
|
||||
clk_put(clk);
|
||||
}
|
||||
|
||||
static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
|
||||
{
|
||||
struct resource res;
|
||||
int id = 0;
|
||||
int id = 0, ret;
|
||||
|
||||
if (of_address_to_resource(bank->of_node, 0, &res)) {
|
||||
dev_err(bank->dev, "cannot find IO resource for bank\n");
|
||||
|
|
@ -656,11 +663,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
|
|||
if (!bank->irq)
|
||||
return -EINVAL;
|
||||
|
||||
bank->clk = of_clk_get(bank->of_node, 0);
|
||||
bank->clk = devm_clk_get_enabled(bank->dev, NULL);
|
||||
if (IS_ERR(bank->clk))
|
||||
return PTR_ERR(bank->clk);
|
||||
|
||||
clk_prepare_enable(bank->clk);
|
||||
id = readl(bank->reg_base + gpio_regs_v2.version_id);
|
||||
|
||||
switch (id) {
|
||||
|
|
@ -672,9 +678,13 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
|
|||
bank->db_clk = of_clk_get(bank->of_node, 1);
|
||||
if (IS_ERR(bank->db_clk)) {
|
||||
dev_err(bank->dev, "cannot find debounce clk\n");
|
||||
clk_disable_unprepare(bank->clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(bank->dev, rockchip_clk_put,
|
||||
bank->db_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case GPIO_TYPE_V1:
|
||||
bank->gpio_regs = &gpio_regs_v1;
|
||||
|
|
@ -751,7 +761,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
ret = rockchip_gpiolib_register(bank);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(bank->clk);
|
||||
mutex_unlock(&bank->deferred_lock);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -792,7 +801,9 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(bank->clk);
|
||||
irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
|
||||
if (bank->domain)
|
||||
irq_domain_remove(bank->domain);
|
||||
gpiochip_remove(&bank->gpio_chip);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,9 +103,18 @@ static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset)
|
|||
{
|
||||
struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
|
||||
struct gpio_shared_desc *shared_desc = proxy->shared_desc;
|
||||
int ret;
|
||||
|
||||
guard(gpio_shared_desc_lock)(shared_desc);
|
||||
|
||||
if (proxy->voted_high) {
|
||||
ret = gpio_shared_proxy_set_unlocked(proxy,
|
||||
shared_desc->can_sleep ? gpiod_set_value_cansleep : gpiod_set_value, 0);
|
||||
if (ret)
|
||||
dev_err(proxy->dev,
|
||||
"Failed to unset the shared GPIO value on release: %d\n", ret);
|
||||
}
|
||||
|
||||
proxy->shared_desc->usecnt--;
|
||||
|
||||
dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n",
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file,
|
|||
char buf[32], *trimmed;
|
||||
int ret, dir, val = 0;
|
||||
|
||||
if (count >= sizeof(buf))
|
||||
if (*ppos != 0 || count >= sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
|
|
@ -622,7 +622,7 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file,
|
|||
char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2];
|
||||
int ret;
|
||||
|
||||
if (count >= sizeof(buf))
|
||||
if (*ppos != 0 || count >= sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ struct gpio_shared_entry {
|
|||
unsigned int offset;
|
||||
/* Index in the property value array. */
|
||||
size_t index;
|
||||
/* Synchronizes the modification of shared_desc. */
|
||||
/* Synchronizes the modification of shared_desc and offset. */
|
||||
struct mutex lock;
|
||||
struct gpio_shared_desc *shared_desc;
|
||||
struct kref ref;
|
||||
|
|
@ -598,16 +598,13 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
|
|||
struct gpio_shared_ref *ref;
|
||||
|
||||
list_for_each_entry(entry, &gpio_shared_list, list) {
|
||||
guard(mutex)(&entry->lock);
|
||||
|
||||
if (!device_match_fwnode(&gdev->dev, entry->fwnode))
|
||||
continue;
|
||||
|
||||
gpiod_free_commit(&gdev->descs[entry->offset]);
|
||||
scoped_guard(mutex, &entry->lock)
|
||||
gpiod_free_commit(&gdev->descs[entry->offset]);
|
||||
|
||||
list_for_each_entry(ref, &entry->refs, list) {
|
||||
guard(mutex)(&ref->lock);
|
||||
|
||||
if (ref->lookup) {
|
||||
gpiod_remove_lookup_table(ref->lookup);
|
||||
kfree(ref->lookup->table[0].key);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user