• Lv Zheng's avatar
    ACPI / EC: Add asynchronous command byte write support · f92fca00
    Lv Zheng authored
    Move the first command byte write into advance_transaction() so that all
    EC register accesses that can affect the command processing state machine
    can happen in this asynchronous state machine advancement function.
    
    The advance_transaction() function then can be a complete implementation
    of an asyncrhonous transaction for a single command so that:
     1. The first command byte can be written in the interrupt context;
     2. The command completion waiter can also be used to wait the first command
        byte's timeout;
     3. In BURST mode, the follow-up command bytes can be written in the
        interrupt context directly, so that it doesn't need to return to the
        task context. Returning to the task context reduces the throughput of
        the BURST mode and in the worst cases where the system workload is very
        high, this leads to the hardware driven automatic BURST mode exit.
    
    In order not to increase memory consumption, convert 'done' into 'flags'
    to contain multiple indications:
     1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition,
        indicating the completion of the command transaction.
     2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first
        command byte. A new command can utilize this flag to compete for the
        right of accessing the underlying hardware. There is a follow-up bug
        fix that has utilized this new flag.
    
    The 2 flags are important because it also reflects a key concept of IO
    programs' design used in the system softwares. Normally an IO program
    running in the kernel should first be implemented in the asynchronous way.
    And the 2 flags are the most common way to implement its synchronous
    operations on top of the asynchronous operations:
    1. POLL: This flag can be used to block until the asynchronous operations
             can happen.
    2. COMPLETE: This flag can be used to block until the asynchronous
                 operations have completed.
    By constructing code cleanly in this way, many difficult problems can be
    solved smoothly.
    
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911Reported-and-tested-by: default avatarGareth Williams <gareth@garethwilliams.me.uk>
    Reported-and-tested-by: default avatarHans de Goede <jwrdegoede@fedoraproject.org>
    Reported-by: default avatarBarton Xu <tank.xuhan@gmail.com>
    Tested-by: default avatarSteffen Weber <steffen.weber@gmail.com>
    Tested-by: default avatarArthur Chen <axchen@nvidia.com>
    Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
    Cc: All applicable <stable@vger.kernel.org>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    f92fca00
ec.c 29.9 KB