[PATCH v5 8/9] driver core: Replace dev->of_node_reused with dev_of_node_reused()

Manivannan Sadhasivam mani at kernel.org
Tue Apr 7 17:27:19 AEST 2026


On Mon, Apr 06, 2026 at 04:23:01PM -0700, Douglas Anderson wrote:
> In C, bitfields are not necessarily safe to modify from multiple
> threads without locking. Switch "of_node_reused" over to the "flags"
> field so modifications are safe.
> 
> Cc: Johan Hovold <johan at kernel.org>
> Acked-by: Mark Brown <broonie at kernel.org>
> Reviewed-by: Rafael J. Wysocki (Intel) <rafael at kernel.org>
> Reviewed-by: Danilo Krummrich <dakr at kernel.org>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>

Acked-by: Manivannan Sadhasivam <mani at kernel.org> # PCI_PWRCTRL

- Mani

> ---
> Not fixing any known bugs; problem is theoretical and found by code
> inspection. Change is done somewhat manually and only lightly tested
> (mostly compile-time tested).
> 
> (no changes since v4)
> 
> Changes in v4:
> - Use accessor functions for flags
> 
> Changes in v3:
> - New
> 
>  drivers/base/core.c                      | 2 +-
>  drivers/base/pinctrl.c                   | 2 +-
>  drivers/base/platform.c                  | 2 +-
>  drivers/net/pcs/pcs-xpcs-plat.c          | 2 +-
>  drivers/of/device.c                      | 6 +++---
>  drivers/pci/of.c                         | 2 +-
>  drivers/pci/pwrctrl/core.c               | 2 +-
>  drivers/regulator/bq257xx-regulator.c    | 2 +-
>  drivers/regulator/rk808-regulator.c      | 2 +-
>  drivers/tty/serial/serial_base_bus.c     | 2 +-
>  drivers/usb/gadget/udc/aspeed-vhub/dev.c | 2 +-
>  include/linux/device.h                   | 7 ++++---
>  12 files changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 8a83d7c93361..30825bf83234 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -5283,7 +5283,7 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)
>  {
>  	of_node_put(dev->of_node);
>  	dev->of_node = of_node_get(dev2->of_node);
> -	dev->of_node_reused = true;
> +	dev_set_of_node_reused(dev);
>  }
>  EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);
>  
> diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c
> index 6e250272c843..0bbc83231234 100644
> --- a/drivers/base/pinctrl.c
> +++ b/drivers/base/pinctrl.c
> @@ -24,7 +24,7 @@ int pinctrl_bind_pins(struct device *dev)
>  {
>  	int ret;
>  
> -	if (dev->of_node_reused)
> +	if (dev_of_node_reused(dev))
>  		return 0;
>  
>  	dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index d44591d52e36..199e6fb25770 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -856,7 +856,7 @@ struct platform_device *platform_device_register_full(
>  	pdev->dev.parent = pdevinfo->parent;
>  	pdev->dev.fwnode = pdevinfo->fwnode;
>  	pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
> -	pdev->dev.of_node_reused = pdevinfo->of_node_reused;
> +	dev_assign_of_node_reused(&pdev->dev, pdevinfo->of_node_reused);
>  
>  	if (pdevinfo->dma_mask) {
>  		pdev->platform_dma_mask = pdevinfo->dma_mask;
> diff --git a/drivers/net/pcs/pcs-xpcs-plat.c b/drivers/net/pcs/pcs-xpcs-plat.c
> index b8c48f9effbf..f4b1b8246ce9 100644
> --- a/drivers/net/pcs/pcs-xpcs-plat.c
> +++ b/drivers/net/pcs/pcs-xpcs-plat.c
> @@ -349,7 +349,7 @@ static int xpcs_plat_init_dev(struct dw_xpcs_plat *pxpcs)
>  	 * up later. Make sure DD-core is aware of the OF-node being re-used.
>  	 */
>  	device_set_node(&mdiodev->dev, fwnode_handle_get(dev_fwnode(dev)));
> -	mdiodev->dev.of_node_reused = true;
> +	dev_set_of_node_reused(&mdiodev->dev);
>  
>  	/* Pass the data further so the DW XPCS driver core could use it */
>  	mdiodev->dev.platform_data = (void *)device_get_match_data(dev);
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index f7e75e527667..be4e1584e0af 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -26,7 +26,7 @@
>  const struct of_device_id *of_match_device(const struct of_device_id *matches,
>  					   const struct device *dev)
>  {
> -	if (!matches || !dev->of_node || dev->of_node_reused)
> +	if (!matches || !dev->of_node || dev_of_node_reused(dev))
>  		return NULL;
>  	return of_match_node(matches, dev->of_node);
>  }
> @@ -192,7 +192,7 @@ ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
>  {
>  	ssize_t sl;
>  
> -	if (!dev || !dev->of_node || dev->of_node_reused)
> +	if (!dev || !dev->of_node || dev_of_node_reused(dev))
>  		return -ENODEV;
>  
>  	sl = of_modalias(dev->of_node, str, len - 2);
> @@ -254,7 +254,7 @@ int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *
>  {
>  	int sl;
>  
> -	if ((!dev) || (!dev->of_node) || dev->of_node_reused)
> +	if ((!dev) || (!dev->of_node) || dev_of_node_reused(dev))
>  		return -ENODEV;
>  
>  	/* Devicetree modalias is tricky, we add it in 2 steps */
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index 9f8eb5df279e..1f9b669abdb0 100644
> --- a/drivers/pci/of.c
> +++ b/drivers/pci/of.c
> @@ -38,7 +38,7 @@ int pci_set_of_node(struct pci_dev *dev)
>  	struct device *pdev __free(put_device) =
>  		bus_find_device_by_of_node(&platform_bus_type, node);
>  	if (pdev)
> -		dev->bus->dev.of_node_reused = true;
> +		dev_set_of_node_reused(&dev->bus->dev);
>  
>  	device_set_node(&dev->dev, of_fwnode_handle(no_free_ptr(node)));
>  	return 0;
> diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c
> index 7754baed67f2..72963a92362a 100644
> --- a/drivers/pci/pwrctrl/core.c
> +++ b/drivers/pci/pwrctrl/core.c
> @@ -39,7 +39,7 @@ static int pci_pwrctrl_notify(struct notifier_block *nb, unsigned long action,
>  		 * If we got here then the PCI device is the second after the
>  		 * power control platform device. Mark its OF node as reused.
>  		 */
> -		dev->of_node_reused = true;
> +		dev_set_of_node_reused(dev);
>  		break;
>  	}
>  
> diff --git a/drivers/regulator/bq257xx-regulator.c b/drivers/regulator/bq257xx-regulator.c
> index dab8f1ab4450..40e0f1a7ae81 100644
> --- a/drivers/regulator/bq257xx-regulator.c
> +++ b/drivers/regulator/bq257xx-regulator.c
> @@ -143,7 +143,7 @@ static int bq257xx_regulator_probe(struct platform_device *pdev)
>  	struct regulator_config cfg = {};
>  
>  	pdev->dev.of_node = pdev->dev.parent->of_node;
> -	pdev->dev.of_node_reused = true;
> +	dev_set_of_node_reused(&pdev->dev);
>  
>  	pdata = devm_kzalloc(&pdev->dev, sizeof(struct bq257xx_reg_data), GFP_KERNEL);
>  	if (!pdata)
> diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
> index e66408f23bb6..8297d31cde9f 100644
> --- a/drivers/regulator/rk808-regulator.c
> +++ b/drivers/regulator/rk808-regulator.c
> @@ -2115,7 +2115,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
>  	int ret, i, nregulators;
>  
>  	pdev->dev.of_node = pdev->dev.parent->of_node;
> -	pdev->dev.of_node_reused = true;
> +	dev_set_of_node_reused(&pdev->dev);
>  
>  	regmap = dev_get_regmap(pdev->dev.parent, NULL);
>  	if (!regmap)
> diff --git a/drivers/tty/serial/serial_base_bus.c b/drivers/tty/serial/serial_base_bus.c
> index a12935f6b992..5f23284a8778 100644
> --- a/drivers/tty/serial/serial_base_bus.c
> +++ b/drivers/tty/serial/serial_base_bus.c
> @@ -74,7 +74,7 @@ static int serial_base_device_init(struct uart_port *port,
>  	dev->parent = parent_dev;
>  	dev->bus = &serial_base_bus_type;
>  	dev->release = release;
> -	dev->of_node_reused = true;
> +	dev_set_of_node_reused(dev);
>  
>  	device_set_node(dev, fwnode_handle_get(dev_fwnode(parent_dev)));
>  
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> index 2ecd049dacc2..8b9449d16324 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> @@ -593,7 +593,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
>  		d->gadget.max_speed = USB_SPEED_HIGH;
>  	d->gadget.speed = USB_SPEED_UNKNOWN;
>  	d->gadget.dev.of_node = vhub->pdev->dev.of_node;
> -	d->gadget.dev.of_node_reused = true;
> +	dev_set_of_node_reused(&d->gadget.dev);
>  
>  	rc = usb_add_gadget_udc(d->port_dev, &d->gadget);
>  	if (rc != 0)
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 5b0fb6ad4c72..a79865a212e9 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -483,6 +483,8 @@ struct device_physical_location {
>   *		driver/bus sync_state() callback.
>   * @DEV_FLAG_DMA_COHERENT: This particular device is dma coherent, even if the
>   *		architecture supports non-coherent devices.
> + * @DEV_FLAG_OF_NODE_REUSED: Set if the device-tree node is shared with an
> + *		ancestor device.
>   */
>  enum struct_device_flags {
>  	DEV_FLAG_READY_TO_PROBE = 0,
> @@ -492,6 +494,7 @@ enum struct_device_flags {
>  	DEV_FLAG_DMA_OPS_BYPASS = 4,
>  	DEV_FLAG_STATE_SYNCED = 5,
>  	DEV_FLAG_DMA_COHERENT = 6,
> +	DEV_FLAG_OF_NODE_REUSED = 7,
>  
>  	DEV_FLAG_COUNT
>  };
> @@ -573,8 +576,6 @@ enum struct_device_flags {
>   *
>   * @offline_disabled: If set, the device is permanently online.
>   * @offline:	Set after successful invocation of bus type's .offline().
> - * @of_node_reused: Set if the device-tree node is shared with an ancestor
> - *              device.
>   * @flags:	DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
>   *
>   * At the lowest level, every device in a Linux system is represented by an
> @@ -681,7 +682,6 @@ struct device {
>  
>  	bool			offline_disabled:1;
>  	bool			offline:1;
> -	bool			of_node_reused:1;
>  
>  	DECLARE_BITMAP(flags, DEV_FLAG_COUNT);
>  };
> @@ -715,6 +715,7 @@ __create_dev_flag_accessors(dma_skip_sync, DEV_FLAG_DMA_SKIP_SYNC);
>  __create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DMA_OPS_BYPASS);
>  __create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED);
>  __create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT);
> +__create_dev_flag_accessors(of_node_reused, DEV_FLAG_OF_NODE_REUSED);
>  
>  #undef __create_dev_flag_accessors
>  
> -- 
> 2.53.0.1213.gd9a14994de-goog
> 

-- 
மணிவண்ணன் சதாசிவம்


More information about the Linux-aspeed mailing list