~ubuntu-branches/ubuntu/quantal/linux-lowlatency/quantal

« back to all changes in this revision

Viewing changes to drivers/pci/pcie/aspm.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-04kado7d1u2er2rl
Tags: 3.2.0-16.25
Add new lowlatency kernel flavour

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
        struct aspm_latency acceptable[8];
69
69
};
70
70
 
71
 
static int aspm_disabled, aspm_force, aspm_clear_state;
 
71
static int aspm_disabled, aspm_force;
72
72
static bool aspm_support_enabled = true;
73
73
static DEFINE_MUTEX(aspm_lock);
74
74
static LIST_HEAD(link_list);
500
500
        int pos;
501
501
        u32 reg32;
502
502
 
503
 
        if (aspm_clear_state)
504
 
                return -EINVAL;
505
 
 
506
503
        /*
507
504
         * Some functions in a slot might not all be PCIe functions,
508
505
         * very strange. Disable ASPM for the whole slot
574
571
            pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
575
572
                return;
576
573
 
577
 
        if (aspm_disabled && !aspm_clear_state)
578
 
                return;
579
 
 
580
574
        /* VIA has a strange chipset, root port is under a bridge */
581
575
        if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
582
576
            pdev->bus->self)
608
602
         * the BIOS's expectation, we'll do so once pci_enable_device() is
609
603
         * called.
610
604
         */
611
 
        if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) {
 
605
        if (aspm_policy != POLICY_POWERSAVE) {
612
606
                pcie_config_aspm_path(link);
613
607
                pcie_set_clkpm(link, policy_to_clkpm_state(link));
614
608
        }
649
643
        struct pci_dev *parent = pdev->bus->self;
650
644
        struct pcie_link_state *link, *root, *parent_link;
651
645
 
652
 
        if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
653
 
            !parent || !parent->link_state)
 
646
        if (!pci_is_pcie(pdev) || !parent || !parent->link_state)
654
647
                return;
655
648
        if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
656
649
            (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
734
727
 * pci_disable_link_state - disable pci device's link state, so the link will
735
728
 * never enter specific states
736
729
 */
737
 
static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 
730
static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
 
731
                                     bool force)
738
732
{
739
733
        struct pci_dev *parent = pdev->bus->self;
740
734
        struct pcie_link_state *link;
741
735
 
742
 
        if (aspm_disabled || !pci_is_pcie(pdev))
743
 
                return;
 
736
        if (aspm_disabled && !force)
 
737
                return;
 
738
 
 
739
        if (!pci_is_pcie(pdev))
 
740
                return;
 
741
 
744
742
        if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
745
743
            pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
746
744
                parent = pdev;
768
766
 
769
767
void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
770
768
{
771
 
        __pci_disable_link_state(pdev, state, false);
 
769
        __pci_disable_link_state(pdev, state, false, false);
772
770
}
773
771
EXPORT_SYMBOL(pci_disable_link_state_locked);
774
772
 
775
773
void pci_disable_link_state(struct pci_dev *pdev, int state)
776
774
{
777
 
        __pci_disable_link_state(pdev, state, true);
 
775
        __pci_disable_link_state(pdev, state, true, false);
778
776
}
779
777
EXPORT_SYMBOL(pci_disable_link_state);
780
778
 
 
779
void pcie_clear_aspm(struct pci_bus *bus)
 
780
{
 
781
        struct pci_dev *child;
 
782
 
 
783
        /*
 
784
         * Clear any ASPM setup that the firmware has carried out on this bus
 
785
         */
 
786
        list_for_each_entry(child, &bus->devices, bus_list) {
 
787
                __pci_disable_link_state(child, PCIE_LINK_STATE_L0S |
 
788
                                         PCIE_LINK_STATE_L1 |
 
789
                                         PCIE_LINK_STATE_CLKPM,
 
790
                                         false, true);
 
791
        }
 
792
}
 
793
 
781
794
static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
782
795
{
783
796
        int i;
935
948
static int __init pcie_aspm_disable(char *str)
936
949
{
937
950
        if (!strcmp(str, "off")) {
 
951
                aspm_policy = POLICY_DEFAULT;
938
952
                aspm_disabled = 1;
939
953
                aspm_support_enabled = false;
940
954
                printk(KERN_INFO "PCIe ASPM is disabled\n");
947
961
 
948
962
__setup("pcie_aspm=", pcie_aspm_disable);
949
963
 
950
 
void pcie_clear_aspm(void)
951
 
{
952
 
        if (!aspm_force)
953
 
                aspm_clear_state = 1;
954
 
}
955
 
 
956
964
void pcie_no_aspm(void)
957
965
{
958
 
        if (!aspm_force)
 
966
        /*
 
967
         * Disabling ASPM is intended to prevent the kernel from modifying
 
968
         * existing hardware state, not to clear existing state. To that end:
 
969
         * (a) set policy to POLICY_DEFAULT in order to avoid changing state
 
970
         * (b) prevent userspace from changing policy
 
971
         */
 
972
        if (!aspm_force) {
 
973
                aspm_policy = POLICY_DEFAULT;
959
974
                aspm_disabled = 1;
 
975
        }
960
976
}
961
977
 
962
978
/**