mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 15:29:16 +00:00
gpio fixes for v6.9-rc3
- make sure GPIO devices are registered with the subsystem before trying to return them to a caller of gpio_device_find() - fix two issues with incorrect sanitization of the interrupt labels -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAmYQJwAACgkQEacuoBRx 13L73Q//fhvrFLJ7C3pl2leHh+GxbFpe2kfAfeDTVLaWE2rJ29eOv0bgeIgWdOSg rsTKk07gkeTte577DQAuL4t2gLl3ueJTEw81PXVOyD6rnyDUzcnuJmX1w9a8nauH nGPaDhF8aZC9h72jpnfH4nns6CugvfaNjo0YoVe6yWRbo0rkqY1XDEicYPanEg4e B6trNt2A2NqGOLWmasVx2TFtW56C+gXvkgqY2Xrrs2ait9UNo4ELyD9VWAtrw2X4 pj/luTV1A24oZyvysBeMHHTPURVls/d6GuAEfuxzv8Cxur2zm2xCl/pY6MZjtPE4 8KtDGokE+6yVuYl1YqIqyrt8sOKPixdjuVqOMCov4xYx4tZVckrstkyKpyq0lAVo iMVa4DvnuYmh7h76A+0fWCMiNWCBtbemCtjnWOe7qsNDcBTF2WG5i9dux22Vx+0X /Vln0n50hdNJeMp8FMuKiJLCHnteNN/tyfateIHiyIghyJyzgOGWsuVh0nEC9EmD dWHcj+8Udd30HT6XCmtgebotpaM3DrA1FrWH60pEzUKgJg8k1DAjzvKxqRrUB0UY lGL6IxSwbT2wXHMC4zjq+oee2gYd9+SNFIUpzYYXhgnJiHJ2R3oy26+tf5yT65QK 6MPuBapWpVDNKItRTlLafxOQfvFA3IJ8dqrK2ym4YuJLdPANqT8= =k/k1 -----END PGP SIGNATURE----- Merge tag 'gpio-fixes-for-v6.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux Pull gpio fixes from Bartosz Golaszewski: - make sure GPIO devices are registered with the subsystem before trying to return them to a caller of gpio_device_find() - fix two issues with incorrect sanitization of the interrupt labels * tag 'gpio-fixes-for-v6.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: gpio: cdev: fix missed label sanitizing in debounce_setup() gpio: cdev: check for NULL labels when sanitizing them for irqs gpiolib: Fix triggering "kobject: 'gpiochipX' is not initialized, yet" kobject_get() errors
This commit is contained in:
commit
2e69af16b0
@ -728,6 +728,25 @@ static u32 line_event_id(int level)
|
|||||||
GPIO_V2_LINE_EVENT_FALLING_EDGE;
|
GPIO_V2_LINE_EVENT_FALLING_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char *make_irq_label(const char *orig)
|
||||||
|
{
|
||||||
|
char *new;
|
||||||
|
|
||||||
|
if (!orig)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
new = kstrdup_and_replace(orig, '/', ':', GFP_KERNEL);
|
||||||
|
if (!new)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void free_irq_label(const char *label)
|
||||||
|
{
|
||||||
|
kfree(label);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HTE
|
#ifdef CONFIG_HTE
|
||||||
|
|
||||||
static enum hte_return process_hw_ts_thread(void *p)
|
static enum hte_return process_hw_ts_thread(void *p)
|
||||||
@ -1015,6 +1034,7 @@ static int debounce_setup(struct line *line, unsigned int debounce_period_us)
|
|||||||
{
|
{
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
int ret, level, irq;
|
int ret, level, irq;
|
||||||
|
char *label;
|
||||||
|
|
||||||
/* try hardware */
|
/* try hardware */
|
||||||
ret = gpiod_set_debounce(line->desc, debounce_period_us);
|
ret = gpiod_set_debounce(line->desc, debounce_period_us);
|
||||||
@ -1037,11 +1057,17 @@ static int debounce_setup(struct line *line, unsigned int debounce_period_us)
|
|||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
|
label = make_irq_label(line->req->label);
|
||||||
|
if (IS_ERR(label))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
irqflags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
|
irqflags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
|
||||||
ret = request_irq(irq, debounce_irq_handler, irqflags,
|
ret = request_irq(irq, debounce_irq_handler, irqflags,
|
||||||
line->req->label, line);
|
label, line);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
free_irq_label(label);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
line->irq = irq;
|
line->irq = irq;
|
||||||
} else {
|
} else {
|
||||||
ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH);
|
ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH);
|
||||||
@ -1083,16 +1109,6 @@ static u32 gpio_v2_line_config_debounce_period(struct gpio_v2_line_config *lc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *make_irq_label(const char *orig)
|
|
||||||
{
|
|
||||||
return kstrdup_and_replace(orig, '/', ':', GFP_KERNEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void free_irq_label(const char *label)
|
|
||||||
{
|
|
||||||
kfree(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void edge_detector_stop(struct line *line)
|
static void edge_detector_stop(struct line *line)
|
||||||
{
|
{
|
||||||
if (line->irq) {
|
if (line->irq) {
|
||||||
@ -1158,8 +1174,8 @@ static int edge_detector_setup(struct line *line,
|
|||||||
irqflags |= IRQF_ONESHOT;
|
irqflags |= IRQF_ONESHOT;
|
||||||
|
|
||||||
label = make_irq_label(line->req->label);
|
label = make_irq_label(line->req->label);
|
||||||
if (!label)
|
if (IS_ERR(label))
|
||||||
return -ENOMEM;
|
return PTR_ERR(label);
|
||||||
|
|
||||||
/* Request a thread to read the events */
|
/* Request a thread to read the events */
|
||||||
ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread,
|
ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread,
|
||||||
@ -2217,8 +2233,8 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
|
|||||||
goto out_free_le;
|
goto out_free_le;
|
||||||
|
|
||||||
label = make_irq_label(le->label);
|
label = make_irq_label(le->label);
|
||||||
if (!label) {
|
if (IS_ERR(label)) {
|
||||||
ret = -ENOMEM;
|
ret = PTR_ERR(label);
|
||||||
goto out_free_le;
|
goto out_free_le;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,6 +1175,9 @@ struct gpio_device *gpio_device_find(const void *data,
|
|||||||
|
|
||||||
list_for_each_entry_srcu(gdev, &gpio_devices, list,
|
list_for_each_entry_srcu(gdev, &gpio_devices, list,
|
||||||
srcu_read_lock_held(&gpio_devices_srcu)) {
|
srcu_read_lock_held(&gpio_devices_srcu)) {
|
||||||
|
if (!device_is_registered(&gdev->dev))
|
||||||
|
continue;
|
||||||
|
|
||||||
guard(srcu)(&gdev->srcu);
|
guard(srcu)(&gdev->srcu);
|
||||||
|
|
||||||
gc = srcu_dereference(gdev->chip, &gdev->srcu);
|
gc = srcu_dereference(gdev->chip, &gdev->srcu);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user