diff options
Diffstat (limited to 'drivers/acpi/sbshc.c')
| -rw-r--r-- | drivers/acpi/sbshc.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 26e5b5060523..bf034f8b7c1a 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 17 | #include <linux/dmi.h> | ||
| 17 | #include "sbshc.h" | 18 | #include "sbshc.h" |
| 18 | 19 | ||
| 19 | #define PREFIX "ACPI: " | 20 | #define PREFIX "ACPI: " |
| @@ -87,6 +88,8 @@ enum acpi_smb_offset { | |||
| 87 | ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ | 88 | ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ |
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 91 | static bool macbook; | ||
| 92 | |||
| 90 | static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) | 93 | static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) |
| 91 | { | 94 | { |
| 92 | return ec_read(hc->offset + address, data); | 95 | return ec_read(hc->offset + address, data); |
| @@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, | |||
| 132 | } | 135 | } |
| 133 | 136 | ||
| 134 | mutex_lock(&hc->lock); | 137 | mutex_lock(&hc->lock); |
| 138 | if (macbook) | ||
| 139 | udelay(5); | ||
| 135 | if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) | 140 | if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) |
| 136 | goto end; | 141 | goto end; |
| 137 | if (temp) { | 142 | if (temp) { |
| @@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | |||
| 257 | acpi_handle handle, acpi_ec_query_func func, | 262 | acpi_handle handle, acpi_ec_query_func func, |
| 258 | void *data); | 263 | void *data); |
| 259 | 264 | ||
| 265 | static int macbook_dmi_match(const struct dmi_system_id *d) | ||
| 266 | { | ||
| 267 | pr_debug("Detected MacBook, enabling workaround\n"); | ||
| 268 | macbook = true; | ||
| 269 | return 0; | ||
| 270 | } | ||
| 271 | |||
| 272 | static struct dmi_system_id acpi_smbus_dmi_table[] = { | ||
| 273 | { macbook_dmi_match, "Apple MacBook", { | ||
| 274 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
| 275 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") }, | ||
| 276 | }, | ||
| 277 | { }, | ||
| 278 | }; | ||
| 279 | |||
| 260 | static int acpi_smbus_hc_add(struct acpi_device *device) | 280 | static int acpi_smbus_hc_add(struct acpi_device *device) |
| 261 | { | 281 | { |
| 262 | int status; | 282 | int status; |
| 263 | unsigned long long val; | 283 | unsigned long long val; |
| 264 | struct acpi_smb_hc *hc; | 284 | struct acpi_smb_hc *hc; |
| 265 | 285 | ||
| 286 | dmi_check_system(acpi_smbus_dmi_table); | ||
| 287 | |||
| 266 | if (!device) | 288 | if (!device) |
| 267 | return -EINVAL; | 289 | return -EINVAL; |
| 268 | 290 | ||
