EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
EC_FLAGS_QUERY_PENDING, /* Query is pending */
EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
-- - - EC_FLAGS_ONLY_IBF_GPE, /* Expect GPE only for IBF = 0 event */
++ + + EC_FLAGS_NO_ADDRESS_GPE, /* Expect GPE only for non-address event */
++ + + EC_FLAGS_ADDRESS, /* Address is being written */
++ + + EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */
++ + + EC_FLAGS_WDATA, /* Data is being written */
+++++++ ++ ++ EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */
};
static int acpi_ec_remove(struct acpi_device *device, int type);
static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
{
-- - - return inb(ec->command_addr);
++ + + u8 x = inb(ec->command_addr);
- --- - -- pr_debug(PREFIX "---> status = 0x%2x\n", x);
+++++++ ++ ++ pr_debug(PREFIX "---> status = 0x%2.2x\n", x);
++ + + return x;
}
static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
{
- --- - -- pr_debug(PREFIX "---> data = 0x%2x\n", x);
++ + + u8 x = inb(ec->data_addr);
+++++++ ++ ++ pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
return inb(ec->data_addr);
}
static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
{
- --- - -- pr_debug(PREFIX "<--- command = 0x%2x\n", command);
+++++++ ++ ++ pr_debug(PREFIX "<--- command = 0x%2.2x\n", command);
outb(command, ec->command_addr);
}
static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
{
- --- - -- pr_debug(PREFIX "<--- data = 0x%2x\n", data);
+++++++ ++ ++ pr_debug(PREFIX "<--- data = 0x%2.2x\n", data);
outb(data, ec->data_addr);
}
static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
{
++ + + int ret = 0;
+++++++ ++ ++
+++++++ ++ ++ if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
+++++++ ++ ++ test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
+++++++ ++ ++ force_poll = 1;
++ + + if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
++ + + test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
++ + + force_poll = 1;
++ + + if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) &&
++ + + test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags)))
++ + + force_poll = 1;
if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
likely(!force_poll)) {
if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
msecs_to_jiffies(ACPI_EC_DELAY)))
-- - - return 0;
++ + + goto end;
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
if (acpi_ec_check_status(ec, event)) {
- --- - -- if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
+ +++ + ++ if (event == ACPI_EC_EVENT_OBF_1) {
-- - - /* miss OBF = 1 GPE, don't expect it anymore */
-- - - printk(KERN_INFO PREFIX "missing OBF_1 confirmation,"
-- - - "switching to degraded mode.\n");
-- - - set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags);
+++++++ ++ ++ /* miss OBF_1 GPE, don't expect it */
+++++++ ++ ++ pr_info(PREFIX "missing OBF confirmation, "
+++++++ ++ ++ "don't expect it any longer.\n");
+++++++ ++ ++ set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
+++++++ ++ ++ } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
++ + + /* miss address GPE, don't expect it anymore */
++ + + pr_info(PREFIX "missing address confirmation, "
++ + + "don't expect it any longer.\n");
++ + + set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags);
++ + + } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) {
++ + + /* miss write data GPE, don't expect it */
++ + + pr_info(PREFIX "missing write data confirmation, "
++ + + "don't expect it any longer.\n");
++ + + set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags);
} else {
/* missing GPEs, switch back to poll mode */
-- - - printk(KERN_INFO PREFIX "missing IBF_1 confirmations,"
-- - - "switch off interrupt mode.\n");
++ + + if (printk_ratelimit())
++ + + pr_info(PREFIX "missing confirmations, "
++ + + "switch off interrupt mode.\n");
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
}
-- - - return 0;
++ + + goto end;
}
} else {
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
/* Check that acpi_get_devices actually find something */
if (ACPI_FAILURE(status) || !boot_ec->handle)
goto error;
- --- - -- goto error;
++ + + /* We really need to limit this workaround, the only ASUS,
++ + + * which needs it, has fake EC._INI method, so use it as flag.
+++++++ ++ ++ * Keep boot_ec struct as it will be needed soon.
++ + + */
++ + + if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x)))
+++++++ ++ ++ return -ENODEV;
}
ret = ec_install_handlers(boot_ec);
__setup("acpi_os_name=", acpi_os_name_setup);
------- -- --static void enable_osi_linux(int enable) {
+++++++ ++ ++static void __init set_osi_linux(unsigned int enable)
+++++++ ++ ++{
+++++++ ++ ++ if (osi_linux.enable != enable) {
+++++++ ++ ++ osi_linux.enable = enable;
+++++++ ++ ++ printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
+++++++ ++ ++ enable ? "Add": "Delet");
+++++++ ++ ++ }
+++++++ ++ ++ return;
+++++++ ++ ++}
+++++++ + ++
- if (osi_linux != enable)
- printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
- enable ? "En": "Dis");
+++++++ ++ ++static void __init acpi_cmdline_osi_linux(unsigned int enable)
+++++++ ++ ++{
+++++++ ++ ++ osi_linux.cmdline = 1; /* cmdline set the default */
+++++++ ++ ++ set_osi_linux(enable);
+++++++ ++ ++
+++++++ ++ ++ return;
+++++++ ++ ++}
+++++++ ++ ++
+++++++ ++ ++void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
+++++++ ++ ++{
+++++++ ++ ++ osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
+ +++ ++ ++
-- - if (osi_linux != enable)
-- - printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
-- - enable ? "En": "Dis");
+++++++ ++ ++ printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
+++++++ ++ ++
+++++++ ++ ++ if (enable == -1)
+++++++ ++ ++ return;
+++++++ ++ ++
+++++++ ++ ++ osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
++ + +
- --- - -- if (osi_linux != enable)
- --- - -- printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
- --- - -- enable ? "En": "Dis");
+++++++ ++ ++ set_osi_linux(enable);
------- -- -- osi_linux = enable;
return;
}