diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-04 10:08:40 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-04 10:08:40 -0800 |
| commit | 2aa680df68062e4e0c356ec2aa7100c13654907b (patch) | |
| tree | ee3dc5125e11aac04f2e33922cfad4260e47de34 /drivers/gpio/gpiolib.c | |
| parent | 6dfafbd0299a60bfb5d5e277fdf100037c7ded07 (diff) | |
| parent | eaf526cfa4e537af86543d77f402b9ae803f606e (diff) | |
Merge tag 'sound-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"The majority of changes at this time were about ASoC with a lot of
code refactoring works. From the functionality POV, there isn't much
to see, but we have a wide range of device-specific fixes and updates.
Here are some highlights:
- Continued ASoC API cleanup work, spanned over many files
- Added a SoundWire SCDA generic class driver with regmap support
- Enhancements and fixes for Cirrus, Intel, Maxim and Qualcomm.
- Support for ASoC Allwinner A523, Mediatek MT8189, Qualcomm QCM2290,
QRB2210 and SM6115, SpacemiT K1, and TI TAS2568, TAS5802, TAS5806,
TAS5815, TAS5828 and TAS5830
- Usual HD-audio and USB-audio quirks and fixups
- Support for Onkyo SE-300PCIE, TASCAM IF-FW/DM MkII
Some gpiolib changes for shared GPIOs are included along with this PR
for covering ASoC drivers changes"
* tag 'sound-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (739 commits)
ALSA: hda/realtek: Add PCI SSIDs to HP ProBook quirks
ALSA: usb-audio: Simplify with usb_endpoint_max_periodic_payload()
ALSA: hda/realtek: fix mute/micmute LEDs don't work for more HP laptops
ALSA: rawmidi: Fix inconsistent indenting warning reported by smatch
ALSA: dice: fix buffer overflow in detect_stream_formats()
ASoC: codecs: Modify awinic amplifier dsp read and write functions
ASoC: SDCA: Fixup some more Kconfig issues
ASoC: cs35l56: Log a message if firmware is missing
ASoC: nau8325: Delete a stray tab
firmware: cs_dsp: Add test cases for client_ops == NULL
firmware: cs_dsp: Don't require client to provide a struct cs_dsp_client_ops
ASoC: fsl_micfil: Set channel range control
ASoC: fsl_micfil: Add default quality for different platforms
ASoC: intel: sof_sdw: Add codec_info for cs42l45
ASoC: sdw_utils: Add cs42l45 support functions
ASoC: intel: sof_sdw: Add ability to have auxiliary devices
ASoC: sdw_utils: Move codec_name to dai info
ASoC: sdw_utils: Add codec_conf for every DAI
ASoC: SDCA: Add terminal type into input/output widget name
ASoC: SDCA: Align mute controls to ALSA expectations
...
Diffstat (limited to 'drivers/gpio/gpiolib.c')
| -rw-r--r-- | drivers/gpio/gpiolib.c | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index cd8800ba5825..476fcc897d90 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -37,6 +37,7 @@ #include "gpiolib-acpi.h" #include "gpiolib-cdev.h" #include "gpiolib-of.h" +#include "gpiolib-shared.h" #include "gpiolib-swnode.h" #include "gpiolib-sysfs.h" #include "gpiolib.h" @@ -1200,6 +1201,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, if (ret) goto err_remove_irqchip_mask; + ret = gpio_device_setup_shared(gdev); + if (ret) + goto err_remove_irqchip; + /* * By first adding the chardev, and then adding the device, * 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, if (gpiolib_initialized) { ret = gpiochip_setup_dev(gdev); if (ret) - goto err_remove_irqchip; + goto err_teardown_shared; } + return 0; +err_teardown_shared: + gpio_device_teardown_shared(gdev); err_remove_irqchip: gpiochip_irqchip_remove(gc); err_remove_irqchip_mask: @@ -1283,6 +1291,7 @@ void gpiochip_remove(struct gpio_chip *gc) /* Numb the device, cancelling all outstanding operations */ rcu_assign_pointer(gdev->chip, NULL); synchronize_srcu(&gdev->srcu); + gpio_device_teardown_shared(gdev); gpiochip_irqchip_remove(gc); acpi_gpiochip_remove(gc); of_gpiochip_remove(gc); @@ -3982,6 +3991,26 @@ int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name) EXPORT_SYMBOL_GPL(gpiod_set_consumer_name); /** + * gpiod_is_shared() - check if this GPIO can be shared by multiple consumers + * @desc: GPIO to inspect + * + * Returns: + * True if this GPIO can be shared by multiple consumers at once. False if it's + * a regular, exclusive GPIO. + * + * Note: + * This function returning true does not mean that this GPIO is currently being + * shared. It means the GPIO core has registered the fact that the firmware + * configuration indicates that it can be shared by multiple consumers and is + * in charge of arbitrating the access. + */ +bool gpiod_is_shared(const struct gpio_desc *desc) +{ + return test_bit(GPIOD_FLAG_SHARED_PROXY, &desc->flags); +} +EXPORT_SYMBOL_GPL(gpiod_is_shared); + +/** * gpiod_to_irq() - return the IRQ corresponding to a GPIO * @desc: gpio whose IRQ will be returned (already requested) * @@ -4652,11 +4681,29 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer, scoped_guard(srcu, &gpio_devices_srcu) { desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx, &flags, &lookupflags); + if (!IS_ERR_OR_NULL(desc) && + test_bit(GPIOD_FLAG_SHARED, &desc->flags)) { + /* + * We're dealing with a GPIO shared by multiple + * consumers. This is the moment to add the machine + * lookup table for the proxy device as previously + * we only knew the consumer's fwnode. + */ + ret = gpio_shared_add_proxy_lookup(consumer, lookupflags); + if (ret) + return ERR_PTR(ret); + + /* Trigger platform lookup for shared GPIO proxy. */ + desc = ERR_PTR(-ENOENT); + /* Trigger it even for fwnode-only gpiod_get(). */ + platform_lookup_allowed = true; + } + if (gpiod_not_found(desc) && platform_lookup_allowed) { /* * Either we are not using DT or ACPI, or their lookup - * did not return a result. In that case, use platform - * lookup as a fallback. + * did not return a result or this is a shared GPIO. In + * that case, use platform lookup as a fallback. */ dev_dbg(consumer, "using lookup tables for GPIO lookup\n"); @@ -4679,14 +4726,19 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer, return ERR_PTR(ret); /* - * This happens when there are several consumers for - * the same GPIO line: we just return here without - * further initialization. It is a bit of a hack. - * This is necessary to support fixed regulators. + * This happens when there are several consumers for the same + * GPIO line: we just return here without further + * initialization. It's a hack introduced long ago to support + * fixed regulators. We now have a better solution with + * automated scanning where affected platforms just need to + * select the provided Kconfig option. * - * FIXME: Make this more sane and safe. + * FIXME: Remove the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag after + * making sure all platforms use the new mechanism. */ - dev_info(consumer, "nonexclusive access to GPIO for %s\n", name); + dev_info(consumer, + "nonexclusive access to GPIO for %s, consider updating your code to using gpio-shared-proxy\n", + name); return desc; } |