diff options
Diffstat (limited to 'drivers/acpi/scan.c')
| -rw-r--r-- | drivers/acpi/scan.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fb7fc24fe727..189cbc2585fa 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/acpi.h> | 8 | #include <linux/acpi.h> |
| 9 | #include <linux/signal.h> | 9 | #include <linux/signal.h> |
| 10 | #include <linux/kthread.h> | 10 | #include <linux/kthread.h> |
| 11 | #include <linux/dmi.h> | ||
| 11 | 12 | ||
| 12 | #include <acpi/acpi_drivers.h> | 13 | #include <acpi/acpi_drivers.h> |
| 13 | 14 | ||
| @@ -1032,6 +1033,41 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id) | |||
| 1032 | list_add_tail(&id->list, &device->pnp.ids); | 1033 | list_add_tail(&id->list, &device->pnp.ids); |
| 1033 | } | 1034 | } |
| 1034 | 1035 | ||
| 1036 | /* | ||
| 1037 | * Old IBM workstations have a DSDT bug wherein the SMBus object | ||
| 1038 | * lacks the SMBUS01 HID and the methods do not have the necessary "_" | ||
| 1039 | * prefix. Work around this. | ||
| 1040 | */ | ||
| 1041 | static int acpi_ibm_smbus_match(struct acpi_device *device) | ||
| 1042 | { | ||
| 1043 | acpi_handle h_dummy; | ||
| 1044 | struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
| 1045 | int result; | ||
| 1046 | |||
| 1047 | if (!dmi_name_in_vendors("IBM")) | ||
| 1048 | return -ENODEV; | ||
| 1049 | |||
| 1050 | /* Look for SMBS object */ | ||
| 1051 | result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path); | ||
| 1052 | if (result) | ||
| 1053 | return result; | ||
| 1054 | |||
| 1055 | if (strcmp("SMBS", path.pointer)) { | ||
| 1056 | result = -ENODEV; | ||
| 1057 | goto out; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | /* Does it have the necessary (but misnamed) methods? */ | ||
| 1061 | result = -ENODEV; | ||
| 1062 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) && | ||
| 1063 | ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) && | ||
| 1064 | ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy))) | ||
| 1065 | result = 0; | ||
| 1066 | out: | ||
| 1067 | kfree(path.pointer); | ||
| 1068 | return result; | ||
| 1069 | } | ||
| 1070 | |||
| 1035 | static void acpi_device_set_id(struct acpi_device *device) | 1071 | static void acpi_device_set_id(struct acpi_device *device) |
| 1036 | { | 1072 | { |
| 1037 | acpi_status status; | 1073 | acpi_status status; |
| @@ -1082,6 +1118,8 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
| 1082 | acpi_add_id(device, ACPI_BAY_HID); | 1118 | acpi_add_id(device, ACPI_BAY_HID); |
| 1083 | else if (ACPI_SUCCESS(acpi_dock_match(device))) | 1119 | else if (ACPI_SUCCESS(acpi_dock_match(device))) |
| 1084 | acpi_add_id(device, ACPI_DOCK_HID); | 1120 | acpi_add_id(device, ACPI_DOCK_HID); |
| 1121 | else if (!acpi_ibm_smbus_match(device)) | ||
| 1122 | acpi_add_id(device, ACPI_SMBUS_IBM_HID); | ||
| 1085 | 1123 | ||
| 1086 | break; | 1124 | break; |
| 1087 | case ACPI_BUS_TYPE_POWER: | 1125 | case ACPI_BUS_TYPE_POWER: |
