gpio fixes for v5.9-rc6
- fix the interrupt configuration in gpio-tc35894 - explicitly support only threaded irqs in gpio-siox - fix a resource leak in error path in gpio-mockup - fix line event handling in syscall compatible mode in GPIO chardev -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAl9jSLwACgkQEacuoBRx 13LfAg//b6AuexMoAeedl/zd5BEN+MULYUkQVwAEOyrse0fMpEFsTK48wX/JoVYO 43zczzWJnXmLXZ6avzZnhA9vDktXXQpvBjNbFoxJQ5NVZFpSEQSt3TU2p9X19KxP dD10QryPiY9I97yz39HLWjT6/8YPOcGN5Lh1j78vtwZiIsx3wPFxQw/+uKmIjpMf rubAYIuJdiudO/SlABMC3Rig/3K1lNooGrwIb6dw9FPr5NN7/6YN2xhU249rYeT/ OOQ2b+UJffmvBXZvMdxvdp0dc90ts0pDXT03dMfSWZiZysKmtT7mgaELnHFxfPIe Y1z8PVdXCsBs5whmRpcgCWk4t+6UnnGvA0xxRnir8Rq/5+B4tu5EFDpTOH0We/k8 3aQ6wFtZ3Sk8X9rzct7afaJnlcSDtfdo/t+3Y0SHuPFtbFLqKJtqVcOMgrG+r9zE +sj2AjDetHhboMj9BBLblNyVMMZOS3YelFBnzI/QSpWWqd9MoPIlVHGtJJvipUmi 7h2hCVUcG7YyIWSWC+NSZ4tfmb7I49Tw+vSGTcANl9SvfTT4SurXcOq63WY0fv3F 60GoATthmSqywlfbLbM0ACbY7iXFRc+hXirJhkfZ49laAhiJCgToGzvtuTtXT4wY bJmKbLNJvJZmDb6H84K+eLP4yWklsMWVnfBIcce6DwTrmX/5s6c= =J/T0 -----END PGP SIGNATURE----- Merge tag 'gpio-fixes-for-v5.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into fixes gpio fixes for v5.9-rc6 - fix the interrupt configuration in gpio-tc35894 - explicitly support only threaded irqs in gpio-siox - fix a resource leak in error path in gpio-mockup - fix line event handling in syscall compatible mode in GPIO chardev
This commit is contained in:
commit
53c14e237b
|
@ -552,6 +552,7 @@ static int __init gpio_mockup_init(void)
|
|||
err = platform_driver_register(&gpio_mockup_driver);
|
||||
if (err) {
|
||||
gpio_mockup_err("error registering platform driver\n");
|
||||
debugfs_remove_recursive(gpio_mockup_dbg_dir);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -582,6 +583,7 @@ static int __init gpio_mockup_init(void)
|
|||
gpio_mockup_err("error registering device");
|
||||
platform_driver_unregister(&gpio_mockup_driver);
|
||||
gpio_mockup_unregister_pdevs();
|
||||
debugfs_remove_recursive(gpio_mockup_dbg_dir);
|
||||
return PTR_ERR(pdev);
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,7 @@ static int gpio_siox_probe(struct siox_device *sdevice)
|
|||
girq->chip = &ddata->ichip;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_level_irq;
|
||||
girq->threaded = true;
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, &ddata->gchip, NULL);
|
||||
if (ret)
|
||||
|
|
|
@ -212,7 +212,7 @@ static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d)
|
|||
continue;
|
||||
|
||||
tc3589x_gpio->oldregs[i][j] = new;
|
||||
tc3589x_reg_write(tc3589x, regmap[i] + j * 8, new);
|
||||
tc3589x_reg_write(tc3589x, regmap[i] + j, new);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -423,6 +423,21 @@ static __poll_t lineevent_poll(struct file *file,
|
|||
return events;
|
||||
}
|
||||
|
||||
static ssize_t lineevent_get_size(void)
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
/* i386 has no padding after 'id' */
|
||||
if (in_ia32_syscall()) {
|
||||
struct compat_gpioeevent_data {
|
||||
compat_u64 timestamp;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
return sizeof(struct compat_gpioeevent_data);
|
||||
}
|
||||
#endif
|
||||
return sizeof(struct gpioevent_data);
|
||||
}
|
||||
|
||||
static ssize_t lineevent_read(struct file *file,
|
||||
char __user *buf,
|
||||
|
@ -432,9 +447,20 @@ static ssize_t lineevent_read(struct file *file,
|
|||
struct lineevent_state *le = file->private_data;
|
||||
struct gpioevent_data ge;
|
||||
ssize_t bytes_read = 0;
|
||||
ssize_t ge_size;
|
||||
int ret;
|
||||
|
||||
if (count < sizeof(ge))
|
||||
/*
|
||||
* When compatible system call is being used the struct gpioevent_data,
|
||||
* in case of at least ia32, has different size due to the alignment
|
||||
* differences. Because we have first member 64 bits followed by one of
|
||||
* 32 bits there is no gap between them. The only difference is the
|
||||
* padding at the end of the data structure. Hence, we calculate the
|
||||
* actual sizeof() and pass this as an argument to copy_to_user() to
|
||||
* drop unneeded bytes from the output.
|
||||
*/
|
||||
ge_size = lineevent_get_size();
|
||||
if (count < ge_size)
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
|
@ -470,10 +496,10 @@ static ssize_t lineevent_read(struct file *file,
|
|||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user(buf + bytes_read, &ge, sizeof(ge)))
|
||||
if (copy_to_user(buf + bytes_read, &ge, ge_size))
|
||||
return -EFAULT;
|
||||
bytes_read += sizeof(ge);
|
||||
} while (count >= bytes_read + sizeof(ge));
|
||||
bytes_read += ge_size;
|
||||
} while (count >= bytes_read + ge_size);
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue