Contents of /trunk/kernel-magellan/patches-3.2/0104-3.2.5-all-fixes.patch
Parent Directory | Revision Log
Revision 1644 -
(show annotations)
(download)
Thu Feb 16 12:24:52 2012 UTC (12 years, 7 months ago) by niro
File size: 6453 byte(s)
Thu Feb 16 12:24:52 2012 UTC (12 years, 7 months ago) by niro
File size: 6453 byte(s)
-3.2.6-magellan-r1
1 | diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c |
2 | index 2672c79..7aff631 100644 |
3 | --- a/drivers/acpi/pci_root.c |
4 | +++ b/drivers/acpi/pci_root.c |
5 | @@ -596,6 +596,13 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) |
6 | if (ACPI_SUCCESS(status)) { |
7 | dev_info(root->bus->bridge, |
8 | "ACPI _OSC control (0x%02x) granted\n", flags); |
9 | + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { |
10 | + /* |
11 | + * We have ASPM control, but the FADT indicates |
12 | + * that it's unsupported. Clear it. |
13 | + */ |
14 | + pcie_clear_aspm(root->bus); |
15 | + } |
16 | } else { |
17 | dev_info(root->bus->bridge, |
18 | "ACPI _OSC request failed (%s), " |
19 | diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c |
20 | index 4ecb640..c8e7585 100644 |
21 | --- a/drivers/pci/pci-acpi.c |
22 | +++ b/drivers/pci/pci-acpi.c |
23 | @@ -395,7 +395,6 @@ static int __init acpi_pci_init(void) |
24 | |
25 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { |
26 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); |
27 | - pcie_clear_aspm(); |
28 | pcie_no_aspm(); |
29 | } |
30 | |
31 | diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c |
32 | index cbfbab1..1cfbf22 100644 |
33 | --- a/drivers/pci/pcie/aspm.c |
34 | +++ b/drivers/pci/pcie/aspm.c |
35 | @@ -68,7 +68,7 @@ struct pcie_link_state { |
36 | struct aspm_latency acceptable[8]; |
37 | }; |
38 | |
39 | -static int aspm_disabled, aspm_force, aspm_clear_state; |
40 | +static int aspm_disabled, aspm_force; |
41 | static bool aspm_support_enabled = true; |
42 | static DEFINE_MUTEX(aspm_lock); |
43 | static LIST_HEAD(link_list); |
44 | @@ -500,9 +500,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) |
45 | int pos; |
46 | u32 reg32; |
47 | |
48 | - if (aspm_clear_state) |
49 | - return -EINVAL; |
50 | - |
51 | /* |
52 | * Some functions in a slot might not all be PCIe functions, |
53 | * very strange. Disable ASPM for the whole slot |
54 | @@ -574,9 +571,6 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) |
55 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
56 | return; |
57 | |
58 | - if (aspm_disabled && !aspm_clear_state) |
59 | - return; |
60 | - |
61 | /* VIA has a strange chipset, root port is under a bridge */ |
62 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && |
63 | pdev->bus->self) |
64 | @@ -608,7 +602,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) |
65 | * the BIOS's expectation, we'll do so once pci_enable_device() is |
66 | * called. |
67 | */ |
68 | - if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) { |
69 | + if (aspm_policy != POLICY_POWERSAVE) { |
70 | pcie_config_aspm_path(link); |
71 | pcie_set_clkpm(link, policy_to_clkpm_state(link)); |
72 | } |
73 | @@ -649,8 +643,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) |
74 | struct pci_dev *parent = pdev->bus->self; |
75 | struct pcie_link_state *link, *root, *parent_link; |
76 | |
77 | - if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || |
78 | - !parent || !parent->link_state) |
79 | + if (!pci_is_pcie(pdev) || !parent || !parent->link_state) |
80 | return; |
81 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
82 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
83 | @@ -734,13 +727,18 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev) |
84 | * pci_disable_link_state - disable pci device's link state, so the link will |
85 | * never enter specific states |
86 | */ |
87 | -static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) |
88 | +static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, |
89 | + bool force) |
90 | { |
91 | struct pci_dev *parent = pdev->bus->self; |
92 | struct pcie_link_state *link; |
93 | |
94 | - if (aspm_disabled || !pci_is_pcie(pdev)) |
95 | + if (aspm_disabled && !force) |
96 | + return; |
97 | + |
98 | + if (!pci_is_pcie(pdev)) |
99 | return; |
100 | + |
101 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || |
102 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
103 | parent = pdev; |
104 | @@ -768,16 +766,31 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) |
105 | |
106 | void pci_disable_link_state_locked(struct pci_dev *pdev, int state) |
107 | { |
108 | - __pci_disable_link_state(pdev, state, false); |
109 | + __pci_disable_link_state(pdev, state, false, false); |
110 | } |
111 | EXPORT_SYMBOL(pci_disable_link_state_locked); |
112 | |
113 | void pci_disable_link_state(struct pci_dev *pdev, int state) |
114 | { |
115 | - __pci_disable_link_state(pdev, state, true); |
116 | + __pci_disable_link_state(pdev, state, true, false); |
117 | } |
118 | EXPORT_SYMBOL(pci_disable_link_state); |
119 | |
120 | +void pcie_clear_aspm(struct pci_bus *bus) |
121 | +{ |
122 | + struct pci_dev *child; |
123 | + |
124 | + /* |
125 | + * Clear any ASPM setup that the firmware has carried out on this bus |
126 | + */ |
127 | + list_for_each_entry(child, &bus->devices, bus_list) { |
128 | + __pci_disable_link_state(child, PCIE_LINK_STATE_L0S | |
129 | + PCIE_LINK_STATE_L1 | |
130 | + PCIE_LINK_STATE_CLKPM, |
131 | + false, true); |
132 | + } |
133 | +} |
134 | + |
135 | static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp) |
136 | { |
137 | int i; |
138 | @@ -935,6 +948,7 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) |
139 | static int __init pcie_aspm_disable(char *str) |
140 | { |
141 | if (!strcmp(str, "off")) { |
142 | + aspm_policy = POLICY_DEFAULT; |
143 | aspm_disabled = 1; |
144 | aspm_support_enabled = false; |
145 | printk(KERN_INFO "PCIe ASPM is disabled\n"); |
146 | @@ -947,16 +961,18 @@ static int __init pcie_aspm_disable(char *str) |
147 | |
148 | __setup("pcie_aspm=", pcie_aspm_disable); |
149 | |
150 | -void pcie_clear_aspm(void) |
151 | -{ |
152 | - if (!aspm_force) |
153 | - aspm_clear_state = 1; |
154 | -} |
155 | - |
156 | void pcie_no_aspm(void) |
157 | { |
158 | - if (!aspm_force) |
159 | + /* |
160 | + * Disabling ASPM is intended to prevent the kernel from modifying |
161 | + * existing hardware state, not to clear existing state. To that end: |
162 | + * (a) set policy to POLICY_DEFAULT in order to avoid changing state |
163 | + * (b) prevent userspace from changing policy |
164 | + */ |
165 | + if (!aspm_force) { |
166 | + aspm_policy = POLICY_DEFAULT; |
167 | aspm_disabled = 1; |
168 | + } |
169 | } |
170 | |
171 | /** |
172 | diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h |
173 | index 7cea7b6..c832014 100644 |
174 | --- a/include/linux/pci-aspm.h |
175 | +++ b/include/linux/pci-aspm.h |
176 | @@ -29,7 +29,7 @@ extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); |
177 | extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); |
178 | extern void pci_disable_link_state(struct pci_dev *pdev, int state); |
179 | extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state); |
180 | -extern void pcie_clear_aspm(void); |
181 | +extern void pcie_clear_aspm(struct pci_bus *bus); |
182 | extern void pcie_no_aspm(void); |
183 | #else |
184 | static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) |
185 | @@ -47,7 +47,7 @@ static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) |
186 | static inline void pci_disable_link_state(struct pci_dev *pdev, int state) |
187 | { |
188 | } |
189 | -static inline void pcie_clear_aspm(void) |
190 | +static inline void pcie_clear_aspm(struct pci_bus *bus) |
191 | { |
192 | } |
193 | static inline void pcie_no_aspm(void) |