Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: cs42l43: Use actual ACPI firmware node for chip selects

On some systems the cs42l43 has amplifiers attached to its SPI
controller that are not properly defined in ACPI. Currently
software nodes are added to support this case, however, the chip
selects for these devices are specified using a hack. A software
node is added with the same name as the pinctrl driver, as the
look up was name based, this allowed the GPIO look up to return
the pinctrl driver even though the swnode was not owned by it.
This was necessary as the swnodes did not support directly
linking to real firmware nodes.

Since commit e5d527be7e69 ("gpio: swnode: don't use the swnode's
name as the key for GPIO lookup") changed the lookup to be
fwnode based this hack will no longer find the pinctrl driver,
resulting in the driver not probing. There is no pinctrl driver
attached to the swnode itself. But other patches did add support
for linking a swnode to a real fwnode node [1]. As such the hack
is no longer needed, so switch over to just passing the real
fwnode for the pinctrl property to avoid any issues.

[Bartosz:
- remove unneeded Fixes: tag,
- use PROPERTY_ENTRY_REF_ARRAY() instead of PROPERTY_ENTRY_REF_ARRAY_LEN()]

Link: https://lore.kernel.org/linux-gpio/20251106-reset-gpios-swnodes-v6-0-69aa852de9e4@linaro.org/ [1]
Fixes: 439fbc97502a ("spi: cs42l43: Add bridged cs35l56 amplifiers")
Cc: stable+noautosel@kernel.org # Don't backport, previous approach works, fix relies on swnode changes
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Acked-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

authored by

Charles Keepax and committed by
Philipp Zabel
d2a6cea4 d7cdbbc9

+10 -30
+10 -30
drivers/spi/spi-cs42l43.c
··· 52 52 .mode = SPI_MODE_0, 53 53 }; 54 54 55 - static const struct software_node cs42l43_gpiochip_swnode = { 56 - .name = "cs42l43-pinctrl", 57 - }; 58 - 59 - static const struct software_node_ref_args cs42l43_cs_refs[] = { 60 - SOFTWARE_NODE_REFERENCE(&cs42l43_gpiochip_swnode, 0, GPIO_ACTIVE_LOW), 61 - SOFTWARE_NODE_REFERENCE(&swnode_gpio_undefined), 62 - }; 63 - 64 - static const struct property_entry cs42l43_cs_props[] = { 65 - PROPERTY_ENTRY_REF_ARRAY("cs-gpios", cs42l43_cs_refs), 66 - {} 67 - }; 68 - 69 55 static int cs42l43_spi_tx(struct regmap *regmap, const u8 *buf, unsigned int len) 70 56 { 71 57 const u8 *end = buf + len; ··· 310 324 fwnode_handle_put(data); 311 325 } 312 326 313 - static void cs42l43_release_sw_node(void *data) 314 - { 315 - software_node_unregister(&cs42l43_gpiochip_swnode); 316 - } 317 - 318 327 static int cs42l43_spi_probe(struct platform_device *pdev) 319 328 { 320 329 struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent); ··· 372 391 fwnode_property_read_u32(xu_fwnode, "01fa-sidecar-instances", &nsidecars); 373 392 374 393 if (nsidecars) { 394 + struct software_node_ref_args args[] = { 395 + SOFTWARE_NODE_REFERENCE(fwnode, 0, GPIO_ACTIVE_LOW), 396 + SOFTWARE_NODE_REFERENCE(&swnode_gpio_undefined), 397 + }; 398 + struct property_entry props[] = { 399 + PROPERTY_ENTRY_REF_ARRAY("cs-gpios", args), 400 + { } 401 + }; 402 + 375 403 ret = fwnode_property_read_u32(xu_fwnode, "01fa-spk-id-val", &spkid); 376 404 if (!ret) { 377 405 dev_dbg(priv->dev, "01fa-spk-id-val = %d\n", spkid); ··· 393 403 "Failed to get spk-id-gpios\n"); 394 404 } 395 405 396 - ret = software_node_register(&cs42l43_gpiochip_swnode); 397 - if (ret) 398 - return dev_err_probe(priv->dev, ret, 399 - "Failed to register gpio swnode\n"); 400 - 401 - ret = devm_add_action_or_reset(priv->dev, cs42l43_release_sw_node, NULL); 402 - if (ret) 403 - return ret; 404 - 405 - ret = device_create_managed_software_node(&priv->ctlr->dev, 406 - cs42l43_cs_props, NULL); 406 + ret = device_create_managed_software_node(&priv->ctlr->dev, props, NULL); 407 407 if (ret) 408 408 return dev_err_probe(priv->dev, ret, "Failed to add swnode\n"); 409 409 } else {