lkml.org 
[lkml]   [2012]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: Linux 3.2.5
    diff --git a/Makefile b/Makefile
    index c8e187e..e9dd0ff 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -1,6 +1,6 @@
    VERSION = 3
    PATCHLEVEL = 2
    -SUBLEVEL = 4
    +SUBLEVEL = 5
    EXTRAVERSION =
    NAME = Saber-toothed Squirrel

    diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
    index 2672c79..7aff631 100644
    --- a/drivers/acpi/pci_root.c
    +++ b/drivers/acpi/pci_root.c
    @@ -596,6 +596,13 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
    if (ACPI_SUCCESS(status)) {
    dev_info(root->bus->bridge,
    "ACPI _OSC control (0x%02x) granted\n", flags);
    + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
    + /*
    + * We have ASPM control, but the FADT indicates
    + * that it's unsupported. Clear it.
    + */
    + pcie_clear_aspm(root->bus);
    + }
    } else {
    dev_info(root->bus->bridge,
    "ACPI _OSC request failed (%s), "
    diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
    index 4ecb640..c8e7585 100644
    --- a/drivers/pci/pci-acpi.c
    +++ b/drivers/pci/pci-acpi.c
    @@ -395,7 +395,6 @@ static int __init acpi_pci_init(void)

    if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
    printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
    - pcie_clear_aspm();
    pcie_no_aspm();
    }

    diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
    index cbfbab1..1cfbf22 100644
    --- a/drivers/pci/pcie/aspm.c
    +++ b/drivers/pci/pcie/aspm.c
    @@ -68,7 +68,7 @@ struct pcie_link_state {
    struct aspm_latency acceptable[8];
    };

    -static int aspm_disabled, aspm_force, aspm_clear_state;
    +static int aspm_disabled, aspm_force;
    static bool aspm_support_enabled = true;
    static DEFINE_MUTEX(aspm_lock);
    static LIST_HEAD(link_list);
    @@ -500,9 +500,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
    int pos;
    u32 reg32;

    - if (aspm_clear_state)
    - return -EINVAL;
    -
    /*
    * Some functions in a slot might not all be PCIe functions,
    * very strange. Disable ASPM for the whole slot
    @@ -574,9 +571,6 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
    pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
    return;

    - if (aspm_disabled && !aspm_clear_state)
    - return;
    -
    /* VIA has a strange chipset, root port is under a bridge */
    if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
    pdev->bus->self)
    @@ -608,7 +602,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
    * the BIOS's expectation, we'll do so once pci_enable_device() is
    * called.
    */
    - if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) {
    + if (aspm_policy != POLICY_POWERSAVE) {
    pcie_config_aspm_path(link);
    pcie_set_clkpm(link, policy_to_clkpm_state(link));
    }
    @@ -649,8 +643,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
    struct pci_dev *parent = pdev->bus->self;
    struct pcie_link_state *link, *root, *parent_link;

    - if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
    - !parent || !parent->link_state)
    + if (!pci_is_pcie(pdev) || !parent || !parent->link_state)
    return;
    if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
    (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
    @@ -734,13 +727,18 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
    * pci_disable_link_state - disable pci device's link state, so the link will
    * never enter specific states
    */
    -static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
    +static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
    + bool force)
    {
    struct pci_dev *parent = pdev->bus->self;
    struct pcie_link_state *link;

    - if (aspm_disabled || !pci_is_pcie(pdev))
    + if (aspm_disabled && !force)
    + return;
    +
    + if (!pci_is_pcie(pdev))
    return;
    +
    if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
    pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
    parent = pdev;
    @@ -768,16 +766,31 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)

    void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
    {
    - __pci_disable_link_state(pdev, state, false);
    + __pci_disable_link_state(pdev, state, false, false);
    }
    EXPORT_SYMBOL(pci_disable_link_state_locked);

    void pci_disable_link_state(struct pci_dev *pdev, int state)
    {
    - __pci_disable_link_state(pdev, state, true);
    + __pci_disable_link_state(pdev, state, true, false);
    }
    EXPORT_SYMBOL(pci_disable_link_state);

    +void pcie_clear_aspm(struct pci_bus *bus)
    +{
    + struct pci_dev *child;
    +
    + /*
    + * Clear any ASPM setup that the firmware has carried out on this bus
    + */
    + list_for_each_entry(child, &bus->devices, bus_list) {
    + __pci_disable_link_state(child, PCIE_LINK_STATE_L0S |
    + PCIE_LINK_STATE_L1 |
    + PCIE_LINK_STATE_CLKPM,
    + false, true);
    + }
    +}
    +
    static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
    {
    int i;
    @@ -935,6 +948,7 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
    static int __init pcie_aspm_disable(char *str)
    {
    if (!strcmp(str, "off")) {
    + aspm_policy = POLICY_DEFAULT;
    aspm_disabled = 1;
    aspm_support_enabled = false;
    printk(KERN_INFO "PCIe ASPM is disabled\n");
    @@ -947,16 +961,18 @@ static int __init pcie_aspm_disable(char *str)

    __setup("pcie_aspm=", pcie_aspm_disable);

    -void pcie_clear_aspm(void)
    -{
    - if (!aspm_force)
    - aspm_clear_state = 1;
    -}
    -
    void pcie_no_aspm(void)
    {
    - if (!aspm_force)
    + /*
    + * Disabling ASPM is intended to prevent the kernel from modifying
    + * existing hardware state, not to clear existing state. To that end:
    + * (a) set policy to POLICY_DEFAULT in order to avoid changing state
    + * (b) prevent userspace from changing policy
    + */
    + if (!aspm_force) {
    + aspm_policy = POLICY_DEFAULT;
    aspm_disabled = 1;
    + }
    }

    /**
    diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
    index 7cea7b6..c832014 100644
    --- a/include/linux/pci-aspm.h
    +++ b/include/linux/pci-aspm.h
    @@ -29,7 +29,7 @@ extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
    extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
    extern void pci_disable_link_state(struct pci_dev *pdev, int state);
    extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
    -extern void pcie_clear_aspm(void);
    +extern void pcie_clear_aspm(struct pci_bus *bus);
    extern void pcie_no_aspm(void);
    #else
    static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
    @@ -47,7 +47,7 @@ static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
    static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
    {
    }
    -static inline void pcie_clear_aspm(void)
    +static inline void pcie_clear_aspm(struct pci_bus *bus)
    {
    }
    static inline void pcie_no_aspm(void)

    \
     
     \ /
      Last update: 2012-02-06 19:19    [W:0.030 / U:89.368 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site