3737#include "gpiolib-acpi.h"
3838#include "gpiolib-cdev.h"
3939#include "gpiolib-of.h"
40+ #include "gpiolib-shared.h"
4041#include "gpiolib-swnode.h"
4142#include "gpiolib-sysfs.h"
4243#include "gpiolib.h"
@@ -1200,6 +1201,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
12001201 if (ret )
12011202 goto err_remove_irqchip_mask ;
12021203
1204+ ret = gpio_device_setup_shared (gdev );
1205+ if (ret )
1206+ goto err_remove_irqchip ;
1207+
12031208 /*
12041209 * By first adding the chardev, and then adding the device,
12051210 * we get a device node entry in sysfs under
@@ -1211,10 +1216,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
12111216 if (gpiolib_initialized ) {
12121217 ret = gpiochip_setup_dev (gdev );
12131218 if (ret )
1214- goto err_remove_irqchip ;
1219+ goto err_teardown_shared ;
12151220 }
1221+
12161222 return 0 ;
12171223
1224+ err_teardown_shared :
1225+ gpio_device_teardown_shared (gdev );
12181226err_remove_irqchip :
12191227 gpiochip_irqchip_remove (gc );
12201228err_remove_irqchip_mask :
@@ -1283,6 +1291,7 @@ void gpiochip_remove(struct gpio_chip *gc)
12831291 /* Numb the device, cancelling all outstanding operations */
12841292 rcu_assign_pointer (gdev -> chip , NULL );
12851293 synchronize_srcu (& gdev -> srcu );
1294+ gpio_device_teardown_shared (gdev );
12861295 gpiochip_irqchip_remove (gc );
12871296 acpi_gpiochip_remove (gc );
12881297 of_gpiochip_remove (gc );
@@ -4652,11 +4661,29 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
46524661 scoped_guard (srcu , & gpio_devices_srcu ) {
46534662 desc = gpiod_fwnode_lookup (fwnode , consumer , con_id , idx ,
46544663 & flags , & lookupflags );
4664+ if (!IS_ERR_OR_NULL (desc ) &&
4665+ test_bit (GPIOD_FLAG_SHARED , & desc -> flags )) {
4666+ /*
4667+ * We're dealing with a GPIO shared by multiple
4668+ * consumers. This is the moment to add the machine
4669+ * lookup table for the proxy device as previously
4670+ * we only knew the consumer's fwnode.
4671+ */
4672+ ret = gpio_shared_add_proxy_lookup (consumer , lookupflags );
4673+ if (ret )
4674+ return ERR_PTR (ret );
4675+
4676+ /* Trigger platform lookup for shared GPIO proxy. */
4677+ desc = ERR_PTR (- ENOENT );
4678+ /* Trigger it even for fwnode-only gpiod_get(). */
4679+ platform_lookup_allowed = true;
4680+ }
4681+
46554682 if (gpiod_not_found (desc ) && platform_lookup_allowed ) {
46564683 /*
46574684 * Either we are not using DT or ACPI, or their lookup
4658- * did not return a result. In that case, use platform
4659- * lookup as a fallback.
4685+ * did not return a result or this is a shared GPIO. In
4686+ * that case, use platform lookup as a fallback.
46604687 */
46614688 dev_dbg (consumer ,
46624689 "using lookup tables for GPIO lookup\n" );
@@ -4679,14 +4706,19 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
46794706 return ERR_PTR (ret );
46804707
46814708 /*
4682- * This happens when there are several consumers for
4683- * the same GPIO line: we just return here without
4684- * further initialization. It is a bit of a hack.
4685- * This is necessary to support fixed regulators.
4709+ * This happens when there are several consumers for the same
4710+ * GPIO line: we just return here without further
4711+ * initialization. It's a hack introduced long ago to support
4712+ * fixed regulators. We now have a better solution with
4713+ * automated scanning where affected platforms just need to
4714+ * select the provided Kconfig option.
46864715 *
4687- * FIXME: Make this more sane and safe.
4716+ * FIXME: Remove the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag after
4717+ * making sure all platforms use the new mechanism.
46884718 */
4689- dev_info (consumer , "nonexclusive access to GPIO for %s\n" , name );
4719+ dev_info (consumer ,
4720+ "nonexclusive access to GPIO for %s, consider updating your code to using gpio-shared-proxy\n" ,
4721+ name );
46904722 return desc ;
46914723 }
46924724
0 commit comments