Skip to content

Commit 3349fb6

Browse files
chrisbainbridgerafaeljw
authored andcommitted
ACPI / SBS: Add 5 us delay to fix SBS hangs on MacBook
Commit 7bc5a2b 'ACPI: Support _OSI("Darwin") correctly' caused the MacBook firmware to expose the SBS, resulting in intermittent hangs of several minutes on boot, and failure to detect or report the battery. Fix this by adding a 5 us delay to the start of each SMBUS transaction. This timing is the result of experimentation - hangs were observed with 3 us but never with 5 us. Fixes: 7bc5a2b 'ACPI: Support _OSI("Darwin") correctly' Link: https://bugzilla.kernel.org/show_bug.cgi?id=94651 Signed-off-by: Chris Bainbridge <chris.bainbridge@gmail.com> Cc: 3.18+ <stable@vger.kernel.org> # 3.18+ [ rjw: Subject and changelog ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 61f8ff6 commit 3349fb6

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

drivers/acpi/sbshc.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/delay.h>
1515
#include <linux/module.h>
1616
#include <linux/interrupt.h>
17+
#include <linux/dmi.h>
1718
#include "sbshc.h"
1819

1920
#define PREFIX "ACPI: "
@@ -87,6 +88,8 @@ enum acpi_smb_offset {
8788
ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
8889
};
8990

91+
static bool macbook;
92+
9093
static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
9194
{
9295
return ec_read(hc->offset + address, data);
@@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol,
132135
}
133136

134137
mutex_lock(&hc->lock);
138+
if (macbook)
139+
udelay(5);
135140
if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
136141
goto end;
137142
if (temp) {
@@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
257262
acpi_handle handle, acpi_ec_query_func func,
258263
void *data);
259264

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+
260280
static int acpi_smbus_hc_add(struct acpi_device *device)
261281
{
262282
int status;
263283
unsigned long long val;
264284
struct acpi_smb_hc *hc;
265285

286+
dmi_check_system(acpi_smbus_dmi_table);
287+
266288
if (!device)
267289
return -EINVAL;
268290

0 commit comments

Comments
 (0)