diff options
Diffstat (limited to 'drivers/acpi/utils.c')
-rw-r--r-- | drivers/acpi/utils.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 22c09952e177..27d0dcfcf47d 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -736,6 +736,72 @@ bool acpi_dev_found(const char *hid) | |||
736 | } | 736 | } |
737 | EXPORT_SYMBOL(acpi_dev_found); | 737 | EXPORT_SYMBOL(acpi_dev_found); |
738 | 738 | ||
739 | struct acpi_dev_present_info { | ||
740 | struct acpi_device_id hid[2]; | ||
741 | const char *uid; | ||
742 | s64 hrv; | ||
743 | }; | ||
744 | |||
745 | static int acpi_dev_present_cb(struct device *dev, void *data) | ||
746 | { | ||
747 | struct acpi_device *adev = to_acpi_device(dev); | ||
748 | struct acpi_dev_present_info *match = data; | ||
749 | unsigned long long hrv; | ||
750 | acpi_status status; | ||
751 | |||
752 | if (acpi_match_device_ids(adev, match->hid)) | ||
753 | return 0; | ||
754 | |||
755 | if (match->uid && (!adev->pnp.unique_id || | ||
756 | strcmp(adev->pnp.unique_id, match->uid))) | ||
757 | return 0; | ||
758 | |||
759 | if (match->hrv == -1) | ||
760 | return 1; | ||
761 | |||
762 | status = acpi_evaluate_integer(adev->handle, "_HRV", NULL, &hrv); | ||
763 | if (ACPI_FAILURE(status)) | ||
764 | return 0; | ||
765 | |||
766 | return hrv == match->hrv; | ||
767 | } | ||
768 | |||
769 | /** | ||
770 | * acpi_dev_present - Detect that a given ACPI device is present | ||
771 | * @hid: Hardware ID of the device. | ||
772 | * @uid: Unique ID of the device, pass NULL to not check _UID | ||
773 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV | ||
774 | * | ||
775 | * Return %true if a matching device was present at the moment of invocation. | ||
776 | * Note that if the device is pluggable, it may since have disappeared. | ||
777 | * | ||
778 | * Note that unlike acpi_dev_found() this function checks the status | ||
779 | * of the device. So for devices which are present in the dsdt, but | ||
780 | * which are disabled (their _STA callback returns 0) this function | ||
781 | * will return false. | ||
782 | * | ||
783 | * For this function to work, acpi_bus_scan() must have been executed | ||
784 | * which happens in the subsys_initcall() subsection. Hence, do not | ||
785 | * call from a subsys_initcall() or earlier (use acpi_get_devices() | ||
786 | * instead). Calling from module_init() is fine (which is synonymous | ||
787 | * with device_initcall()). | ||
788 | */ | ||
789 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) | ||
790 | { | ||
791 | struct acpi_dev_present_info match = {}; | ||
792 | struct device *dev; | ||
793 | |||
794 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | ||
795 | match.uid = uid; | ||
796 | match.hrv = hrv; | ||
797 | |||
798 | dev = bus_find_device(&acpi_bus_type, NULL, &match, | ||
799 | acpi_dev_present_cb); | ||
800 | |||
801 | return !!dev; | ||
802 | } | ||
803 | EXPORT_SYMBOL(acpi_dev_present); | ||
804 | |||
739 | /* | 805 | /* |
740 | * acpi_backlight= handling, this is done here rather then in video_detect.c | 806 | * acpi_backlight= handling, this is done here rather then in video_detect.c |
741 | * because __setup cannot be used in modules. | 807 | * because __setup cannot be used in modules. |