Skip to content

Commit ec42a3a

Browse files
author
Bartosz Golaszewski
committed
gpio: shared: handle pins shared by child nodes of devices
Shared GPIOs may be assigned to child nodes of device nodes which don't themselves bind to any struct device. We need to pass the firmware node that is the actual consumer to gpiolib-shared and compare against it instead of unconditionally using the fwnode of the consumer device. Fixes: a060b8c ("gpiolib: implement low-level, shared GPIO support") Reported-by: Jon Hunter <jonathanh@nvidia.com> Closes: https://lore.kernel.org/all/921ba8ce-b18e-4a99-966d-c763d22081e2@nvidia.com/ Tested-by: Jon Hunter <jonathanh@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> Link: https://patch.msgid.link/20260318-gpio-shared-xlate-v2-2-0ce34c707e81@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
1 parent 710abda commit ec42a3a

3 files changed

Lines changed: 10 additions & 7 deletions

File tree

drivers/gpio/gpiolib-shared.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,8 @@ static bool gpio_shared_dev_is_reset_gpio(struct device *consumer,
443443
}
444444
#endif /* CONFIG_RESET_GPIO */
445445

446-
int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,
447-
unsigned long lflags)
446+
int gpio_shared_add_proxy_lookup(struct device *consumer, struct fwnode_handle *fwnode,
447+
const char *con_id, unsigned long lflags)
448448
{
449449
const char *dev_id = dev_name(consumer);
450450
struct gpiod_lookup_table *lookup;
@@ -458,7 +458,7 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,
458458
if (!ref->fwnode && device_is_compatible(consumer, "reset-gpio")) {
459459
if (!gpio_shared_dev_is_reset_gpio(consumer, entry, ref))
460460
continue;
461-
} else if (!device_match_fwnode(consumer, ref->fwnode)) {
461+
} else if (fwnode != ref->fwnode) {
462462
continue;
463463
}
464464

drivers/gpio/gpiolib-shared.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
struct gpio_device;
1212
struct gpio_desc;
1313
struct device;
14+
struct fwnode_handle;
1415

1516
#if IS_ENABLED(CONFIG_GPIO_SHARED)
1617

1718
int gpiochip_setup_shared(struct gpio_chip *gc);
1819
void gpio_device_teardown_shared(struct gpio_device *gdev);
19-
int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,
20-
unsigned long lflags);
20+
int gpio_shared_add_proxy_lookup(struct device *consumer,
21+
struct fwnode_handle *fwnode,
22+
const char *con_id, unsigned long lflags);
2123

2224
#else
2325

@@ -29,6 +31,7 @@ static inline int gpiochip_setup_shared(struct gpio_chip *gc)
2931
static inline void gpio_device_teardown_shared(struct gpio_device *gdev) { }
3032

3133
static inline int gpio_shared_add_proxy_lookup(struct device *consumer,
34+
struct fwnode_handle *fwnode,
3235
const char *con_id,
3336
unsigned long lflags)
3437
{

drivers/gpio/gpiolib.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4714,8 +4714,8 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
47144714
* lookup table for the proxy device as previously
47154715
* we only knew the consumer's fwnode.
47164716
*/
4717-
ret = gpio_shared_add_proxy_lookup(consumer, con_id,
4718-
lookupflags);
4717+
ret = gpio_shared_add_proxy_lookup(consumer, fwnode,
4718+
con_id, lookupflags);
47194719
if (ret)
47204720
return ERR_PTR(ret);
47214721

0 commit comments

Comments
 (0)