sst-match-acpi.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * sst_match_apci.c - SST (LPE) match for ACPI enumeration.
  3. *
  4. * Copyright (c) 2013-15, Intel Corporation.
  5. *
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms and conditions of the GNU General Public License,
  9. * version 2, as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. */
  16. #include "sst-acpi.h"
  17. static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level,
  18. void *context, void **ret)
  19. {
  20. struct acpi_device *adev;
  21. const char *name = NULL;
  22. if (acpi_bus_get_device(handle, &adev))
  23. return AE_OK;
  24. if (adev->status.present && adev->status.functional) {
  25. name = acpi_dev_name(adev);
  26. *(const char **)ret = name;
  27. return AE_CTRL_TERMINATE;
  28. }
  29. return AE_OK;
  30. }
  31. const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
  32. {
  33. const char *name = NULL;
  34. acpi_status status;
  35. status = acpi_get_devices(hid, sst_acpi_find_name, NULL,
  36. (void **)&name);
  37. if (ACPI_FAILURE(status) || name[0] == '\0')
  38. return NULL;
  39. return name;
  40. }
  41. EXPORT_SYMBOL_GPL(sst_acpi_find_name_from_hid);
  42. static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
  43. void *context, void **ret)
  44. {
  45. unsigned long long sta;
  46. acpi_status status;
  47. *(bool *)context = true;
  48. status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
  49. if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
  50. *(bool *)context = false;
  51. return AE_OK;
  52. }
  53. struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
  54. {
  55. struct sst_acpi_mach *mach;
  56. bool found = false;
  57. for (mach = machines; mach->id[0]; mach++)
  58. if (ACPI_SUCCESS(acpi_get_devices(mach->id,
  59. sst_acpi_mach_match,
  60. &found, NULL)) && found)
  61. return mach;
  62. return NULL;
  63. }
  64. EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
  65. static acpi_status sst_acpi_find_package(acpi_handle handle, u32 level,
  66. void *context, void **ret)
  67. {
  68. struct acpi_device *adev;
  69. acpi_status status = AE_OK;
  70. struct sst_acpi_package_context *pkg_ctx = context;
  71. pkg_ctx->data_valid = false;
  72. if (acpi_bus_get_device(handle, &adev))
  73. return AE_OK;
  74. if (adev->status.present && adev->status.functional) {
  75. struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
  76. union acpi_object *myobj = NULL;
  77. status = acpi_evaluate_object_typed(handle, pkg_ctx->name,
  78. NULL, &buffer,
  79. ACPI_TYPE_PACKAGE);
  80. if (ACPI_FAILURE(status))
  81. return AE_OK;
  82. myobj = buffer.pointer;
  83. if (!myobj || myobj->package.count != pkg_ctx->length) {
  84. kfree(buffer.pointer);
  85. return AE_OK;
  86. }
  87. status = acpi_extract_package(myobj,
  88. pkg_ctx->format, pkg_ctx->state);
  89. if (ACPI_FAILURE(status)) {
  90. kfree(buffer.pointer);
  91. return AE_OK;
  92. }
  93. kfree(buffer.pointer);
  94. pkg_ctx->data_valid = true;
  95. return AE_CTRL_TERMINATE;
  96. }
  97. return AE_OK;
  98. }
  99. bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
  100. struct sst_acpi_package_context *ctx)
  101. {
  102. acpi_status status;
  103. status = acpi_get_devices(hid, sst_acpi_find_package, ctx, NULL);
  104. if (ACPI_FAILURE(status) || !ctx->data_valid)
  105. return false;
  106. return true;
  107. }
  108. EXPORT_SYMBOL_GPL(sst_acpi_find_package_from_hid);
  109. MODULE_LICENSE("GPL v2");
  110. MODULE_DESCRIPTION("Intel Common ACPI Match module");