mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ACPI / utils: Add new acpi_dev_present helper
acpi_dev_found just iterates over all ACPI-ids and sees if one matches. This means that it will return true for devices which are in the DSDT but disabled (their _STA method returns 0). For some drivers it is useful to be able to check if a certain HID is not only present in the namespace, but also actually present as in acpi_device_is_present() will return true for the device. For example because if a certain device is present then the driver will want to use an extcon or IIO ADC channel provided by that device. This commit adds a new acpi_dev_present helper which drivers can use to this end. Like acpi_dev_found, acpi_dev_present take a HID as argument, but it also has 2 extra optional arguments to only check for an ACPI device with a specific UID and/or HRV value. This makes it more generic and allows it to replace custom code doing similar checks in several places. Arguably acpi_dev_present is what acpi_dev_found should have been, but there are too many users to just change acpi_dev_found without the risk of breaking something. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
		
							parent
							
								
									4f7d029b9b
								
							
						
					
					
						commit
						8661423eea
					
				
					 3 changed files with 72 additions and 0 deletions
				
			
		| 
						 | 
					@ -736,6 +736,72 @@ bool acpi_dev_found(const char *hid)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(acpi_dev_found);
 | 
					EXPORT_SYMBOL(acpi_dev_found);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct acpi_dev_present_info {
 | 
				
			||||||
 | 
						struct acpi_device_id hid[2];
 | 
				
			||||||
 | 
						const char *uid;
 | 
				
			||||||
 | 
						s64 hrv;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int acpi_dev_present_cb(struct device *dev, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct acpi_device *adev = to_acpi_device(dev);
 | 
				
			||||||
 | 
						struct acpi_dev_present_info *match = data;
 | 
				
			||||||
 | 
						unsigned long long hrv;
 | 
				
			||||||
 | 
						acpi_status status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (acpi_match_device_ids(adev, match->hid))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (match->uid && (!adev->pnp.unique_id ||
 | 
				
			||||||
 | 
						    strcmp(adev->pnp.unique_id, match->uid)))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (match->hrv == -1)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv);
 | 
				
			||||||
 | 
						if (ACPI_FAILURE(status))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return hrv == match->hrv;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * acpi_dev_present - Detect that a given ACPI device is present
 | 
				
			||||||
 | 
					 * @hid: Hardware ID of the device.
 | 
				
			||||||
 | 
					 * @uid: Unique ID of the device, pass NULL to not check _UID
 | 
				
			||||||
 | 
					 * @hrv: Hardware Revision of the device, pass -1 to not check _HRV
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return %true if a matching device was present at the moment of invocation.
 | 
				
			||||||
 | 
					 * Note that if the device is pluggable, it may since have disappeared.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that unlike acpi_dev_found() this function checks the status
 | 
				
			||||||
 | 
					 * of the device. So for devices which are present in the dsdt, but
 | 
				
			||||||
 | 
					 * which are disabled (their _STA callback returns 0) this function
 | 
				
			||||||
 | 
					 * will return false.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For this function to work, acpi_bus_scan() must have been executed
 | 
				
			||||||
 | 
					 * which happens in the subsys_initcall() subsection. Hence, do not
 | 
				
			||||||
 | 
					 * call from a subsys_initcall() or earlier (use acpi_get_devices()
 | 
				
			||||||
 | 
					 * instead). Calling from module_init() is fine (which is synonymous
 | 
				
			||||||
 | 
					 * with device_initcall()).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct acpi_dev_present_info match = {};
 | 
				
			||||||
 | 
						struct device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
 | 
				
			||||||
 | 
						match.uid = uid;
 | 
				
			||||||
 | 
						match.hrv = hrv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev = bus_find_device(&acpi_bus_type, NULL, &match,
 | 
				
			||||||
 | 
								      acpi_dev_present_cb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return !!dev;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(acpi_dev_present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * acpi_backlight= handling, this is done here rather then in video_detect.c
 | 
					 * acpi_backlight= handling, this is done here rather then in video_detect.c
 | 
				
			||||||
 * because __setup cannot be used in modules.
 | 
					 * because __setup cannot be used in modules.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,6 +88,7 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool acpi_dev_found(const char *hid);
 | 
					bool acpi_dev_found(const char *hid);
 | 
				
			||||||
 | 
					bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_ACPI
 | 
					#ifdef CONFIG_ACPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -611,6 +611,11 @@ static inline bool acpi_dev_found(const char *hid)
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 | 
					static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue