[libcamera-devel] [PATCH v8 2/9] libcamera: sysfs: Add helper to lookup device firmware node path

Laurent Pinchart laurent.pinchart at ideasonboard.com
Wed Aug 5 15:27:17 CEST 2020


Hi Niklas,

Thank you for the patch.

On Wed, Aug 05, 2020 at 12:48:53PM +0200, Niklas Söderlund wrote:
> A system's firmware description is recorded differently in sysfs
> depending if the system uses DT or ACPI. Add a helper to abstract
> this, allowing users not to care which of the two are used.
> 
> For DT-based systems, the path is the full name of the DT node that
> represents the device. For ACPI-based systems, the path is the absolute
> namespace path to the ACPI object that represents the device. In both
> cases, the path is guaranteed to be unique and persistent as long as the
> system firmware is not modified.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> * Changes since v7
> - Rename function to firmwareNodePath()
> - Rename argument to device
> - Return firmware path instead of passing storage as argument
> - Update documentation
> - Keep leading slash for DT-based paths
> - Use File::exists()
> ---
>  include/libcamera/internal/sysfs.h |  2 ++
>  src/libcamera/sysfs.cpp            | 57 ++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+)
> 
> diff --git a/include/libcamera/internal/sysfs.h b/include/libcamera/internal/sysfs.h
> index 247a376ab7e0e8ee..bc6c1620b55d43a2 100644
> --- a/include/libcamera/internal/sysfs.h
> +++ b/include/libcamera/internal/sysfs.h
> @@ -15,6 +15,8 @@ namespace sysfs {
>  
>  std::string charDevPath(const std::string &deviceNode);
>  
> +std::string firmwareNodePath(const std::string &device);
> +
>  } /* namespace sysfs */
>  
>  } /* namespace libcamera */
> diff --git a/src/libcamera/sysfs.cpp b/src/libcamera/sysfs.cpp
> index 398df2c2be114908..39fe0c468f5e703a 100644
> --- a/src/libcamera/sysfs.cpp
> +++ b/src/libcamera/sysfs.cpp
> @@ -7,10 +7,12 @@
>  
>  #include "libcamera/internal/sysfs.h"
>  
> +#include <fstream>
>  #include <sstream>
>  #include <sys/stat.h>
>  #include <sys/sysmacros.h>
>  
> +#include "libcamera/internal/file.h"
>  #include "libcamera/internal/log.h"
>  
>  /**
> @@ -47,6 +49,61 @@ std::string charDevPath(const std::string &deviceNode)
>  	return dev.str();
>  }
>  
> +/**
> + * \brief Retrieve the path of the firmware node for a device
> + * \param[in] device Path in sysfs to search
> + *
> + * Physical devices in a system are described by the system firmware. Depending
> + * on the type of platform, devices are identified using different naming
> + * schemes. The Linux kernel abstract those differences with "firmware nodes".
> + * This function retrieves the firmware node path corresponding to the
> + * \a device.
> + *
> + * For DT-based systems, the path is the full name of the DT node that
> + * represents the device. For ACPI-based systems, the path is the absolute
> + * namespace path to the ACPI object that represents the device. In both cases,
> + * the path is guaranteed to be unique and persistent as long as the system
> + * firmware is not modified.
> + *
> + * \return The firmware node path on success or an empty string on failure
> + */
> +std::string firmwareNodePath(const std::string &device)
> +{
> +	std::string fwPath, node;
> +
> +	/* Lookup for DT-based systems */
> +	node = device + "/of_node";
> +	if (File::exists(node)) {
> +		char *ofPath = realpath(node.c_str(), nullptr);
> +		if (!ofPath)
> +			return {};
> +
> +		fwPath = ofPath;
> +		free(ofPath);
> +
> +		static const std::string dropStr = "/sys/firmware/devicetree";
> +		if (fwPath.find(dropStr) == 0)
> +			fwPath.erase(0, dropStr.length());
> +
> +		return fwPath;

Maybe a bit more efficient

		static const char prefix[] = "/sys/firmware/devicetree";
		if (strncmp(ofPath, prefix, strlen(prefix)) == 0)
			fwPath = ofPath + strlen(prefix);
		else
			fwPath = ofPath

		free(ofPath);

		return fwPath;

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> +	}
> +
> +	/* Lookup for ACPI-based systems */
> +	node = device + "/firmware_node/path";
> +	if (File::exists(node)) {
> +		std::ifstream file(node);
> +		if (!file.is_open())
> +			return {};
> +
> +		std::getline(file, fwPath);
> +		file.close();
> +
> +		return fwPath;
> +	}
> +
> +	return {};
> +}
> +
>  } /* namespace sysfs */
>  
>  } /* namespace libcamera */

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list