lkml.org 
[lkml]   [2015]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.16.y-ckt 170/185] ACPI / init: Switch over platform to the ACPI mode later
    Date
    3.16.7-ckt15 -stable review patch.  If anyone has any objections, please let me know.

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

    From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

    commit b064a8fa77dfead647564c46ac8fc5b13bd1ab73 upstream.

    Commit 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before
    timekeeping_init()" moved the ACPI subsystem initialization,
    including the ACPI mode enabling, to an earlier point in the
    initialization sequence, to allow the timekeeping subsystem
    use ACPI early. Unfortunately, that resulted in boot regressions
    on some systems and the early ACPI initialization was moved toward
    its original position in the kernel initialization code by commit
    c4e1acbb35e4 "ACPI / init: Invoke early ACPI initialization later".

    However, that turns out to be insufficient, as boot is still broken
    on the Tyan S8812 mainboard.

    To fix that issue, split the ACPI early initialization code into
    two pieces so the majority of it still located in acpi_early_init()
    and the part switching over the platform into the ACPI mode goes into
    a new function, acpi_subsystem_init(), executed at the original early
    ACPI initialization spot.

    That fixes the Tyan S8812 boot problem, but still allows ACPI
    tables to be loaded earlier which is useful to the EFI code in
    efi_enter_virtual_mode().

    Link: https://bugzilla.kernel.org/show_bug.cgi?id=97141
    Fixes: 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before timekeeping_init()"
    Reported-and-tested-by: Marius Tolzmann <tolzmann@molgen.mpg.de>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    Acked-by: Toshi Kani <toshi.kani@hp.com>
    Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
    Reviewed-by: Lee, Chun-Yi <jlee@suse.com>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    drivers/acpi/bus.c | 56 ++++++++++++++++++++++++++++++++++++++--------------
    include/linux/acpi.h | 2 ++
    init/main.c | 1 +
    3 files changed, 44 insertions(+), 15 deletions(-)

    diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
    index c5bc8cfe09fa..60a38349f297 100644
    --- a/drivers/acpi/bus.c
    +++ b/drivers/acpi/bus.c
    @@ -480,6 +480,16 @@ static int __init acpi_bus_init_irq(void)
    u8 acpi_gbl_permanent_mmap;


    +/**
    + * acpi_early_init - Initialize ACPICA and populate the ACPI namespace.
    + *
    + * The ACPI tables are accessible after this, but the handling of events has not
    + * been initialized and the global lock is not available yet, so AML should not
    + * be executed at this point.
    + *
    + * Doing this before switching the EFI runtime services to virtual mode allows
    + * the EfiBootServices memory to be freed slightly earlier on boot.
    + */
    void __init acpi_early_init(void)
    {
    acpi_status status;
    @@ -543,26 +553,42 @@ void __init acpi_early_init(void)
    acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
    }
    #endif
    + return;
    +
    + error0:
    + disable_acpi();
    +}
    +
    +/**
    + * acpi_subsystem_init - Finalize the early initialization of ACPI.
    + *
    + * Switch over the platform to the ACPI mode (if possible), initialize the
    + * handling of ACPI events, install the interrupt and global lock handlers.
    + *
    + * Doing this too early is generally unsafe, but at the same time it needs to be
    + * done before all things that really depend on ACPI. The right spot appears to
    + * be before finalizing the EFI initialization.
    + */
    +void __init acpi_subsystem_init(void)
    +{
    + acpi_status status;
    +
    + if (acpi_disabled)
    + return;

    status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
    if (ACPI_FAILURE(status)) {
    printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
    - goto error0;
    + disable_acpi();
    + } else {
    + /*
    + * If the system is using ACPI then we can be reasonably
    + * confident that any regulators are managed by the firmware
    + * so tell the regulator core it has everything it needs to
    + * know.
    + */
    + regulator_has_full_constraints();
    }
    -
    - /*
    - * If the system is using ACPI then we can be reasonably
    - * confident that any regulators are managed by the firmware
    - * so tell the regulator core it has everything it needs to
    - * know.
    - */
    - regulator_has_full_constraints();
    -
    - return;
    -
    - error0:
    - disable_acpi();
    - return;
    }

    static int __init acpi_bus_init(void)
    diff --git a/include/linux/acpi.h b/include/linux/acpi.h
    index fa91beba3cd0..ef152461bd46 100644
    --- a/include/linux/acpi.h
    +++ b/include/linux/acpi.h
    @@ -406,6 +406,7 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
    #define ACPI_OST_SC_INSERT_NOT_SUPPORTED 0x82

    extern void acpi_early_init(void);
    +extern void acpi_subsystem_init(void);

    extern int acpi_nvs_register(__u64 start, __u64 size);

    @@ -440,6 +441,7 @@ static inline const char *acpi_dev_name(struct acpi_device *adev)
    }

    static inline void acpi_early_init(void) { }
    +static inline void acpi_subsystem_init(void) { }

    static inline int early_acpi_boot_init(void)
    {
    diff --git a/init/main.c b/init/main.c
    index ed5f48edc7a8..44af5b583cf4 100644
    --- a/init/main.c
    +++ b/init/main.c
    @@ -666,6 +666,7 @@ asmlinkage __visible void __init start_kernel(void)

    check_bugs();

    + acpi_subsystem_init();
    sfi_init_late();

    if (efi_enabled(EFI_RUNTIME_SERVICES)) {

    \
     
     \ /
      Last update: 2015-07-15 11:41    [W:2.850 / U:0.584 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site