lkml.org 
[lkml]   [2008]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 43/46] ACPI: EC: wait for last write gpe
    2.6.27-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Alexey Starikovskiy <astarikovskiy@suse.de>

    commit dd15f8c42af09031e27da5b4d697ce925511f2e1 upstream.

    There is a possibility that EC might break if next command is
    issued within 1 us after write or burst-disable command.

    Suggestd-by: Zhao Yakui <yakui.zhao@intel.com>
    Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
    Signed-off-by: Len Brown <len.brown@intel.com>
    Cc: Rafael J. Wysocki <rjw@sisk.pl>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/acpi/ec.c | 21 +++++++++++++--------
    1 file changed, 13 insertions(+), 8 deletions(-)

    --- a/drivers/acpi/ec.c
    +++ b/drivers/acpi/ec.c
    @@ -102,6 +102,7 @@ struct transaction {
    u8 command;
    u8 wlen;
    u8 rlen;
    + bool done;
    };

    static struct acpi_ec {
    @@ -178,7 +179,7 @@ static int ec_transaction_done(struct ac
    unsigned long flags;
    int ret = 0;
    spin_lock_irqsave(&ec->curr_lock, flags);
    - if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
    + if (!ec->curr || ec->curr->done)
    ret = 1;
    spin_unlock_irqrestore(&ec->curr_lock, flags);
    return ret;
    @@ -195,17 +196,20 @@ static void gpe_transaction(struct acpi_
    acpi_ec_write_data(ec, *(ec->curr->wdata++));
    --ec->curr->wlen;
    } else
    - /* false interrupt, state didn't change */
    - ++ec->curr->irq_count;
    -
    + goto err;
    } else if (ec->curr->rlen > 0) {
    if ((status & ACPI_EC_FLAG_OBF) == 1) {
    *(ec->curr->rdata++) = acpi_ec_read_data(ec);
    - --ec->curr->rlen;
    + if (--ec->curr->rlen == 0)
    + ec->curr->done = true;
    } else
    - /* false interrupt, state didn't change */
    - ++ec->curr->irq_count;
    - }
    + goto err;
    + } else if (ec->curr->wlen == 0 && (status & ACPI_EC_FLAG_IBF) == 0)
    + ec->curr->done = true;
    + goto unlock;
    +err:
    + /* false interrupt, state didn't change */
    + ++ec->curr->irq_count;
    unlock:
    spin_unlock_irqrestore(&ec->curr_lock, flags);
    }
    @@ -265,6 +269,7 @@ static int acpi_ec_transaction_unlocked(
    spin_lock_irqsave(&ec->curr_lock, tmp);
    /* following two actions should be kept atomic */
    t->irq_count = 0;
    + t->done = false;
    ec->curr = t;
    acpi_ec_write_cmd(ec, ec->curr->command);
    if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
    --


    \
     
     \ /
      Last update: 2008-11-17 08:39    [W:4.143 / U:0.148 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site