1 |
commit: a838f1a04fa377a8802ee180e41f322299a2660d |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Apr 12 18:01:04 2017 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Apr 12 18:01:04 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a838f1a0 |
7 |
|
8 |
Linux patch 4.9.22 |
9 |
|
10 |
0000_README | 4 + |
11 |
1021_linux-4.9.22.patch | 6069 +++++++++++++++++++++++++++++++++++++++++++++++ |
12 |
2 files changed, 6073 insertions(+) |
13 |
|
14 |
diff --git a/0000_README b/0000_README |
15 |
index 76c6f86..9eac63e 100644 |
16 |
--- a/0000_README |
17 |
+++ b/0000_README |
18 |
@@ -127,6 +127,10 @@ Patch: 1020_linux-4.9.21.patch |
19 |
From: http://www.kernel.org |
20 |
Desc: Linux 4.9.21 |
21 |
|
22 |
+Patch: 1021_linux-4.9.22.patch |
23 |
+From: http://www.kernel.org |
24 |
+Desc: Linux 4.9.22 |
25 |
+ |
26 |
Patch: 1500_XATTR_USER_PREFIX.patch |
27 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
28 |
Desc: Support for namespace user.pax.* on tmpfs. |
29 |
|
30 |
diff --git a/1021_linux-4.9.22.patch b/1021_linux-4.9.22.patch |
31 |
new file mode 100644 |
32 |
index 0000000..68b5b54 |
33 |
--- /dev/null |
34 |
+++ b/1021_linux-4.9.22.patch |
35 |
@@ -0,0 +1,6069 @@ |
36 |
+diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt |
37 |
+index ef5fbe9a77c7..ad440a2b8051 100644 |
38 |
+--- a/Documentation/devicetree/bindings/arm/arch_timer.txt |
39 |
++++ b/Documentation/devicetree/bindings/arm/arch_timer.txt |
40 |
+@@ -38,6 +38,11 @@ to deliver its interrupts via SPIs. |
41 |
+ architecturally-defined reset values. Only supported for 32-bit |
42 |
+ systems which follow the ARMv7 architected reset values. |
43 |
+ |
44 |
++- arm,no-tick-in-suspend : The main counter does not tick when the system is in |
45 |
++ low-power system suspend on some SoCs. This behavior does not match the |
46 |
++ Architecture Reference Manual's specification that the system counter "must |
47 |
++ be implemented in an always-on power domain." |
48 |
++ |
49 |
+ |
50 |
+ Example: |
51 |
+ |
52 |
+diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt |
53 |
+index b95696d748c7..4f7ae7555758 100644 |
54 |
+--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt |
55 |
++++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt |
56 |
+@@ -28,6 +28,8 @@ The TCON acts as a timing controller for RGB, LVDS and TV interfaces. |
57 |
+ Required properties: |
58 |
+ - compatible: value must be either: |
59 |
+ * allwinner,sun5i-a13-tcon |
60 |
++ * allwinner,sun6i-a31-tcon |
61 |
++ * allwinner,sun6i-a31s-tcon |
62 |
+ * allwinner,sun8i-a33-tcon |
63 |
+ - reg: base address and size of memory-mapped region |
64 |
+ - interrupts: interrupt associated to this IP |
65 |
+@@ -50,7 +52,7 @@ Required properties: |
66 |
+ second the block connected to the TCON channel 1 (usually the TV |
67 |
+ encoder) |
68 |
+ |
69 |
+-On the A13, there is one more clock required: |
70 |
++On SoCs other than the A33, there is one more clock required: |
71 |
+ - 'tcon-ch1': The clock driving the TCON channel 1 |
72 |
+ |
73 |
+ DRC |
74 |
+@@ -87,6 +89,7 @@ system. |
75 |
+ Required properties: |
76 |
+ - compatible: value must be one of: |
77 |
+ * allwinner,sun5i-a13-display-backend |
78 |
++ * allwinner,sun6i-a31-display-backend |
79 |
+ * allwinner,sun8i-a33-display-backend |
80 |
+ - reg: base address and size of the memory-mapped region. |
81 |
+ - clocks: phandles to the clocks feeding the frontend and backend |
82 |
+@@ -117,6 +120,7 @@ deinterlacing and color space conversion. |
83 |
+ Required properties: |
84 |
+ - compatible: value must be one of: |
85 |
+ * allwinner,sun5i-a13-display-frontend |
86 |
++ * allwinner,sun6i-a31-display-frontend |
87 |
+ * allwinner,sun8i-a33-display-frontend |
88 |
+ - reg: base address and size of the memory-mapped region. |
89 |
+ - interrupts: interrupt associated to this IP |
90 |
+@@ -142,6 +146,8 @@ extra node. |
91 |
+ Required properties: |
92 |
+ - compatible: value must be one of: |
93 |
+ * allwinner,sun5i-a13-display-engine |
94 |
++ * allwinner,sun6i-a31-display-engine |
95 |
++ * allwinner,sun6i-a31s-display-engine |
96 |
+ * allwinner,sun8i-a33-display-engine |
97 |
+ |
98 |
+ - allwinner,pipelines: list of phandle to the display engine |
99 |
+diff --git a/Documentation/devicetree/bindings/usb/usb-xhci.txt b/Documentation/devicetree/bindings/usb/usb-xhci.txt |
100 |
+index 966885c636d0..7790c819859a 100644 |
101 |
+--- a/Documentation/devicetree/bindings/usb/usb-xhci.txt |
102 |
++++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt |
103 |
+@@ -26,6 +26,7 @@ Required properties: |
104 |
+ Optional properties: |
105 |
+ - clocks: reference to a clock |
106 |
+ - usb3-lpm-capable: determines if platform is USB3 LPM capable |
107 |
++ - quirk-broken-port-ped: set if the controller has broken port disable mechanism |
108 |
+ |
109 |
+ Example: |
110 |
+ usb@f0931000 { |
111 |
+diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt |
112 |
+index 8f3d96af81d7..1f6e101e299a 100644 |
113 |
+--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt |
114 |
++++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt |
115 |
+@@ -6,10 +6,11 @@ occurred. |
116 |
+ |
117 |
+ Required properties: |
118 |
+ - compatible : should be one among the following |
119 |
+- (a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs |
120 |
+- (b) "samsung,exynos5250-wdt" for Exynos5250 |
121 |
+- (c) "samsung,exynos5420-wdt" for Exynos5420 |
122 |
+- (c) "samsung,exynos7-wdt" for Exynos7 |
123 |
++ - "samsung,s3c2410-wdt" for S3C2410 |
124 |
++ - "samsung,s3c6410-wdt" for S3C6410, S5PV210 and Exynos4 |
125 |
++ - "samsung,exynos5250-wdt" for Exynos5250 |
126 |
++ - "samsung,exynos5420-wdt" for Exynos5420 |
127 |
++ - "samsung,exynos7-wdt" for Exynos7 |
128 |
+ |
129 |
+ - reg : base physical address of the controller and length of memory mapped |
130 |
+ region. |
131 |
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt |
132 |
+index 65b05ba6ef98..a6fadef92d6d 100644 |
133 |
+--- a/Documentation/kernel-parameters.txt |
134 |
++++ b/Documentation/kernel-parameters.txt |
135 |
+@@ -305,6 +305,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted. |
136 |
+ use by PCI |
137 |
+ Format: <irq>,<irq>... |
138 |
+ |
139 |
++ acpi_mask_gpe= [HW,ACPI] |
140 |
++ Due to the existence of _Lxx/_Exx, some GPEs triggered |
141 |
++ by unsupported hardware/firmware features can result in |
142 |
++ GPE floodings that cannot be automatically disabled by |
143 |
++ the GPE dispatcher. |
144 |
++ This facility can be used to prevent such uncontrolled |
145 |
++ GPE floodings. |
146 |
++ Format: <int> |
147 |
++ Support masking of GPEs numbered from 0x00 to 0x7f. |
148 |
++ |
149 |
+ acpi_no_auto_serialize [HW,ACPI] |
150 |
+ Disable auto-serialization of AML methods |
151 |
+ AML control methods that contain the opcodes to create |
152 |
+diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt |
153 |
+index 4d82e31b7958..501af5d5feba 100644 |
154 |
+--- a/Documentation/stable_kernel_rules.txt |
155 |
++++ b/Documentation/stable_kernel_rules.txt |
156 |
+@@ -124,7 +124,7 @@ specified in the following format in the sign-off area: |
157 |
+ |
158 |
+ .. code-block:: none |
159 |
+ |
160 |
+- Cc: <stable@×××××××××××.org> # 3.3.x- |
161 |
++ Cc: <stable@×××××××××××.org> # 3.3.x |
162 |
+ |
163 |
+ The tag has the meaning of: |
164 |
+ |
165 |
+diff --git a/Makefile b/Makefile |
166 |
+index 1523557bd61f..4bf4648d97db 100644 |
167 |
+--- a/Makefile |
168 |
++++ b/Makefile |
169 |
+@@ -1,6 +1,6 @@ |
170 |
+ VERSION = 4 |
171 |
+ PATCHLEVEL = 9 |
172 |
+-SUBLEVEL = 21 |
173 |
++SUBLEVEL = 22 |
174 |
+ EXTRAVERSION = |
175 |
+ NAME = Roaring Lionus |
176 |
+ |
177 |
+@@ -370,7 +370,7 @@ LDFLAGS_MODULE = |
178 |
+ CFLAGS_KERNEL = |
179 |
+ AFLAGS_KERNEL = |
180 |
+ LDFLAGS_vmlinux = |
181 |
+-CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized |
182 |
++CFLAGS_GCOV := -fprofile-arcs -ftest-coverage -fno-tree-loop-im $(call cc-disable-warning,maybe-uninitialized,) |
183 |
+ CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) |
184 |
+ |
185 |
+ |
186 |
+diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi |
187 |
+index 8f79b4147bba..acdcbf99a22f 100644 |
188 |
+--- a/arch/arm/boot/dts/stih407-family.dtsi |
189 |
++++ b/arch/arm/boot/dts/stih407-family.dtsi |
190 |
+@@ -680,6 +680,7 @@ |
191 |
+ phy-names = "usb2-phy", "usb3-phy"; |
192 |
+ phys = <&usb2_picophy0>, |
193 |
+ <&phy_port2 PHY_TYPE_USB3>; |
194 |
++ snps,dis_u3_susphy_quirk; |
195 |
+ }; |
196 |
+ }; |
197 |
+ |
198 |
+diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c |
199 |
+index 7e45f69a0ddc..8e8d20cdbce7 100644 |
200 |
+--- a/arch/arm/kernel/armksyms.c |
201 |
++++ b/arch/arm/kernel/armksyms.c |
202 |
+@@ -178,6 +178,6 @@ EXPORT_SYMBOL(__pv_offset); |
203 |
+ #endif |
204 |
+ |
205 |
+ #ifdef CONFIG_HAVE_ARM_SMCCC |
206 |
+-EXPORT_SYMBOL(arm_smccc_smc); |
207 |
+-EXPORT_SYMBOL(arm_smccc_hvc); |
208 |
++EXPORT_SYMBOL(__arm_smccc_smc); |
209 |
++EXPORT_SYMBOL(__arm_smccc_hvc); |
210 |
+ #endif |
211 |
+diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S |
212 |
+index 2e48b674aab1..e5d43066b889 100644 |
213 |
+--- a/arch/arm/kernel/smccc-call.S |
214 |
++++ b/arch/arm/kernel/smccc-call.S |
215 |
+@@ -46,17 +46,19 @@ UNWIND( .fnend) |
216 |
+ /* |
217 |
+ * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, |
218 |
+ * unsigned long a3, unsigned long a4, unsigned long a5, |
219 |
+- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) |
220 |
++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, |
221 |
++ * struct arm_smccc_quirk *quirk) |
222 |
+ */ |
223 |
+-ENTRY(arm_smccc_smc) |
224 |
++ENTRY(__arm_smccc_smc) |
225 |
+ SMCCC SMCCC_SMC |
226 |
+-ENDPROC(arm_smccc_smc) |
227 |
++ENDPROC(__arm_smccc_smc) |
228 |
+ |
229 |
+ /* |
230 |
+ * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, |
231 |
+ * unsigned long a3, unsigned long a4, unsigned long a5, |
232 |
+- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) |
233 |
++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, |
234 |
++ * struct arm_smccc_quirk *quirk) |
235 |
+ */ |
236 |
+-ENTRY(arm_smccc_hvc) |
237 |
++ENTRY(__arm_smccc_hvc) |
238 |
+ SMCCC SMCCC_HVC |
239 |
+-ENDPROC(arm_smccc_hvc) |
240 |
++ENDPROC(__arm_smccc_hvc) |
241 |
+diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c |
242 |
+index a5265edbeeab..2fd5c135e8a4 100644 |
243 |
+--- a/arch/arm/kvm/mmu.c |
244 |
++++ b/arch/arm/kvm/mmu.c |
245 |
+@@ -292,11 +292,18 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) |
246 |
+ phys_addr_t addr = start, end = start + size; |
247 |
+ phys_addr_t next; |
248 |
+ |
249 |
++ assert_spin_locked(&kvm->mmu_lock); |
250 |
+ pgd = kvm->arch.pgd + stage2_pgd_index(addr); |
251 |
+ do { |
252 |
+ next = stage2_pgd_addr_end(addr, end); |
253 |
+ if (!stage2_pgd_none(*pgd)) |
254 |
+ unmap_stage2_puds(kvm, pgd, addr, next); |
255 |
++ /* |
256 |
++ * If the range is too large, release the kvm->mmu_lock |
257 |
++ * to prevent starvation and lockup detector warnings. |
258 |
++ */ |
259 |
++ if (next != end) |
260 |
++ cond_resched_lock(&kvm->mmu_lock); |
261 |
+ } while (pgd++, addr = next, addr != end); |
262 |
+ } |
263 |
+ |
264 |
+@@ -803,6 +810,7 @@ void stage2_unmap_vm(struct kvm *kvm) |
265 |
+ int idx; |
266 |
+ |
267 |
+ idx = srcu_read_lock(&kvm->srcu); |
268 |
++ down_read(¤t->mm->mmap_sem); |
269 |
+ spin_lock(&kvm->mmu_lock); |
270 |
+ |
271 |
+ slots = kvm_memslots(kvm); |
272 |
+@@ -810,6 +818,7 @@ void stage2_unmap_vm(struct kvm *kvm) |
273 |
+ stage2_unmap_memslot(kvm, memslot); |
274 |
+ |
275 |
+ spin_unlock(&kvm->mmu_lock); |
276 |
++ up_read(¤t->mm->mmap_sem); |
277 |
+ srcu_read_unlock(&kvm->srcu, idx); |
278 |
+ } |
279 |
+ |
280 |
+@@ -829,7 +838,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) |
281 |
+ if (kvm->arch.pgd == NULL) |
282 |
+ return; |
283 |
+ |
284 |
++ spin_lock(&kvm->mmu_lock); |
285 |
+ unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); |
286 |
++ spin_unlock(&kvm->mmu_lock); |
287 |
++ |
288 |
+ /* Free the HW pgd, one page at a time */ |
289 |
+ free_pages_exact(kvm->arch.pgd, S2_PGD_SIZE); |
290 |
+ kvm->arch.pgd = NULL; |
291 |
+@@ -1804,6 +1816,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, |
292 |
+ (KVM_PHYS_SIZE >> PAGE_SHIFT)) |
293 |
+ return -EFAULT; |
294 |
+ |
295 |
++ down_read(¤t->mm->mmap_sem); |
296 |
+ /* |
297 |
+ * A memory region could potentially cover multiple VMAs, and any holes |
298 |
+ * between them, so iterate over all of them to find out if we can map |
299 |
+@@ -1847,8 +1860,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, |
300 |
+ pa += vm_start - vma->vm_start; |
301 |
+ |
302 |
+ /* IO region dirty page logging not allowed */ |
303 |
+- if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) |
304 |
+- return -EINVAL; |
305 |
++ if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) { |
306 |
++ ret = -EINVAL; |
307 |
++ goto out; |
308 |
++ } |
309 |
+ |
310 |
+ ret = kvm_phys_addr_ioremap(kvm, gpa, pa, |
311 |
+ vm_end - vm_start, |
312 |
+@@ -1860,7 +1875,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, |
313 |
+ } while (hva < reg_end); |
314 |
+ |
315 |
+ if (change == KVM_MR_FLAGS_ONLY) |
316 |
+- return ret; |
317 |
++ goto out; |
318 |
+ |
319 |
+ spin_lock(&kvm->mmu_lock); |
320 |
+ if (ret) |
321 |
+@@ -1868,6 +1883,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, |
322 |
+ else |
323 |
+ stage2_flush_memslot(kvm, memslot); |
324 |
+ spin_unlock(&kvm->mmu_lock); |
325 |
++out: |
326 |
++ up_read(¤t->mm->mmap_sem); |
327 |
+ return ret; |
328 |
+ } |
329 |
+ |
330 |
+diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c |
331 |
+index c9f7e9274aa8..aed44dcdfd30 100644 |
332 |
+--- a/arch/arm/mach-davinci/da8xx-dt.c |
333 |
++++ b/arch/arm/mach-davinci/da8xx-dt.c |
334 |
+@@ -46,6 +46,7 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = { |
335 |
+ static void __init da850_init_machine(void) |
336 |
+ { |
337 |
+ of_platform_default_populate(NULL, da850_auxdata_lookup, NULL); |
338 |
++ davinci_pm_init(); |
339 |
+ } |
340 |
+ |
341 |
+ static const char *const da850_boards_compat[] __initconst = { |
342 |
+diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi |
343 |
+index af450413b9dd..f2eb12c6ed83 100644 |
344 |
+--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi |
345 |
++++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi |
346 |
+@@ -590,7 +590,7 @@ |
347 |
+ reg = <0 0xa2000000 0 0x10000>; |
348 |
+ sas-addr = [50 01 88 20 16 00 00 00]; |
349 |
+ hisilicon,sas-syscon = <&pcie_subctl>; |
350 |
+- am-max-trans; |
351 |
++ hip06-sas-v2-quirk-amt; |
352 |
+ ctrl-reset-reg = <0xa18>; |
353 |
+ ctrl-reset-sts-reg = <0x5a0c>; |
354 |
+ ctrl-clock-ena-reg = <0x318>; |
355 |
+diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c |
356 |
+index 78f368039c79..e9c4dc9e0ada 100644 |
357 |
+--- a/arch/arm64/kernel/arm64ksyms.c |
358 |
++++ b/arch/arm64/kernel/arm64ksyms.c |
359 |
+@@ -73,5 +73,5 @@ NOKPROBE_SYMBOL(_mcount); |
360 |
+ #endif |
361 |
+ |
362 |
+ /* arm-smccc */ |
363 |
+-EXPORT_SYMBOL(arm_smccc_smc); |
364 |
+-EXPORT_SYMBOL(arm_smccc_hvc); |
365 |
++EXPORT_SYMBOL(__arm_smccc_smc); |
366 |
++EXPORT_SYMBOL(__arm_smccc_hvc); |
367 |
+diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c |
368 |
+index 4a2f0f0fef32..c58ddf8c4062 100644 |
369 |
+--- a/arch/arm64/kernel/asm-offsets.c |
370 |
++++ b/arch/arm64/kernel/asm-offsets.c |
371 |
+@@ -140,8 +140,11 @@ int main(void) |
372 |
+ DEFINE(SLEEP_STACK_DATA_SYSTEM_REGS, offsetof(struct sleep_stack_data, system_regs)); |
373 |
+ DEFINE(SLEEP_STACK_DATA_CALLEE_REGS, offsetof(struct sleep_stack_data, callee_saved_regs)); |
374 |
+ #endif |
375 |
+- DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); |
376 |
+- DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); |
377 |
++ DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); |
378 |
++ DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); |
379 |
++ DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); |
380 |
++ DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); |
381 |
++ |
382 |
+ BLANK(); |
383 |
+ DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); |
384 |
+ DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address)); |
385 |
+diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c |
386 |
+index acf38722457b..409abc45bdb6 100644 |
387 |
+--- a/arch/arm64/kernel/pci.c |
388 |
++++ b/arch/arm64/kernel/pci.c |
389 |
+@@ -121,6 +121,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) |
390 |
+ static struct pci_config_window * |
391 |
+ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) |
392 |
+ { |
393 |
++ struct device *dev = &root->device->dev; |
394 |
+ struct resource *bus_res = &root->secondary; |
395 |
+ u16 seg = root->segment; |
396 |
+ struct pci_config_window *cfg; |
397 |
+@@ -132,8 +133,7 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) |
398 |
+ root->mcfg_addr = pci_mcfg_lookup(seg, bus_res); |
399 |
+ |
400 |
+ if (!root->mcfg_addr) { |
401 |
+- dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", |
402 |
+- seg, bus_res); |
403 |
++ dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res); |
404 |
+ return NULL; |
405 |
+ } |
406 |
+ |
407 |
+@@ -141,11 +141,10 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) |
408 |
+ cfgres.start = root->mcfg_addr + bus_res->start * bsz; |
409 |
+ cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; |
410 |
+ cfgres.flags = IORESOURCE_MEM; |
411 |
+- cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, |
412 |
+- &pci_generic_ecam_ops); |
413 |
++ cfg = pci_ecam_create(dev, &cfgres, bus_res, &pci_generic_ecam_ops); |
414 |
+ if (IS_ERR(cfg)) { |
415 |
+- dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", |
416 |
+- seg, bus_res, PTR_ERR(cfg)); |
417 |
++ dev_err(dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, |
418 |
++ PTR_ERR(cfg)); |
419 |
+ return NULL; |
420 |
+ } |
421 |
+ |
422 |
+@@ -159,33 +158,36 @@ static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) |
423 |
+ |
424 |
+ ri = container_of(ci, struct acpi_pci_generic_root_info, common); |
425 |
+ pci_ecam_free(ri->cfg); |
426 |
++ kfree(ci->ops); |
427 |
+ kfree(ri); |
428 |
+ } |
429 |
+ |
430 |
+-static struct acpi_pci_root_ops acpi_pci_root_ops = { |
431 |
+- .release_info = pci_acpi_generic_release_info, |
432 |
+-}; |
433 |
+- |
434 |
+ /* Interface called from ACPI code to setup PCI host controller */ |
435 |
+ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) |
436 |
+ { |
437 |
+ int node = acpi_get_node(root->device->handle); |
438 |
+ struct acpi_pci_generic_root_info *ri; |
439 |
+ struct pci_bus *bus, *child; |
440 |
++ struct acpi_pci_root_ops *root_ops; |
441 |
+ |
442 |
+ ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); |
443 |
+ if (!ri) |
444 |
+ return NULL; |
445 |
+ |
446 |
++ root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node); |
447 |
++ if (!root_ops) |
448 |
++ return NULL; |
449 |
++ |
450 |
+ ri->cfg = pci_acpi_setup_ecam_mapping(root); |
451 |
+ if (!ri->cfg) { |
452 |
+ kfree(ri); |
453 |
++ kfree(root_ops); |
454 |
+ return NULL; |
455 |
+ } |
456 |
+ |
457 |
+- acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; |
458 |
+- bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, |
459 |
+- ri->cfg); |
460 |
++ root_ops->release_info = pci_acpi_generic_release_info; |
461 |
++ root_ops->pci_ops = &ri->cfg->ops->pci_ops; |
462 |
++ bus = acpi_pci_root_create(root, root_ops, &ri->common, ri->cfg); |
463 |
+ if (!bus) |
464 |
+ return NULL; |
465 |
+ |
466 |
+diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S |
467 |
+index ae0496fa4235..62522342e1e4 100644 |
468 |
+--- a/arch/arm64/kernel/smccc-call.S |
469 |
++++ b/arch/arm64/kernel/smccc-call.S |
470 |
+@@ -12,6 +12,7 @@ |
471 |
+ * |
472 |
+ */ |
473 |
+ #include <linux/linkage.h> |
474 |
++#include <linux/arm-smccc.h> |
475 |
+ #include <asm/asm-offsets.h> |
476 |
+ |
477 |
+ .macro SMCCC instr |
478 |
+@@ -20,24 +21,32 @@ |
479 |
+ ldr x4, [sp] |
480 |
+ stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] |
481 |
+ stp x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS] |
482 |
+- ret |
483 |
++ ldr x4, [sp, #8] |
484 |
++ cbz x4, 1f /* no quirk structure */ |
485 |
++ ldr x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS] |
486 |
++ cmp x9, #ARM_SMCCC_QUIRK_QCOM_A6 |
487 |
++ b.ne 1f |
488 |
++ str x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS] |
489 |
++1: ret |
490 |
+ .cfi_endproc |
491 |
+ .endm |
492 |
+ |
493 |
+ /* |
494 |
+ * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, |
495 |
+ * unsigned long a3, unsigned long a4, unsigned long a5, |
496 |
+- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) |
497 |
++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, |
498 |
++ * struct arm_smccc_quirk *quirk) |
499 |
+ */ |
500 |
+-ENTRY(arm_smccc_smc) |
501 |
++ENTRY(__arm_smccc_smc) |
502 |
+ SMCCC smc |
503 |
+-ENDPROC(arm_smccc_smc) |
504 |
++ENDPROC(__arm_smccc_smc) |
505 |
+ |
506 |
+ /* |
507 |
+ * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, |
508 |
+ * unsigned long a3, unsigned long a4, unsigned long a5, |
509 |
+- * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) |
510 |
++ * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, |
511 |
++ * struct arm_smccc_quirk *quirk) |
512 |
+ */ |
513 |
+-ENTRY(arm_smccc_hvc) |
514 |
++ENTRY(__arm_smccc_hvc) |
515 |
+ SMCCC hvc |
516 |
+-ENDPROC(arm_smccc_hvc) |
517 |
++ENDPROC(__arm_smccc_hvc) |
518 |
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c |
519 |
+index 0f8788374815..8b8ac3db4092 100644 |
520 |
+--- a/arch/arm64/mm/fault.c |
521 |
++++ b/arch/arm64/mm/fault.c |
522 |
+@@ -41,7 +41,20 @@ |
523 |
+ #include <asm/pgtable.h> |
524 |
+ #include <asm/tlbflush.h> |
525 |
+ |
526 |
+-static const char *fault_name(unsigned int esr); |
527 |
++struct fault_info { |
528 |
++ int (*fn)(unsigned long addr, unsigned int esr, |
529 |
++ struct pt_regs *regs); |
530 |
++ int sig; |
531 |
++ int code; |
532 |
++ const char *name; |
533 |
++}; |
534 |
++ |
535 |
++static const struct fault_info fault_info[]; |
536 |
++ |
537 |
++static inline const struct fault_info *esr_to_fault_info(unsigned int esr) |
538 |
++{ |
539 |
++ return fault_info + (esr & 63); |
540 |
++} |
541 |
+ |
542 |
+ #ifdef CONFIG_KPROBES |
543 |
+ static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) |
544 |
+@@ -196,10 +209,12 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, |
545 |
+ struct pt_regs *regs) |
546 |
+ { |
547 |
+ struct siginfo si; |
548 |
++ const struct fault_info *inf; |
549 |
+ |
550 |
+ if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) { |
551 |
++ inf = esr_to_fault_info(esr); |
552 |
+ pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", |
553 |
+- tsk->comm, task_pid_nr(tsk), fault_name(esr), sig, |
554 |
++ tsk->comm, task_pid_nr(tsk), inf->name, sig, |
555 |
+ addr, esr); |
556 |
+ show_pte(tsk->mm, addr); |
557 |
+ show_regs(regs); |
558 |
+@@ -218,14 +233,16 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re |
559 |
+ { |
560 |
+ struct task_struct *tsk = current; |
561 |
+ struct mm_struct *mm = tsk->active_mm; |
562 |
++ const struct fault_info *inf; |
563 |
+ |
564 |
+ /* |
565 |
+ * If we are in kernel mode at this point, we have no context to |
566 |
+ * handle this fault with. |
567 |
+ */ |
568 |
+- if (user_mode(regs)) |
569 |
+- __do_user_fault(tsk, addr, esr, SIGSEGV, SEGV_MAPERR, regs); |
570 |
+- else |
571 |
++ if (user_mode(regs)) { |
572 |
++ inf = esr_to_fault_info(esr); |
573 |
++ __do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs); |
574 |
++ } else |
575 |
+ __do_kernel_fault(mm, addr, esr, regs); |
576 |
+ } |
577 |
+ |
578 |
+@@ -481,12 +498,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) |
579 |
+ return 1; |
580 |
+ } |
581 |
+ |
582 |
+-static const struct fault_info { |
583 |
+- int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); |
584 |
+- int sig; |
585 |
+- int code; |
586 |
+- const char *name; |
587 |
+-} fault_info[] = { |
588 |
++static const struct fault_info fault_info[] = { |
589 |
+ { do_bad, SIGBUS, 0, "ttbr address size fault" }, |
590 |
+ { do_bad, SIGBUS, 0, "level 1 address size fault" }, |
591 |
+ { do_bad, SIGBUS, 0, "level 2 address size fault" }, |
592 |
+@@ -553,19 +565,13 @@ static const struct fault_info { |
593 |
+ { do_bad, SIGBUS, 0, "unknown 63" }, |
594 |
+ }; |
595 |
+ |
596 |
+-static const char *fault_name(unsigned int esr) |
597 |
+-{ |
598 |
+- const struct fault_info *inf = fault_info + (esr & 63); |
599 |
+- return inf->name; |
600 |
+-} |
601 |
+- |
602 |
+ /* |
603 |
+ * Dispatch a data abort to the relevant handler. |
604 |
+ */ |
605 |
+ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, |
606 |
+ struct pt_regs *regs) |
607 |
+ { |
608 |
+- const struct fault_info *inf = fault_info + (esr & 63); |
609 |
++ const struct fault_info *inf = esr_to_fault_info(esr); |
610 |
+ struct siginfo info; |
611 |
+ |
612 |
+ if (!inf->fn(addr, esr, regs)) |
613 |
+diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h |
614 |
+index 273e61225c27..07238b39638c 100644 |
615 |
+--- a/arch/metag/include/asm/uaccess.h |
616 |
++++ b/arch/metag/include/asm/uaccess.h |
617 |
+@@ -197,20 +197,21 @@ extern long __must_check strnlen_user(const char __user *src, long count); |
618 |
+ |
619 |
+ #define strlen_user(str) strnlen_user(str, 32767) |
620 |
+ |
621 |
+-extern unsigned long __must_check __copy_user_zeroing(void *to, |
622 |
+- const void __user *from, |
623 |
+- unsigned long n); |
624 |
++extern unsigned long raw_copy_from_user(void *to, const void __user *from, |
625 |
++ unsigned long n); |
626 |
+ |
627 |
+ static inline unsigned long |
628 |
+ copy_from_user(void *to, const void __user *from, unsigned long n) |
629 |
+ { |
630 |
++ unsigned long res = n; |
631 |
+ if (likely(access_ok(VERIFY_READ, from, n))) |
632 |
+- return __copy_user_zeroing(to, from, n); |
633 |
+- memset(to, 0, n); |
634 |
+- return n; |
635 |
++ res = raw_copy_from_user(to, from, n); |
636 |
++ if (unlikely(res)) |
637 |
++ memset(to + (n - res), 0, res); |
638 |
++ return res; |
639 |
+ } |
640 |
+ |
641 |
+-#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) |
642 |
++#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n) |
643 |
+ #define __copy_from_user_inatomic __copy_from_user |
644 |
+ |
645 |
+ extern unsigned long __must_check __copy_user(void __user *to, |
646 |
+diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c |
647 |
+index b3ebfe9c8e88..2792fc621088 100644 |
648 |
+--- a/arch/metag/lib/usercopy.c |
649 |
++++ b/arch/metag/lib/usercopy.c |
650 |
+@@ -29,7 +29,6 @@ |
651 |
+ COPY \ |
652 |
+ "1:\n" \ |
653 |
+ " .section .fixup,\"ax\"\n" \ |
654 |
+- " MOV D1Ar1,#0\n" \ |
655 |
+ FIXUP \ |
656 |
+ " MOVT D1Ar1,#HI(1b)\n" \ |
657 |
+ " JUMP D1Ar1,#LO(1b)\n" \ |
658 |
+@@ -260,27 +259,31 @@ |
659 |
+ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
660 |
+ "22:\n" \ |
661 |
+ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
662 |
+- "SUB %3, %3, #32\n" \ |
663 |
+ "23:\n" \ |
664 |
+- "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
665 |
++ "SUB %3, %3, #32\n" \ |
666 |
+ "24:\n" \ |
667 |
++ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
668 |
++ "25:\n" \ |
669 |
+ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
670 |
++ "26:\n" \ |
671 |
+ "SUB %3, %3, #32\n" \ |
672 |
+ "DCACHE [%1+#-64], D0Ar6\n" \ |
673 |
+ "BR $Lloop"id"\n" \ |
674 |
+ \ |
675 |
+ "MOV RAPF, %1\n" \ |
676 |
+- "25:\n" \ |
677 |
++ "27:\n" \ |
678 |
+ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
679 |
+- "26:\n" \ |
680 |
++ "28:\n" \ |
681 |
+ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
682 |
++ "29:\n" \ |
683 |
+ "SUB %3, %3, #32\n" \ |
684 |
+- "27:\n" \ |
685 |
++ "30:\n" \ |
686 |
+ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
687 |
+- "28:\n" \ |
688 |
++ "31:\n" \ |
689 |
+ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
690 |
++ "32:\n" \ |
691 |
+ "SUB %0, %0, #8\n" \ |
692 |
+- "29:\n" \ |
693 |
++ "33:\n" \ |
694 |
+ "SETL [%0++], D0.7, D1.7\n" \ |
695 |
+ "SUB %3, %3, #32\n" \ |
696 |
+ "1:" \ |
697 |
+@@ -312,11 +315,15 @@ |
698 |
+ " .long 26b,3b\n" \ |
699 |
+ " .long 27b,3b\n" \ |
700 |
+ " .long 28b,3b\n" \ |
701 |
+- " .long 29b,4b\n" \ |
702 |
++ " .long 29b,3b\n" \ |
703 |
++ " .long 30b,3b\n" \ |
704 |
++ " .long 31b,3b\n" \ |
705 |
++ " .long 32b,3b\n" \ |
706 |
++ " .long 33b,4b\n" \ |
707 |
+ " .previous\n" \ |
708 |
+ : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ |
709 |
+ : "0" (to), "1" (from), "2" (ret), "3" (n) \ |
710 |
+- : "D1Ar1", "D0Ar2", "memory") |
711 |
++ : "D1Ar1", "D0Ar2", "cc", "memory") |
712 |
+ |
713 |
+ /* rewind 'to' and 'from' pointers when a fault occurs |
714 |
+ * |
715 |
+@@ -342,7 +349,7 @@ |
716 |
+ #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ |
717 |
+ __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ |
718 |
+ "LSR D0Ar2, D0Ar2, #8\n" \ |
719 |
+- "AND D0Ar2, D0Ar2, #0x7\n" \ |
720 |
++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ |
721 |
+ "ADDZ D0Ar2, D0Ar2, #4\n" \ |
722 |
+ "SUB D0Ar2, D0Ar2, #1\n" \ |
723 |
+ "MOV D1Ar1, #4\n" \ |
724 |
+@@ -403,47 +410,55 @@ |
725 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
726 |
+ "22:\n" \ |
727 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
728 |
+- "SUB %3, %3, #16\n" \ |
729 |
+ "23:\n" \ |
730 |
+- "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
731 |
+- "24:\n" \ |
732 |
+- "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
733 |
+ "SUB %3, %3, #16\n" \ |
734 |
+- "25:\n" \ |
735 |
++ "24:\n" \ |
736 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
737 |
+- "26:\n" \ |
738 |
++ "25:\n" \ |
739 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
740 |
++ "26:\n" \ |
741 |
+ "SUB %3, %3, #16\n" \ |
742 |
+ "27:\n" \ |
743 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
744 |
+ "28:\n" \ |
745 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
746 |
++ "29:\n" \ |
747 |
++ "SUB %3, %3, #16\n" \ |
748 |
++ "30:\n" \ |
749 |
++ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
750 |
++ "31:\n" \ |
751 |
++ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
752 |
++ "32:\n" \ |
753 |
+ "SUB %3, %3, #16\n" \ |
754 |
+ "DCACHE [%1+#-64], D0Ar6\n" \ |
755 |
+ "BR $Lloop"id"\n" \ |
756 |
+ \ |
757 |
+ "MOV RAPF, %1\n" \ |
758 |
+- "29:\n" \ |
759 |
++ "33:\n" \ |
760 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
761 |
+- "30:\n" \ |
762 |
++ "34:\n" \ |
763 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
764 |
++ "35:\n" \ |
765 |
+ "SUB %3, %3, #16\n" \ |
766 |
+- "31:\n" \ |
767 |
++ "36:\n" \ |
768 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
769 |
+- "32:\n" \ |
770 |
++ "37:\n" \ |
771 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
772 |
++ "38:\n" \ |
773 |
+ "SUB %3, %3, #16\n" \ |
774 |
+- "33:\n" \ |
775 |
++ "39:\n" \ |
776 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
777 |
+- "34:\n" \ |
778 |
++ "40:\n" \ |
779 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
780 |
++ "41:\n" \ |
781 |
+ "SUB %3, %3, #16\n" \ |
782 |
+- "35:\n" \ |
783 |
++ "42:\n" \ |
784 |
+ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ |
785 |
+- "36:\n" \ |
786 |
++ "43:\n" \ |
787 |
+ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ |
788 |
++ "44:\n" \ |
789 |
+ "SUB %0, %0, #4\n" \ |
790 |
+- "37:\n" \ |
791 |
++ "45:\n" \ |
792 |
+ "SETD [%0++], D0.7\n" \ |
793 |
+ "SUB %3, %3, #16\n" \ |
794 |
+ "1:" \ |
795 |
+@@ -483,11 +498,19 @@ |
796 |
+ " .long 34b,3b\n" \ |
797 |
+ " .long 35b,3b\n" \ |
798 |
+ " .long 36b,3b\n" \ |
799 |
+- " .long 37b,4b\n" \ |
800 |
++ " .long 37b,3b\n" \ |
801 |
++ " .long 38b,3b\n" \ |
802 |
++ " .long 39b,3b\n" \ |
803 |
++ " .long 40b,3b\n" \ |
804 |
++ " .long 41b,3b\n" \ |
805 |
++ " .long 42b,3b\n" \ |
806 |
++ " .long 43b,3b\n" \ |
807 |
++ " .long 44b,3b\n" \ |
808 |
++ " .long 45b,4b\n" \ |
809 |
+ " .previous\n" \ |
810 |
+ : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ |
811 |
+ : "0" (to), "1" (from), "2" (ret), "3" (n) \ |
812 |
+- : "D1Ar1", "D0Ar2", "memory") |
813 |
++ : "D1Ar1", "D0Ar2", "cc", "memory") |
814 |
+ |
815 |
+ /* rewind 'to' and 'from' pointers when a fault occurs |
816 |
+ * |
817 |
+@@ -513,7 +536,7 @@ |
818 |
+ #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ |
819 |
+ __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ |
820 |
+ "LSR D0Ar2, D0Ar2, #8\n" \ |
821 |
+- "AND D0Ar2, D0Ar2, #0x7\n" \ |
822 |
++ "ANDS D0Ar2, D0Ar2, #0x7\n" \ |
823 |
+ "ADDZ D0Ar2, D0Ar2, #4\n" \ |
824 |
+ "SUB D0Ar2, D0Ar2, #1\n" \ |
825 |
+ "MOV D1Ar1, #4\n" \ |
826 |
+@@ -538,23 +561,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, |
827 |
+ if ((unsigned long) src & 1) { |
828 |
+ __asm_copy_to_user_1(dst, src, retn); |
829 |
+ n--; |
830 |
++ if (retn) |
831 |
++ return retn + n; |
832 |
+ } |
833 |
+ if ((unsigned long) dst & 1) { |
834 |
+ /* Worst case - byte copy */ |
835 |
+ while (n > 0) { |
836 |
+ __asm_copy_to_user_1(dst, src, retn); |
837 |
+ n--; |
838 |
++ if (retn) |
839 |
++ return retn + n; |
840 |
+ } |
841 |
+ } |
842 |
+ if (((unsigned long) src & 2) && n >= 2) { |
843 |
+ __asm_copy_to_user_2(dst, src, retn); |
844 |
+ n -= 2; |
845 |
++ if (retn) |
846 |
++ return retn + n; |
847 |
+ } |
848 |
+ if ((unsigned long) dst & 2) { |
849 |
+ /* Second worst case - word copy */ |
850 |
+ while (n >= 2) { |
851 |
+ __asm_copy_to_user_2(dst, src, retn); |
852 |
+ n -= 2; |
853 |
++ if (retn) |
854 |
++ return retn + n; |
855 |
+ } |
856 |
+ } |
857 |
+ |
858 |
+@@ -569,6 +600,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, |
859 |
+ while (n >= 8) { |
860 |
+ __asm_copy_to_user_8x64(dst, src, retn); |
861 |
+ n -= 8; |
862 |
++ if (retn) |
863 |
++ return retn + n; |
864 |
+ } |
865 |
+ } |
866 |
+ if (n >= RAPF_MIN_BUF_SIZE) { |
867 |
+@@ -581,6 +614,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, |
868 |
+ while (n >= 8) { |
869 |
+ __asm_copy_to_user_8x64(dst, src, retn); |
870 |
+ n -= 8; |
871 |
++ if (retn) |
872 |
++ return retn + n; |
873 |
+ } |
874 |
+ } |
875 |
+ #endif |
876 |
+@@ -588,11 +623,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, |
877 |
+ while (n >= 16) { |
878 |
+ __asm_copy_to_user_16(dst, src, retn); |
879 |
+ n -= 16; |
880 |
++ if (retn) |
881 |
++ return retn + n; |
882 |
+ } |
883 |
+ |
884 |
+ while (n >= 4) { |
885 |
+ __asm_copy_to_user_4(dst, src, retn); |
886 |
+ n -= 4; |
887 |
++ if (retn) |
888 |
++ return retn + n; |
889 |
+ } |
890 |
+ |
891 |
+ switch (n) { |
892 |
+@@ -609,6 +648,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, |
893 |
+ break; |
894 |
+ } |
895 |
+ |
896 |
++ /* |
897 |
++ * If we get here, retn correctly reflects the number of failing |
898 |
++ * bytes. |
899 |
++ */ |
900 |
+ return retn; |
901 |
+ } |
902 |
+ EXPORT_SYMBOL(__copy_user); |
903 |
+@@ -617,16 +660,14 @@ EXPORT_SYMBOL(__copy_user); |
904 |
+ __asm_copy_user_cont(to, from, ret, \ |
905 |
+ " GETB D1Ar1,[%1++]\n" \ |
906 |
+ "2: SETB [%0++],D1Ar1\n", \ |
907 |
+- "3: ADD %2,%2,#1\n" \ |
908 |
+- " SETB [%0++],D1Ar1\n", \ |
909 |
++ "3: ADD %2,%2,#1\n", \ |
910 |
+ " .long 2b,3b\n") |
911 |
+ |
912 |
+ #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
913 |
+ __asm_copy_user_cont(to, from, ret, \ |
914 |
+ " GETW D1Ar1,[%1++]\n" \ |
915 |
+ "2: SETW [%0++],D1Ar1\n" COPY, \ |
916 |
+- "3: ADD %2,%2,#2\n" \ |
917 |
+- " SETW [%0++],D1Ar1\n" FIXUP, \ |
918 |
++ "3: ADD %2,%2,#2\n" FIXUP, \ |
919 |
+ " .long 2b,3b\n" TENTRY) |
920 |
+ |
921 |
+ #define __asm_copy_from_user_2(to, from, ret) \ |
922 |
+@@ -636,145 +677,26 @@ EXPORT_SYMBOL(__copy_user); |
923 |
+ __asm_copy_from_user_2x_cont(to, from, ret, \ |
924 |
+ " GETB D1Ar1,[%1++]\n" \ |
925 |
+ "4: SETB [%0++],D1Ar1\n", \ |
926 |
+- "5: ADD %2,%2,#1\n" \ |
927 |
+- " SETB [%0++],D1Ar1\n", \ |
928 |
++ "5: ADD %2,%2,#1\n", \ |
929 |
+ " .long 4b,5b\n") |
930 |
+ |
931 |
+ #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
932 |
+ __asm_copy_user_cont(to, from, ret, \ |
933 |
+ " GETD D1Ar1,[%1++]\n" \ |
934 |
+ "2: SETD [%0++],D1Ar1\n" COPY, \ |
935 |
+- "3: ADD %2,%2,#4\n" \ |
936 |
+- " SETD [%0++],D1Ar1\n" FIXUP, \ |
937 |
++ "3: ADD %2,%2,#4\n" FIXUP, \ |
938 |
+ " .long 2b,3b\n" TENTRY) |
939 |
+ |
940 |
+ #define __asm_copy_from_user_4(to, from, ret) \ |
941 |
+ __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") |
942 |
+ |
943 |
+-#define __asm_copy_from_user_5(to, from, ret) \ |
944 |
+- __asm_copy_from_user_4x_cont(to, from, ret, \ |
945 |
+- " GETB D1Ar1,[%1++]\n" \ |
946 |
+- "4: SETB [%0++],D1Ar1\n", \ |
947 |
+- "5: ADD %2,%2,#1\n" \ |
948 |
+- " SETB [%0++],D1Ar1\n", \ |
949 |
+- " .long 4b,5b\n") |
950 |
+- |
951 |
+-#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
952 |
+- __asm_copy_from_user_4x_cont(to, from, ret, \ |
953 |
+- " GETW D1Ar1,[%1++]\n" \ |
954 |
+- "4: SETW [%0++],D1Ar1\n" COPY, \ |
955 |
+- "5: ADD %2,%2,#2\n" \ |
956 |
+- " SETW [%0++],D1Ar1\n" FIXUP, \ |
957 |
+- " .long 4b,5b\n" TENTRY) |
958 |
+- |
959 |
+-#define __asm_copy_from_user_6(to, from, ret) \ |
960 |
+- __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") |
961 |
+- |
962 |
+-#define __asm_copy_from_user_7(to, from, ret) \ |
963 |
+- __asm_copy_from_user_6x_cont(to, from, ret, \ |
964 |
+- " GETB D1Ar1,[%1++]\n" \ |
965 |
+- "6: SETB [%0++],D1Ar1\n", \ |
966 |
+- "7: ADD %2,%2,#1\n" \ |
967 |
+- " SETB [%0++],D1Ar1\n", \ |
968 |
+- " .long 6b,7b\n") |
969 |
+- |
970 |
+-#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
971 |
+- __asm_copy_from_user_4x_cont(to, from, ret, \ |
972 |
+- " GETD D1Ar1,[%1++]\n" \ |
973 |
+- "4: SETD [%0++],D1Ar1\n" COPY, \ |
974 |
+- "5: ADD %2,%2,#4\n" \ |
975 |
+- " SETD [%0++],D1Ar1\n" FIXUP, \ |
976 |
+- " .long 4b,5b\n" TENTRY) |
977 |
+- |
978 |
+-#define __asm_copy_from_user_8(to, from, ret) \ |
979 |
+- __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") |
980 |
+- |
981 |
+-#define __asm_copy_from_user_9(to, from, ret) \ |
982 |
+- __asm_copy_from_user_8x_cont(to, from, ret, \ |
983 |
+- " GETB D1Ar1,[%1++]\n" \ |
984 |
+- "6: SETB [%0++],D1Ar1\n", \ |
985 |
+- "7: ADD %2,%2,#1\n" \ |
986 |
+- " SETB [%0++],D1Ar1\n", \ |
987 |
+- " .long 6b,7b\n") |
988 |
+- |
989 |
+-#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
990 |
+- __asm_copy_from_user_8x_cont(to, from, ret, \ |
991 |
+- " GETW D1Ar1,[%1++]\n" \ |
992 |
+- "6: SETW [%0++],D1Ar1\n" COPY, \ |
993 |
+- "7: ADD %2,%2,#2\n" \ |
994 |
+- " SETW [%0++],D1Ar1\n" FIXUP, \ |
995 |
+- " .long 6b,7b\n" TENTRY) |
996 |
+- |
997 |
+-#define __asm_copy_from_user_10(to, from, ret) \ |
998 |
+- __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") |
999 |
+- |
1000 |
+-#define __asm_copy_from_user_11(to, from, ret) \ |
1001 |
+- __asm_copy_from_user_10x_cont(to, from, ret, \ |
1002 |
+- " GETB D1Ar1,[%1++]\n" \ |
1003 |
+- "8: SETB [%0++],D1Ar1\n", \ |
1004 |
+- "9: ADD %2,%2,#1\n" \ |
1005 |
+- " SETB [%0++],D1Ar1\n", \ |
1006 |
+- " .long 8b,9b\n") |
1007 |
+- |
1008 |
+-#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
1009 |
+- __asm_copy_from_user_8x_cont(to, from, ret, \ |
1010 |
+- " GETD D1Ar1,[%1++]\n" \ |
1011 |
+- "6: SETD [%0++],D1Ar1\n" COPY, \ |
1012 |
+- "7: ADD %2,%2,#4\n" \ |
1013 |
+- " SETD [%0++],D1Ar1\n" FIXUP, \ |
1014 |
+- " .long 6b,7b\n" TENTRY) |
1015 |
+- |
1016 |
+-#define __asm_copy_from_user_12(to, from, ret) \ |
1017 |
+- __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") |
1018 |
+- |
1019 |
+-#define __asm_copy_from_user_13(to, from, ret) \ |
1020 |
+- __asm_copy_from_user_12x_cont(to, from, ret, \ |
1021 |
+- " GETB D1Ar1,[%1++]\n" \ |
1022 |
+- "8: SETB [%0++],D1Ar1\n", \ |
1023 |
+- "9: ADD %2,%2,#1\n" \ |
1024 |
+- " SETB [%0++],D1Ar1\n", \ |
1025 |
+- " .long 8b,9b\n") |
1026 |
+- |
1027 |
+-#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
1028 |
+- __asm_copy_from_user_12x_cont(to, from, ret, \ |
1029 |
+- " GETW D1Ar1,[%1++]\n" \ |
1030 |
+- "8: SETW [%0++],D1Ar1\n" COPY, \ |
1031 |
+- "9: ADD %2,%2,#2\n" \ |
1032 |
+- " SETW [%0++],D1Ar1\n" FIXUP, \ |
1033 |
+- " .long 8b,9b\n" TENTRY) |
1034 |
+- |
1035 |
+-#define __asm_copy_from_user_14(to, from, ret) \ |
1036 |
+- __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") |
1037 |
+- |
1038 |
+-#define __asm_copy_from_user_15(to, from, ret) \ |
1039 |
+- __asm_copy_from_user_14x_cont(to, from, ret, \ |
1040 |
+- " GETB D1Ar1,[%1++]\n" \ |
1041 |
+- "10: SETB [%0++],D1Ar1\n", \ |
1042 |
+- "11: ADD %2,%2,#1\n" \ |
1043 |
+- " SETB [%0++],D1Ar1\n", \ |
1044 |
+- " .long 10b,11b\n") |
1045 |
+- |
1046 |
+-#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ |
1047 |
+- __asm_copy_from_user_12x_cont(to, from, ret, \ |
1048 |
+- " GETD D1Ar1,[%1++]\n" \ |
1049 |
+- "8: SETD [%0++],D1Ar1\n" COPY, \ |
1050 |
+- "9: ADD %2,%2,#4\n" \ |
1051 |
+- " SETD [%0++],D1Ar1\n" FIXUP, \ |
1052 |
+- " .long 8b,9b\n" TENTRY) |
1053 |
+- |
1054 |
+-#define __asm_copy_from_user_16(to, from, ret) \ |
1055 |
+- __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") |
1056 |
+- |
1057 |
+ #define __asm_copy_from_user_8x64(to, from, ret) \ |
1058 |
+ asm volatile ( \ |
1059 |
+ " GETL D0Ar2,D1Ar1,[%1++]\n" \ |
1060 |
+ "2: SETL [%0++],D0Ar2,D1Ar1\n" \ |
1061 |
+ "1:\n" \ |
1062 |
+ " .section .fixup,\"ax\"\n" \ |
1063 |
+- " MOV D1Ar1,#0\n" \ |
1064 |
+- " MOV D0Ar2,#0\n" \ |
1065 |
+ "3: ADD %2,%2,#8\n" \ |
1066 |
+- " SETL [%0++],D0Ar2,D1Ar1\n" \ |
1067 |
+ " MOVT D0Ar2,#HI(1b)\n" \ |
1068 |
+ " JUMP D0Ar2,#LO(1b)\n" \ |
1069 |
+ " .previous\n" \ |
1070 |
+@@ -789,36 +711,57 @@ EXPORT_SYMBOL(__copy_user); |
1071 |
+ * |
1072 |
+ * Rationale: |
1073 |
+ * A fault occurs while reading from user buffer, which is the |
1074 |
+- * source. Since the fault is at a single address, we only |
1075 |
+- * need to rewind by 8 bytes. |
1076 |
++ * source. |
1077 |
+ * Since we don't write to kernel buffer until we read first, |
1078 |
+ * the kernel buffer is at the right state and needn't be |
1079 |
+- * corrected. |
1080 |
++ * corrected, but the source must be rewound to the beginning of |
1081 |
++ * the block, which is LSM_STEP*8 bytes. |
1082 |
++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read |
1083 |
++ * and stored in D0Ar2 |
1084 |
++ * |
1085 |
++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL |
1086 |
++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if |
1087 |
++ * a fault happens at the 4th write, LSM_STEP will be 0 |
1088 |
++ * instead of 4. The code copes with that. |
1089 |
+ */ |
1090 |
+ #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ |
1091 |
+ __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ |
1092 |
+- "SUB %1, %1, #8\n") |
1093 |
++ "LSR D0Ar2, D0Ar2, #5\n" \ |
1094 |
++ "ANDS D0Ar2, D0Ar2, #0x38\n" \ |
1095 |
++ "ADDZ D0Ar2, D0Ar2, #32\n" \ |
1096 |
++ "SUB %1, %1, D0Ar2\n") |
1097 |
+ |
1098 |
+ /* rewind 'from' pointer when a fault occurs |
1099 |
+ * |
1100 |
+ * Rationale: |
1101 |
+ * A fault occurs while reading from user buffer, which is the |
1102 |
+- * source. Since the fault is at a single address, we only |
1103 |
+- * need to rewind by 4 bytes. |
1104 |
++ * source. |
1105 |
+ * Since we don't write to kernel buffer until we read first, |
1106 |
+ * the kernel buffer is at the right state and needn't be |
1107 |
+- * corrected. |
1108 |
++ * corrected, but the source must be rewound to the beginning of |
1109 |
++ * the block, which is LSM_STEP*4 bytes. |
1110 |
++ * LSM_STEP is bits 10:8 in TXSTATUS which is already read |
1111 |
++ * and stored in D0Ar2 |
1112 |
++ * |
1113 |
++ * NOTE: If a fault occurs at the last operation in M{G,S}ETL |
1114 |
++ * LSM_STEP will be 0. ie: we do 4 writes in our case, if |
1115 |
++ * a fault happens at the 4th write, LSM_STEP will be 0 |
1116 |
++ * instead of 4. The code copes with that. |
1117 |
+ */ |
1118 |
+ #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ |
1119 |
+ __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ |
1120 |
+- "SUB %1, %1, #4\n") |
1121 |
++ "LSR D0Ar2, D0Ar2, #6\n" \ |
1122 |
++ "ANDS D0Ar2, D0Ar2, #0x1c\n" \ |
1123 |
++ "ADDZ D0Ar2, D0Ar2, #16\n" \ |
1124 |
++ "SUB %1, %1, D0Ar2\n") |
1125 |
+ |
1126 |
+ |
1127 |
+-/* Copy from user to kernel, zeroing the bytes that were inaccessible in |
1128 |
+- userland. The return-value is the number of bytes that were |
1129 |
+- inaccessible. */ |
1130 |
+-unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1131 |
+- unsigned long n) |
1132 |
++/* |
1133 |
++ * Copy from user to kernel. The return-value is the number of bytes that were |
1134 |
++ * inaccessible. |
1135 |
++ */ |
1136 |
++unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, |
1137 |
++ unsigned long n) |
1138 |
+ { |
1139 |
+ register char *dst asm ("A0.2") = pdst; |
1140 |
+ register const char __user *src asm ("A1.2") = psrc; |
1141 |
+@@ -830,6 +773,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1142 |
+ if ((unsigned long) src & 1) { |
1143 |
+ __asm_copy_from_user_1(dst, src, retn); |
1144 |
+ n--; |
1145 |
++ if (retn) |
1146 |
++ return retn + n; |
1147 |
+ } |
1148 |
+ if ((unsigned long) dst & 1) { |
1149 |
+ /* Worst case - byte copy */ |
1150 |
+@@ -837,12 +782,14 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1151 |
+ __asm_copy_from_user_1(dst, src, retn); |
1152 |
+ n--; |
1153 |
+ if (retn) |
1154 |
+- goto copy_exception_bytes; |
1155 |
++ return retn + n; |
1156 |
+ } |
1157 |
+ } |
1158 |
+ if (((unsigned long) src & 2) && n >= 2) { |
1159 |
+ __asm_copy_from_user_2(dst, src, retn); |
1160 |
+ n -= 2; |
1161 |
++ if (retn) |
1162 |
++ return retn + n; |
1163 |
+ } |
1164 |
+ if ((unsigned long) dst & 2) { |
1165 |
+ /* Second worst case - word copy */ |
1166 |
+@@ -850,16 +797,10 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1167 |
+ __asm_copy_from_user_2(dst, src, retn); |
1168 |
+ n -= 2; |
1169 |
+ if (retn) |
1170 |
+- goto copy_exception_bytes; |
1171 |
++ return retn + n; |
1172 |
+ } |
1173 |
+ } |
1174 |
+ |
1175 |
+- /* We only need one check after the unalignment-adjustments, |
1176 |
+- because if both adjustments were done, either both or |
1177 |
+- neither reference had an exception. */ |
1178 |
+- if (retn != 0) |
1179 |
+- goto copy_exception_bytes; |
1180 |
+- |
1181 |
+ #ifdef USE_RAPF |
1182 |
+ /* 64 bit copy loop */ |
1183 |
+ if (!(((unsigned long) src | (unsigned long) dst) & 7)) { |
1184 |
+@@ -872,7 +813,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1185 |
+ __asm_copy_from_user_8x64(dst, src, retn); |
1186 |
+ n -= 8; |
1187 |
+ if (retn) |
1188 |
+- goto copy_exception_bytes; |
1189 |
++ return retn + n; |
1190 |
+ } |
1191 |
+ } |
1192 |
+ |
1193 |
+@@ -888,7 +829,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1194 |
+ __asm_copy_from_user_8x64(dst, src, retn); |
1195 |
+ n -= 8; |
1196 |
+ if (retn) |
1197 |
+- goto copy_exception_bytes; |
1198 |
++ return retn + n; |
1199 |
+ } |
1200 |
+ } |
1201 |
+ #endif |
1202 |
+@@ -898,7 +839,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1203 |
+ n -= 4; |
1204 |
+ |
1205 |
+ if (retn) |
1206 |
+- goto copy_exception_bytes; |
1207 |
++ return retn + n; |
1208 |
+ } |
1209 |
+ |
1210 |
+ /* If we get here, there were no memory read faults. */ |
1211 |
+@@ -924,21 +865,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, |
1212 |
+ /* If we get here, retn correctly reflects the number of failing |
1213 |
+ bytes. */ |
1214 |
+ return retn; |
1215 |
+- |
1216 |
+- copy_exception_bytes: |
1217 |
+- /* We already have "retn" bytes cleared, and need to clear the |
1218 |
+- remaining "n" bytes. A non-optimized simple byte-for-byte in-line |
1219 |
+- memset is preferred here, since this isn't speed-critical code and |
1220 |
+- we'd rather have this a leaf-function than calling memset. */ |
1221 |
+- { |
1222 |
+- char *endp; |
1223 |
+- for (endp = dst + n; dst < endp; dst++) |
1224 |
+- *dst = 0; |
1225 |
+- } |
1226 |
+- |
1227 |
+- return retn + n; |
1228 |
+ } |
1229 |
+-EXPORT_SYMBOL(__copy_user_zeroing); |
1230 |
++EXPORT_SYMBOL(raw_copy_from_user); |
1231 |
+ |
1232 |
+ #define __asm_clear_8x64(to, ret) \ |
1233 |
+ asm volatile ( \ |
1234 |
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig |
1235 |
+index b3c5bde43d34..9a6e11b6f457 100644 |
1236 |
+--- a/arch/mips/Kconfig |
1237 |
++++ b/arch/mips/Kconfig |
1238 |
+@@ -1526,7 +1526,7 @@ config CPU_MIPS64_R6 |
1239 |
+ select CPU_SUPPORTS_HIGHMEM |
1240 |
+ select CPU_SUPPORTS_MSA |
1241 |
+ select GENERIC_CSUM |
1242 |
+- select MIPS_O32_FP64_SUPPORT if MIPS32_O32 |
1243 |
++ select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 |
1244 |
+ select HAVE_KVM |
1245 |
+ help |
1246 |
+ Choose this option to build a kernel for release 6 or later of the |
1247 |
+diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h |
1248 |
+index f485afe51514..a8df44d60607 100644 |
1249 |
+--- a/arch/mips/include/asm/spinlock.h |
1250 |
++++ b/arch/mips/include/asm/spinlock.h |
1251 |
+@@ -127,7 +127,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) |
1252 |
+ " andi %[ticket], %[ticket], 0xffff \n" |
1253 |
+ " bne %[ticket], %[my_ticket], 4f \n" |
1254 |
+ " subu %[ticket], %[my_ticket], %[ticket] \n" |
1255 |
+- "2: \n" |
1256 |
++ "2: .insn \n" |
1257 |
+ " .subsection 2 \n" |
1258 |
+ "4: andi %[ticket], %[ticket], 0xffff \n" |
1259 |
+ " sll %[ticket], 5 \n" |
1260 |
+@@ -202,7 +202,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) |
1261 |
+ " sc %[ticket], %[ticket_ptr] \n" |
1262 |
+ " beqz %[ticket], 1b \n" |
1263 |
+ " li %[ticket], 1 \n" |
1264 |
+- "2: \n" |
1265 |
++ "2: .insn \n" |
1266 |
+ " .subsection 2 \n" |
1267 |
+ "3: b 2b \n" |
1268 |
+ " li %[ticket], 0 \n" |
1269 |
+@@ -382,7 +382,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) |
1270 |
+ " .set reorder \n" |
1271 |
+ __WEAK_LLSC_MB |
1272 |
+ " li %2, 1 \n" |
1273 |
+- "2: \n" |
1274 |
++ "2: .insn \n" |
1275 |
+ : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
1276 |
+ : GCC_OFF_SMALL_ASM() (rw->lock) |
1277 |
+ : "memory"); |
1278 |
+@@ -422,7 +422,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) |
1279 |
+ " lui %1, 0x8000 \n" |
1280 |
+ " sc %1, %0 \n" |
1281 |
+ " li %2, 1 \n" |
1282 |
+- "2: \n" |
1283 |
++ "2: .insn \n" |
1284 |
+ : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), |
1285 |
+ "=&r" (ret) |
1286 |
+ : GCC_OFF_SMALL_ASM() (rw->lock) |
1287 |
+diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c |
1288 |
+index dd3175442c9e..921211bcd2ba 100644 |
1289 |
+--- a/arch/mips/kernel/cpu-probe.c |
1290 |
++++ b/arch/mips/kernel/cpu-probe.c |
1291 |
+@@ -1824,7 +1824,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) |
1292 |
+ } |
1293 |
+ |
1294 |
+ decode_configs(c); |
1295 |
+- c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; |
1296 |
++ c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; |
1297 |
+ c->writecombine = _CACHE_UNCACHED_ACCELERATED; |
1298 |
+ break; |
1299 |
+ default: |
1300 |
+diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S |
1301 |
+index dc0b29612891..52a4fdfc8513 100644 |
1302 |
+--- a/arch/mips/kernel/genex.S |
1303 |
++++ b/arch/mips/kernel/genex.S |
1304 |
+@@ -448,7 +448,7 @@ NESTED(nmi_handler, PT_SIZE, sp) |
1305 |
+ BUILD_HANDLER reserved reserved sti verbose /* others */ |
1306 |
+ |
1307 |
+ .align 5 |
1308 |
+- LEAF(handle_ri_rdhwr_vivt) |
1309 |
++ LEAF(handle_ri_rdhwr_tlbp) |
1310 |
+ .set push |
1311 |
+ .set noat |
1312 |
+ .set noreorder |
1313 |
+@@ -467,7 +467,7 @@ NESTED(nmi_handler, PT_SIZE, sp) |
1314 |
+ .set pop |
1315 |
+ bltz k1, handle_ri /* slow path */ |
1316 |
+ /* fall thru */ |
1317 |
+- END(handle_ri_rdhwr_vivt) |
1318 |
++ END(handle_ri_rdhwr_tlbp) |
1319 |
+ |
1320 |
+ LEAF(handle_ri_rdhwr) |
1321 |
+ .set push |
1322 |
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c |
1323 |
+index 3905003dfe2b..ec87ef93267b 100644 |
1324 |
+--- a/arch/mips/kernel/traps.c |
1325 |
++++ b/arch/mips/kernel/traps.c |
1326 |
+@@ -81,7 +81,7 @@ extern asmlinkage void handle_dbe(void); |
1327 |
+ extern asmlinkage void handle_sys(void); |
1328 |
+ extern asmlinkage void handle_bp(void); |
1329 |
+ extern asmlinkage void handle_ri(void); |
1330 |
+-extern asmlinkage void handle_ri_rdhwr_vivt(void); |
1331 |
++extern asmlinkage void handle_ri_rdhwr_tlbp(void); |
1332 |
+ extern asmlinkage void handle_ri_rdhwr(void); |
1333 |
+ extern asmlinkage void handle_cpu(void); |
1334 |
+ extern asmlinkage void handle_ov(void); |
1335 |
+@@ -2352,9 +2352,18 @@ void __init trap_init(void) |
1336 |
+ |
1337 |
+ set_except_vector(EXCCODE_SYS, handle_sys); |
1338 |
+ set_except_vector(EXCCODE_BP, handle_bp); |
1339 |
+- set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri : |
1340 |
+- (cpu_has_vtag_icache ? |
1341 |
+- handle_ri_rdhwr_vivt : handle_ri_rdhwr)); |
1342 |
++ |
1343 |
++ if (rdhwr_noopt) |
1344 |
++ set_except_vector(EXCCODE_RI, handle_ri); |
1345 |
++ else { |
1346 |
++ if (cpu_has_vtag_icache) |
1347 |
++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); |
1348 |
++ else if (current_cpu_type() == CPU_LOONGSON3) |
1349 |
++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); |
1350 |
++ else |
1351 |
++ set_except_vector(EXCCODE_RI, handle_ri_rdhwr); |
1352 |
++ } |
1353 |
++ |
1354 |
+ set_except_vector(EXCCODE_CPU, handle_cpu); |
1355 |
+ set_except_vector(EXCCODE_OV, handle_ov); |
1356 |
+ set_except_vector(EXCCODE_TR, handle_tr); |
1357 |
+diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c |
1358 |
+index 9a61671c00a7..90565477dfbd 100644 |
1359 |
+--- a/arch/mips/lantiq/xway/sysctrl.c |
1360 |
++++ b/arch/mips/lantiq/xway/sysctrl.c |
1361 |
+@@ -467,7 +467,7 @@ void __init ltq_soc_init(void) |
1362 |
+ |
1363 |
+ if (!np_xbar) |
1364 |
+ panic("Failed to load xbar nodes from devicetree"); |
1365 |
+- if (of_address_to_resource(np_pmu, 0, &res_xbar)) |
1366 |
++ if (of_address_to_resource(np_xbar, 0, &res_xbar)) |
1367 |
+ panic("Failed to get xbar resources"); |
1368 |
+ if (request_mem_region(res_xbar.start, resource_size(&res_xbar), |
1369 |
+ res_xbar.name) < 0) |
1370 |
+diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c |
1371 |
+index 88cfaf81c958..9d0107fbb169 100644 |
1372 |
+--- a/arch/mips/mm/c-r4k.c |
1373 |
++++ b/arch/mips/mm/c-r4k.c |
1374 |
+@@ -1558,6 +1558,7 @@ static void probe_vcache(void) |
1375 |
+ vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz; |
1376 |
+ |
1377 |
+ c->vcache.waybit = 0; |
1378 |
++ c->vcache.waysize = vcache_size / c->vcache.ways; |
1379 |
+ |
1380 |
+ pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", |
1381 |
+ vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); |
1382 |
+@@ -1660,6 +1661,7 @@ static void __init loongson3_sc_init(void) |
1383 |
+ /* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */ |
1384 |
+ scache_size *= 4; |
1385 |
+ c->scache.waybit = 0; |
1386 |
++ c->scache.waysize = scache_size / c->scache.ways; |
1387 |
+ pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", |
1388 |
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); |
1389 |
+ if (scache_size) |
1390 |
+diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c |
1391 |
+index 55ce39606cb8..2da5649fc545 100644 |
1392 |
+--- a/arch/mips/mm/tlbex.c |
1393 |
++++ b/arch/mips/mm/tlbex.c |
1394 |
+@@ -762,7 +762,8 @@ static void build_huge_update_entries(u32 **p, unsigned int pte, |
1395 |
+ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, |
1396 |
+ struct uasm_label **l, |
1397 |
+ unsigned int pte, |
1398 |
+- unsigned int ptr) |
1399 |
++ unsigned int ptr, |
1400 |
++ unsigned int flush) |
1401 |
+ { |
1402 |
+ #ifdef CONFIG_SMP |
1403 |
+ UASM_i_SC(p, pte, 0, ptr); |
1404 |
+@@ -771,6 +772,22 @@ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, |
1405 |
+ #else |
1406 |
+ UASM_i_SW(p, pte, 0, ptr); |
1407 |
+ #endif |
1408 |
++ if (cpu_has_ftlb && flush) { |
1409 |
++ BUG_ON(!cpu_has_tlbinv); |
1410 |
++ |
1411 |
++ UASM_i_MFC0(p, ptr, C0_ENTRYHI); |
1412 |
++ uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); |
1413 |
++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); |
1414 |
++ build_tlb_write_entry(p, l, r, tlb_indexed); |
1415 |
++ |
1416 |
++ uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); |
1417 |
++ UASM_i_MTC0(p, ptr, C0_ENTRYHI); |
1418 |
++ build_huge_update_entries(p, pte, ptr); |
1419 |
++ build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); |
1420 |
++ |
1421 |
++ return; |
1422 |
++ } |
1423 |
++ |
1424 |
+ build_huge_update_entries(p, pte, ptr); |
1425 |
+ build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); |
1426 |
+ } |
1427 |
+@@ -2197,7 +2214,7 @@ static void build_r4000_tlb_load_handler(void) |
1428 |
+ uasm_l_tlbl_goaround2(&l, p); |
1429 |
+ } |
1430 |
+ uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); |
1431 |
+- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); |
1432 |
++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); |
1433 |
+ #endif |
1434 |
+ |
1435 |
+ uasm_l_nopage_tlbl(&l, p); |
1436 |
+@@ -2252,7 +2269,7 @@ static void build_r4000_tlb_store_handler(void) |
1437 |
+ build_tlb_probe_entry(&p); |
1438 |
+ uasm_i_ori(&p, wr.r1, wr.r1, |
1439 |
+ _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); |
1440 |
+- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); |
1441 |
++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); |
1442 |
+ #endif |
1443 |
+ |
1444 |
+ uasm_l_nopage_tlbs(&l, p); |
1445 |
+@@ -2308,7 +2325,7 @@ static void build_r4000_tlb_modify_handler(void) |
1446 |
+ build_tlb_probe_entry(&p); |
1447 |
+ uasm_i_ori(&p, wr.r1, wr.r1, |
1448 |
+ _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); |
1449 |
+- build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); |
1450 |
++ build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); |
1451 |
+ #endif |
1452 |
+ |
1453 |
+ uasm_l_nopage_tlbm(&l, p); |
1454 |
+diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c |
1455 |
+index 3e0aa09c6b55..9e4631acfcb5 100644 |
1456 |
+--- a/arch/mips/ralink/rt3883.c |
1457 |
++++ b/arch/mips/ralink/rt3883.c |
1458 |
+@@ -36,7 +36,7 @@ static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; |
1459 |
+ static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
1460 |
+ static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
1461 |
+ static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; |
1462 |
+-static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; |
1463 |
++static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) }; |
1464 |
+ static struct rt2880_pmx_func pci_func[] = { |
1465 |
+ FUNC("pci-dev", 0, 40, 32), |
1466 |
+ FUNC("pci-host2", 1, 40, 32), |
1467 |
+@@ -44,7 +44,7 @@ static struct rt2880_pmx_func pci_func[] = { |
1468 |
+ FUNC("pci-fnc", 3, 40, 32) |
1469 |
+ }; |
1470 |
+ static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; |
1471 |
+-static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; |
1472 |
++static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) }; |
1473 |
+ |
1474 |
+ static struct rt2880_pmx_group rt3883_pinmux_data[] = { |
1475 |
+ GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), |
1476 |
+diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c |
1477 |
+index 367c5426157b..3901b80d4420 100644 |
1478 |
+--- a/arch/nios2/kernel/prom.c |
1479 |
++++ b/arch/nios2/kernel/prom.c |
1480 |
+@@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) |
1481 |
+ return alloc_bootmem_align(size, align); |
1482 |
+ } |
1483 |
+ |
1484 |
++int __init early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, |
1485 |
++ bool nomap) |
1486 |
++{ |
1487 |
++ reserve_bootmem(base, size, BOOTMEM_DEFAULT); |
1488 |
++ return 0; |
1489 |
++} |
1490 |
++ |
1491 |
+ void __init early_init_devtree(void *params) |
1492 |
+ { |
1493 |
+ __be32 *dtb = (u32 *)__dtb_start; |
1494 |
+diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c |
1495 |
+index a4ff86d58d5c..6c4e351a7930 100644 |
1496 |
+--- a/arch/nios2/kernel/setup.c |
1497 |
++++ b/arch/nios2/kernel/setup.c |
1498 |
+@@ -195,6 +195,9 @@ void __init setup_arch(char **cmdline_p) |
1499 |
+ } |
1500 |
+ #endif /* CONFIG_BLK_DEV_INITRD */ |
1501 |
+ |
1502 |
++ early_init_fdt_reserve_self(); |
1503 |
++ early_init_fdt_scan_reserved_mem(); |
1504 |
++ |
1505 |
+ unflatten_and_copy_device_tree(); |
1506 |
+ |
1507 |
+ setup_cpuinfo(); |
1508 |
+diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c |
1509 |
+index 411994551afc..f058e0c3e4d4 100644 |
1510 |
+--- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c |
1511 |
++++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c |
1512 |
+@@ -33,10 +33,13 @@ static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len) |
1513 |
+ } |
1514 |
+ |
1515 |
+ if (len & ~VMX_ALIGN_MASK) { |
1516 |
++ preempt_disable(); |
1517 |
+ pagefault_disable(); |
1518 |
+ enable_kernel_altivec(); |
1519 |
+ crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); |
1520 |
++ disable_kernel_altivec(); |
1521 |
+ pagefault_enable(); |
1522 |
++ preempt_enable(); |
1523 |
+ } |
1524 |
+ |
1525 |
+ tail = len & VMX_ALIGN_MASK; |
1526 |
+diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c |
1527 |
+index 033f3385fa49..b2da7c8baed7 100644 |
1528 |
+--- a/arch/powerpc/kernel/align.c |
1529 |
++++ b/arch/powerpc/kernel/align.c |
1530 |
+@@ -807,14 +807,25 @@ int fix_alignment(struct pt_regs *regs) |
1531 |
+ nb = aligninfo[instr].len; |
1532 |
+ flags = aligninfo[instr].flags; |
1533 |
+ |
1534 |
+- /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ |
1535 |
+- if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { |
1536 |
+- nb = 8; |
1537 |
+- flags = LD+SW; |
1538 |
+- } else if (IS_XFORM(instruction) && |
1539 |
+- ((instruction >> 1) & 0x3ff) == 660) { |
1540 |
+- nb = 8; |
1541 |
+- flags = ST+SW; |
1542 |
++ /* |
1543 |
++ * Handle some cases which give overlaps in the DSISR values. |
1544 |
++ */ |
1545 |
++ if (IS_XFORM(instruction)) { |
1546 |
++ switch (get_xop(instruction)) { |
1547 |
++ case 532: /* ldbrx */ |
1548 |
++ nb = 8; |
1549 |
++ flags = LD+SW; |
1550 |
++ break; |
1551 |
++ case 660: /* stdbrx */ |
1552 |
++ nb = 8; |
1553 |
++ flags = ST+SW; |
1554 |
++ break; |
1555 |
++ case 20: /* lwarx */ |
1556 |
++ case 84: /* ldarx */ |
1557 |
++ case 116: /* lharx */ |
1558 |
++ case 276: /* lqarx */ |
1559 |
++ return 0; /* not emulated ever */ |
1560 |
++ } |
1561 |
+ } |
1562 |
+ |
1563 |
+ /* Byteswap little endian loads and stores */ |
1564 |
+diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S |
1565 |
+index 4f178671f230..4cefe6888b18 100644 |
1566 |
+--- a/arch/powerpc/kernel/misc_64.S |
1567 |
++++ b/arch/powerpc/kernel/misc_64.S |
1568 |
+@@ -67,7 +67,7 @@ PPC64_CACHES: |
1569 |
+ * flush all bytes from start through stop-1 inclusive |
1570 |
+ */ |
1571 |
+ |
1572 |
+-_GLOBAL(flush_icache_range) |
1573 |
++_GLOBAL_TOC(flush_icache_range) |
1574 |
+ BEGIN_FTR_SECTION |
1575 |
+ PURGE_PREFETCHED_INS |
1576 |
+ blr |
1577 |
+@@ -120,7 +120,7 @@ EXPORT_SYMBOL(flush_icache_range) |
1578 |
+ * |
1579 |
+ * flush all bytes from start to stop-1 inclusive |
1580 |
+ */ |
1581 |
+-_GLOBAL(flush_dcache_range) |
1582 |
++_GLOBAL_TOC(flush_dcache_range) |
1583 |
+ |
1584 |
+ /* |
1585 |
+ * Flush the data cache to memory |
1586 |
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c |
1587 |
+index 8d586cff8a41..a12be60181bf 100644 |
1588 |
+--- a/arch/powerpc/kernel/setup_64.c |
1589 |
++++ b/arch/powerpc/kernel/setup_64.c |
1590 |
+@@ -245,6 +245,15 @@ static void cpu_ready_for_interrupts(void) |
1591 |
+ mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); |
1592 |
+ } |
1593 |
+ |
1594 |
++ /* |
1595 |
++ * Fixup HFSCR:TM based on CPU features. The bit is set by our |
1596 |
++ * early asm init because at that point we haven't updated our |
1597 |
++ * CPU features from firmware and device-tree. Here we have, |
1598 |
++ * so let's do it. |
1599 |
++ */ |
1600 |
++ if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) |
1601 |
++ mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); |
1602 |
++ |
1603 |
+ /* Set IR and DR in PACA MSR */ |
1604 |
+ get_paca()->kernel_msr = MSR_KERNEL; |
1605 |
+ } |
1606 |
+diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c |
1607 |
+index ad9fd5245be2..197f0a60334a 100644 |
1608 |
+--- a/arch/powerpc/mm/hash_native_64.c |
1609 |
++++ b/arch/powerpc/mm/hash_native_64.c |
1610 |
+@@ -636,6 +636,10 @@ static void native_flush_hash_range(unsigned long number, int local) |
1611 |
+ unsigned long psize = batch->psize; |
1612 |
+ int ssize = batch->ssize; |
1613 |
+ int i; |
1614 |
++ unsigned int use_local; |
1615 |
++ |
1616 |
++ use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && |
1617 |
++ mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use(); |
1618 |
+ |
1619 |
+ local_irq_save(flags); |
1620 |
+ |
1621 |
+@@ -665,8 +669,7 @@ static void native_flush_hash_range(unsigned long number, int local) |
1622 |
+ } pte_iterate_hashed_end(); |
1623 |
+ } |
1624 |
+ |
1625 |
+- if (mmu_has_feature(MMU_FTR_TLBIEL) && |
1626 |
+- mmu_psize_defs[psize].tlbiel && local) { |
1627 |
++ if (use_local) { |
1628 |
+ asm volatile("ptesync":::"memory"); |
1629 |
+ for (i = 0; i < number; i++) { |
1630 |
+ vpn = batch->vpn[i]; |
1631 |
+diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c |
1632 |
+index 4da604ebf6fd..ca15613eaaa4 100644 |
1633 |
+--- a/arch/s390/boot/compressed/misc.c |
1634 |
++++ b/arch/s390/boot/compressed/misc.c |
1635 |
+@@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size) |
1636 |
+ |
1637 |
+ unsigned long decompress_kernel(void) |
1638 |
+ { |
1639 |
+- unsigned long output_addr; |
1640 |
+- unsigned char *output; |
1641 |
++ void *output, *kernel_end; |
1642 |
+ |
1643 |
+- output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL; |
1644 |
+- check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start); |
1645 |
+- memset(&_bss, 0, &_ebss - &_bss); |
1646 |
+- free_mem_ptr = (unsigned long)&_end; |
1647 |
+- free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; |
1648 |
+- output = (unsigned char *) output_addr; |
1649 |
++ output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE); |
1650 |
++ kernel_end = output + SZ__bss_start; |
1651 |
++ check_ipl_parmblock((void *) 0, (unsigned long) kernel_end); |
1652 |
+ |
1653 |
+ #ifdef CONFIG_BLK_DEV_INITRD |
1654 |
+ /* |
1655 |
+ * Move the initrd right behind the end of the decompressed |
1656 |
+- * kernel image. |
1657 |
++ * kernel image. This also prevents initrd corruption caused by |
1658 |
++ * bss clearing since kernel_end will always be located behind the |
1659 |
++ * current bss section.. |
1660 |
+ */ |
1661 |
+- if (INITRD_START && INITRD_SIZE && |
1662 |
+- INITRD_START < (unsigned long) output + SZ__bss_start) { |
1663 |
+- check_ipl_parmblock(output + SZ__bss_start, |
1664 |
+- INITRD_START + INITRD_SIZE); |
1665 |
+- memmove(output + SZ__bss_start, |
1666 |
+- (void *) INITRD_START, INITRD_SIZE); |
1667 |
+- INITRD_START = (unsigned long) output + SZ__bss_start; |
1668 |
++ if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) { |
1669 |
++ check_ipl_parmblock(kernel_end, INITRD_SIZE); |
1670 |
++ memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE); |
1671 |
++ INITRD_START = (unsigned long) kernel_end; |
1672 |
+ } |
1673 |
+ #endif |
1674 |
+ |
1675 |
++ /* |
1676 |
++ * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be |
1677 |
++ * initialized afterwards since they reside in bss. |
1678 |
++ */ |
1679 |
++ memset(&_bss, 0, &_ebss - &_bss); |
1680 |
++ free_mem_ptr = (unsigned long) &_end; |
1681 |
++ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; |
1682 |
++ |
1683 |
+ puts("Uncompressing Linux... "); |
1684 |
+ __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); |
1685 |
+ puts("Ok, booting the kernel.\n"); |
1686 |
+diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h |
1687 |
+index 52d7c8709279..a7ef70220126 100644 |
1688 |
+--- a/arch/s390/include/asm/uaccess.h |
1689 |
++++ b/arch/s390/include/asm/uaccess.h |
1690 |
+@@ -144,7 +144,7 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, |
1691 |
+ " jg 2b\n" \ |
1692 |
+ ".popsection\n" \ |
1693 |
+ EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ |
1694 |
+- : "=d" (__rc), "=Q" (*(to)) \ |
1695 |
++ : "=d" (__rc), "+Q" (*(to)) \ |
1696 |
+ : "d" (size), "Q" (*(from)), \ |
1697 |
+ "d" (__reg0), "K" (-EFAULT) \ |
1698 |
+ : "cc"); \ |
1699 |
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c |
1700 |
+index e244c19a2451..067f9813fd2c 100644 |
1701 |
+--- a/arch/x86/kernel/reboot.c |
1702 |
++++ b/arch/x86/kernel/reboot.c |
1703 |
+@@ -223,6 +223,22 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { |
1704 |
+ DMI_MATCH(DMI_BOARD_NAME, "P4S800"), |
1705 |
+ }, |
1706 |
+ }, |
1707 |
++ { /* Handle problems with rebooting on ASUS EeeBook X205TA */ |
1708 |
++ .callback = set_acpi_reboot, |
1709 |
++ .ident = "ASUS EeeBook X205TA", |
1710 |
++ .matches = { |
1711 |
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
1712 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TA"), |
1713 |
++ }, |
1714 |
++ }, |
1715 |
++ { /* Handle problems with rebooting on ASUS EeeBook X205TAW */ |
1716 |
++ .callback = set_acpi_reboot, |
1717 |
++ .ident = "ASUS EeeBook X205TAW", |
1718 |
++ .matches = { |
1719 |
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
1720 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"), |
1721 |
++ }, |
1722 |
++ }, |
1723 |
+ |
1724 |
+ /* Certec */ |
1725 |
+ { /* Handle problems with rebooting on Certec BPC600 */ |
1726 |
+diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h |
1727 |
+index 976b1d70edbc..4ddbfd57a7c8 100644 |
1728 |
+--- a/arch/xtensa/include/asm/page.h |
1729 |
++++ b/arch/xtensa/include/asm/page.h |
1730 |
+@@ -164,8 +164,21 @@ void copy_user_highpage(struct page *to, struct page *from, |
1731 |
+ |
1732 |
+ #define ARCH_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) |
1733 |
+ |
1734 |
++#ifdef CONFIG_MMU |
1735 |
++static inline unsigned long ___pa(unsigned long va) |
1736 |
++{ |
1737 |
++ unsigned long off = va - PAGE_OFFSET; |
1738 |
++ |
1739 |
++ if (off >= XCHAL_KSEG_SIZE) |
1740 |
++ off -= XCHAL_KSEG_SIZE; |
1741 |
++ |
1742 |
++ return off + PHYS_OFFSET; |
1743 |
++} |
1744 |
++#define __pa(x) ___pa((unsigned long)(x)) |
1745 |
++#else |
1746 |
+ #define __pa(x) \ |
1747 |
+ ((unsigned long) (x) - PAGE_OFFSET + PHYS_OFFSET) |
1748 |
++#endif |
1749 |
+ #define __va(x) \ |
1750 |
+ ((void *)((unsigned long) (x) - PHYS_OFFSET + PAGE_OFFSET)) |
1751 |
+ #define pfn_valid(pfn) \ |
1752 |
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c |
1753 |
+index e19f530f1083..6d5a8c1d3132 100644 |
1754 |
+--- a/drivers/acpi/button.c |
1755 |
++++ b/drivers/acpi/button.c |
1756 |
+@@ -113,7 +113,7 @@ struct acpi_button { |
1757 |
+ |
1758 |
+ static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); |
1759 |
+ static struct acpi_device *lid_device; |
1760 |
+-static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; |
1761 |
++static u8 lid_init_state = ACPI_BUTTON_LID_INIT_OPEN; |
1762 |
+ |
1763 |
+ static unsigned long lid_report_interval __read_mostly = 500; |
1764 |
+ module_param(lid_report_interval, ulong, 0644); |
1765 |
+diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h |
1766 |
+index 1b41a2739dac..0c452265c111 100644 |
1767 |
+--- a/drivers/acpi/internal.h |
1768 |
++++ b/drivers/acpi/internal.h |
1769 |
+@@ -37,6 +37,7 @@ void acpi_amba_init(void); |
1770 |
+ static inline void acpi_amba_init(void) {} |
1771 |
+ #endif |
1772 |
+ int acpi_sysfs_init(void); |
1773 |
++void acpi_gpe_apply_masked_gpes(void); |
1774 |
+ void acpi_container_init(void); |
1775 |
+ void acpi_memory_hotplug_init(void); |
1776 |
+ #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC |
1777 |
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c |
1778 |
+index 3d1856f1f4d0..5a2fdf156ec9 100644 |
1779 |
+--- a/drivers/acpi/scan.c |
1780 |
++++ b/drivers/acpi/scan.c |
1781 |
+@@ -2044,6 +2044,7 @@ int __init acpi_scan_init(void) |
1782 |
+ } |
1783 |
+ } |
1784 |
+ |
1785 |
++ acpi_gpe_apply_masked_gpes(); |
1786 |
+ acpi_update_all_gpes(); |
1787 |
+ acpi_ec_ecdt_start(); |
1788 |
+ |
1789 |
+diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c |
1790 |
+index 54abb26b7366..a4327af676fe 100644 |
1791 |
+--- a/drivers/acpi/sleep.c |
1792 |
++++ b/drivers/acpi/sleep.c |
1793 |
+@@ -130,6 +130,12 @@ void __init acpi_nvs_nosave_s3(void) |
1794 |
+ nvs_nosave_s3 = true; |
1795 |
+ } |
1796 |
+ |
1797 |
++static int __init init_nvs_save_s3(const struct dmi_system_id *d) |
1798 |
++{ |
1799 |
++ nvs_nosave_s3 = false; |
1800 |
++ return 0; |
1801 |
++} |
1802 |
++ |
1803 |
+ /* |
1804 |
+ * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
1805 |
+ * user to request that behavior by using the 'acpi_old_suspend_ordering' |
1806 |
+@@ -324,6 +330,19 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { |
1807 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), |
1808 |
+ }, |
1809 |
+ }, |
1810 |
++ /* |
1811 |
++ * https://bugzilla.kernel.org/show_bug.cgi?id=189431 |
1812 |
++ * Lenovo G50-45 is a platform later than 2012, but needs nvs memory |
1813 |
++ * saving during S3. |
1814 |
++ */ |
1815 |
++ { |
1816 |
++ .callback = init_nvs_save_s3, |
1817 |
++ .ident = "Lenovo G50-45", |
1818 |
++ .matches = { |
1819 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
1820 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), |
1821 |
++ }, |
1822 |
++ }, |
1823 |
+ {}, |
1824 |
+ }; |
1825 |
+ |
1826 |
+diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c |
1827 |
+index 703c26e7022c..cf05ae973381 100644 |
1828 |
+--- a/drivers/acpi/sysfs.c |
1829 |
++++ b/drivers/acpi/sysfs.c |
1830 |
+@@ -708,6 +708,62 @@ static ssize_t counter_set(struct kobject *kobj, |
1831 |
+ return result ? result : size; |
1832 |
+ } |
1833 |
+ |
1834 |
++/* |
1835 |
++ * A Quirk Mechanism for GPE Flooding Prevention: |
1836 |
++ * |
1837 |
++ * Quirks may be needed to prevent GPE flooding on a specific GPE. The |
1838 |
++ * flooding typically cannot be detected and automatically prevented by |
1839 |
++ * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in |
1840 |
++ * the AML tables. This normally indicates a feature gap in Linux, thus |
1841 |
++ * instead of providing endless quirk tables, we provide a boot parameter |
1842 |
++ * for those who want this quirk. For example, if the users want to prevent |
1843 |
++ * the GPE flooding for GPE 00, they need to specify the following boot |
1844 |
++ * parameter: |
1845 |
++ * acpi_mask_gpe=0x00 |
1846 |
++ * The masking status can be modified by the following runtime controlling |
1847 |
++ * interface: |
1848 |
++ * echo unmask > /sys/firmware/acpi/interrupts/gpe00 |
1849 |
++ */ |
1850 |
++ |
1851 |
++/* |
1852 |
++ * Currently, the GPE flooding prevention only supports to mask the GPEs |
1853 |
++ * numbered from 00 to 7f. |
1854 |
++ */ |
1855 |
++#define ACPI_MASKABLE_GPE_MAX 0x80 |
1856 |
++ |
1857 |
++static u64 __initdata acpi_masked_gpes; |
1858 |
++ |
1859 |
++static int __init acpi_gpe_set_masked_gpes(char *val) |
1860 |
++{ |
1861 |
++ u8 gpe; |
1862 |
++ |
1863 |
++ if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX) |
1864 |
++ return -EINVAL; |
1865 |
++ acpi_masked_gpes |= ((u64)1<<gpe); |
1866 |
++ |
1867 |
++ return 1; |
1868 |
++} |
1869 |
++__setup("acpi_mask_gpe=", acpi_gpe_set_masked_gpes); |
1870 |
++ |
1871 |
++void __init acpi_gpe_apply_masked_gpes(void) |
1872 |
++{ |
1873 |
++ acpi_handle handle; |
1874 |
++ acpi_status status; |
1875 |
++ u8 gpe; |
1876 |
++ |
1877 |
++ for (gpe = 0; |
1878 |
++ gpe < min_t(u8, ACPI_MASKABLE_GPE_MAX, acpi_current_gpe_count); |
1879 |
++ gpe++) { |
1880 |
++ if (acpi_masked_gpes & ((u64)1<<gpe)) { |
1881 |
++ status = acpi_get_gpe_device(gpe, &handle); |
1882 |
++ if (ACPI_SUCCESS(status)) { |
1883 |
++ pr_info("Masking GPE 0x%x.\n", gpe); |
1884 |
++ (void)acpi_mask_gpe(handle, gpe, TRUE); |
1885 |
++ } |
1886 |
++ } |
1887 |
++ } |
1888 |
++} |
1889 |
++ |
1890 |
+ void acpi_irq_stats_init(void) |
1891 |
+ { |
1892 |
+ acpi_status status; |
1893 |
+diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c |
1894 |
+index 267a3d3e79f4..52f2674d5e89 100644 |
1895 |
+--- a/drivers/ata/ahci_da850.c |
1896 |
++++ b/drivers/ata/ahci_da850.c |
1897 |
+@@ -54,11 +54,42 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, |
1898 |
+ writel(val, ahci_base + SATA_P0PHYCR_REG); |
1899 |
+ } |
1900 |
+ |
1901 |
++static int ahci_da850_softreset(struct ata_link *link, |
1902 |
++ unsigned int *class, unsigned long deadline) |
1903 |
++{ |
1904 |
++ int pmp, ret; |
1905 |
++ |
1906 |
++ pmp = sata_srst_pmp(link); |
1907 |
++ |
1908 |
++ /* |
1909 |
++ * There's an issue with the SATA controller on da850 SoCs: if we |
1910 |
++ * enable Port Multiplier support, but the drive is connected directly |
1911 |
++ * to the board, it can't be detected. As a workaround: if PMP is |
1912 |
++ * enabled, we first call ahci_do_softreset() and pass it the result of |
1913 |
++ * sata_srst_pmp(). If this call fails, we retry with pmp = 0. |
1914 |
++ */ |
1915 |
++ ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); |
1916 |
++ if (pmp && ret == -EBUSY) |
1917 |
++ return ahci_do_softreset(link, class, 0, |
1918 |
++ deadline, ahci_check_ready); |
1919 |
++ |
1920 |
++ return ret; |
1921 |
++} |
1922 |
++ |
1923 |
++static struct ata_port_operations ahci_da850_port_ops = { |
1924 |
++ .inherits = &ahci_platform_ops, |
1925 |
++ .softreset = ahci_da850_softreset, |
1926 |
++ /* |
1927 |
++ * No need to override .pmp_softreset - it's only used for actual |
1928 |
++ * PMP-enabled ports. |
1929 |
++ */ |
1930 |
++}; |
1931 |
++ |
1932 |
+ static const struct ata_port_info ahci_da850_port_info = { |
1933 |
+ .flags = AHCI_FLAG_COMMON, |
1934 |
+ .pio_mask = ATA_PIO4, |
1935 |
+ .udma_mask = ATA_UDMA6, |
1936 |
+- .port_ops = &ahci_platform_ops, |
1937 |
++ .port_ops = &ahci_da850_port_ops, |
1938 |
+ }; |
1939 |
+ |
1940 |
+ static struct scsi_host_template ahci_platform_sht = { |
1941 |
+diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c |
1942 |
+index 6af1ce04b3da..336d02a488cc 100644 |
1943 |
+--- a/drivers/char/ppdev.c |
1944 |
++++ b/drivers/char/ppdev.c |
1945 |
+@@ -84,8 +84,14 @@ struct pp_struct { |
1946 |
+ struct ieee1284_info state; |
1947 |
+ struct ieee1284_info saved_state; |
1948 |
+ long default_inactivity; |
1949 |
++ int index; |
1950 |
+ }; |
1951 |
+ |
1952 |
++/* should we use PARDEVICE_MAX here? */ |
1953 |
++static struct device *devices[PARPORT_MAX]; |
1954 |
++ |
1955 |
++static DEFINE_IDA(ida_index); |
1956 |
++ |
1957 |
+ /* pp_struct.flags bitfields */ |
1958 |
+ #define PP_CLAIMED (1<<0) |
1959 |
+ #define PP_EXCL (1<<1) |
1960 |
+@@ -287,6 +293,7 @@ static int register_device(int minor, struct pp_struct *pp) |
1961 |
+ struct pardevice *pdev = NULL; |
1962 |
+ char *name; |
1963 |
+ struct pardev_cb ppdev_cb; |
1964 |
++ int index; |
1965 |
+ |
1966 |
+ name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); |
1967 |
+ if (name == NULL) |
1968 |
+@@ -299,20 +306,23 @@ static int register_device(int minor, struct pp_struct *pp) |
1969 |
+ return -ENXIO; |
1970 |
+ } |
1971 |
+ |
1972 |
++ index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); |
1973 |
+ memset(&ppdev_cb, 0, sizeof(ppdev_cb)); |
1974 |
+ ppdev_cb.irq_func = pp_irq; |
1975 |
+ ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; |
1976 |
+ ppdev_cb.private = pp; |
1977 |
+- pdev = parport_register_dev_model(port, name, &ppdev_cb, minor); |
1978 |
++ pdev = parport_register_dev_model(port, name, &ppdev_cb, index); |
1979 |
+ parport_put_port(port); |
1980 |
+ |
1981 |
+ if (!pdev) { |
1982 |
+ printk(KERN_WARNING "%s: failed to register device!\n", name); |
1983 |
++ ida_simple_remove(&ida_index, index); |
1984 |
+ kfree(name); |
1985 |
+ return -ENXIO; |
1986 |
+ } |
1987 |
+ |
1988 |
+ pp->pdev = pdev; |
1989 |
++ pp->index = index; |
1990 |
+ dev_dbg(&pdev->dev, "registered pardevice\n"); |
1991 |
+ return 0; |
1992 |
+ } |
1993 |
+@@ -749,6 +759,7 @@ static int pp_release(struct inode *inode, struct file *file) |
1994 |
+ |
1995 |
+ if (pp->pdev) { |
1996 |
+ parport_unregister_device(pp->pdev); |
1997 |
++ ida_simple_remove(&ida_index, pp->index); |
1998 |
+ pp->pdev = NULL; |
1999 |
+ pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); |
2000 |
+ } |
2001 |
+@@ -789,13 +800,29 @@ static const struct file_operations pp_fops = { |
2002 |
+ |
2003 |
+ static void pp_attach(struct parport *port) |
2004 |
+ { |
2005 |
+- device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), |
2006 |
+- NULL, "parport%d", port->number); |
2007 |
++ struct device *ret; |
2008 |
++ |
2009 |
++ if (devices[port->number]) |
2010 |
++ return; |
2011 |
++ |
2012 |
++ ret = device_create(ppdev_class, port->dev, |
2013 |
++ MKDEV(PP_MAJOR, port->number), NULL, |
2014 |
++ "parport%d", port->number); |
2015 |
++ if (IS_ERR(ret)) { |
2016 |
++ pr_err("Failed to create device parport%d\n", |
2017 |
++ port->number); |
2018 |
++ return; |
2019 |
++ } |
2020 |
++ devices[port->number] = ret; |
2021 |
+ } |
2022 |
+ |
2023 |
+ static void pp_detach(struct parport *port) |
2024 |
+ { |
2025 |
++ if (!devices[port->number]) |
2026 |
++ return; |
2027 |
++ |
2028 |
+ device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); |
2029 |
++ devices[port->number] = NULL; |
2030 |
+ } |
2031 |
+ |
2032 |
+ static int pp_probe(struct pardevice *par_dev) |
2033 |
+diff --git a/drivers/char/random.c b/drivers/char/random.c |
2034 |
+index d6876d506220..08d1dd58c0d2 100644 |
2035 |
+--- a/drivers/char/random.c |
2036 |
++++ b/drivers/char/random.c |
2037 |
+@@ -2042,63 +2042,65 @@ struct ctl_table random_table[] = { |
2038 |
+ }; |
2039 |
+ #endif /* CONFIG_SYSCTL */ |
2040 |
+ |
2041 |
+-static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
2042 |
+- |
2043 |
+-int random_int_secret_init(void) |
2044 |
+-{ |
2045 |
+- get_random_bytes(random_int_secret, sizeof(random_int_secret)); |
2046 |
+- return 0; |
2047 |
+-} |
2048 |
+- |
2049 |
+-static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) |
2050 |
+- __aligned(sizeof(unsigned long)); |
2051 |
++struct batched_entropy { |
2052 |
++ union { |
2053 |
++ unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)]; |
2054 |
++ unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)]; |
2055 |
++ }; |
2056 |
++ unsigned int position; |
2057 |
++}; |
2058 |
+ |
2059 |
+ /* |
2060 |
+- * Get a random word for internal kernel use only. Similar to urandom but |
2061 |
+- * with the goal of minimal entropy pool depletion. As a result, the random |
2062 |
+- * value is not cryptographically secure but for several uses the cost of |
2063 |
+- * depleting entropy is too high |
2064 |
++ * Get a random word for internal kernel use only. The quality of the random |
2065 |
++ * number is either as good as RDRAND or as good as /dev/urandom, with the |
2066 |
++ * goal of being quite fast and not depleting entropy. |
2067 |
+ */ |
2068 |
+-unsigned int get_random_int(void) |
2069 |
++static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long); |
2070 |
++unsigned long get_random_long(void) |
2071 |
+ { |
2072 |
+- __u32 *hash; |
2073 |
+- unsigned int ret; |
2074 |
++ unsigned long ret; |
2075 |
++ struct batched_entropy *batch; |
2076 |
+ |
2077 |
+- if (arch_get_random_int(&ret)) |
2078 |
++ if (arch_get_random_long(&ret)) |
2079 |
+ return ret; |
2080 |
+ |
2081 |
+- hash = get_cpu_var(get_random_int_hash); |
2082 |
+- |
2083 |
+- hash[0] += current->pid + jiffies + random_get_entropy(); |
2084 |
+- md5_transform(hash, random_int_secret); |
2085 |
+- ret = hash[0]; |
2086 |
+- put_cpu_var(get_random_int_hash); |
2087 |
+- |
2088 |
++ batch = &get_cpu_var(batched_entropy_long); |
2089 |
++ if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) { |
2090 |
++ extract_crng((u8 *)batch->entropy_long); |
2091 |
++ batch->position = 0; |
2092 |
++ } |
2093 |
++ ret = batch->entropy_long[batch->position++]; |
2094 |
++ put_cpu_var(batched_entropy_long); |
2095 |
+ return ret; |
2096 |
+ } |
2097 |
+-EXPORT_SYMBOL(get_random_int); |
2098 |
++EXPORT_SYMBOL(get_random_long); |
2099 |
+ |
2100 |
+-/* |
2101 |
+- * Same as get_random_int(), but returns unsigned long. |
2102 |
+- */ |
2103 |
+-unsigned long get_random_long(void) |
2104 |
++#if BITS_PER_LONG == 32 |
2105 |
++unsigned int get_random_int(void) |
2106 |
+ { |
2107 |
+- __u32 *hash; |
2108 |
+- unsigned long ret; |
2109 |
++ return get_random_long(); |
2110 |
++} |
2111 |
++#else |
2112 |
++static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int); |
2113 |
++unsigned int get_random_int(void) |
2114 |
++{ |
2115 |
++ unsigned int ret; |
2116 |
++ struct batched_entropy *batch; |
2117 |
+ |
2118 |
+- if (arch_get_random_long(&ret)) |
2119 |
++ if (arch_get_random_int(&ret)) |
2120 |
+ return ret; |
2121 |
+ |
2122 |
+- hash = get_cpu_var(get_random_int_hash); |
2123 |
+- |
2124 |
+- hash[0] += current->pid + jiffies + random_get_entropy(); |
2125 |
+- md5_transform(hash, random_int_secret); |
2126 |
+- ret = *(unsigned long *)hash; |
2127 |
+- put_cpu_var(get_random_int_hash); |
2128 |
+- |
2129 |
++ batch = &get_cpu_var(batched_entropy_int); |
2130 |
++ if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) { |
2131 |
++ extract_crng((u8 *)batch->entropy_int); |
2132 |
++ batch->position = 0; |
2133 |
++ } |
2134 |
++ ret = batch->entropy_int[batch->position++]; |
2135 |
++ put_cpu_var(batched_entropy_int); |
2136 |
+ return ret; |
2137 |
+ } |
2138 |
+-EXPORT_SYMBOL(get_random_long); |
2139 |
++#endif |
2140 |
++EXPORT_SYMBOL(get_random_int); |
2141 |
+ |
2142 |
+ /** |
2143 |
+ * randomize_page - Generate a random, page aligned address |
2144 |
+diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c |
2145 |
+index 34c97353cdeb..5b98ff9076f3 100644 |
2146 |
+--- a/drivers/clk/nxp/clk-lpc32xx.c |
2147 |
++++ b/drivers/clk/nxp/clk-lpc32xx.c |
2148 |
+@@ -1282,13 +1282,13 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = { |
2149 |
+ |
2150 |
+ LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0), |
2151 |
+ LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL, |
2152 |
+- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), |
2153 |
++ CLK_DIVIDER_ONE_BASED), |
2154 |
+ LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0), |
2155 |
+ LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE), |
2156 |
+ |
2157 |
+ LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0), |
2158 |
+ LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL, |
2159 |
+- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), |
2160 |
++ CLK_DIVIDER_ONE_BASED), |
2161 |
+ LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0), |
2162 |
+ LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE), |
2163 |
+ |
2164 |
+@@ -1335,8 +1335,7 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = { |
2165 |
+ LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0), |
2166 |
+ LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE), |
2167 |
+ |
2168 |
+- LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, |
2169 |
+- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), |
2170 |
++ LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, CLK_DIVIDER_ONE_BASED), |
2171 |
+ LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9), |
2172 |
+ 0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops), |
2173 |
+ LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE), |
2174 |
+@@ -1478,6 +1477,20 @@ static struct clk * __init lpc32xx_clk_register(u32 id) |
2175 |
+ return clk; |
2176 |
+ } |
2177 |
+ |
2178 |
++static void __init lpc32xx_clk_div_quirk(u32 reg, u32 div_mask, u32 gate) |
2179 |
++{ |
2180 |
++ u32 val; |
2181 |
++ |
2182 |
++ regmap_read(clk_regmap, reg, &val); |
2183 |
++ |
2184 |
++ if (!(val & div_mask)) { |
2185 |
++ val &= ~gate; |
2186 |
++ val |= BIT(__ffs(div_mask)); |
2187 |
++ } |
2188 |
++ |
2189 |
++ regmap_update_bits(clk_regmap, reg, gate | div_mask, val); |
2190 |
++} |
2191 |
++ |
2192 |
+ static void __init lpc32xx_clk_init(struct device_node *np) |
2193 |
+ { |
2194 |
+ unsigned int i; |
2195 |
+@@ -1517,6 +1530,17 @@ static void __init lpc32xx_clk_init(struct device_node *np) |
2196 |
+ return; |
2197 |
+ } |
2198 |
+ |
2199 |
++ /* |
2200 |
++ * Divider part of PWM and MS clocks requires a quirk to avoid |
2201 |
++ * a misinterpretation of formally valid zero value in register |
2202 |
++ * bitfield, which indicates another clock gate. Instead of |
2203 |
++ * adding complexity to a gate clock ensure that zero value in |
2204 |
++ * divider clock is never met in runtime. |
2205 |
++ */ |
2206 |
++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf0, BIT(0)); |
2207 |
++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf00, BIT(2)); |
2208 |
++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_MS_CTRL, 0xf, BIT(5) | BIT(9)); |
2209 |
++ |
2210 |
+ for (i = 1; i < LPC32XX_CLK_MAX; i++) { |
2211 |
+ clk[i] = lpc32xx_clk_register(i); |
2212 |
+ if (IS_ERR(clk[i])) { |
2213 |
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c |
2214 |
+index 73c487da6d2a..a2503db7e533 100644 |
2215 |
+--- a/drivers/clocksource/arm_arch_timer.c |
2216 |
++++ b/drivers/clocksource/arm_arch_timer.c |
2217 |
+@@ -81,6 +81,7 @@ static struct clock_event_device __percpu *arch_timer_evt; |
2218 |
+ static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI; |
2219 |
+ static bool arch_timer_c3stop; |
2220 |
+ static bool arch_timer_mem_use_virtual; |
2221 |
++static bool arch_counter_suspend_stop; |
2222 |
+ |
2223 |
+ static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); |
2224 |
+ |
2225 |
+@@ -576,7 +577,7 @@ static struct clocksource clocksource_counter = { |
2226 |
+ .rating = 400, |
2227 |
+ .read = arch_counter_read, |
2228 |
+ .mask = CLOCKSOURCE_MASK(56), |
2229 |
+- .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, |
2230 |
++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
2231 |
+ }; |
2232 |
+ |
2233 |
+ static struct cyclecounter cyclecounter = { |
2234 |
+@@ -616,6 +617,8 @@ static void __init arch_counter_register(unsigned type) |
2235 |
+ arch_timer_read_counter = arch_counter_get_cntvct_mem; |
2236 |
+ } |
2237 |
+ |
2238 |
++ if (!arch_counter_suspend_stop) |
2239 |
++ clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; |
2240 |
+ start_count = arch_timer_read_counter(); |
2241 |
+ clocksource_register_hz(&clocksource_counter, arch_timer_rate); |
2242 |
+ cyclecounter.mult = clocksource_counter.mult; |
2243 |
+@@ -907,6 +910,10 @@ static int __init arch_timer_of_init(struct device_node *np) |
2244 |
+ of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) |
2245 |
+ arch_timer_uses_ppi = PHYS_SECURE_PPI; |
2246 |
+ |
2247 |
++ /* On some systems, the counter stops ticking when in suspend. */ |
2248 |
++ arch_counter_suspend_stop = of_property_read_bool(np, |
2249 |
++ "arm,no-tick-in-suspend"); |
2250 |
++ |
2251 |
+ return arch_timer_init(); |
2252 |
+ } |
2253 |
+ CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); |
2254 |
+diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c |
2255 |
+index 4a0f5ead4fb5..1e2e5198db53 100644 |
2256 |
+--- a/drivers/firmware/qcom_scm-64.c |
2257 |
++++ b/drivers/firmware/qcom_scm-64.c |
2258 |
+@@ -91,6 +91,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, |
2259 |
+ dma_addr_t args_phys = 0; |
2260 |
+ void *args_virt = NULL; |
2261 |
+ size_t alloc_len; |
2262 |
++ struct arm_smccc_quirk quirk = {.id = ARM_SMCCC_QUIRK_QCOM_A6}; |
2263 |
+ |
2264 |
+ if (unlikely(arglen > N_REGISTER_ARGS)) { |
2265 |
+ alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64); |
2266 |
+@@ -131,10 +132,16 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, |
2267 |
+ qcom_smccc_convention, |
2268 |
+ ARM_SMCCC_OWNER_SIP, fn_id); |
2269 |
+ |
2270 |
++ quirk.state.a6 = 0; |
2271 |
++ |
2272 |
+ do { |
2273 |
+- arm_smccc_smc(cmd, desc->arginfo, desc->args[0], |
2274 |
+- desc->args[1], desc->args[2], x5, 0, 0, |
2275 |
+- res); |
2276 |
++ arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0], |
2277 |
++ desc->args[1], desc->args[2], x5, |
2278 |
++ quirk.state.a6, 0, res, &quirk); |
2279 |
++ |
2280 |
++ if (res->a0 == QCOM_SCM_INTERRUPTED) |
2281 |
++ cmd = res->a0; |
2282 |
++ |
2283 |
+ } while (res->a0 == QCOM_SCM_INTERRUPTED); |
2284 |
+ |
2285 |
+ mutex_unlock(&qcom_scm_lock); |
2286 |
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c |
2287 |
+index 72a4b326fd0d..986248f7011a 100644 |
2288 |
+--- a/drivers/gpio/gpiolib-acpi.c |
2289 |
++++ b/drivers/gpio/gpiolib-acpi.c |
2290 |
+@@ -571,8 +571,10 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, |
2291 |
+ } |
2292 |
+ |
2293 |
+ desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); |
2294 |
+- if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) |
2295 |
++ if (!IS_ERR(desc)) |
2296 |
+ break; |
2297 |
++ if (PTR_ERR(desc) == -EPROBE_DEFER) |
2298 |
++ return ERR_CAST(desc); |
2299 |
+ } |
2300 |
+ |
2301 |
+ /* Then from plain _CRS GPIOs */ |
2302 |
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c |
2303 |
+index 7491180698d1..0bc0afb6321e 100644 |
2304 |
+--- a/drivers/gpu/drm/drm_edid.c |
2305 |
++++ b/drivers/gpu/drm/drm_edid.c |
2306 |
+@@ -90,7 +90,7 @@ struct detailed_mode_closure { |
2307 |
+ #define LEVEL_GTF2 2 |
2308 |
+ #define LEVEL_CVT 3 |
2309 |
+ |
2310 |
+-static struct edid_quirk { |
2311 |
++static const struct edid_quirk { |
2312 |
+ char vendor[4]; |
2313 |
+ int product_id; |
2314 |
+ u32 quirks; |
2315 |
+@@ -1449,7 +1449,7 @@ EXPORT_SYMBOL(drm_edid_duplicate); |
2316 |
+ * |
2317 |
+ * Returns true if @vendor is in @edid, false otherwise |
2318 |
+ */ |
2319 |
+-static bool edid_vendor(struct edid *edid, char *vendor) |
2320 |
++static bool edid_vendor(struct edid *edid, const char *vendor) |
2321 |
+ { |
2322 |
+ char edid_vendor[3]; |
2323 |
+ |
2324 |
+@@ -1469,7 +1469,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) |
2325 |
+ */ |
2326 |
+ static u32 edid_get_quirks(struct edid *edid) |
2327 |
+ { |
2328 |
+- struct edid_quirk *quirk; |
2329 |
++ const struct edid_quirk *quirk; |
2330 |
+ int i; |
2331 |
+ |
2332 |
+ for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) { |
2333 |
+diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c |
2334 |
+index 31e6edd08dd0..9e9488639af5 100644 |
2335 |
+--- a/drivers/gpu/drm/i915/i915_pci.c |
2336 |
++++ b/drivers/gpu/drm/i915/i915_pci.c |
2337 |
+@@ -417,6 +417,7 @@ static const struct pci_device_id pciidlist[] = { |
2338 |
+ INTEL_VLV_IDS(&intel_valleyview_info), |
2339 |
+ INTEL_BDW_GT12_IDS(&intel_broadwell_info), |
2340 |
+ INTEL_BDW_GT3_IDS(&intel_broadwell_gt3_info), |
2341 |
++ INTEL_BDW_RSVD_IDS(&intel_broadwell_info), |
2342 |
+ INTEL_CHV_IDS(&intel_cherryview_info), |
2343 |
+ INTEL_SKL_GT1_IDS(&intel_skylake_info), |
2344 |
+ INTEL_SKL_GT2_IDS(&intel_skylake_info), |
2345 |
+diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c |
2346 |
+index 1f2f9ca25901..4556e2b13ac5 100644 |
2347 |
+--- a/drivers/gpu/drm/mga/mga_dma.c |
2348 |
++++ b/drivers/gpu/drm/mga/mga_dma.c |
2349 |
+@@ -392,6 +392,24 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags) |
2350 |
+ drm_mga_private_t *dev_priv; |
2351 |
+ int ret; |
2352 |
+ |
2353 |
++ /* There are PCI versions of the G450. These cards have the |
2354 |
++ * same PCI ID as the AGP G450, but have an additional PCI-to-PCI |
2355 |
++ * bridge chip. We detect these cards, which are not currently |
2356 |
++ * supported by this driver, by looking at the device ID of the |
2357 |
++ * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the |
2358 |
++ * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the |
2359 |
++ * device. |
2360 |
++ */ |
2361 |
++ if ((dev->pdev->device == 0x0525) && dev->pdev->bus->self |
2362 |
++ && (dev->pdev->bus->self->vendor == 0x3388) |
2363 |
++ && (dev->pdev->bus->self->device == 0x0021) |
2364 |
++ && dev->agp) { |
2365 |
++ /* FIXME: This should be quirked in the pci core, but oh well |
2366 |
++ * the hw probably stopped existing. */ |
2367 |
++ arch_phys_wc_del(dev->agp->agp_mtrr); |
2368 |
++ kfree(dev->agp); |
2369 |
++ dev->agp = NULL; |
2370 |
++ } |
2371 |
+ dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL); |
2372 |
+ if (!dev_priv) |
2373 |
+ return -ENOMEM; |
2374 |
+@@ -698,7 +716,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device *dev, |
2375 |
+ static int mga_do_dma_bootstrap(struct drm_device *dev, |
2376 |
+ drm_mga_dma_bootstrap_t *dma_bs) |
2377 |
+ { |
2378 |
+- const int is_agp = (dma_bs->agp_mode != 0) && drm_pci_device_is_agp(dev); |
2379 |
++ const int is_agp = (dma_bs->agp_mode != 0) && dev->agp; |
2380 |
+ int err; |
2381 |
+ drm_mga_private_t *const dev_priv = |
2382 |
+ (drm_mga_private_t *) dev->dev_private; |
2383 |
+diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c |
2384 |
+index 25b2a1a424e6..63ba0699d107 100644 |
2385 |
+--- a/drivers/gpu/drm/mga/mga_drv.c |
2386 |
++++ b/drivers/gpu/drm/mga/mga_drv.c |
2387 |
+@@ -37,8 +37,6 @@ |
2388 |
+ |
2389 |
+ #include <drm/drm_pciids.h> |
2390 |
+ |
2391 |
+-static int mga_driver_device_is_agp(struct drm_device *dev); |
2392 |
+- |
2393 |
+ static struct pci_device_id pciidlist[] = { |
2394 |
+ mga_PCI_IDS |
2395 |
+ }; |
2396 |
+@@ -66,7 +64,6 @@ static struct drm_driver driver = { |
2397 |
+ .lastclose = mga_driver_lastclose, |
2398 |
+ .set_busid = drm_pci_set_busid, |
2399 |
+ .dma_quiescent = mga_driver_dma_quiescent, |
2400 |
+- .device_is_agp = mga_driver_device_is_agp, |
2401 |
+ .get_vblank_counter = mga_get_vblank_counter, |
2402 |
+ .enable_vblank = mga_enable_vblank, |
2403 |
+ .disable_vblank = mga_disable_vblank, |
2404 |
+@@ -107,37 +104,3 @@ module_exit(mga_exit); |
2405 |
+ MODULE_AUTHOR(DRIVER_AUTHOR); |
2406 |
+ MODULE_DESCRIPTION(DRIVER_DESC); |
2407 |
+ MODULE_LICENSE("GPL and additional rights"); |
2408 |
+- |
2409 |
+-/** |
2410 |
+- * Determine if the device really is AGP or not. |
2411 |
+- * |
2412 |
+- * In addition to the usual tests performed by \c drm_device_is_agp, this |
2413 |
+- * function detects PCI G450 cards that appear to the system exactly like |
2414 |
+- * AGP G450 cards. |
2415 |
+- * |
2416 |
+- * \param dev The device to be tested. |
2417 |
+- * |
2418 |
+- * \returns |
2419 |
+- * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. |
2420 |
+- */ |
2421 |
+-static int mga_driver_device_is_agp(struct drm_device *dev) |
2422 |
+-{ |
2423 |
+- const struct pci_dev *const pdev = dev->pdev; |
2424 |
+- |
2425 |
+- /* There are PCI versions of the G450. These cards have the |
2426 |
+- * same PCI ID as the AGP G450, but have an additional PCI-to-PCI |
2427 |
+- * bridge chip. We detect these cards, which are not currently |
2428 |
+- * supported by this driver, by looking at the device ID of the |
2429 |
+- * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the |
2430 |
+- * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the |
2431 |
+- * device. |
2432 |
+- */ |
2433 |
+- |
2434 |
+- if ((pdev->device == 0x0525) && pdev->bus->self |
2435 |
+- && (pdev->bus->self->vendor == 0x3388) |
2436 |
+- && (pdev->bus->self->device == 0x0021)) { |
2437 |
+- return 0; |
2438 |
+- } |
2439 |
+- |
2440 |
+- return 2; |
2441 |
+-} |
2442 |
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c |
2443 |
+index 5127b75dbf40..7250ffc6322f 100644 |
2444 |
+--- a/drivers/gpu/drm/msm/adreno/adreno_device.c |
2445 |
++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c |
2446 |
+@@ -25,9 +25,6 @@ bool hang_debug = false; |
2447 |
+ MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)"); |
2448 |
+ module_param_named(hang_debug, hang_debug, bool, 0600); |
2449 |
+ |
2450 |
+-struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); |
2451 |
+-struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); |
2452 |
+- |
2453 |
+ static const struct adreno_info gpulist[] = { |
2454 |
+ { |
2455 |
+ .rev = ADRENO_REV(3, 0, 5, ANY_ID), |
2456 |
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h |
2457 |
+index a54f6e036b4a..07d99bdf7c99 100644 |
2458 |
+--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h |
2459 |
++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h |
2460 |
+@@ -311,4 +311,7 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu, |
2461 |
+ gpu_write(&gpu->base, reg - 1, data); |
2462 |
+ } |
2463 |
+ |
2464 |
++struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); |
2465 |
++struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); |
2466 |
++ |
2467 |
+ #endif /* __ADRENO_GPU_H__ */ |
2468 |
+diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c |
2469 |
+index 32c0584e3c35..6e6c59a661b6 100644 |
2470 |
+--- a/drivers/gpu/drm/sun4i/sun4i_backend.c |
2471 |
++++ b/drivers/gpu/drm/sun4i/sun4i_backend.c |
2472 |
+@@ -408,6 +408,7 @@ static int sun4i_backend_remove(struct platform_device *pdev) |
2473 |
+ |
2474 |
+ static const struct of_device_id sun4i_backend_of_table[] = { |
2475 |
+ { .compatible = "allwinner,sun5i-a13-display-backend" }, |
2476 |
++ { .compatible = "allwinner,sun6i-a31-display-backend" }, |
2477 |
+ { .compatible = "allwinner,sun8i-a33-display-backend" }, |
2478 |
+ { } |
2479 |
+ }; |
2480 |
+diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c |
2481 |
+index 70e9fd59c5a2..c3b21865443e 100644 |
2482 |
+--- a/drivers/gpu/drm/sun4i/sun4i_drv.c |
2483 |
++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c |
2484 |
+@@ -201,12 +201,15 @@ static const struct component_master_ops sun4i_drv_master_ops = { |
2485 |
+ static bool sun4i_drv_node_is_frontend(struct device_node *node) |
2486 |
+ { |
2487 |
+ return of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") || |
2488 |
++ of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") || |
2489 |
+ of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); |
2490 |
+ } |
2491 |
+ |
2492 |
+ static bool sun4i_drv_node_is_tcon(struct device_node *node) |
2493 |
+ { |
2494 |
+ return of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") || |
2495 |
++ of_device_is_compatible(node, "allwinner,sun6i-a31-tcon") || |
2496 |
++ of_device_is_compatible(node, "allwinner,sun6i-a31s-tcon") || |
2497 |
+ of_device_is_compatible(node, "allwinner,sun8i-a33-tcon"); |
2498 |
+ } |
2499 |
+ |
2500 |
+@@ -322,6 +325,8 @@ static int sun4i_drv_remove(struct platform_device *pdev) |
2501 |
+ |
2502 |
+ static const struct of_device_id sun4i_drv_of_table[] = { |
2503 |
+ { .compatible = "allwinner,sun5i-a13-display-engine" }, |
2504 |
++ { .compatible = "allwinner,sun6i-a31-display-engine" }, |
2505 |
++ { .compatible = "allwinner,sun6i-a31s-display-engine" }, |
2506 |
+ { .compatible = "allwinner,sun8i-a33-display-engine" }, |
2507 |
+ { } |
2508 |
+ }; |
2509 |
+diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c |
2510 |
+index cadacb517f95..c6afb2448655 100644 |
2511 |
+--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c |
2512 |
++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c |
2513 |
+@@ -20,6 +20,7 @@ |
2514 |
+ #include <linux/component.h> |
2515 |
+ #include <linux/ioport.h> |
2516 |
+ #include <linux/of_address.h> |
2517 |
++#include <linux/of_device.h> |
2518 |
+ #include <linux/of_graph.h> |
2519 |
+ #include <linux/of_irq.h> |
2520 |
+ #include <linux/regmap.h> |
2521 |
+@@ -62,7 +63,7 @@ void sun4i_tcon_channel_disable(struct sun4i_tcon *tcon, int channel) |
2522 |
+ return; |
2523 |
+ } |
2524 |
+ |
2525 |
+- WARN_ON(!tcon->has_channel_1); |
2526 |
++ WARN_ON(!tcon->quirks->has_channel_1); |
2527 |
+ regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, |
2528 |
+ SUN4I_TCON1_CTL_TCON_ENABLE, 0); |
2529 |
+ clk_disable_unprepare(tcon->sclk1); |
2530 |
+@@ -80,7 +81,7 @@ void sun4i_tcon_channel_enable(struct sun4i_tcon *tcon, int channel) |
2531 |
+ return; |
2532 |
+ } |
2533 |
+ |
2534 |
+- WARN_ON(!tcon->has_channel_1); |
2535 |
++ WARN_ON(!tcon->quirks->has_channel_1); |
2536 |
+ regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, |
2537 |
+ SUN4I_TCON1_CTL_TCON_ENABLE, |
2538 |
+ SUN4I_TCON1_CTL_TCON_ENABLE); |
2539 |
+@@ -202,7 +203,7 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, |
2540 |
+ u8 clk_delay; |
2541 |
+ u32 val; |
2542 |
+ |
2543 |
+- WARN_ON(!tcon->has_channel_1); |
2544 |
++ WARN_ON(!tcon->quirks->has_channel_1); |
2545 |
+ |
2546 |
+ /* Adjust clock delay */ |
2547 |
+ clk_delay = sun4i_tcon_get_clk_delay(mode, 1); |
2548 |
+@@ -266,7 +267,7 @@ void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, |
2549 |
+ /* |
2550 |
+ * FIXME: Undocumented bits |
2551 |
+ */ |
2552 |
+- if (tcon->has_mux) |
2553 |
++ if (tcon->quirks->has_unknown_mux) |
2554 |
+ regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, 1); |
2555 |
+ } |
2556 |
+ EXPORT_SYMBOL(sun4i_tcon1_mode_set); |
2557 |
+@@ -327,7 +328,7 @@ static int sun4i_tcon_init_clocks(struct device *dev, |
2558 |
+ return PTR_ERR(tcon->sclk0); |
2559 |
+ } |
2560 |
+ |
2561 |
+- if (tcon->has_channel_1) { |
2562 |
++ if (tcon->quirks->has_channel_1) { |
2563 |
+ tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); |
2564 |
+ if (IS_ERR(tcon->sclk1)) { |
2565 |
+ dev_err(dev, "Couldn't get the TCON channel 1 clock\n"); |
2566 |
+@@ -487,14 +488,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, |
2567 |
+ drv->tcon = tcon; |
2568 |
+ tcon->drm = drm; |
2569 |
+ tcon->dev = dev; |
2570 |
+- |
2571 |
+- if (of_device_is_compatible(dev->of_node, "allwinner,sun5i-a13-tcon")) { |
2572 |
+- tcon->has_mux = true; |
2573 |
+- tcon->has_channel_1 = true; |
2574 |
+- } else { |
2575 |
+- tcon->has_mux = false; |
2576 |
+- tcon->has_channel_1 = false; |
2577 |
+- } |
2578 |
++ tcon->quirks = of_device_get_match_data(dev); |
2579 |
+ |
2580 |
+ tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); |
2581 |
+ if (IS_ERR(tcon->lcd_rst)) { |
2582 |
+@@ -588,9 +582,28 @@ static int sun4i_tcon_remove(struct platform_device *pdev) |
2583 |
+ return 0; |
2584 |
+ } |
2585 |
+ |
2586 |
++static const struct sun4i_tcon_quirks sun5i_a13_quirks = { |
2587 |
++ .has_unknown_mux = true, |
2588 |
++ .has_channel_1 = true, |
2589 |
++}; |
2590 |
++ |
2591 |
++static const struct sun4i_tcon_quirks sun6i_a31_quirks = { |
2592 |
++ .has_channel_1 = true, |
2593 |
++}; |
2594 |
++ |
2595 |
++static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { |
2596 |
++ .has_channel_1 = true, |
2597 |
++}; |
2598 |
++ |
2599 |
++static const struct sun4i_tcon_quirks sun8i_a33_quirks = { |
2600 |
++ /* nothing is supported */ |
2601 |
++}; |
2602 |
++ |
2603 |
+ static const struct of_device_id sun4i_tcon_of_table[] = { |
2604 |
+- { .compatible = "allwinner,sun5i-a13-tcon" }, |
2605 |
+- { .compatible = "allwinner,sun8i-a33-tcon" }, |
2606 |
++ { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, |
2607 |
++ { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, |
2608 |
++ { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, |
2609 |
++ { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, |
2610 |
+ { } |
2611 |
+ }; |
2612 |
+ MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); |
2613 |
+diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h |
2614 |
+index 12bd48925f4d..166064bafe2e 100644 |
2615 |
+--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h |
2616 |
++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h |
2617 |
+@@ -142,6 +142,11 @@ |
2618 |
+ |
2619 |
+ #define SUN4I_TCON_MAX_CHANNELS 2 |
2620 |
+ |
2621 |
++struct sun4i_tcon_quirks { |
2622 |
++ bool has_unknown_mux; /* sun5i has undocumented mux */ |
2623 |
++ bool has_channel_1; /* a33 does not have channel 1 */ |
2624 |
++}; |
2625 |
++ |
2626 |
+ struct sun4i_tcon { |
2627 |
+ struct device *dev; |
2628 |
+ struct drm_device *drm; |
2629 |
+@@ -160,12 +165,10 @@ struct sun4i_tcon { |
2630 |
+ /* Reset control */ |
2631 |
+ struct reset_control *lcd_rst; |
2632 |
+ |
2633 |
+- /* Platform adjustments */ |
2634 |
+- bool has_mux; |
2635 |
+- |
2636 |
+ struct drm_panel *panel; |
2637 |
+ |
2638 |
+- bool has_channel_1; |
2639 |
++ /* Platform adjustments */ |
2640 |
++ const struct sun4i_tcon_quirks *quirks; |
2641 |
+ }; |
2642 |
+ |
2643 |
+ struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node); |
2644 |
+diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c |
2645 |
+index 4f5fa8d65fe9..144367c0c28f 100644 |
2646 |
+--- a/drivers/gpu/drm/ttm/ttm_object.c |
2647 |
++++ b/drivers/gpu/drm/ttm/ttm_object.c |
2648 |
+@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile, |
2649 |
+ if (unlikely(ret != 0)) |
2650 |
+ goto out_err0; |
2651 |
+ |
2652 |
+- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); |
2653 |
++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); |
2654 |
+ if (unlikely(ret != 0)) |
2655 |
+ goto out_err1; |
2656 |
+ |
2657 |
+@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists); |
2658 |
+ |
2659 |
+ int ttm_ref_object_add(struct ttm_object_file *tfile, |
2660 |
+ struct ttm_base_object *base, |
2661 |
+- enum ttm_ref_type ref_type, bool *existed) |
2662 |
++ enum ttm_ref_type ref_type, bool *existed, |
2663 |
++ bool require_existed) |
2664 |
+ { |
2665 |
+ struct drm_open_hash *ht = &tfile->ref_hash[ref_type]; |
2666 |
+ struct ttm_ref_object *ref; |
2667 |
+@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, |
2668 |
+ } |
2669 |
+ |
2670 |
+ rcu_read_unlock(); |
2671 |
++ if (require_existed) |
2672 |
++ return -EPERM; |
2673 |
++ |
2674 |
+ ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref), |
2675 |
+ false, false); |
2676 |
+ if (unlikely(ret != 0)) |
2677 |
+@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile, |
2678 |
+ prime = (struct ttm_prime_object *) dma_buf->priv; |
2679 |
+ base = &prime->base; |
2680 |
+ *handle = base->hash.key; |
2681 |
+- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); |
2682 |
++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); |
2683 |
+ |
2684 |
+ dma_buf_put(dma_buf); |
2685 |
+ |
2686 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |
2687 |
+index 26ac8e80a478..967450da9742 100644 |
2688 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |
2689 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |
2690 |
+@@ -538,7 +538,7 @@ int vmw_fence_create(struct vmw_fence_manager *fman, |
2691 |
+ struct vmw_fence_obj **p_fence) |
2692 |
+ { |
2693 |
+ struct vmw_fence_obj *fence; |
2694 |
+- int ret; |
2695 |
++ int ret; |
2696 |
+ |
2697 |
+ fence = kzalloc(sizeof(*fence), GFP_KERNEL); |
2698 |
+ if (unlikely(fence == NULL)) |
2699 |
+@@ -701,6 +701,41 @@ void vmw_fence_fifo_up(struct vmw_fence_manager *fman) |
2700 |
+ } |
2701 |
+ |
2702 |
+ |
2703 |
++/** |
2704 |
++ * vmw_fence_obj_lookup - Look up a user-space fence object |
2705 |
++ * |
2706 |
++ * @tfile: A struct ttm_object_file identifying the caller. |
2707 |
++ * @handle: A handle identifying the fence object. |
2708 |
++ * @return: A struct vmw_user_fence base ttm object on success or |
2709 |
++ * an error pointer on failure. |
2710 |
++ * |
2711 |
++ * The fence object is looked up and type-checked. The caller needs |
2712 |
++ * to have opened the fence object first, but since that happens on |
2713 |
++ * creation and fence objects aren't shareable, that's not an |
2714 |
++ * issue currently. |
2715 |
++ */ |
2716 |
++static struct ttm_base_object * |
2717 |
++vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle) |
2718 |
++{ |
2719 |
++ struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle); |
2720 |
++ |
2721 |
++ if (!base) { |
2722 |
++ pr_err("Invalid fence object handle 0x%08lx.\n", |
2723 |
++ (unsigned long)handle); |
2724 |
++ return ERR_PTR(-EINVAL); |
2725 |
++ } |
2726 |
++ |
2727 |
++ if (base->refcount_release != vmw_user_fence_base_release) { |
2728 |
++ pr_err("Invalid fence object handle 0x%08lx.\n", |
2729 |
++ (unsigned long)handle); |
2730 |
++ ttm_base_object_unref(&base); |
2731 |
++ return ERR_PTR(-EINVAL); |
2732 |
++ } |
2733 |
++ |
2734 |
++ return base; |
2735 |
++} |
2736 |
++ |
2737 |
++ |
2738 |
+ int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, |
2739 |
+ struct drm_file *file_priv) |
2740 |
+ { |
2741 |
+@@ -726,13 +761,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data, |
2742 |
+ arg->kernel_cookie = jiffies + wait_timeout; |
2743 |
+ } |
2744 |
+ |
2745 |
+- base = ttm_base_object_lookup(tfile, arg->handle); |
2746 |
+- if (unlikely(base == NULL)) { |
2747 |
+- printk(KERN_ERR "Wait invalid fence object handle " |
2748 |
+- "0x%08lx.\n", |
2749 |
+- (unsigned long)arg->handle); |
2750 |
+- return -EINVAL; |
2751 |
+- } |
2752 |
++ base = vmw_fence_obj_lookup(tfile, arg->handle); |
2753 |
++ if (IS_ERR(base)) |
2754 |
++ return PTR_ERR(base); |
2755 |
+ |
2756 |
+ fence = &(container_of(base, struct vmw_user_fence, base)->fence); |
2757 |
+ |
2758 |
+@@ -771,13 +802,9 @@ int vmw_fence_obj_signaled_ioctl(struct drm_device *dev, void *data, |
2759 |
+ struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
2760 |
+ struct vmw_private *dev_priv = vmw_priv(dev); |
2761 |
+ |
2762 |
+- base = ttm_base_object_lookup(tfile, arg->handle); |
2763 |
+- if (unlikely(base == NULL)) { |
2764 |
+- printk(KERN_ERR "Fence signaled invalid fence object handle " |
2765 |
+- "0x%08lx.\n", |
2766 |
+- (unsigned long)arg->handle); |
2767 |
+- return -EINVAL; |
2768 |
+- } |
2769 |
++ base = vmw_fence_obj_lookup(tfile, arg->handle); |
2770 |
++ if (IS_ERR(base)) |
2771 |
++ return PTR_ERR(base); |
2772 |
+ |
2773 |
+ fence = &(container_of(base, struct vmw_user_fence, base)->fence); |
2774 |
+ fman = fman_from_fence(fence); |
2775 |
+@@ -1024,6 +1051,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, |
2776 |
+ (struct drm_vmw_fence_event_arg *) data; |
2777 |
+ struct vmw_fence_obj *fence = NULL; |
2778 |
+ struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
2779 |
++ struct ttm_object_file *tfile = vmw_fp->tfile; |
2780 |
+ struct drm_vmw_fence_rep __user *user_fence_rep = |
2781 |
+ (struct drm_vmw_fence_rep __user *)(unsigned long) |
2782 |
+ arg->fence_rep; |
2783 |
+@@ -1037,24 +1065,18 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, |
2784 |
+ */ |
2785 |
+ if (arg->handle) { |
2786 |
+ struct ttm_base_object *base = |
2787 |
+- ttm_base_object_lookup_for_ref(dev_priv->tdev, |
2788 |
+- arg->handle); |
2789 |
+- |
2790 |
+- if (unlikely(base == NULL)) { |
2791 |
+- DRM_ERROR("Fence event invalid fence object handle " |
2792 |
+- "0x%08lx.\n", |
2793 |
+- (unsigned long)arg->handle); |
2794 |
+- return -EINVAL; |
2795 |
+- } |
2796 |
++ vmw_fence_obj_lookup(tfile, arg->handle); |
2797 |
++ |
2798 |
++ if (IS_ERR(base)) |
2799 |
++ return PTR_ERR(base); |
2800 |
++ |
2801 |
+ fence = &(container_of(base, struct vmw_user_fence, |
2802 |
+ base)->fence); |
2803 |
+ (void) vmw_fence_obj_reference(fence); |
2804 |
+ |
2805 |
+ if (user_fence_rep != NULL) { |
2806 |
+- bool existed; |
2807 |
+- |
2808 |
+ ret = ttm_ref_object_add(vmw_fp->tfile, base, |
2809 |
+- TTM_REF_USAGE, &existed); |
2810 |
++ TTM_REF_USAGE, NULL, false); |
2811 |
+ if (unlikely(ret != 0)) { |
2812 |
+ DRM_ERROR("Failed to reference a fence " |
2813 |
+ "object.\n"); |
2814 |
+@@ -1097,8 +1119,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, |
2815 |
+ return 0; |
2816 |
+ out_no_create: |
2817 |
+ if (user_fence_rep != NULL) |
2818 |
+- ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, |
2819 |
+- handle, TTM_REF_USAGE); |
2820 |
++ ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); |
2821 |
+ out_no_ref_obj: |
2822 |
+ vmw_fence_obj_unreference(&fence); |
2823 |
+ return ret; |
2824 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |
2825 |
+index b8c6a03c8c54..5ec24fd801cd 100644 |
2826 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |
2827 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |
2828 |
+@@ -114,8 +114,6 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, |
2829 |
+ param->value = dev_priv->has_dx; |
2830 |
+ break; |
2831 |
+ default: |
2832 |
+- DRM_ERROR("Illegal vmwgfx get param request: %d\n", |
2833 |
+- param->param); |
2834 |
+ return -EINVAL; |
2835 |
+ } |
2836 |
+ |
2837 |
+@@ -186,7 +184,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, |
2838 |
+ bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); |
2839 |
+ struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
2840 |
+ |
2841 |
+- if (unlikely(arg->pad64 != 0)) { |
2842 |
++ if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) { |
2843 |
+ DRM_ERROR("Illegal GET_3D_CAP argument.\n"); |
2844 |
+ return -EINVAL; |
2845 |
+ } |
2846 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |
2847 |
+index 52ca1c9d070e..bc354f7cf5d6 100644 |
2848 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |
2849 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |
2850 |
+@@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo, |
2851 |
+ return ret; |
2852 |
+ |
2853 |
+ ret = ttm_ref_object_add(tfile, &user_bo->prime.base, |
2854 |
+- TTM_REF_SYNCCPU_WRITE, &existed); |
2855 |
++ TTM_REF_SYNCCPU_WRITE, &existed, false); |
2856 |
+ if (ret != 0 || existed) |
2857 |
+ ttm_bo_synccpu_write_release(&user_bo->dma.base); |
2858 |
+ |
2859 |
+@@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile, |
2860 |
+ |
2861 |
+ *handle = user_bo->prime.base.hash.key; |
2862 |
+ return ttm_ref_object_add(tfile, &user_bo->prime.base, |
2863 |
+- TTM_REF_USAGE, NULL); |
2864 |
++ TTM_REF_USAGE, NULL, false); |
2865 |
+ } |
2866 |
+ |
2867 |
+ /* |
2868 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |
2869 |
+index b445ce9b9757..05fa092c942b 100644 |
2870 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |
2871 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |
2872 |
+@@ -713,11 +713,14 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, |
2873 |
+ 128; |
2874 |
+ |
2875 |
+ num_sizes = 0; |
2876 |
+- for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) |
2877 |
++ for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { |
2878 |
++ if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS) |
2879 |
++ return -EINVAL; |
2880 |
+ num_sizes += req->mip_levels[i]; |
2881 |
++ } |
2882 |
+ |
2883 |
+- if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * |
2884 |
+- DRM_VMW_MAX_MIP_LEVELS) |
2885 |
++ if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS || |
2886 |
++ num_sizes == 0) |
2887 |
+ return -EINVAL; |
2888 |
+ |
2889 |
+ size = vmw_user_surface_size + 128 + |
2890 |
+@@ -891,17 +894,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, |
2891 |
+ uint32_t handle; |
2892 |
+ struct ttm_base_object *base; |
2893 |
+ int ret; |
2894 |
++ bool require_exist = false; |
2895 |
+ |
2896 |
+ if (handle_type == DRM_VMW_HANDLE_PRIME) { |
2897 |
+ ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle); |
2898 |
+ if (unlikely(ret != 0)) |
2899 |
+ return ret; |
2900 |
+ } else { |
2901 |
+- if (unlikely(drm_is_render_client(file_priv))) { |
2902 |
+- DRM_ERROR("Render client refused legacy " |
2903 |
+- "surface reference.\n"); |
2904 |
+- return -EACCES; |
2905 |
+- } |
2906 |
++ if (unlikely(drm_is_render_client(file_priv))) |
2907 |
++ require_exist = true; |
2908 |
++ |
2909 |
+ if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) { |
2910 |
+ DRM_ERROR("Locked master refused legacy " |
2911 |
+ "surface reference.\n"); |
2912 |
+@@ -929,17 +931,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, |
2913 |
+ |
2914 |
+ /* |
2915 |
+ * Make sure the surface creator has the same |
2916 |
+- * authenticating master. |
2917 |
++ * authenticating master, or is already registered with us. |
2918 |
+ */ |
2919 |
+ if (drm_is_primary_client(file_priv) && |
2920 |
+- user_srf->master != file_priv->master) { |
2921 |
+- DRM_ERROR("Trying to reference surface outside of" |
2922 |
+- " master domain.\n"); |
2923 |
+- ret = -EACCES; |
2924 |
+- goto out_bad_resource; |
2925 |
+- } |
2926 |
++ user_srf->master != file_priv->master) |
2927 |
++ require_exist = true; |
2928 |
+ |
2929 |
+- ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL); |
2930 |
++ ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, |
2931 |
++ require_exist); |
2932 |
+ if (unlikely(ret != 0)) { |
2933 |
+ DRM_ERROR("Could not add a reference to a surface.\n"); |
2934 |
+ goto out_bad_resource; |
2935 |
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c |
2936 |
+index 2b89c701076f..a5dd7e63ada3 100644 |
2937 |
+--- a/drivers/hid/hid-core.c |
2938 |
++++ b/drivers/hid/hid-core.c |
2939 |
+@@ -728,7 +728,6 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type) |
2940 |
+ hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 || |
2941 |
+ hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP || |
2942 |
+ hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP || |
2943 |
+- hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 || |
2944 |
+ hid->product == USB_DEVICE_ID_MS_POWER_COVER) && |
2945 |
+ hid->group == HID_GROUP_MULTITOUCH) |
2946 |
+ hid->group = HID_GROUP_GENERIC; |
2947 |
+@@ -1984,7 +1983,6 @@ static const struct hid_device_id hid_have_special_driver[] = { |
2948 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, |
2949 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, |
2950 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP) }, |
2951 |
+- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, |
2952 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_7K) }, |
2953 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_600) }, |
2954 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3KV1) }, |
2955 |
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h |
2956 |
+index 9845189fae92..da9307701abe 100644 |
2957 |
+--- a/drivers/hid/hid-ids.h |
2958 |
++++ b/drivers/hid/hid-ids.h |
2959 |
+@@ -318,8 +318,11 @@ |
2960 |
+ #define USB_VENDOR_ID_DMI 0x0c0b |
2961 |
+ #define USB_DEVICE_ID_DMI_ENC 0x5fab |
2962 |
+ |
2963 |
+-#define USB_VENDOR_ID_DRAGONRISE 0x0079 |
2964 |
+-#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 |
2965 |
++#define USB_VENDOR_ID_DRAGONRISE 0x0079 |
2966 |
++#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 |
2967 |
++#define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801 |
2968 |
++#define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 |
2969 |
++#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843 |
2970 |
+ |
2971 |
+ #define USB_VENDOR_ID_DWAV 0x0eef |
2972 |
+ #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
2973 |
+@@ -365,6 +368,9 @@ |
2974 |
+ #define USB_VENDOR_ID_FLATFROG 0x25b5 |
2975 |
+ #define USB_DEVICE_ID_MULTITOUCH_3200 0x0002 |
2976 |
+ |
2977 |
++#define USB_VENDOR_ID_FUTABA 0x0547 |
2978 |
++#define USB_DEVICE_ID_LED_DISPLAY 0x7000 |
2979 |
++ |
2980 |
+ #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
2981 |
+ #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
2982 |
+ |
2983 |
+@@ -722,7 +728,6 @@ |
2984 |
+ #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 0x07e2 |
2985 |
+ #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd |
2986 |
+ #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP 0x07e9 |
2987 |
+-#define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de |
2988 |
+ #define USB_DEVICE_ID_MS_POWER_COVER 0x07da |
2989 |
+ |
2990 |
+ #define USB_VENDOR_ID_MOJO 0x8282 |
2991 |
+@@ -1037,6 +1042,10 @@ |
2992 |
+ #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 |
2993 |
+ #define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502 |
2994 |
+ |
2995 |
++#define USB_VENDOR_ID_WEIDA 0x2575 |
2996 |
++#define USB_DEVICE_ID_WEIDA_8752 0xC300 |
2997 |
++#define USB_DEVICE_ID_WEIDA_8755 0xC301 |
2998 |
++ |
2999 |
+ #define USB_VENDOR_ID_WISEGROUP 0x0925 |
3000 |
+ #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 |
3001 |
+ #define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888 |
3002 |
+diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c |
3003 |
+index c6cd392e9f99..ba02667beb80 100644 |
3004 |
+--- a/drivers/hid/hid-microsoft.c |
3005 |
++++ b/drivers/hid/hid-microsoft.c |
3006 |
+@@ -282,8 +282,6 @@ static const struct hid_device_id ms_devices[] = { |
3007 |
+ .driver_data = MS_HIDINPUT }, |
3008 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP), |
3009 |
+ .driver_data = MS_HIDINPUT }, |
3010 |
+- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3), |
3011 |
+- .driver_data = MS_HIDINPUT }, |
3012 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), |
3013 |
+ .driver_data = MS_HIDINPUT }, |
3014 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD), |
3015 |
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c |
3016 |
+index fb6f1f447279..89e9032ab1e7 100644 |
3017 |
+--- a/drivers/hid/hid-multitouch.c |
3018 |
++++ b/drivers/hid/hid-multitouch.c |
3019 |
+@@ -108,6 +108,7 @@ struct mt_device { |
3020 |
+ int cc_value_index; /* contact count value index in the field */ |
3021 |
+ unsigned last_slot_field; /* the last field of a slot */ |
3022 |
+ unsigned mt_report_id; /* the report ID of the multitouch device */ |
3023 |
++ unsigned long initial_quirks; /* initial quirks state */ |
3024 |
+ __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ |
3025 |
+ __s16 inputmode_index; /* InputMode HID feature index in the report */ |
3026 |
+ __s16 maxcontact_report_id; /* Maximum Contact Number HID feature, |
3027 |
+@@ -318,13 +319,10 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) |
3028 |
+ u8 *buf; |
3029 |
+ |
3030 |
+ /* |
3031 |
+- * Only fetch the feature report if initial reports are not already |
3032 |
+- * been retrieved. Currently this is only done for Windows 8 touch |
3033 |
+- * devices. |
3034 |
++ * Do not fetch the feature report if the device has been explicitly |
3035 |
++ * marked as non-capable. |
3036 |
+ */ |
3037 |
+- if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)) |
3038 |
+- return; |
3039 |
+- if (td->mtclass.name != MT_CLS_WIN_8) |
3040 |
++ if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS) |
3041 |
+ return; |
3042 |
+ |
3043 |
+ buf = hid_alloc_report_buf(report, GFP_KERNEL); |
3044 |
+@@ -842,7 +840,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
3045 |
+ if (!td->mtclass.export_all_inputs && |
3046 |
+ field->application != HID_DG_TOUCHSCREEN && |
3047 |
+ field->application != HID_DG_PEN && |
3048 |
+- field->application != HID_DG_TOUCHPAD) |
3049 |
++ field->application != HID_DG_TOUCHPAD && |
3050 |
++ field->application != HID_GD_KEYBOARD && |
3051 |
++ field->application != HID_CP_CONSUMER_CONTROL) |
3052 |
+ return -1; |
3053 |
+ |
3054 |
+ /* |
3055 |
+@@ -1083,36 +1083,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
3056 |
+ } |
3057 |
+ } |
3058 |
+ |
3059 |
+- /* This allows the driver to correctly support devices |
3060 |
+- * that emit events over several HID messages. |
3061 |
+- */ |
3062 |
+- hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
3063 |
+- |
3064 |
+- /* |
3065 |
+- * This allows the driver to handle different input sensors |
3066 |
+- * that emits events through different reports on the same HID |
3067 |
+- * device. |
3068 |
+- */ |
3069 |
+- hdev->quirks |= HID_QUIRK_MULTI_INPUT; |
3070 |
+- hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; |
3071 |
+- |
3072 |
+- /* |
3073 |
+- * Handle special quirks for Windows 8 certified devices. |
3074 |
+- */ |
3075 |
+- if (id->group == HID_GROUP_MULTITOUCH_WIN_8) |
3076 |
+- /* |
3077 |
+- * Some multitouch screens do not like to be polled for input |
3078 |
+- * reports. Fortunately, the Win8 spec says that all touches |
3079 |
+- * should be sent during each report, making the initialization |
3080 |
+- * of input reports unnecessary. |
3081 |
+- * |
3082 |
+- * In addition some touchpads do not behave well if we read |
3083 |
+- * all feature reports from them. Instead we prevent |
3084 |
+- * initial report fetching and then selectively fetch each |
3085 |
+- * report we are interested in. |
3086 |
+- */ |
3087 |
+- hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; |
3088 |
+- |
3089 |
+ td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); |
3090 |
+ if (!td) { |
3091 |
+ dev_err(&hdev->dev, "cannot allocate multitouch data\n"); |
3092 |
+@@ -1136,6 +1106,39 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
3093 |
+ if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) |
3094 |
+ td->serial_maybe = true; |
3095 |
+ |
3096 |
++ /* |
3097 |
++ * Store the initial quirk state |
3098 |
++ */ |
3099 |
++ td->initial_quirks = hdev->quirks; |
3100 |
++ |
3101 |
++ /* This allows the driver to correctly support devices |
3102 |
++ * that emit events over several HID messages. |
3103 |
++ */ |
3104 |
++ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
3105 |
++ |
3106 |
++ /* |
3107 |
++ * This allows the driver to handle different input sensors |
3108 |
++ * that emits events through different reports on the same HID |
3109 |
++ * device. |
3110 |
++ */ |
3111 |
++ hdev->quirks |= HID_QUIRK_MULTI_INPUT; |
3112 |
++ hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; |
3113 |
++ |
3114 |
++ /* |
3115 |
++ * Some multitouch screens do not like to be polled for input |
3116 |
++ * reports. Fortunately, the Win8 spec says that all touches |
3117 |
++ * should be sent during each report, making the initialization |
3118 |
++ * of input reports unnecessary. For Win7 devices, well, let's hope |
3119 |
++ * they will still be happy (this is only be a problem if a touch |
3120 |
++ * was already there while probing the device). |
3121 |
++ * |
3122 |
++ * In addition some touchpads do not behave well if we read |
3123 |
++ * all feature reports from them. Instead we prevent |
3124 |
++ * initial report fetching and then selectively fetch each |
3125 |
++ * report we are interested in. |
3126 |
++ */ |
3127 |
++ hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; |
3128 |
++ |
3129 |
+ ret = hid_parse(hdev); |
3130 |
+ if (ret != 0) |
3131 |
+ return ret; |
3132 |
+@@ -1204,8 +1207,11 @@ static int mt_resume(struct hid_device *hdev) |
3133 |
+ |
3134 |
+ static void mt_remove(struct hid_device *hdev) |
3135 |
+ { |
3136 |
++ struct mt_device *td = hid_get_drvdata(hdev); |
3137 |
++ |
3138 |
+ sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); |
3139 |
+ hid_hw_stop(hdev); |
3140 |
++ hdev->quirks = td->initial_quirks; |
3141 |
+ } |
3142 |
+ |
3143 |
+ /* |
3144 |
+diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c |
3145 |
+index 8f6c35370f66..4ef73374a8f9 100644 |
3146 |
+--- a/drivers/hid/hid-sensor-hub.c |
3147 |
++++ b/drivers/hid/hid-sensor-hub.c |
3148 |
+@@ -796,6 +796,12 @@ static const struct hid_device_id sensor_hub_devices[] = { |
3149 |
+ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, |
3150 |
+ USB_DEVICE_ID_MS_TYPE_COVER_2), |
3151 |
+ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
3152 |
++ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT, |
3153 |
++ 0x07bd), /* Microsoft Surface 3 */ |
3154 |
++ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
3155 |
++ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROCHIP, |
3156 |
++ 0x0f01), /* MM7150 */ |
3157 |
++ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
3158 |
+ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, |
3159 |
+ USB_DEVICE_ID_STM_HID_SENSOR), |
3160 |
+ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
3161 |
+diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c |
3162 |
+index b3ec4f2de875..b1bce804fe97 100644 |
3163 |
+--- a/drivers/hid/i2c-hid/i2c-hid.c |
3164 |
++++ b/drivers/hid/i2c-hid/i2c-hid.c |
3165 |
+@@ -41,6 +41,11 @@ |
3166 |
+ |
3167 |
+ #include <linux/i2c/i2c-hid.h> |
3168 |
+ |
3169 |
++#include "../hid-ids.h" |
3170 |
++ |
3171 |
++/* quirks to control the device */ |
3172 |
++#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) |
3173 |
++ |
3174 |
+ /* flags */ |
3175 |
+ #define I2C_HID_STARTED 0 |
3176 |
+ #define I2C_HID_RESET_PENDING 1 |
3177 |
+@@ -143,6 +148,7 @@ struct i2c_hid { |
3178 |
+ char *argsbuf; /* Command arguments buffer */ |
3179 |
+ |
3180 |
+ unsigned long flags; /* device flags */ |
3181 |
++ unsigned long quirks; /* Various quirks */ |
3182 |
+ |
3183 |
+ wait_queue_head_t wait; /* For waiting the interrupt */ |
3184 |
+ struct gpio_desc *desc; |
3185 |
+@@ -154,6 +160,39 @@ struct i2c_hid { |
3186 |
+ struct mutex reset_lock; |
3187 |
+ }; |
3188 |
+ |
3189 |
++static const struct i2c_hid_quirks { |
3190 |
++ __u16 idVendor; |
3191 |
++ __u16 idProduct; |
3192 |
++ __u32 quirks; |
3193 |
++} i2c_hid_quirks[] = { |
3194 |
++ { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8752, |
3195 |
++ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, |
3196 |
++ { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8755, |
3197 |
++ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, |
3198 |
++ { 0, 0 } |
3199 |
++}; |
3200 |
++ |
3201 |
++/* |
3202 |
++ * i2c_hid_lookup_quirk: return any quirks associated with a I2C HID device |
3203 |
++ * @idVendor: the 16-bit vendor ID |
3204 |
++ * @idProduct: the 16-bit product ID |
3205 |
++ * |
3206 |
++ * Returns: a u32 quirks value. |
3207 |
++ */ |
3208 |
++static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct) |
3209 |
++{ |
3210 |
++ u32 quirks = 0; |
3211 |
++ int n; |
3212 |
++ |
3213 |
++ for (n = 0; i2c_hid_quirks[n].idVendor; n++) |
3214 |
++ if (i2c_hid_quirks[n].idVendor == idVendor && |
3215 |
++ (i2c_hid_quirks[n].idProduct == (__u16)HID_ANY_ID || |
3216 |
++ i2c_hid_quirks[n].idProduct == idProduct)) |
3217 |
++ quirks = i2c_hid_quirks[n].quirks; |
3218 |
++ |
3219 |
++ return quirks; |
3220 |
++} |
3221 |
++ |
3222 |
+ static int __i2c_hid_command(struct i2c_client *client, |
3223 |
+ const struct i2c_hid_cmd *command, u8 reportID, |
3224 |
+ u8 reportType, u8 *args, int args_len, |
3225 |
+@@ -346,11 +385,27 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) |
3226 |
+ |
3227 |
+ i2c_hid_dbg(ihid, "%s\n", __func__); |
3228 |
+ |
3229 |
++ /* |
3230 |
++ * Some devices require to send a command to wakeup before power on. |
3231 |
++ * The call will get a return value (EREMOTEIO) but device will be |
3232 |
++ * triggered and activated. After that, it goes like a normal device. |
3233 |
++ */ |
3234 |
++ if (power_state == I2C_HID_PWR_ON && |
3235 |
++ ihid->quirks & I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV) { |
3236 |
++ ret = i2c_hid_command(client, &hid_set_power_cmd, NULL, 0); |
3237 |
++ |
3238 |
++ /* Device was already activated */ |
3239 |
++ if (!ret) |
3240 |
++ goto set_pwr_exit; |
3241 |
++ } |
3242 |
++ |
3243 |
+ ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, |
3244 |
+ 0, NULL, 0, NULL, 0); |
3245 |
++ |
3246 |
+ if (ret) |
3247 |
+ dev_err(&client->dev, "failed to change power setting.\n"); |
3248 |
+ |
3249 |
++set_pwr_exit: |
3250 |
+ return ret; |
3251 |
+ } |
3252 |
+ |
3253 |
+@@ -1050,6 +1105,8 @@ static int i2c_hid_probe(struct i2c_client *client, |
3254 |
+ client->name, hid->vendor, hid->product); |
3255 |
+ strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); |
3256 |
+ |
3257 |
++ ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); |
3258 |
++ |
3259 |
+ ret = hid_add_device(hid); |
3260 |
+ if (ret) { |
3261 |
+ if (ret != -ENODEV) |
3262 |
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c |
3263 |
+index cde060fefa91..97dbb2562ace 100644 |
3264 |
+--- a/drivers/hid/usbhid/hid-quirks.c |
3265 |
++++ b/drivers/hid/usbhid/hid-quirks.c |
3266 |
+@@ -83,10 +83,14 @@ static const struct hid_blacklist { |
3267 |
+ { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, |
3268 |
+ { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
3269 |
+ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, |
3270 |
++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, |
3271 |
++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT }, |
3272 |
++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT }, |
3273 |
+ { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, |
3274 |
+ { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
3275 |
+ { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, |
3276 |
+ { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
3277 |
++ { USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS }, |
3278 |
+ { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, |
3279 |
+ { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, |
3280 |
+ { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, |
3281 |
+@@ -103,7 +107,6 @@ static const struct hid_blacklist { |
3282 |
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2, HID_QUIRK_NO_INIT_REPORTS }, |
3283 |
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP, HID_QUIRK_NO_INIT_REPORTS }, |
3284 |
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_4_JP, HID_QUIRK_NO_INIT_REPORTS }, |
3285 |
+- { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, |
3286 |
+ { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS }, |
3287 |
+ { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
3288 |
+ { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, |
3289 |
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c |
3290 |
+index 623be90704ab..0e07a769df7c 100644 |
3291 |
+--- a/drivers/hid/wacom_wac.c |
3292 |
++++ b/drivers/hid/wacom_wac.c |
3293 |
+@@ -2896,6 +2896,9 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, |
3294 |
+ { |
3295 |
+ struct wacom_features *features = &wacom_wac->features; |
3296 |
+ |
3297 |
++ if ((features->type == HID_GENERIC) && features->numbered_buttons > 0) |
3298 |
++ features->device_type |= WACOM_DEVICETYPE_PAD; |
3299 |
++ |
3300 |
+ if (!(features->device_type & WACOM_DEVICETYPE_PAD)) |
3301 |
+ return -ENODEV; |
3302 |
+ |
3303 |
+diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c |
3304 |
+index 4466a2f969d7..5ded9b22b015 100644 |
3305 |
+--- a/drivers/idle/intel_idle.c |
3306 |
++++ b/drivers/idle/intel_idle.c |
3307 |
+@@ -724,6 +724,50 @@ static struct cpuidle_state atom_cstates[] = { |
3308 |
+ { |
3309 |
+ .enter = NULL } |
3310 |
+ }; |
3311 |
++static struct cpuidle_state tangier_cstates[] = { |
3312 |
++ { |
3313 |
++ .name = "C1-TNG", |
3314 |
++ .desc = "MWAIT 0x00", |
3315 |
++ .flags = MWAIT2flg(0x00), |
3316 |
++ .exit_latency = 1, |
3317 |
++ .target_residency = 4, |
3318 |
++ .enter = &intel_idle, |
3319 |
++ .enter_freeze = intel_idle_freeze, }, |
3320 |
++ { |
3321 |
++ .name = "C4-TNG", |
3322 |
++ .desc = "MWAIT 0x30", |
3323 |
++ .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, |
3324 |
++ .exit_latency = 100, |
3325 |
++ .target_residency = 400, |
3326 |
++ .enter = &intel_idle, |
3327 |
++ .enter_freeze = intel_idle_freeze, }, |
3328 |
++ { |
3329 |
++ .name = "C6-TNG", |
3330 |
++ .desc = "MWAIT 0x52", |
3331 |
++ .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, |
3332 |
++ .exit_latency = 140, |
3333 |
++ .target_residency = 560, |
3334 |
++ .enter = &intel_idle, |
3335 |
++ .enter_freeze = intel_idle_freeze, }, |
3336 |
++ { |
3337 |
++ .name = "C7-TNG", |
3338 |
++ .desc = "MWAIT 0x60", |
3339 |
++ .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, |
3340 |
++ .exit_latency = 1200, |
3341 |
++ .target_residency = 4000, |
3342 |
++ .enter = &intel_idle, |
3343 |
++ .enter_freeze = intel_idle_freeze, }, |
3344 |
++ { |
3345 |
++ .name = "C9-TNG", |
3346 |
++ .desc = "MWAIT 0x64", |
3347 |
++ .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, |
3348 |
++ .exit_latency = 10000, |
3349 |
++ .target_residency = 20000, |
3350 |
++ .enter = &intel_idle, |
3351 |
++ .enter_freeze = intel_idle_freeze, }, |
3352 |
++ { |
3353 |
++ .enter = NULL } |
3354 |
++}; |
3355 |
+ static struct cpuidle_state avn_cstates[] = { |
3356 |
+ { |
3357 |
+ .name = "C1-AVN", |
3358 |
+@@ -978,6 +1022,10 @@ static const struct idle_cpu idle_cpu_atom = { |
3359 |
+ .state_table = atom_cstates, |
3360 |
+ }; |
3361 |
+ |
3362 |
++static const struct idle_cpu idle_cpu_tangier = { |
3363 |
++ .state_table = tangier_cstates, |
3364 |
++}; |
3365 |
++ |
3366 |
+ static const struct idle_cpu idle_cpu_lincroft = { |
3367 |
+ .state_table = atom_cstates, |
3368 |
+ .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, |
3369 |
+@@ -1066,6 +1114,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { |
3370 |
+ ICPU(INTEL_FAM6_SANDYBRIDGE_X, idle_cpu_snb), |
3371 |
+ ICPU(INTEL_FAM6_ATOM_CEDARVIEW, idle_cpu_atom), |
3372 |
+ ICPU(INTEL_FAM6_ATOM_SILVERMONT1, idle_cpu_byt), |
3373 |
++ ICPU(INTEL_FAM6_ATOM_MERRIFIELD, idle_cpu_tangier), |
3374 |
+ ICPU(INTEL_FAM6_ATOM_AIRMONT, idle_cpu_cht), |
3375 |
+ ICPU(INTEL_FAM6_IVYBRIDGE, idle_cpu_ivb), |
3376 |
+ ICPU(INTEL_FAM6_IVYBRIDGE_X, idle_cpu_ivt), |
3377 |
+diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c |
3378 |
+index f7fcfa886f72..821919dd245b 100644 |
3379 |
+--- a/drivers/iio/gyro/bmg160_core.c |
3380 |
++++ b/drivers/iio/gyro/bmg160_core.c |
3381 |
+@@ -27,6 +27,7 @@ |
3382 |
+ #include <linux/iio/trigger_consumer.h> |
3383 |
+ #include <linux/iio/triggered_buffer.h> |
3384 |
+ #include <linux/regmap.h> |
3385 |
++#include <linux/delay.h> |
3386 |
+ #include "bmg160.h" |
3387 |
+ |
3388 |
+ #define BMG160_IRQ_NAME "bmg160_event" |
3389 |
+@@ -52,6 +53,9 @@ |
3390 |
+ #define BMG160_DEF_BW 100 |
3391 |
+ #define BMG160_REG_PMU_BW_RES BIT(7) |
3392 |
+ |
3393 |
++#define BMG160_GYRO_REG_RESET 0x14 |
3394 |
++#define BMG160_GYRO_RESET_VAL 0xb6 |
3395 |
++ |
3396 |
+ #define BMG160_REG_INT_MAP_0 0x17 |
3397 |
+ #define BMG160_INT_MAP_0_BIT_ANY BIT(1) |
3398 |
+ |
3399 |
+@@ -236,6 +240,14 @@ static int bmg160_chip_init(struct bmg160_data *data) |
3400 |
+ int ret; |
3401 |
+ unsigned int val; |
3402 |
+ |
3403 |
++ /* |
3404 |
++ * Reset chip to get it in a known good state. A delay of 30ms after |
3405 |
++ * reset is required according to the datasheet. |
3406 |
++ */ |
3407 |
++ regmap_write(data->regmap, BMG160_GYRO_REG_RESET, |
3408 |
++ BMG160_GYRO_RESET_VAL); |
3409 |
++ usleep_range(30000, 30700); |
3410 |
++ |
3411 |
+ ret = regmap_read(data->regmap, BMG160_REG_CHIP_ID, &val); |
3412 |
+ if (ret < 0) { |
3413 |
+ dev_err(dev, "Error reading reg_chip_id\n"); |
3414 |
+diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c |
3415 |
+index 29093657f2ef..9b8079ca0fb4 100644 |
3416 |
+--- a/drivers/input/keyboard/gpio_keys.c |
3417 |
++++ b/drivers/input/keyboard/gpio_keys.c |
3418 |
+@@ -26,6 +26,7 @@ |
3419 |
+ #include <linux/gpio_keys.h> |
3420 |
+ #include <linux/workqueue.h> |
3421 |
+ #include <linux/gpio.h> |
3422 |
++#include <linux/gpio/consumer.h> |
3423 |
+ #include <linux/of.h> |
3424 |
+ #include <linux/of_platform.h> |
3425 |
+ #include <linux/of_gpio.h> |
3426 |
+@@ -35,6 +36,7 @@ |
3427 |
+ struct gpio_button_data { |
3428 |
+ const struct gpio_keys_button *button; |
3429 |
+ struct input_dev *input; |
3430 |
++ struct gpio_desc *gpiod; |
3431 |
+ |
3432 |
+ struct timer_list release_timer; |
3433 |
+ unsigned int release_delay; /* in msecs, for IRQ-only buttons */ |
3434 |
+@@ -140,7 +142,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) |
3435 |
+ */ |
3436 |
+ disable_irq(bdata->irq); |
3437 |
+ |
3438 |
+- if (gpio_is_valid(bdata->button->gpio)) |
3439 |
++ if (bdata->gpiod) |
3440 |
+ cancel_delayed_work_sync(&bdata->work); |
3441 |
+ else |
3442 |
+ del_timer_sync(&bdata->release_timer); |
3443 |
+@@ -358,19 +360,20 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) |
3444 |
+ const struct gpio_keys_button *button = bdata->button; |
3445 |
+ struct input_dev *input = bdata->input; |
3446 |
+ unsigned int type = button->type ?: EV_KEY; |
3447 |
+- int state = gpio_get_value_cansleep(button->gpio); |
3448 |
++ int state; |
3449 |
+ |
3450 |
++ state = gpiod_get_value_cansleep(bdata->gpiod); |
3451 |
+ if (state < 0) { |
3452 |
+- dev_err(input->dev.parent, "failed to get gpio state\n"); |
3453 |
++ dev_err(input->dev.parent, |
3454 |
++ "failed to get gpio state: %d\n", state); |
3455 |
+ return; |
3456 |
+ } |
3457 |
+ |
3458 |
+- state = (state ? 1 : 0) ^ button->active_low; |
3459 |
+ if (type == EV_ABS) { |
3460 |
+ if (state) |
3461 |
+ input_event(input, type, button->code, button->value); |
3462 |
+ } else { |
3463 |
+- input_event(input, type, button->code, !!state); |
3464 |
++ input_event(input, type, button->code, state); |
3465 |
+ } |
3466 |
+ input_sync(input); |
3467 |
+ } |
3468 |
+@@ -456,7 +459,7 @@ static void gpio_keys_quiesce_key(void *data) |
3469 |
+ { |
3470 |
+ struct gpio_button_data *bdata = data; |
3471 |
+ |
3472 |
+- if (gpio_is_valid(bdata->button->gpio)) |
3473 |
++ if (bdata->gpiod) |
3474 |
+ cancel_delayed_work_sync(&bdata->work); |
3475 |
+ else |
3476 |
+ del_timer_sync(&bdata->release_timer); |
3477 |
+@@ -478,18 +481,30 @@ static int gpio_keys_setup_key(struct platform_device *pdev, |
3478 |
+ bdata->button = button; |
3479 |
+ spin_lock_init(&bdata->lock); |
3480 |
+ |
3481 |
++ /* |
3482 |
++ * Legacy GPIO number, so request the GPIO here and |
3483 |
++ * convert it to descriptor. |
3484 |
++ */ |
3485 |
+ if (gpio_is_valid(button->gpio)) { |
3486 |
++ unsigned flags = GPIOF_IN; |
3487 |
++ |
3488 |
++ if (button->active_low) |
3489 |
++ flags |= GPIOF_ACTIVE_LOW; |
3490 |
+ |
3491 |
+- error = devm_gpio_request_one(&pdev->dev, button->gpio, |
3492 |
+- GPIOF_IN, desc); |
3493 |
++ error = devm_gpio_request_one(&pdev->dev, button->gpio, flags, |
3494 |
++ desc); |
3495 |
+ if (error < 0) { |
3496 |
+ dev_err(dev, "Failed to request GPIO %d, error %d\n", |
3497 |
+ button->gpio, error); |
3498 |
+ return error; |
3499 |
+ } |
3500 |
+ |
3501 |
++ bdata->gpiod = gpio_to_desc(button->gpio); |
3502 |
++ if (!bdata->gpiod) |
3503 |
++ return -EINVAL; |
3504 |
++ |
3505 |
+ if (button->debounce_interval) { |
3506 |
+- error = gpio_set_debounce(button->gpio, |
3507 |
++ error = gpiod_set_debounce(bdata->gpiod, |
3508 |
+ button->debounce_interval * 1000); |
3509 |
+ /* use timer if gpiolib doesn't provide debounce */ |
3510 |
+ if (error < 0) |
3511 |
+@@ -500,7 +515,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, |
3512 |
+ if (button->irq) { |
3513 |
+ bdata->irq = button->irq; |
3514 |
+ } else { |
3515 |
+- irq = gpio_to_irq(button->gpio); |
3516 |
++ irq = gpiod_to_irq(bdata->gpiod); |
3517 |
+ if (irq < 0) { |
3518 |
+ error = irq; |
3519 |
+ dev_err(dev, |
3520 |
+@@ -575,7 +590,7 @@ static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata) |
3521 |
+ |
3522 |
+ for (i = 0; i < ddata->pdata->nbuttons; i++) { |
3523 |
+ struct gpio_button_data *bdata = &ddata->data[i]; |
3524 |
+- if (gpio_is_valid(bdata->button->gpio)) |
3525 |
++ if (bdata->gpiod) |
3526 |
+ gpio_keys_gpio_report_event(bdata); |
3527 |
+ } |
3528 |
+ input_sync(input); |
3529 |
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c |
3530 |
+index 15daa36fcea6..ee75e3510be6 100644 |
3531 |
+--- a/drivers/md/dm-raid.c |
3532 |
++++ b/drivers/md/dm-raid.c |
3533 |
+@@ -3589,7 +3589,7 @@ static int raid_preresume(struct dm_target *ti) |
3534 |
+ return r; |
3535 |
+ |
3536 |
+ /* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) */ |
3537 |
+- if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && |
3538 |
++ if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap && |
3539 |
+ mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)) { |
3540 |
+ r = bitmap_resize(mddev->bitmap, mddev->dev_sectors, |
3541 |
+ to_bytes(rs->requested_bitmap_chunk_sectors), 0); |
3542 |
+diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c |
3543 |
+index 0f0eb8a3d922..78f36012eaca 100644 |
3544 |
+--- a/drivers/md/dm-verity-fec.c |
3545 |
++++ b/drivers/md/dm-verity-fec.c |
3546 |
+@@ -146,8 +146,6 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, |
3547 |
+ block = fec_buffer_rs_block(v, fio, n, i); |
3548 |
+ res = fec_decode_rs8(v, fio, block, &par[offset], neras); |
3549 |
+ if (res < 0) { |
3550 |
+- dm_bufio_release(buf); |
3551 |
+- |
3552 |
+ r = res; |
3553 |
+ goto error; |
3554 |
+ } |
3555 |
+@@ -172,6 +170,8 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio, |
3556 |
+ done: |
3557 |
+ r = corrected; |
3558 |
+ error: |
3559 |
++ dm_bufio_release(buf); |
3560 |
++ |
3561 |
+ if (r < 0 && neras) |
3562 |
+ DMERR_LIMIT("%s: FEC %llu: failed to correct: %d", |
3563 |
+ v->data_dev->name, (unsigned long long)rsb, r); |
3564 |
+@@ -269,7 +269,7 @@ static int fec_read_bufs(struct dm_verity *v, struct dm_verity_io *io, |
3565 |
+ &is_zero) == 0) { |
3566 |
+ /* skip known zero blocks entirely */ |
3567 |
+ if (is_zero) |
3568 |
+- continue; |
3569 |
++ goto done; |
3570 |
+ |
3571 |
+ /* |
3572 |
+ * skip if we have already found the theoretical |
3573 |
+@@ -439,6 +439,13 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, |
3574 |
+ if (!verity_fec_is_enabled(v)) |
3575 |
+ return -EOPNOTSUPP; |
3576 |
+ |
3577 |
++ if (fio->level >= DM_VERITY_FEC_MAX_RECURSION) { |
3578 |
++ DMWARN_LIMIT("%s: FEC: recursion too deep", v->data_dev->name); |
3579 |
++ return -EIO; |
3580 |
++ } |
3581 |
++ |
3582 |
++ fio->level++; |
3583 |
++ |
3584 |
+ if (type == DM_VERITY_BLOCK_TYPE_METADATA) |
3585 |
+ block += v->data_blocks; |
3586 |
+ |
3587 |
+@@ -470,7 +477,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, |
3588 |
+ if (r < 0) { |
3589 |
+ r = fec_decode_rsb(v, io, fio, rsb, offset, true); |
3590 |
+ if (r < 0) |
3591 |
+- return r; |
3592 |
++ goto done; |
3593 |
+ } |
3594 |
+ |
3595 |
+ if (dest) |
3596 |
+@@ -480,6 +487,8 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, |
3597 |
+ r = verity_for_bv_block(v, io, iter, fec_bv_copy); |
3598 |
+ } |
3599 |
+ |
3600 |
++done: |
3601 |
++ fio->level--; |
3602 |
+ return r; |
3603 |
+ } |
3604 |
+ |
3605 |
+@@ -520,6 +529,7 @@ void verity_fec_init_io(struct dm_verity_io *io) |
3606 |
+ memset(fio->bufs, 0, sizeof(fio->bufs)); |
3607 |
+ fio->nbufs = 0; |
3608 |
+ fio->output = NULL; |
3609 |
++ fio->level = 0; |
3610 |
+ } |
3611 |
+ |
3612 |
+ /* |
3613 |
+diff --git a/drivers/md/dm-verity-fec.h b/drivers/md/dm-verity-fec.h |
3614 |
+index 7fa0298b995e..bb31ce87a933 100644 |
3615 |
+--- a/drivers/md/dm-verity-fec.h |
3616 |
++++ b/drivers/md/dm-verity-fec.h |
3617 |
+@@ -27,6 +27,9 @@ |
3618 |
+ #define DM_VERITY_FEC_BUF_MAX \ |
3619 |
+ (1 << (PAGE_SHIFT - DM_VERITY_FEC_BUF_RS_BITS)) |
3620 |
+ |
3621 |
++/* maximum recursion level for verity_fec_decode */ |
3622 |
++#define DM_VERITY_FEC_MAX_RECURSION 4 |
3623 |
++ |
3624 |
+ #define DM_VERITY_OPT_FEC_DEV "use_fec_from_device" |
3625 |
+ #define DM_VERITY_OPT_FEC_BLOCKS "fec_blocks" |
3626 |
+ #define DM_VERITY_OPT_FEC_START "fec_start" |
3627 |
+@@ -58,6 +61,7 @@ struct dm_verity_fec_io { |
3628 |
+ unsigned nbufs; /* number of buffers allocated */ |
3629 |
+ u8 *output; /* buffer for corrected output */ |
3630 |
+ size_t output_pos; |
3631 |
++ unsigned level; /* recursion level */ |
3632 |
+ }; |
3633 |
+ |
3634 |
+ #ifdef CONFIG_DM_VERITY_FEC |
3635 |
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c |
3636 |
+index 90ed2e12d345..437e4807727d 100644 |
3637 |
+--- a/drivers/mmc/host/sdhci-msm.c |
3638 |
++++ b/drivers/mmc/host/sdhci-msm.c |
3639 |
+@@ -524,7 +524,9 @@ static const struct sdhci_ops sdhci_msm_ops = { |
3640 |
+ static const struct sdhci_pltfm_data sdhci_msm_pdata = { |
3641 |
+ .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
3642 |
+ SDHCI_QUIRK_NO_CARD_NO_RESET | |
3643 |
+- SDHCI_QUIRK_SINGLE_POWER_WRITE, |
3644 |
++ SDHCI_QUIRK_SINGLE_POWER_WRITE | |
3645 |
++ SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
3646 |
++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
3647 |
+ .ops = &sdhci_msm_ops, |
3648 |
+ }; |
3649 |
+ |
3650 |
+diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c |
3651 |
+index 1bb11e4a9fe5..3c27401cf7fe 100644 |
3652 |
+--- a/drivers/mmc/host/sdhci-of-esdhc.c |
3653 |
++++ b/drivers/mmc/host/sdhci-of-esdhc.c |
3654 |
+@@ -559,16 +559,19 @@ static const struct sdhci_ops sdhci_esdhc_le_ops = { |
3655 |
+ }; |
3656 |
+ |
3657 |
+ static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { |
3658 |
+- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION |
3659 |
+- | SDHCI_QUIRK_NO_CARD_NO_RESET |
3660 |
+- | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
3661 |
++ .quirks = ESDHC_DEFAULT_QUIRKS | |
3662 |
++#ifdef CONFIG_PPC |
3663 |
++ SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
3664 |
++#endif |
3665 |
++ SDHCI_QUIRK_NO_CARD_NO_RESET | |
3666 |
++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
3667 |
+ .ops = &sdhci_esdhc_be_ops, |
3668 |
+ }; |
3669 |
+ |
3670 |
+ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { |
3671 |
+- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION |
3672 |
+- | SDHCI_QUIRK_NO_CARD_NO_RESET |
3673 |
+- | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
3674 |
++ .quirks = ESDHC_DEFAULT_QUIRKS | |
3675 |
++ SDHCI_QUIRK_NO_CARD_NO_RESET | |
3676 |
++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
3677 |
+ .ops = &sdhci_esdhc_le_ops, |
3678 |
+ }; |
3679 |
+ |
3680 |
+@@ -623,8 +626,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) |
3681 |
+ of_device_is_compatible(np, "fsl,p5020-esdhc") || |
3682 |
+ of_device_is_compatible(np, "fsl,p4080-esdhc") || |
3683 |
+ of_device_is_compatible(np, "fsl,p1020-esdhc") || |
3684 |
+- of_device_is_compatible(np, "fsl,t1040-esdhc") || |
3685 |
+- of_device_is_compatible(np, "fsl,ls1021a-esdhc")) |
3686 |
++ of_device_is_compatible(np, "fsl,t1040-esdhc")) |
3687 |
+ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
3688 |
+ |
3689 |
+ if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) |
3690 |
+diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c |
3691 |
+index 75d07fa9d0b1..b2ca8a635b2e 100644 |
3692 |
+--- a/drivers/net/ethernet/mellanox/mlx4/main.c |
3693 |
++++ b/drivers/net/ethernet/mellanox/mlx4/main.c |
3694 |
+@@ -4020,49 +4020,51 @@ int mlx4_restart_one(struct pci_dev *pdev) |
3695 |
+ return err; |
3696 |
+ } |
3697 |
+ |
3698 |
++#define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT } |
3699 |
++#define MLX_VF(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_IS_VF } |
3700 |
++#define MLX_GN(id) { PCI_VDEVICE(MELLANOX, id), 0 } |
3701 |
++ |
3702 |
+ static const struct pci_device_id mlx4_pci_table[] = { |
3703 |
+- /* MT25408 "Hermon" SDR */ |
3704 |
+- { PCI_VDEVICE(MELLANOX, 0x6340), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3705 |
+- /* MT25408 "Hermon" DDR */ |
3706 |
+- { PCI_VDEVICE(MELLANOX, 0x634a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3707 |
+- /* MT25408 "Hermon" QDR */ |
3708 |
+- { PCI_VDEVICE(MELLANOX, 0x6354), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3709 |
+- /* MT25408 "Hermon" DDR PCIe gen2 */ |
3710 |
+- { PCI_VDEVICE(MELLANOX, 0x6732), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3711 |
+- /* MT25408 "Hermon" QDR PCIe gen2 */ |
3712 |
+- { PCI_VDEVICE(MELLANOX, 0x673c), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3713 |
+- /* MT25408 "Hermon" EN 10GigE */ |
3714 |
+- { PCI_VDEVICE(MELLANOX, 0x6368), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3715 |
+- /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ |
3716 |
+- { PCI_VDEVICE(MELLANOX, 0x6750), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3717 |
+- /* MT25458 ConnectX EN 10GBASE-T 10GigE */ |
3718 |
+- { PCI_VDEVICE(MELLANOX, 0x6372), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3719 |
+- /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ |
3720 |
+- { PCI_VDEVICE(MELLANOX, 0x675a), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3721 |
+- /* MT26468 ConnectX EN 10GigE PCIe gen2*/ |
3722 |
+- { PCI_VDEVICE(MELLANOX, 0x6764), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3723 |
+- /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ |
3724 |
+- { PCI_VDEVICE(MELLANOX, 0x6746), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3725 |
+- /* MT26478 ConnectX2 40GigE PCIe gen2 */ |
3726 |
+- { PCI_VDEVICE(MELLANOX, 0x676e), MLX4_PCI_DEV_FORCE_SENSE_PORT }, |
3727 |
+- /* MT25400 Family [ConnectX-2 Virtual Function] */ |
3728 |
+- { PCI_VDEVICE(MELLANOX, 0x1002), MLX4_PCI_DEV_IS_VF }, |
3729 |
++ /* MT25408 "Hermon" */ |
3730 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_SDR), /* SDR */ |
3731 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR), /* DDR */ |
3732 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR), /* QDR */ |
3733 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_DDR_GEN2), /* DDR Gen2 */ |
3734 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_QDR_GEN2), /* QDR Gen2 */ |
3735 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN), /* EN 10GigE */ |
3736 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_HERMON_EN_GEN2), /* EN 10GigE Gen2 */ |
3737 |
++ /* MT25458 ConnectX EN 10GBASE-T */ |
3738 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN), |
3739 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_T_GEN2), /* Gen2 */ |
3740 |
++ /* MT26468 ConnectX EN 10GigE PCIe Gen2*/ |
3741 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_GEN2), |
3742 |
++ /* MT26438 ConnectX EN 40GigE PCIe Gen2 5GT/s */ |
3743 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX_EN_5_GEN2), |
3744 |
++ /* MT26478 ConnectX2 40GigE PCIe Gen2 */ |
3745 |
++ MLX_SP(PCI_DEVICE_ID_MELLANOX_CONNECTX2), |
3746 |
++ /* MT25400 Family [ConnectX-2] */ |
3747 |
++ MLX_VF(0x1002), /* Virtual Function */ |
3748 |
+ /* MT27500 Family [ConnectX-3] */ |
3749 |
+- { PCI_VDEVICE(MELLANOX, 0x1003), 0 }, |
3750 |
+- /* MT27500 Family [ConnectX-3 Virtual Function] */ |
3751 |
+- { PCI_VDEVICE(MELLANOX, 0x1004), MLX4_PCI_DEV_IS_VF }, |
3752 |
+- { PCI_VDEVICE(MELLANOX, 0x1005), 0 }, /* MT27510 Family */ |
3753 |
+- { PCI_VDEVICE(MELLANOX, 0x1006), 0 }, /* MT27511 Family */ |
3754 |
+- { PCI_VDEVICE(MELLANOX, 0x1007), 0 }, /* MT27520 Family */ |
3755 |
+- { PCI_VDEVICE(MELLANOX, 0x1008), 0 }, /* MT27521 Family */ |
3756 |
+- { PCI_VDEVICE(MELLANOX, 0x1009), 0 }, /* MT27530 Family */ |
3757 |
+- { PCI_VDEVICE(MELLANOX, 0x100a), 0 }, /* MT27531 Family */ |
3758 |
+- { PCI_VDEVICE(MELLANOX, 0x100b), 0 }, /* MT27540 Family */ |
3759 |
+- { PCI_VDEVICE(MELLANOX, 0x100c), 0 }, /* MT27541 Family */ |
3760 |
+- { PCI_VDEVICE(MELLANOX, 0x100d), 0 }, /* MT27550 Family */ |
3761 |
+- { PCI_VDEVICE(MELLANOX, 0x100e), 0 }, /* MT27551 Family */ |
3762 |
+- { PCI_VDEVICE(MELLANOX, 0x100f), 0 }, /* MT27560 Family */ |
3763 |
+- { PCI_VDEVICE(MELLANOX, 0x1010), 0 }, /* MT27561 Family */ |
3764 |
++ MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3), |
3765 |
++ MLX_VF(0x1004), /* Virtual Function */ |
3766 |
++ MLX_GN(0x1005), /* MT27510 Family */ |
3767 |
++ MLX_GN(0x1006), /* MT27511 Family */ |
3768 |
++ MLX_GN(PCI_DEVICE_ID_MELLANOX_CONNECTX3_PRO), /* MT27520 Family */ |
3769 |
++ MLX_GN(0x1008), /* MT27521 Family */ |
3770 |
++ MLX_GN(0x1009), /* MT27530 Family */ |
3771 |
++ MLX_GN(0x100a), /* MT27531 Family */ |
3772 |
++ MLX_GN(0x100b), /* MT27540 Family */ |
3773 |
++ MLX_GN(0x100c), /* MT27541 Family */ |
3774 |
++ MLX_GN(0x100d), /* MT27550 Family */ |
3775 |
++ MLX_GN(0x100e), /* MT27551 Family */ |
3776 |
++ MLX_GN(0x100f), /* MT27560 Family */ |
3777 |
++ MLX_GN(0x1010), /* MT27561 Family */ |
3778 |
++ |
3779 |
++ /* |
3780 |
++ * See the mellanox_check_broken_intx_masking() quirk when |
3781 |
++ * adding devices |
3782 |
++ */ |
3783 |
++ |
3784 |
+ { 0, } |
3785 |
+ }; |
3786 |
+ |
3787 |
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |
3788 |
+index de19c7c92bc6..85d949e03f79 100644 |
3789 |
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |
3790 |
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |
3791 |
+@@ -2238,14 +2238,16 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) |
3792 |
+ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |
3793 |
+ struct brcmf_p2p_info *p2p = &cfg->p2p; |
3794 |
+ struct brcmf_cfg80211_vif *vif; |
3795 |
++ enum nl80211_iftype iftype; |
3796 |
+ bool wait_for_disable = false; |
3797 |
+ int err; |
3798 |
+ |
3799 |
+ brcmf_dbg(TRACE, "delete P2P vif\n"); |
3800 |
+ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); |
3801 |
+ |
3802 |
++ iftype = vif->wdev.iftype; |
3803 |
+ brcmf_cfg80211_arm_vif_event(cfg, vif); |
3804 |
+- switch (vif->wdev.iftype) { |
3805 |
++ switch (iftype) { |
3806 |
+ case NL80211_IFTYPE_P2P_CLIENT: |
3807 |
+ if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state)) |
3808 |
+ wait_for_disable = true; |
3809 |
+@@ -2275,7 +2277,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) |
3810 |
+ BRCMF_P2P_DISABLE_TIMEOUT); |
3811 |
+ |
3812 |
+ err = 0; |
3813 |
+- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) { |
3814 |
++ if (iftype != NL80211_IFTYPE_P2P_DEVICE) { |
3815 |
+ brcmf_vif_clear_mgmt_ies(vif); |
3816 |
+ err = brcmf_p2p_release_p2p_if(vif); |
3817 |
+ } |
3818 |
+@@ -2291,7 +2293,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) |
3819 |
+ brcmf_remove_interface(vif->ifp, true); |
3820 |
+ |
3821 |
+ brcmf_cfg80211_arm_vif_event(cfg, NULL); |
3822 |
+- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) |
3823 |
++ if (iftype != NL80211_IFTYPE_P2P_DEVICE) |
3824 |
+ p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; |
3825 |
+ |
3826 |
+ return err; |
3827 |
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c |
3828 |
+index bde769b11e3b..5f2feeef8905 100644 |
3829 |
+--- a/drivers/nvme/host/core.c |
3830 |
++++ b/drivers/nvme/host/core.c |
3831 |
+@@ -1204,8 +1204,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, |
3832 |
+ blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); |
3833 |
+ blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); |
3834 |
+ } |
3835 |
+- if (ctrl->stripe_size) |
3836 |
+- blk_queue_chunk_sectors(q, ctrl->stripe_size >> 9); |
3837 |
++ if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) |
3838 |
++ blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); |
3839 |
+ blk_queue_virt_boundary(q, ctrl->page_size - 1); |
3840 |
+ if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) |
3841 |
+ vwc = true; |
3842 |
+@@ -1261,19 +1261,6 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) |
3843 |
+ ctrl->max_hw_sectors = |
3844 |
+ min_not_zero(ctrl->max_hw_sectors, max_hw_sectors); |
3845 |
+ |
3846 |
+- if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && id->vs[3]) { |
3847 |
+- unsigned int max_hw_sectors; |
3848 |
+- |
3849 |
+- ctrl->stripe_size = 1 << (id->vs[3] + page_shift); |
3850 |
+- max_hw_sectors = ctrl->stripe_size >> (page_shift - 9); |
3851 |
+- if (ctrl->max_hw_sectors) { |
3852 |
+- ctrl->max_hw_sectors = min(max_hw_sectors, |
3853 |
+- ctrl->max_hw_sectors); |
3854 |
+- } else { |
3855 |
+- ctrl->max_hw_sectors = max_hw_sectors; |
3856 |
+- } |
3857 |
+- } |
3858 |
+- |
3859 |
+ nvme_set_queue_limits(ctrl, ctrl->admin_q); |
3860 |
+ ctrl->sgls = le32_to_cpu(id->sgls); |
3861 |
+ ctrl->kas = le16_to_cpu(id->kas); |
3862 |
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h |
3863 |
+index d47f5a5d18c7..8edafd8cb8ce 100644 |
3864 |
+--- a/drivers/nvme/host/nvme.h |
3865 |
++++ b/drivers/nvme/host/nvme.h |
3866 |
+@@ -121,7 +121,6 @@ struct nvme_ctrl { |
3867 |
+ |
3868 |
+ u32 page_size; |
3869 |
+ u32 max_hw_sectors; |
3870 |
+- u32 stripe_size; |
3871 |
+ u16 oncs; |
3872 |
+ u16 vid; |
3873 |
+ atomic_t abort_limit; |
3874 |
+diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c |
3875 |
+index 6abaf80ffb39..c3276eede82a 100644 |
3876 |
+--- a/drivers/pci/host/pci-thunder-pem.c |
3877 |
++++ b/drivers/pci/host/pci-thunder-pem.c |
3878 |
+@@ -284,35 +284,16 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, |
3879 |
+ return pci_generic_config_write(bus, devfn, where, size, val); |
3880 |
+ } |
3881 |
+ |
3882 |
+-static int thunder_pem_init(struct pci_config_window *cfg) |
3883 |
++static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg, |
3884 |
++ struct resource *res_pem) |
3885 |
+ { |
3886 |
+- struct device *dev = cfg->parent; |
3887 |
+- resource_size_t bar4_start; |
3888 |
+- struct resource *res_pem; |
3889 |
+ struct thunder_pem_pci *pem_pci; |
3890 |
+- struct platform_device *pdev; |
3891 |
+- |
3892 |
+- /* Only OF support for now */ |
3893 |
+- if (!dev->of_node) |
3894 |
+- return -EINVAL; |
3895 |
++ resource_size_t bar4_start; |
3896 |
+ |
3897 |
+ pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL); |
3898 |
+ if (!pem_pci) |
3899 |
+ return -ENOMEM; |
3900 |
+ |
3901 |
+- pdev = to_platform_device(dev); |
3902 |
+- |
3903 |
+- /* |
3904 |
+- * The second register range is the PEM bridge to the PCIe |
3905 |
+- * bus. It has a different config access method than those |
3906 |
+- * devices behind the bridge. |
3907 |
+- */ |
3908 |
+- res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
3909 |
+- if (!res_pem) { |
3910 |
+- dev_err(dev, "missing \"reg[1]\"property\n"); |
3911 |
+- return -EINVAL; |
3912 |
+- } |
3913 |
+- |
3914 |
+ pem_pci->pem_reg_base = devm_ioremap(dev, res_pem->start, 0x10000); |
3915 |
+ if (!pem_pci->pem_reg_base) |
3916 |
+ return -ENOMEM; |
3917 |
+@@ -332,9 +313,32 @@ static int thunder_pem_init(struct pci_config_window *cfg) |
3918 |
+ return 0; |
3919 |
+ } |
3920 |
+ |
3921 |
++static int thunder_pem_platform_init(struct pci_config_window *cfg) |
3922 |
++{ |
3923 |
++ struct device *dev = cfg->parent; |
3924 |
++ struct platform_device *pdev = to_platform_device(dev); |
3925 |
++ struct resource *res_pem; |
3926 |
++ |
3927 |
++ if (!dev->of_node) |
3928 |
++ return -EINVAL; |
3929 |
++ |
3930 |
++ /* |
3931 |
++ * The second register range is the PEM bridge to the PCIe |
3932 |
++ * bus. It has a different config access method than those |
3933 |
++ * devices behind the bridge. |
3934 |
++ */ |
3935 |
++ res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
3936 |
++ if (!res_pem) { |
3937 |
++ dev_err(dev, "missing \"reg[1]\"property\n"); |
3938 |
++ return -EINVAL; |
3939 |
++ } |
3940 |
++ |
3941 |
++ return thunder_pem_init(dev, cfg, res_pem); |
3942 |
++} |
3943 |
++ |
3944 |
+ static struct pci_ecam_ops pci_thunder_pem_ops = { |
3945 |
+ .bus_shift = 24, |
3946 |
+- .init = thunder_pem_init, |
3947 |
++ .init = thunder_pem_platform_init, |
3948 |
+ .pci_ops = { |
3949 |
+ .map_bus = pci_ecam_map_bus, |
3950 |
+ .read = thunder_pem_config_read, |
3951 |
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
3952 |
+index 087a218a875f..5d8151b43fbb 100644 |
3953 |
+--- a/drivers/pci/quirks.c |
3954 |
++++ b/drivers/pci/quirks.c |
3955 |
+@@ -1634,6 +1634,7 @@ static void quirk_pcie_mch(struct pci_dev *pdev) |
3956 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch); |
3957 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch); |
3958 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch); |
3959 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, quirk_pcie_mch); |
3960 |
+ |
3961 |
+ |
3962 |
+ /* |
3963 |
+@@ -2156,7 +2157,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev) |
3964 |
+ { |
3965 |
+ if (dev->vpd) { |
3966 |
+ dev->vpd->len = 0; |
3967 |
+- dev_warn(&dev->dev, FW_BUG "VPD access disabled\n"); |
3968 |
++ dev_warn(&dev->dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n"); |
3969 |
+ } |
3970 |
+ } |
3971 |
+ |
3972 |
+@@ -2240,6 +2241,27 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_BROADCOM, |
3973 |
+ PCI_DEVICE_ID_TIGON3_5719, |
3974 |
+ quirk_brcm_5719_limit_mrrs); |
3975 |
+ |
3976 |
++#ifdef CONFIG_PCIE_IPROC_PLATFORM |
3977 |
++static void quirk_paxc_bridge(struct pci_dev *pdev) |
3978 |
++{ |
3979 |
++ /* The PCI config space is shared with the PAXC root port and the first |
3980 |
++ * Ethernet device. So, we need to workaround this by telling the PCI |
3981 |
++ * code that the bridge is not an Ethernet device. |
3982 |
++ */ |
3983 |
++ if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) |
3984 |
++ pdev->class = PCI_CLASS_BRIDGE_PCI << 8; |
3985 |
++ |
3986 |
++ /* MPSS is not being set properly (as it is currently 0). This is |
3987 |
++ * because that area of the PCI config space is hard coded to zero, and |
3988 |
++ * is not modifiable by firmware. Set this to 2 (e.g., 512 byte MPS) |
3989 |
++ * so that the MPS can be set to the real max value. |
3990 |
++ */ |
3991 |
++ pdev->pcie_mpss = 2; |
3992 |
++} |
3993 |
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); |
3994 |
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); |
3995 |
++#endif |
3996 |
++ |
3997 |
+ /* Originally in EDAC sources for i82875P: |
3998 |
+ * Intel tells BIOS developers to hide device 6 which |
3999 |
+ * configures the overflow device access containing |
4000 |
+@@ -3114,30 +3136,32 @@ static void quirk_remove_d3_delay(struct pci_dev *dev) |
4001 |
+ { |
4002 |
+ dev->d3_delay = 0; |
4003 |
+ } |
4004 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); |
4005 |
++/* C600 Series devices do not need 10ms d3_delay */ |
4006 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3_delay); |
4007 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); |
4008 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3_delay); |
4009 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); |
4010 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); |
4011 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); |
4012 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); |
4013 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); |
4014 |
++/* Lynxpoint-H PCH devices do not need 10ms d3_delay */ |
4015 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); |
4016 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3_delay); |
4017 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3_delay); |
4018 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); |
4019 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); |
4020 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay); |
4021 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); |
4022 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); |
4023 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); |
4024 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); |
4025 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay); |
4026 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); |
4027 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); |
4028 |
+ /* Intel Cherrytrail devices do not need 10ms d3_delay */ |
4029 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay); |
4030 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); |
4031 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); |
4032 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay); |
4033 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); |
4034 |
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); |
4035 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay); |
4036 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay); |
4037 |
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay); |
4038 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); |
4039 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); |
4040 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); |
4041 |
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); |
4042 |
+ |
4043 |
+ /* |
4044 |
+ * Some devices may pass our check in pci_intx_mask_supported() if |
4045 |
+@@ -4137,6 +4161,26 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) |
4046 |
+ } |
4047 |
+ |
4048 |
+ /* |
4049 |
++ * These QCOM root ports do provide ACS-like features to disable peer |
4050 |
++ * transactions and validate bus numbers in requests, but do not provide an |
4051 |
++ * actual PCIe ACS capability. Hardware supports source validation but it |
4052 |
++ * will report the issue as Completer Abort instead of ACS Violation. |
4053 |
++ * Hardware doesn't support peer-to-peer and each root port is a root |
4054 |
++ * complex with unique segment numbers. It is not possible for one root |
4055 |
++ * port to pass traffic to another root port. All PCIe transactions are |
4056 |
++ * terminated inside the root port. |
4057 |
++ */ |
4058 |
++static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags) |
4059 |
++{ |
4060 |
++ u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV); |
4061 |
++ int ret = acs_flags & ~flags ? 0 : 1; |
4062 |
++ |
4063 |
++ dev_info(&dev->dev, "Using QCOM ACS Quirk (%d)\n", ret); |
4064 |
++ |
4065 |
++ return ret; |
4066 |
++} |
4067 |
++ |
4068 |
++/* |
4069 |
+ * Sunrise Point PCH root ports implement ACS, but unfortunately as shown in |
4070 |
+ * the datasheet (Intel 100 Series Chipset Family PCH Datasheet, Vol. 2, |
4071 |
+ * 12.1.46, 12.1.47)[1] this chipset uses dwords for the ACS capability and |
4072 |
+@@ -4151,15 +4195,35 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) |
4073 |
+ * |
4074 |
+ * N.B. This doesn't fix what lspci shows. |
4075 |
+ * |
4076 |
++ * The 100 series chipset specification update includes this as errata #23[3]. |
4077 |
++ * |
4078 |
++ * The 200 series chipset (Union Point) has the same bug according to the |
4079 |
++ * specification update (Intel 200 Series Chipset Family Platform Controller |
4080 |
++ * Hub, Specification Update, January 2017, Revision 001, Document# 335194-001, |
4081 |
++ * Errata 22)[4]. Per the datasheet[5], root port PCI Device IDs for this |
4082 |
++ * chipset include: |
4083 |
++ * |
4084 |
++ * 0xa290-0xa29f PCI Express Root port #{0-16} |
4085 |
++ * 0xa2e7-0xa2ee PCI Express Root port #{17-24} |
4086 |
++ * |
4087 |
+ * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html |
4088 |
+ * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html |
4089 |
++ * [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html |
4090 |
++ * [4] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-spec-update.html |
4091 |
++ * [5] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-datasheet-vol-1.html |
4092 |
+ */ |
4093 |
+ static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev) |
4094 |
+ { |
4095 |
+- return pci_is_pcie(dev) && |
4096 |
+- pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT && |
4097 |
+- ((dev->device & ~0xf) == 0xa110 || |
4098 |
+- (dev->device >= 0xa167 && dev->device <= 0xa16a)); |
4099 |
++ if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) |
4100 |
++ return false; |
4101 |
++ |
4102 |
++ switch (dev->device) { |
4103 |
++ case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */ |
4104 |
++ case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */ |
4105 |
++ return true; |
4106 |
++ } |
4107 |
++ |
4108 |
++ return false; |
4109 |
+ } |
4110 |
+ |
4111 |
+ #define INTEL_SPT_ACS_CTRL (PCI_ACS_CAP + 4) |
4112 |
+@@ -4272,6 +4336,9 @@ static const struct pci_dev_acs_enabled { |
4113 |
+ /* I219 */ |
4114 |
+ { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, |
4115 |
+ { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs }, |
4116 |
++ /* QCOM QDF2xxx root ports */ |
4117 |
++ { 0x17cb, 0x400, pci_quirk_qcom_rp_acs }, |
4118 |
++ { 0x17cb, 0x401, pci_quirk_qcom_rp_acs }, |
4119 |
+ /* Intel PCH root ports */ |
4120 |
+ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, |
4121 |
+ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs }, |
4122 |
+diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c |
4123 |
+index 79d64ea00bfb..a66192f692e3 100644 |
4124 |
+--- a/drivers/platform/x86/acer-wmi.c |
4125 |
++++ b/drivers/platform/x86/acer-wmi.c |
4126 |
+@@ -355,6 +355,32 @@ static const struct dmi_system_id acer_blacklist[] __initconst = { |
4127 |
+ {} |
4128 |
+ }; |
4129 |
+ |
4130 |
++static const struct dmi_system_id amw0_whitelist[] __initconst = { |
4131 |
++ { |
4132 |
++ .ident = "Acer", |
4133 |
++ .matches = { |
4134 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
4135 |
++ }, |
4136 |
++ }, |
4137 |
++ { |
4138 |
++ .ident = "Gateway", |
4139 |
++ .matches = { |
4140 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Gateway"), |
4141 |
++ }, |
4142 |
++ }, |
4143 |
++ { |
4144 |
++ .ident = "Packard Bell", |
4145 |
++ .matches = { |
4146 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"), |
4147 |
++ }, |
4148 |
++ }, |
4149 |
++ {} |
4150 |
++}; |
4151 |
++ |
4152 |
++/* |
4153 |
++ * This quirk table is only for Acer/Gateway/Packard Bell family |
4154 |
++ * that those machines are supported by acer-wmi driver. |
4155 |
++ */ |
4156 |
+ static const struct dmi_system_id acer_quirks[] __initconst = { |
4157 |
+ { |
4158 |
+ .callback = dmi_matched, |
4159 |
+@@ -464,6 +490,17 @@ static const struct dmi_system_id acer_quirks[] __initconst = { |
4160 |
+ }, |
4161 |
+ .driver_data = &quirk_acer_travelmate_2490, |
4162 |
+ }, |
4163 |
++ {} |
4164 |
++}; |
4165 |
++ |
4166 |
++/* |
4167 |
++ * This quirk list is for those non-acer machines that have AMW0_GUID1 |
4168 |
++ * but supported by acer-wmi in past days. Keeping this quirk list here |
4169 |
++ * is only for backward compatible. Please do not add new machine to |
4170 |
++ * here anymore. Those non-acer machines should be supported by |
4171 |
++ * appropriate wmi drivers. |
4172 |
++ */ |
4173 |
++static const struct dmi_system_id non_acer_quirks[] __initconst = { |
4174 |
+ { |
4175 |
+ .callback = dmi_matched, |
4176 |
+ .ident = "Fujitsu Siemens Amilo Li 1718", |
4177 |
+@@ -598,6 +635,7 @@ static void __init find_quirks(void) |
4178 |
+ { |
4179 |
+ if (!force_series) { |
4180 |
+ dmi_check_system(acer_quirks); |
4181 |
++ dmi_check_system(non_acer_quirks); |
4182 |
+ } else if (force_series == 2490) { |
4183 |
+ quirks = &quirk_acer_travelmate_2490; |
4184 |
+ } |
4185 |
+@@ -2108,6 +2146,24 @@ static int __init acer_wmi_init(void) |
4186 |
+ find_quirks(); |
4187 |
+ |
4188 |
+ /* |
4189 |
++ * The AMW0_GUID1 wmi is not only found on Acer family but also other |
4190 |
++ * machines like Lenovo, Fujitsu and Medion. In the past days, |
4191 |
++ * acer-wmi driver handled those non-Acer machines by quirks list. |
4192 |
++ * But actually acer-wmi driver was loaded on any machines that have |
4193 |
++ * AMW0_GUID1. This behavior is strange because those machines should |
4194 |
++ * be supported by appropriate wmi drivers. e.g. fujitsu-laptop, |
4195 |
++ * ideapad-laptop. So, here checks the machine that has AMW0_GUID1 |
4196 |
++ * should be in Acer/Gateway/Packard Bell white list, or it's already |
4197 |
++ * in the past quirk list. |
4198 |
++ */ |
4199 |
++ if (wmi_has_guid(AMW0_GUID1) && |
4200 |
++ !dmi_check_system(amw0_whitelist) && |
4201 |
++ quirks == &quirk_unknown) { |
4202 |
++ pr_err("Unsupported machine has AMW0_GUID1, unable to load\n"); |
4203 |
++ return -ENODEV; |
4204 |
++ } |
4205 |
++ |
4206 |
++ /* |
4207 |
+ * Detect which ACPI-WMI interface we're using. |
4208 |
+ */ |
4209 |
+ if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) |
4210 |
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c |
4211 |
+index 6032b7085582..6eb2837f6b89 100644 |
4212 |
+--- a/drivers/platform/x86/asus-nb-wmi.c |
4213 |
++++ b/drivers/platform/x86/asus-nb-wmi.c |
4214 |
+@@ -116,6 +116,10 @@ static struct quirk_entry quirk_asus_ux303ub = { |
4215 |
+ .wmi_backlight_native = true, |
4216 |
+ }; |
4217 |
+ |
4218 |
++static struct quirk_entry quirk_asus_x550lb = { |
4219 |
++ .xusb2pr = 0x01D9, |
4220 |
++}; |
4221 |
++ |
4222 |
+ static int dmi_matched(const struct dmi_system_id *dmi) |
4223 |
+ { |
4224 |
+ quirks = dmi->driver_data; |
4225 |
+@@ -407,6 +411,15 @@ static const struct dmi_system_id asus_quirks[] = { |
4226 |
+ }, |
4227 |
+ .driver_data = &quirk_asus_ux303ub, |
4228 |
+ }, |
4229 |
++ { |
4230 |
++ .callback = dmi_matched, |
4231 |
++ .ident = "ASUSTeK COMPUTER INC. X550LB", |
4232 |
++ .matches = { |
4233 |
++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
4234 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"), |
4235 |
++ }, |
4236 |
++ .driver_data = &quirk_asus_x550lb, |
4237 |
++ }, |
4238 |
+ {}, |
4239 |
+ }; |
4240 |
+ |
4241 |
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c |
4242 |
+index ce6ca31a2d09..8499d3ae4257 100644 |
4243 |
+--- a/drivers/platform/x86/asus-wmi.c |
4244 |
++++ b/drivers/platform/x86/asus-wmi.c |
4245 |
+@@ -156,6 +156,11 @@ MODULE_LICENSE("GPL"); |
4246 |
+ #define ASUS_FAN_CTRL_MANUAL 1 |
4247 |
+ #define ASUS_FAN_CTRL_AUTO 2 |
4248 |
+ |
4249 |
++#define USB_INTEL_XUSB2PR 0xD0 |
4250 |
++#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 |
4251 |
++ |
4252 |
++static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; |
4253 |
++ |
4254 |
+ struct bios_args { |
4255 |
+ u32 arg0; |
4256 |
+ u32 arg1; |
4257 |
+@@ -1080,6 +1085,29 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) |
4258 |
+ return result; |
4259 |
+ } |
4260 |
+ |
4261 |
++static void asus_wmi_set_xusb2pr(struct asus_wmi *asus) |
4262 |
++{ |
4263 |
++ struct pci_dev *xhci_pdev; |
4264 |
++ u32 orig_ports_available; |
4265 |
++ u32 ports_available = asus->driver->quirks->xusb2pr; |
4266 |
++ |
4267 |
++ xhci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
4268 |
++ PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI, |
4269 |
++ NULL); |
4270 |
++ |
4271 |
++ if (!xhci_pdev) |
4272 |
++ return; |
4273 |
++ |
4274 |
++ pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, |
4275 |
++ &orig_ports_available); |
4276 |
++ |
4277 |
++ pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, |
4278 |
++ cpu_to_le32(ports_available)); |
4279 |
++ |
4280 |
++ pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n", |
4281 |
++ orig_ports_available, ports_available); |
4282 |
++} |
4283 |
++ |
4284 |
+ /* |
4285 |
+ * Hwmon device |
4286 |
+ */ |
4287 |
+@@ -2025,6 +2053,16 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) |
4288 |
+ return 0; |
4289 |
+ } |
4290 |
+ |
4291 |
++static bool ashs_present(void) |
4292 |
++{ |
4293 |
++ int i = 0; |
4294 |
++ while (ashs_ids[i]) { |
4295 |
++ if (acpi_dev_found(ashs_ids[i++])) |
4296 |
++ return true; |
4297 |
++ } |
4298 |
++ return false; |
4299 |
++} |
4300 |
++ |
4301 |
+ /* |
4302 |
+ * WMI Driver |
4303 |
+ */ |
4304 |
+@@ -2069,6 +2107,13 @@ static int asus_wmi_add(struct platform_device *pdev) |
4305 |
+ if (err) |
4306 |
+ goto fail_leds; |
4307 |
+ |
4308 |
++ asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); |
4309 |
++ if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) |
4310 |
++ asus->driver->wlan_ctrl_by_user = 1; |
4311 |
++ |
4312 |
++ if (asus->driver->wlan_ctrl_by_user && ashs_present()) |
4313 |
++ asus->driver->quirks->no_rfkill = 1; |
4314 |
++ |
4315 |
+ if (!asus->driver->quirks->no_rfkill) { |
4316 |
+ err = asus_wmi_rfkill_init(asus); |
4317 |
+ if (err) |
4318 |
+@@ -2087,6 +2132,9 @@ static int asus_wmi_add(struct platform_device *pdev) |
4319 |
+ if (asus->driver->quirks->wmi_backlight_native) |
4320 |
+ acpi_video_set_dmi_backlight_type(acpi_backlight_native); |
4321 |
+ |
4322 |
++ if (asus->driver->quirks->xusb2pr) |
4323 |
++ asus_wmi_set_xusb2pr(asus); |
4324 |
++ |
4325 |
+ if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { |
4326 |
+ err = asus_wmi_backlight_init(asus); |
4327 |
+ if (err && err != -ENODEV) |
4328 |
+@@ -2105,10 +2153,6 @@ static int asus_wmi_add(struct platform_device *pdev) |
4329 |
+ if (err) |
4330 |
+ goto fail_debugfs; |
4331 |
+ |
4332 |
+- asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); |
4333 |
+- if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) |
4334 |
+- asus->driver->wlan_ctrl_by_user = 1; |
4335 |
+- |
4336 |
+ return 0; |
4337 |
+ |
4338 |
+ fail_debugfs: |
4339 |
+diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h |
4340 |
+index 0e19014e9f54..fdff626c3b51 100644 |
4341 |
+--- a/drivers/platform/x86/asus-wmi.h |
4342 |
++++ b/drivers/platform/x86/asus-wmi.h |
4343 |
+@@ -53,6 +53,7 @@ struct quirk_entry { |
4344 |
+ * and let the ACPI interrupt to send out the key event. |
4345 |
+ */ |
4346 |
+ int no_display_toggle; |
4347 |
++ u32 xusb2pr; |
4348 |
+ |
4349 |
+ bool (*i8042_filter)(unsigned char data, unsigned char str, |
4350 |
+ struct serio *serio); |
4351 |
+diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c |
4352 |
+index 3aedf73f1131..462bf42dd19c 100644 |
4353 |
+--- a/drivers/scsi/ufs/ufs-qcom.c |
4354 |
++++ b/drivers/scsi/ufs/ufs-qcom.c |
4355 |
+@@ -23,6 +23,7 @@ |
4356 |
+ #include "unipro.h" |
4357 |
+ #include "ufs-qcom.h" |
4358 |
+ #include "ufshci.h" |
4359 |
++#include "ufs_quirks.h" |
4360 |
+ #define UFS_QCOM_DEFAULT_DBG_PRINT_EN \ |
4361 |
+ (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN) |
4362 |
+ |
4363 |
+@@ -1031,6 +1032,34 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, |
4364 |
+ return ret; |
4365 |
+ } |
4366 |
+ |
4367 |
++static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba) |
4368 |
++{ |
4369 |
++ int err; |
4370 |
++ u32 pa_vs_config_reg1; |
4371 |
++ |
4372 |
++ err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1), |
4373 |
++ &pa_vs_config_reg1); |
4374 |
++ if (err) |
4375 |
++ goto out; |
4376 |
++ |
4377 |
++ /* Allow extension of MSB bits of PA_SaveConfigTime attribute */ |
4378 |
++ err = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1), |
4379 |
++ (pa_vs_config_reg1 | (1 << 12))); |
4380 |
++ |
4381 |
++out: |
4382 |
++ return err; |
4383 |
++} |
4384 |
++ |
4385 |
++static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba) |
4386 |
++{ |
4387 |
++ int err = 0; |
4388 |
++ |
4389 |
++ if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME) |
4390 |
++ err = ufs_qcom_quirk_host_pa_saveconfigtime(hba); |
4391 |
++ |
4392 |
++ return err; |
4393 |
++} |
4394 |
++ |
4395 |
+ static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba) |
4396 |
+ { |
4397 |
+ struct ufs_qcom_host *host = ufshcd_get_variant(hba); |
4398 |
+@@ -1616,6 +1645,7 @@ static struct ufs_hba_variant_ops ufs_hba_qcom_vops = { |
4399 |
+ .hce_enable_notify = ufs_qcom_hce_enable_notify, |
4400 |
+ .link_startup_notify = ufs_qcom_link_startup_notify, |
4401 |
+ .pwr_change_notify = ufs_qcom_pwr_change_notify, |
4402 |
++ .apply_dev_quirks = ufs_qcom_apply_dev_quirks, |
4403 |
+ .suspend = ufs_qcom_suspend, |
4404 |
+ .resume = ufs_qcom_resume, |
4405 |
+ .dbg_register_dump = ufs_qcom_dump_dbg_regs, |
4406 |
+diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h |
4407 |
+index a19307a57ce2..fe517cd7dac3 100644 |
4408 |
+--- a/drivers/scsi/ufs/ufs-qcom.h |
4409 |
++++ b/drivers/scsi/ufs/ufs-qcom.h |
4410 |
+@@ -142,6 +142,7 @@ enum ufs_qcom_phy_init_type { |
4411 |
+ UFS_QCOM_DBG_PRINT_TEST_BUS_EN) |
4412 |
+ |
4413 |
+ /* QUniPro Vendor specific attributes */ |
4414 |
++#define PA_VS_CONFIG_REG1 0x9000 |
4415 |
+ #define DME_VS_CORE_CLK_CTRL 0xD002 |
4416 |
+ /* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */ |
4417 |
+ #define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8) |
4418 |
+diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h |
4419 |
+index 22f881e9253a..08b799d4efcc 100644 |
4420 |
+--- a/drivers/scsi/ufs/ufs_quirks.h |
4421 |
++++ b/drivers/scsi/ufs/ufs_quirks.h |
4422 |
+@@ -128,26 +128,23 @@ struct ufs_dev_fix { |
4423 |
+ */ |
4424 |
+ #define UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM (1 << 6) |
4425 |
+ |
4426 |
++/* |
4427 |
++ * Some UFS devices require host PA_TACTIVATE to be lower than device |
4428 |
++ * PA_TACTIVATE, enabling this quirk ensure this. |
4429 |
++ */ |
4430 |
++#define UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE (1 << 7) |
4431 |
++ |
4432 |
++/* |
4433 |
++ * The max. value PA_SaveConfigTime is 250 (10us) but this is not enough for |
4434 |
++ * some vendors. |
4435 |
++ * Gear switch from PWM to HS may fail even with this max. PA_SaveConfigTime. |
4436 |
++ * Gear switch can be issued by host controller as an error recovery and any |
4437 |
++ * software delay will not help on this case so we need to increase |
4438 |
++ * PA_SaveConfigTime to >32us as per vendor recommendation. |
4439 |
++ */ |
4440 |
++#define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME (1 << 8) |
4441 |
++ |
4442 |
+ struct ufs_hba; |
4443 |
+ void ufs_advertise_fixup_device(struct ufs_hba *hba); |
4444 |
+ |
4445 |
+-static struct ufs_dev_fix ufs_fixups[] = { |
4446 |
+- /* UFS cards deviations table */ |
4447 |
+- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4448 |
+- UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), |
4449 |
+- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), |
4450 |
+- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4451 |
+- UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS), |
4452 |
+- UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4453 |
+- UFS_DEVICE_NO_FASTAUTO), |
4454 |
+- UFS_FIX(UFS_VENDOR_TOSHIBA, UFS_ANY_MODEL, |
4455 |
+- UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), |
4456 |
+- UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG", |
4457 |
+- UFS_DEVICE_QUIRK_PA_TACTIVATE), |
4458 |
+- UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG", |
4459 |
+- UFS_DEVICE_QUIRK_PA_TACTIVATE), |
4460 |
+- UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), |
4461 |
+- |
4462 |
+- END_FIX |
4463 |
+-}; |
4464 |
+ #endif /* UFS_QUIRKS_H_ */ |
4465 |
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c |
4466 |
+index 05c745663c10..edb06e466224 100644 |
4467 |
+--- a/drivers/scsi/ufs/ufshcd.c |
4468 |
++++ b/drivers/scsi/ufs/ufshcd.c |
4469 |
+@@ -123,6 +123,7 @@ enum { |
4470 |
+ UFSHCD_STATE_RESET, |
4471 |
+ UFSHCD_STATE_ERROR, |
4472 |
+ UFSHCD_STATE_OPERATIONAL, |
4473 |
++ UFSHCD_STATE_EH_SCHEDULED, |
4474 |
+ }; |
4475 |
+ |
4476 |
+ /* UFSHCD error handling flags */ |
4477 |
+@@ -188,6 +189,30 @@ ufs_get_pm_lvl_to_link_pwr_state(enum ufs_pm_level lvl) |
4478 |
+ return ufs_pm_lvl_states[lvl].link_state; |
4479 |
+ } |
4480 |
+ |
4481 |
++static struct ufs_dev_fix ufs_fixups[] = { |
4482 |
++ /* UFS cards deviations table */ |
4483 |
++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4484 |
++ UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), |
4485 |
++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), |
4486 |
++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4487 |
++ UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS), |
4488 |
++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4489 |
++ UFS_DEVICE_NO_FASTAUTO), |
4490 |
++ UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, |
4491 |
++ UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE), |
4492 |
++ UFS_FIX(UFS_VENDOR_TOSHIBA, UFS_ANY_MODEL, |
4493 |
++ UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), |
4494 |
++ UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9C8KBADG", |
4495 |
++ UFS_DEVICE_QUIRK_PA_TACTIVATE), |
4496 |
++ UFS_FIX(UFS_VENDOR_TOSHIBA, "THGLF2G9D8KBADG", |
4497 |
++ UFS_DEVICE_QUIRK_PA_TACTIVATE), |
4498 |
++ UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, UFS_DEVICE_NO_VCCQ), |
4499 |
++ UFS_FIX(UFS_VENDOR_SKHYNIX, UFS_ANY_MODEL, |
4500 |
++ UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME), |
4501 |
++ |
4502 |
++ END_FIX |
4503 |
++}; |
4504 |
++ |
4505 |
+ static void ufshcd_tmc_handler(struct ufs_hba *hba); |
4506 |
+ static void ufshcd_async_scan(void *data, async_cookie_t cookie); |
4507 |
+ static int ufshcd_reset_and_restore(struct ufs_hba *hba); |
4508 |
+@@ -1088,7 +1113,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) |
4509 |
+ * |
4510 |
+ * Returns 0 in case of success, non-zero value in case of failure |
4511 |
+ */ |
4512 |
+-static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) |
4513 |
++static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) |
4514 |
+ { |
4515 |
+ struct ufshcd_sg_entry *prd_table; |
4516 |
+ struct scatterlist *sg; |
4517 |
+@@ -1102,8 +1127,13 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) |
4518 |
+ return sg_segments; |
4519 |
+ |
4520 |
+ if (sg_segments) { |
4521 |
+- lrbp->utr_descriptor_ptr->prd_table_length = |
4522 |
+- cpu_to_le16((u16) (sg_segments)); |
4523 |
++ if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) |
4524 |
++ lrbp->utr_descriptor_ptr->prd_table_length = |
4525 |
++ cpu_to_le16((u16)(sg_segments * |
4526 |
++ sizeof(struct ufshcd_sg_entry))); |
4527 |
++ else |
4528 |
++ lrbp->utr_descriptor_ptr->prd_table_length = |
4529 |
++ cpu_to_le16((u16) (sg_segments)); |
4530 |
+ |
4531 |
+ prd_table = (struct ufshcd_sg_entry *)lrbp->ucd_prdt_ptr; |
4532 |
+ |
4533 |
+@@ -1410,6 +1440,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
4534 |
+ switch (hba->ufshcd_state) { |
4535 |
+ case UFSHCD_STATE_OPERATIONAL: |
4536 |
+ break; |
4537 |
++ case UFSHCD_STATE_EH_SCHEDULED: |
4538 |
+ case UFSHCD_STATE_RESET: |
4539 |
+ err = SCSI_MLQUEUE_HOST_BUSY; |
4540 |
+ goto out_unlock; |
4541 |
+@@ -1465,7 +1496,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
4542 |
+ |
4543 |
+ ufshcd_comp_scsi_upiu(hba, lrbp); |
4544 |
+ |
4545 |
+- err = ufshcd_map_sg(lrbp); |
4546 |
++ err = ufshcd_map_sg(hba, lrbp); |
4547 |
+ if (err) { |
4548 |
+ lrbp->cmd = NULL; |
4549 |
+ clear_bit_unlock(tag, &hba->lrb_in_use); |
4550 |
+@@ -2320,12 +2351,21 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) |
4551 |
+ cpu_to_le32(upper_32_bits(cmd_desc_element_addr)); |
4552 |
+ |
4553 |
+ /* Response upiu and prdt offset should be in double words */ |
4554 |
+- utrdlp[i].response_upiu_offset = |
4555 |
++ if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) { |
4556 |
++ utrdlp[i].response_upiu_offset = |
4557 |
++ cpu_to_le16(response_offset); |
4558 |
++ utrdlp[i].prd_table_offset = |
4559 |
++ cpu_to_le16(prdt_offset); |
4560 |
++ utrdlp[i].response_upiu_length = |
4561 |
++ cpu_to_le16(ALIGNED_UPIU_SIZE); |
4562 |
++ } else { |
4563 |
++ utrdlp[i].response_upiu_offset = |
4564 |
+ cpu_to_le16((response_offset >> 2)); |
4565 |
+- utrdlp[i].prd_table_offset = |
4566 |
++ utrdlp[i].prd_table_offset = |
4567 |
+ cpu_to_le16((prdt_offset >> 2)); |
4568 |
+- utrdlp[i].response_upiu_length = |
4569 |
++ utrdlp[i].response_upiu_length = |
4570 |
+ cpu_to_le16(ALIGNED_UPIU_SIZE >> 2); |
4571 |
++ } |
4572 |
+ |
4573 |
+ hba->lrb[i].utr_descriptor_ptr = (utrdlp + i); |
4574 |
+ hba->lrb[i].ucd_req_ptr = |
4575 |
+@@ -3090,7 +3130,16 @@ static int ufshcd_link_startup(struct ufs_hba *hba) |
4576 |
+ { |
4577 |
+ int ret; |
4578 |
+ int retries = DME_LINKSTARTUP_RETRIES; |
4579 |
++ bool link_startup_again = false; |
4580 |
+ |
4581 |
++ /* |
4582 |
++ * If UFS device isn't active then we will have to issue link startup |
4583 |
++ * 2 times to make sure the device state move to active. |
4584 |
++ */ |
4585 |
++ if (!ufshcd_is_ufs_dev_active(hba)) |
4586 |
++ link_startup_again = true; |
4587 |
++ |
4588 |
++link_startup: |
4589 |
+ do { |
4590 |
+ ufshcd_vops_link_startup_notify(hba, PRE_CHANGE); |
4591 |
+ |
4592 |
+@@ -3116,6 +3165,12 @@ static int ufshcd_link_startup(struct ufs_hba *hba) |
4593 |
+ /* failed to get the link up... retire */ |
4594 |
+ goto out; |
4595 |
+ |
4596 |
++ if (link_startup_again) { |
4597 |
++ link_startup_again = false; |
4598 |
++ retries = DME_LINKSTARTUP_RETRIES; |
4599 |
++ goto link_startup; |
4600 |
++ } |
4601 |
++ |
4602 |
+ if (hba->quirks & UFSHCD_QUIRK_BROKEN_LCC) { |
4603 |
+ ret = ufshcd_disable_device_tx_lcc(hba); |
4604 |
+ if (ret) |
4605 |
+@@ -4158,7 +4213,7 @@ static void ufshcd_check_errors(struct ufs_hba *hba) |
4606 |
+ /* block commands from scsi mid-layer */ |
4607 |
+ scsi_block_requests(hba->host); |
4608 |
+ |
4609 |
+- hba->ufshcd_state = UFSHCD_STATE_ERROR; |
4610 |
++ hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED; |
4611 |
+ schedule_work(&hba->eh_work); |
4612 |
+ } |
4613 |
+ } |
4614 |
+@@ -4965,6 +5020,76 @@ static int ufshcd_tune_pa_hibern8time(struct ufs_hba *hba) |
4615 |
+ return ret; |
4616 |
+ } |
4617 |
+ |
4618 |
++/** |
4619 |
++ * ufshcd_quirk_tune_host_pa_tactivate - Ensures that host PA_TACTIVATE is |
4620 |
++ * less than device PA_TACTIVATE time. |
4621 |
++ * @hba: per-adapter instance |
4622 |
++ * |
4623 |
++ * Some UFS devices require host PA_TACTIVATE to be lower than device |
4624 |
++ * PA_TACTIVATE, we need to enable UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE quirk |
4625 |
++ * for such devices. |
4626 |
++ * |
4627 |
++ * Returns zero on success, non-zero error value on failure. |
4628 |
++ */ |
4629 |
++static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba) |
4630 |
++{ |
4631 |
++ int ret = 0; |
4632 |
++ u32 granularity, peer_granularity; |
4633 |
++ u32 pa_tactivate, peer_pa_tactivate; |
4634 |
++ u32 pa_tactivate_us, peer_pa_tactivate_us; |
4635 |
++ u8 gran_to_us_table[] = {1, 4, 8, 16, 32, 100}; |
4636 |
++ |
4637 |
++ ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY), |
4638 |
++ &granularity); |
4639 |
++ if (ret) |
4640 |
++ goto out; |
4641 |
++ |
4642 |
++ ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_GRANULARITY), |
4643 |
++ &peer_granularity); |
4644 |
++ if (ret) |
4645 |
++ goto out; |
4646 |
++ |
4647 |
++ if ((granularity < PA_GRANULARITY_MIN_VAL) || |
4648 |
++ (granularity > PA_GRANULARITY_MAX_VAL)) { |
4649 |
++ dev_err(hba->dev, "%s: invalid host PA_GRANULARITY %d", |
4650 |
++ __func__, granularity); |
4651 |
++ return -EINVAL; |
4652 |
++ } |
4653 |
++ |
4654 |
++ if ((peer_granularity < PA_GRANULARITY_MIN_VAL) || |
4655 |
++ (peer_granularity > PA_GRANULARITY_MAX_VAL)) { |
4656 |
++ dev_err(hba->dev, "%s: invalid device PA_GRANULARITY %d", |
4657 |
++ __func__, peer_granularity); |
4658 |
++ return -EINVAL; |
4659 |
++ } |
4660 |
++ |
4661 |
++ ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_TACTIVATE), &pa_tactivate); |
4662 |
++ if (ret) |
4663 |
++ goto out; |
4664 |
++ |
4665 |
++ ret = ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_TACTIVATE), |
4666 |
++ &peer_pa_tactivate); |
4667 |
++ if (ret) |
4668 |
++ goto out; |
4669 |
++ |
4670 |
++ pa_tactivate_us = pa_tactivate * gran_to_us_table[granularity - 1]; |
4671 |
++ peer_pa_tactivate_us = peer_pa_tactivate * |
4672 |
++ gran_to_us_table[peer_granularity - 1]; |
4673 |
++ |
4674 |
++ if (pa_tactivate_us > peer_pa_tactivate_us) { |
4675 |
++ u32 new_peer_pa_tactivate; |
4676 |
++ |
4677 |
++ new_peer_pa_tactivate = pa_tactivate_us / |
4678 |
++ gran_to_us_table[peer_granularity - 1]; |
4679 |
++ new_peer_pa_tactivate++; |
4680 |
++ ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TACTIVATE), |
4681 |
++ new_peer_pa_tactivate); |
4682 |
++ } |
4683 |
++ |
4684 |
++out: |
4685 |
++ return ret; |
4686 |
++} |
4687 |
++ |
4688 |
+ static void ufshcd_tune_unipro_params(struct ufs_hba *hba) |
4689 |
+ { |
4690 |
+ if (ufshcd_is_unipro_pa_params_tuning_req(hba)) { |
4691 |
+@@ -4975,6 +5100,11 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba) |
4692 |
+ if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_TACTIVATE) |
4693 |
+ /* set 1ms timeout for PA_TACTIVATE */ |
4694 |
+ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 10); |
4695 |
++ |
4696 |
++ if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE) |
4697 |
++ ufshcd_quirk_tune_host_pa_tactivate(hba); |
4698 |
++ |
4699 |
++ ufshcd_vops_apply_dev_quirks(hba); |
4700 |
+ } |
4701 |
+ |
4702 |
+ /** |
4703 |
+@@ -6515,10 +6645,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) |
4704 |
+ pm_runtime_get_sync(dev); |
4705 |
+ |
4706 |
+ /* |
4707 |
+- * The device-initialize-sequence hasn't been invoked yet. |
4708 |
+- * Set the device to power-off state |
4709 |
++ * We are assuming that device wasn't put in sleep/power-down |
4710 |
++ * state exclusively during the boot stage before kernel. |
4711 |
++ * This assumption helps avoid doing link startup twice during |
4712 |
++ * ufshcd_probe_hba(). |
4713 |
+ */ |
4714 |
+- ufshcd_set_ufs_dev_poweroff(hba); |
4715 |
++ ufshcd_set_ufs_dev_active(hba); |
4716 |
+ |
4717 |
+ async_schedule(ufshcd_async_scan, hba); |
4718 |
+ |
4719 |
+diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h |
4720 |
+index 430bef111293..04509827fe64 100644 |
4721 |
+--- a/drivers/scsi/ufs/ufshcd.h |
4722 |
++++ b/drivers/scsi/ufs/ufshcd.h |
4723 |
+@@ -261,6 +261,7 @@ struct ufs_pwr_mode_info { |
4724 |
+ * @pwr_change_notify: called before and after a power mode change |
4725 |
+ * is carried out to allow vendor spesific capabilities |
4726 |
+ * to be set. |
4727 |
++ * @apply_dev_quirks: called to apply device specific quirks |
4728 |
+ * @suspend: called during host controller PM callback |
4729 |
+ * @resume: called during host controller PM callback |
4730 |
+ * @dbg_register_dump: used to dump controller debug information |
4731 |
+@@ -283,6 +284,7 @@ struct ufs_hba_variant_ops { |
4732 |
+ enum ufs_notify_change_status status, |
4733 |
+ struct ufs_pa_layer_attr *, |
4734 |
+ struct ufs_pa_layer_attr *); |
4735 |
++ int (*apply_dev_quirks)(struct ufs_hba *); |
4736 |
+ int (*suspend)(struct ufs_hba *, enum ufs_pm_op); |
4737 |
+ int (*resume)(struct ufs_hba *, enum ufs_pm_op); |
4738 |
+ void (*dbg_register_dump)(struct ufs_hba *hba); |
4739 |
+@@ -474,6 +476,12 @@ struct ufs_hba { |
4740 |
+ */ |
4741 |
+ #define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION UFS_BIT(5) |
4742 |
+ |
4743 |
++ /* |
4744 |
++ * This quirk needs to be enabled if the host contoller regards |
4745 |
++ * resolution of the values of PRDTO and PRDTL in UTRD as byte. |
4746 |
++ */ |
4747 |
++ #define UFSHCD_QUIRK_PRDT_BYTE_GRAN UFS_BIT(7) |
4748 |
++ |
4749 |
+ unsigned int quirks; /* Deviations from standard UFSHCI spec. */ |
4750 |
+ |
4751 |
+ /* Device deviations from standard UFS device spec. */ |
4752 |
+@@ -799,6 +807,13 @@ static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba, |
4753 |
+ return -ENOTSUPP; |
4754 |
+ } |
4755 |
+ |
4756 |
++static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba) |
4757 |
++{ |
4758 |
++ if (hba->vops && hba->vops->apply_dev_quirks) |
4759 |
++ return hba->vops->apply_dev_quirks(hba); |
4760 |
++ return 0; |
4761 |
++} |
4762 |
++ |
4763 |
+ static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op) |
4764 |
+ { |
4765 |
+ if (hba->vops && hba->vops->suspend) |
4766 |
+diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h |
4767 |
+index eff8b5675575..23129d7b2678 100644 |
4768 |
+--- a/drivers/scsi/ufs/unipro.h |
4769 |
++++ b/drivers/scsi/ufs/unipro.h |
4770 |
+@@ -123,6 +123,7 @@ |
4771 |
+ #define PA_MAXRXHSGEAR 0x1587 |
4772 |
+ #define PA_RXHSUNTERMCAP 0x15A5 |
4773 |
+ #define PA_RXLSTERMCAP 0x15A6 |
4774 |
++#define PA_GRANULARITY 0x15AA |
4775 |
+ #define PA_PACPREQTIMEOUT 0x1590 |
4776 |
+ #define PA_PACPREQEOBTIMEOUT 0x1591 |
4777 |
+ #define PA_HIBERN8TIME 0x15A7 |
4778 |
+@@ -158,6 +159,9 @@ |
4779 |
+ #define VS_DEBUGOMC 0xD09E |
4780 |
+ #define VS_POWERSTATE 0xD083 |
4781 |
+ |
4782 |
++#define PA_GRANULARITY_MIN_VAL 1 |
4783 |
++#define PA_GRANULARITY_MAX_VAL 6 |
4784 |
++ |
4785 |
+ /* PHY Adapter Protocol Constants */ |
4786 |
+ #define PA_MAXDATALANES 4 |
4787 |
+ |
4788 |
+diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c |
4789 |
+index ca9a53c03f0f..2b770cb0c488 100644 |
4790 |
+--- a/drivers/staging/android/ashmem.c |
4791 |
++++ b/drivers/staging/android/ashmem.c |
4792 |
+@@ -405,6 +405,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) |
4793 |
+ ret = PTR_ERR(vmfile); |
4794 |
+ goto out; |
4795 |
+ } |
4796 |
++ vmfile->f_mode |= FMODE_LSEEK; |
4797 |
+ asma->file = vmfile; |
4798 |
+ } |
4799 |
+ get_file(asma->file); |
4800 |
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c |
4801 |
+index 61ad6c3b20a0..f4eb807a2616 100644 |
4802 |
+--- a/drivers/tty/serial/8250/8250_omap.c |
4803 |
++++ b/drivers/tty/serial/8250/8250_omap.c |
4804 |
+@@ -1075,15 +1075,15 @@ static int omap8250_no_handle_irq(struct uart_port *port) |
4805 |
+ } |
4806 |
+ |
4807 |
+ static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE; |
4808 |
+-static const u8 am4372_habit = UART_ERRATA_CLOCK_DISABLE; |
4809 |
++static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE; |
4810 |
+ |
4811 |
+ static const struct of_device_id omap8250_dt_ids[] = { |
4812 |
+ { .compatible = "ti,omap2-uart" }, |
4813 |
+ { .compatible = "ti,omap3-uart" }, |
4814 |
+ { .compatible = "ti,omap4-uart" }, |
4815 |
+ { .compatible = "ti,am3352-uart", .data = &am3352_habit, }, |
4816 |
+- { .compatible = "ti,am4372-uart", .data = &am4372_habit, }, |
4817 |
+- { .compatible = "ti,dra742-uart", .data = &am4372_habit, }, |
4818 |
++ { .compatible = "ti,am4372-uart", .data = &am3352_habit, }, |
4819 |
++ { .compatible = "ti,dra742-uart", .data = &dra742_habit, }, |
4820 |
+ {}, |
4821 |
+ }; |
4822 |
+ MODULE_DEVICE_TABLE(of, omap8250_dt_ids); |
4823 |
+@@ -1218,9 +1218,6 @@ static int omap8250_probe(struct platform_device *pdev) |
4824 |
+ priv->omap8250_dma.rx_size = RX_TRIGGER; |
4825 |
+ priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER; |
4826 |
+ priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER; |
4827 |
+- |
4828 |
+- if (of_machine_is_compatible("ti,am33xx")) |
4829 |
+- priv->habit |= OMAP_DMA_TX_KICK; |
4830 |
+ /* |
4831 |
+ * pause is currently not supported atleast on omap-sdma |
4832 |
+ * and edma on most earlier kernels. |
4833 |
+diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c |
4834 |
+index 3889809fd0c4..37591a4b1346 100644 |
4835 |
+--- a/drivers/usb/chipidea/ci_hdrc_msm.c |
4836 |
++++ b/drivers/usb/chipidea/ci_hdrc_msm.c |
4837 |
+@@ -24,7 +24,6 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event) |
4838 |
+ switch (event) { |
4839 |
+ case CI_HDRC_CONTROLLER_RESET_EVENT: |
4840 |
+ dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n"); |
4841 |
+- writel(0, USB_AHBBURST); |
4842 |
+ /* use AHB transactor, allow posted data writes */ |
4843 |
+ writel(0x8, USB_AHBMODE); |
4844 |
+ usb_phy_init(ci->usb_phy); |
4845 |
+@@ -47,7 +46,8 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { |
4846 |
+ .name = "ci_hdrc_msm", |
4847 |
+ .capoffset = DEF_CAPOFFSET, |
4848 |
+ .flags = CI_HDRC_REGS_SHARED | |
4849 |
+- CI_HDRC_DISABLE_STREAMING, |
4850 |
++ CI_HDRC_DISABLE_STREAMING | |
4851 |
++ CI_HDRC_OVERRIDE_AHB_BURST, |
4852 |
+ |
4853 |
+ .notify_event = ci_hdrc_msm_notify_event, |
4854 |
+ }; |
4855 |
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c |
4856 |
+index 5dc6bfc91f4b..ce603dcbd493 100644 |
4857 |
+--- a/drivers/usb/dwc3/gadget.c |
4858 |
++++ b/drivers/usb/dwc3/gadget.c |
4859 |
+@@ -174,6 +174,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, |
4860 |
+ int status) |
4861 |
+ { |
4862 |
+ struct dwc3 *dwc = dep->dwc; |
4863 |
++ unsigned int unmap_after_complete = false; |
4864 |
+ |
4865 |
+ req->started = false; |
4866 |
+ list_del(&req->list); |
4867 |
+@@ -182,11 +183,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, |
4868 |
+ if (req->request.status == -EINPROGRESS) |
4869 |
+ req->request.status = status; |
4870 |
+ |
4871 |
+- if (dwc->ep0_bounced && dep->number <= 1) |
4872 |
++ /* |
4873 |
++ * NOTICE we don't want to unmap before calling ->complete() if we're |
4874 |
++ * dealing with a bounced ep0 request. If we unmap it here, we would end |
4875 |
++ * up overwritting the contents of req->buf and this could confuse the |
4876 |
++ * gadget driver. |
4877 |
++ */ |
4878 |
++ if (dwc->ep0_bounced && dep->number <= 1) { |
4879 |
+ dwc->ep0_bounced = false; |
4880 |
+- |
4881 |
+- usb_gadget_unmap_request(&dwc->gadget, &req->request, |
4882 |
+- req->direction); |
4883 |
++ unmap_after_complete = true; |
4884 |
++ } else { |
4885 |
++ usb_gadget_unmap_request(&dwc->gadget, |
4886 |
++ &req->request, req->direction); |
4887 |
++ } |
4888 |
+ |
4889 |
+ trace_dwc3_gadget_giveback(req); |
4890 |
+ |
4891 |
+@@ -194,6 +203,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, |
4892 |
+ usb_gadget_giveback_request(&dep->endpoint, &req->request); |
4893 |
+ spin_lock(&dwc->lock); |
4894 |
+ |
4895 |
++ if (unmap_after_complete) |
4896 |
++ usb_gadget_unmap_request(&dwc->gadget, |
4897 |
++ &req->request, req->direction); |
4898 |
++ |
4899 |
+ if (dep->number > 1) |
4900 |
+ pm_runtime_put(dwc->dev); |
4901 |
+ } |
4902 |
+diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c |
4903 |
+index f6533c68fed1..626d87d545fc 100644 |
4904 |
+--- a/drivers/usb/dwc3/host.c |
4905 |
++++ b/drivers/usb/dwc3/host.c |
4906 |
+@@ -21,11 +21,12 @@ |
4907 |
+ |
4908 |
+ int dwc3_host_init(struct dwc3 *dwc) |
4909 |
+ { |
4910 |
+- struct property_entry props[2]; |
4911 |
++ struct property_entry props[3]; |
4912 |
+ struct platform_device *xhci; |
4913 |
+ int ret, irq; |
4914 |
+ struct resource *res; |
4915 |
+ struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); |
4916 |
++ int prop_idx = 0; |
4917 |
+ |
4918 |
+ irq = platform_get_irq_byname(dwc3_pdev, "host"); |
4919 |
+ if (irq == -EPROBE_DEFER) |
4920 |
+@@ -89,8 +90,22 @@ int dwc3_host_init(struct dwc3 *dwc) |
4921 |
+ |
4922 |
+ memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); |
4923 |
+ |
4924 |
+- if (dwc->usb3_lpm_capable) { |
4925 |
+- props[0].name = "usb3-lpm-capable"; |
4926 |
++ if (dwc->usb3_lpm_capable) |
4927 |
++ props[prop_idx++].name = "usb3-lpm-capable"; |
4928 |
++ |
4929 |
++ /** |
4930 |
++ * WORKAROUND: dwc3 revisions <=3.00a have a limitation |
4931 |
++ * where Port Disable command doesn't work. |
4932 |
++ * |
4933 |
++ * The suggested workaround is that we avoid Port Disable |
4934 |
++ * completely. |
4935 |
++ * |
4936 |
++ * This following flag tells XHCI to do just that. |
4937 |
++ */ |
4938 |
++ if (dwc->revision <= DWC3_REVISION_300A) |
4939 |
++ props[prop_idx++].name = "quirk-broken-port-ped"; |
4940 |
++ |
4941 |
++ if (prop_idx) { |
4942 |
+ ret = platform_device_add_properties(xhci, props); |
4943 |
+ if (ret) { |
4944 |
+ dev_err(dwc->dev, "failed to add properties to xHCI\n"); |
4945 |
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c |
4946 |
+index 0ef16900efed..1d41637a53e5 100644 |
4947 |
+--- a/drivers/usb/host/xhci-hub.c |
4948 |
++++ b/drivers/usb/host/xhci-hub.c |
4949 |
+@@ -458,6 +458,12 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, |
4950 |
+ return; |
4951 |
+ } |
4952 |
+ |
4953 |
++ if (xhci->quirks & XHCI_BROKEN_PORT_PED) { |
4954 |
++ xhci_dbg(xhci, |
4955 |
++ "Broken Port Enabled/Disabled, ignoring port disable request.\n"); |
4956 |
++ return; |
4957 |
++ } |
4958 |
++ |
4959 |
+ /* Write 1 to disable the port */ |
4960 |
+ writel(port_status | PORT_PE, addr); |
4961 |
+ port_status = readl(addr); |
4962 |
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c |
4963 |
+index 5895e84f9dcc..be1572331a64 100644 |
4964 |
+--- a/drivers/usb/host/xhci-plat.c |
4965 |
++++ b/drivers/usb/host/xhci-plat.c |
4966 |
+@@ -223,6 +223,9 @@ static int xhci_plat_probe(struct platform_device *pdev) |
4967 |
+ if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) |
4968 |
+ xhci->quirks |= XHCI_LPM_SUPPORT; |
4969 |
+ |
4970 |
++ if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) |
4971 |
++ xhci->quirks |= XHCI_BROKEN_PORT_PED; |
4972 |
++ |
4973 |
+ hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); |
4974 |
+ if (IS_ERR(hcd->usb_phy)) { |
4975 |
+ ret = PTR_ERR(hcd->usb_phy); |
4976 |
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h |
4977 |
+index c525722aa934..f97b009ffc40 100644 |
4978 |
+--- a/drivers/usb/host/xhci.h |
4979 |
++++ b/drivers/usb/host/xhci.h |
4980 |
+@@ -1657,6 +1657,9 @@ struct xhci_hcd { |
4981 |
+ #define XHCI_SSIC_PORT_UNUSED (1 << 22) |
4982 |
+ #define XHCI_NO_64BIT_SUPPORT (1 << 23) |
4983 |
+ #define XHCI_MISSING_CAS (1 << 24) |
4984 |
++/* For controller with a broken Port Disable implementation */ |
4985 |
++#define XHCI_BROKEN_PORT_PED (1 << 25) |
4986 |
++ |
4987 |
+ unsigned int num_active_eps; |
4988 |
+ unsigned int limit_active_eps; |
4989 |
+ /* There are two roothubs to keep track of bus suspend info for */ |
4990 |
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h |
4991 |
+index 16cc18369111..9129f6cb8230 100644 |
4992 |
+--- a/drivers/usb/storage/unusual_devs.h |
4993 |
++++ b/drivers/usb/storage/unusual_devs.h |
4994 |
+@@ -2071,6 +2071,20 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, |
4995 |
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
4996 |
+ US_FL_IGNORE_RESIDUE ), |
4997 |
+ |
4998 |
++/* |
4999 |
++ * Reported by Tobias Jakobi <tjakobi@××××××××××××××××××.de> |
5000 |
++ * The INIC-3619 bridge is used in the StarTech SLSODDU33B |
5001 |
++ * SATA-USB enclosure for slimline optical drives. |
5002 |
++ * |
5003 |
++ * The quirk enables MakeMKV to properly exchange keys with |
5004 |
++ * an installed BD drive. |
5005 |
++ */ |
5006 |
++UNUSUAL_DEV( 0x13fd, 0x3609, 0x0209, 0x0209, |
5007 |
++ "Initio Corporation", |
5008 |
++ "INIC-3619", |
5009 |
++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
5010 |
++ US_FL_IGNORE_RESIDUE ), |
5011 |
++ |
5012 |
+ /* Reported by Qinglin Ye <yestyle@×××××.com> */ |
5013 |
+ UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, |
5014 |
+ "Kingston", |
5015 |
+diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c |
5016 |
+index 59e95762a6de..c5a567a73f59 100644 |
5017 |
+--- a/drivers/watchdog/s3c2410_wdt.c |
5018 |
++++ b/drivers/watchdog/s3c2410_wdt.c |
5019 |
+@@ -46,6 +46,7 @@ |
5020 |
+ #define S3C2410_WTCON 0x00 |
5021 |
+ #define S3C2410_WTDAT 0x04 |
5022 |
+ #define S3C2410_WTCNT 0x08 |
5023 |
++#define S3C2410_WTCLRINT 0x0c |
5024 |
+ |
5025 |
+ #define S3C2410_WTCNT_MAXCNT 0xffff |
5026 |
+ |
5027 |
+@@ -72,6 +73,7 @@ |
5028 |
+ #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c |
5029 |
+ #define QUIRK_HAS_PMU_CONFIG (1 << 0) |
5030 |
+ #define QUIRK_HAS_RST_STAT (1 << 1) |
5031 |
++#define QUIRK_HAS_WTCLRINT_REG (1 << 2) |
5032 |
+ |
5033 |
+ /* These quirks require that we have a PMU register map */ |
5034 |
+ #define QUIRKS_HAVE_PMUREG (QUIRK_HAS_PMU_CONFIG | \ |
5035 |
+@@ -143,13 +145,18 @@ static const struct s3c2410_wdt_variant drv_data_s3c2410 = { |
5036 |
+ }; |
5037 |
+ |
5038 |
+ #ifdef CONFIG_OF |
5039 |
++static const struct s3c2410_wdt_variant drv_data_s3c6410 = { |
5040 |
++ .quirks = QUIRK_HAS_WTCLRINT_REG, |
5041 |
++}; |
5042 |
++ |
5043 |
+ static const struct s3c2410_wdt_variant drv_data_exynos5250 = { |
5044 |
+ .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, |
5045 |
+ .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, |
5046 |
+ .mask_bit = 20, |
5047 |
+ .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, |
5048 |
+ .rst_stat_bit = 20, |
5049 |
+- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, |
5050 |
++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ |
5051 |
++ | QUIRK_HAS_WTCLRINT_REG, |
5052 |
+ }; |
5053 |
+ |
5054 |
+ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { |
5055 |
+@@ -158,7 +165,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { |
5056 |
+ .mask_bit = 0, |
5057 |
+ .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, |
5058 |
+ .rst_stat_bit = 9, |
5059 |
+- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, |
5060 |
++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ |
5061 |
++ | QUIRK_HAS_WTCLRINT_REG, |
5062 |
+ }; |
5063 |
+ |
5064 |
+ static const struct s3c2410_wdt_variant drv_data_exynos7 = { |
5065 |
+@@ -167,12 +175,15 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { |
5066 |
+ .mask_bit = 23, |
5067 |
+ .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, |
5068 |
+ .rst_stat_bit = 23, /* A57 WDTRESET */ |
5069 |
+- .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, |
5070 |
++ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ |
5071 |
++ | QUIRK_HAS_WTCLRINT_REG, |
5072 |
+ }; |
5073 |
+ |
5074 |
+ static const struct of_device_id s3c2410_wdt_match[] = { |
5075 |
+ { .compatible = "samsung,s3c2410-wdt", |
5076 |
+ .data = &drv_data_s3c2410 }, |
5077 |
++ { .compatible = "samsung,s3c6410-wdt", |
5078 |
++ .data = &drv_data_s3c6410 }, |
5079 |
+ { .compatible = "samsung,exynos5250-wdt", |
5080 |
+ .data = &drv_data_exynos5250 }, |
5081 |
+ { .compatible = "samsung,exynos5420-wdt", |
5082 |
+@@ -418,6 +429,10 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param) |
5083 |
+ dev_info(wdt->dev, "watchdog timer expired (irq)\n"); |
5084 |
+ |
5085 |
+ s3c2410wdt_keepalive(&wdt->wdt_device); |
5086 |
++ |
5087 |
++ if (wdt->drv_data->quirks & QUIRK_HAS_WTCLRINT_REG) |
5088 |
++ writel(0x1, wdt->reg_base + S3C2410_WTCLRINT); |
5089 |
++ |
5090 |
+ return IRQ_HANDLED; |
5091 |
+ } |
5092 |
+ |
5093 |
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c |
5094 |
+index 87457227812c..bdd32925a15e 100644 |
5095 |
+--- a/fs/cifs/smb2pdu.c |
5096 |
++++ b/fs/cifs/smb2pdu.c |
5097 |
+@@ -1104,6 +1104,10 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, |
5098 |
+ return -EINVAL; |
5099 |
+ } |
5100 |
+ |
5101 |
++ /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */ |
5102 |
++ if (tcon) |
5103 |
++ tcon->tid = 0; |
5104 |
++ |
5105 |
+ rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req); |
5106 |
+ if (rc) { |
5107 |
+ kfree(unc_path); |
5108 |
+diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c |
5109 |
+index 67c24351a67f..cd261c8de53a 100644 |
5110 |
+--- a/fs/orangefs/super.c |
5111 |
++++ b/fs/orangefs/super.c |
5112 |
+@@ -263,8 +263,13 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb) |
5113 |
+ if (!new_op) |
5114 |
+ return -ENOMEM; |
5115 |
+ new_op->upcall.req.features.features = 0; |
5116 |
+- ret = service_operation(new_op, "orangefs_features", 0); |
5117 |
+- orangefs_features = new_op->downcall.resp.features.features; |
5118 |
++ ret = service_operation(new_op, "orangefs_features", |
5119 |
++ ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_MUTEX); |
5120 |
++ if (!ret) |
5121 |
++ orangefs_features = |
5122 |
++ new_op->downcall.resp.features.features; |
5123 |
++ else |
5124 |
++ orangefs_features = 0; |
5125 |
+ op_release(new_op); |
5126 |
+ } else { |
5127 |
+ orangefs_features = 0; |
5128 |
+diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c |
5129 |
+index b803213d1307..39c75a86c67f 100644 |
5130 |
+--- a/fs/sysfs/file.c |
5131 |
++++ b/fs/sysfs/file.c |
5132 |
+@@ -108,7 +108,7 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, |
5133 |
+ { |
5134 |
+ const struct sysfs_ops *ops = sysfs_file_ops(of->kn); |
5135 |
+ struct kobject *kobj = of->kn->parent->priv; |
5136 |
+- size_t len; |
5137 |
++ ssize_t len; |
5138 |
+ |
5139 |
+ /* |
5140 |
+ * If buf != of->prealloc_buf, we don't know how |
5141 |
+@@ -117,13 +117,15 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, |
5142 |
+ if (WARN_ON_ONCE(buf != of->prealloc_buf)) |
5143 |
+ return 0; |
5144 |
+ len = ops->show(kobj, of->kn->priv, buf); |
5145 |
++ if (len < 0) |
5146 |
++ return len; |
5147 |
+ if (pos) { |
5148 |
+ if (len <= pos) |
5149 |
+ return 0; |
5150 |
+ len -= pos; |
5151 |
+ memmove(buf, buf + pos, len); |
5152 |
+ } |
5153 |
+- return min(count, len); |
5154 |
++ return min_t(ssize_t, count, len); |
5155 |
+ } |
5156 |
+ |
5157 |
+ /* kernfs write callback for regular sysfs files */ |
5158 |
+diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c |
5159 |
+index 5c395e485170..5328ecdd03d4 100644 |
5160 |
+--- a/fs/xfs/xfs_bmap_util.c |
5161 |
++++ b/fs/xfs/xfs_bmap_util.c |
5162 |
+@@ -1318,8 +1318,16 @@ xfs_free_file_space( |
5163 |
+ /* |
5164 |
+ * Now that we've unmap all full blocks we'll have to zero out any |
5165 |
+ * partial block at the beginning and/or end. xfs_zero_range is |
5166 |
+- * smart enough to skip any holes, including those we just created. |
5167 |
++ * smart enough to skip any holes, including those we just created, |
5168 |
++ * but we must take care not to zero beyond EOF and enlarge i_size. |
5169 |
+ */ |
5170 |
++ |
5171 |
++ if (offset >= XFS_ISIZE(ip)) |
5172 |
++ return 0; |
5173 |
++ |
5174 |
++ if (offset + len > XFS_ISIZE(ip)) |
5175 |
++ len = XFS_ISIZE(ip) - offset; |
5176 |
++ |
5177 |
+ return xfs_zero_range(ip, offset, len, NULL); |
5178 |
+ } |
5179 |
+ |
5180 |
+diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h |
5181 |
+index 0d5f4268d75f..61766a420f6b 100644 |
5182 |
+--- a/include/drm/i915_pciids.h |
5183 |
++++ b/include/drm/i915_pciids.h |
5184 |
+@@ -226,23 +226,18 @@ |
5185 |
+ INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ |
5186 |
+ INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ |
5187 |
+ |
5188 |
+-#define INTEL_BDW_RSVDM_IDS(info) \ |
5189 |
++#define INTEL_BDW_RSVD_IDS(info) \ |
5190 |
+ INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \ |
5191 |
+ INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \ |
5192 |
+ INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \ |
5193 |
+- INTEL_VGA_DEVICE(0x163E, info) /* ULX */ |
5194 |
+- |
5195 |
+-#define INTEL_BDW_RSVDD_IDS(info) \ |
5196 |
++ INTEL_VGA_DEVICE(0x163E, info), /* ULX */ \ |
5197 |
+ INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ |
5198 |
+ INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ |
5199 |
+ |
5200 |
+ #define INTEL_BDW_IDS(info) \ |
5201 |
+ INTEL_BDW_GT12_IDS(info), \ |
5202 |
+ INTEL_BDW_GT3_IDS(info), \ |
5203 |
+- INTEL_BDW_RSVDM_IDS(info), \ |
5204 |
+- INTEL_BDW_GT12_IDS(info), \ |
5205 |
+- INTEL_BDW_GT3_IDS(info), \ |
5206 |
+- INTEL_BDW_RSVDD_IDS(info) |
5207 |
++ INTEL_BDW_RSVD_IDS(info) |
5208 |
+ |
5209 |
+ #define INTEL_CHV_IDS(info) \ |
5210 |
+ INTEL_VGA_DEVICE(0x22b0, info), \ |
5211 |
+diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h |
5212 |
+index ed953f98f0e1..1487011fe057 100644 |
5213 |
+--- a/include/drm/ttm/ttm_object.h |
5214 |
++++ b/include/drm/ttm/ttm_object.h |
5215 |
+@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); |
5216 |
+ * @ref_type: The type of reference. |
5217 |
+ * @existed: Upon completion, indicates that an identical reference object |
5218 |
+ * already existed, and the refcount was upped on that object instead. |
5219 |
++ * @require_existed: Fail with -EPERM if an identical ref object didn't |
5220 |
++ * already exist. |
5221 |
+ * |
5222 |
+ * Checks that the base object is shareable and adds a ref object to it. |
5223 |
+ * |
5224 |
+@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base); |
5225 |
+ */ |
5226 |
+ extern int ttm_ref_object_add(struct ttm_object_file *tfile, |
5227 |
+ struct ttm_base_object *base, |
5228 |
+- enum ttm_ref_type ref_type, bool *existed); |
5229 |
++ enum ttm_ref_type ref_type, bool *existed, |
5230 |
++ bool require_existed); |
5231 |
+ |
5232 |
+ extern bool ttm_ref_object_exists(struct ttm_object_file *tfile, |
5233 |
+ struct ttm_base_object *base); |
5234 |
+diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h |
5235 |
+index b5abfda80465..4c5bca38c653 100644 |
5236 |
+--- a/include/linux/arm-smccc.h |
5237 |
++++ b/include/linux/arm-smccc.h |
5238 |
+@@ -14,9 +14,6 @@ |
5239 |
+ #ifndef __LINUX_ARM_SMCCC_H |
5240 |
+ #define __LINUX_ARM_SMCCC_H |
5241 |
+ |
5242 |
+-#include <linux/linkage.h> |
5243 |
+-#include <linux/types.h> |
5244 |
+- |
5245 |
+ /* |
5246 |
+ * This file provides common defines for ARM SMC Calling Convention as |
5247 |
+ * specified in |
5248 |
+@@ -60,6 +57,13 @@ |
5249 |
+ #define ARM_SMCCC_OWNER_TRUSTED_OS 50 |
5250 |
+ #define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 |
5251 |
+ |
5252 |
++#define ARM_SMCCC_QUIRK_NONE 0 |
5253 |
++#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ |
5254 |
++ |
5255 |
++#ifndef __ASSEMBLY__ |
5256 |
++ |
5257 |
++#include <linux/linkage.h> |
5258 |
++#include <linux/types.h> |
5259 |
+ /** |
5260 |
+ * struct arm_smccc_res - Result from SMC/HVC call |
5261 |
+ * @a0-a3 result values from registers 0 to 3 |
5262 |
+@@ -72,33 +76,59 @@ struct arm_smccc_res { |
5263 |
+ }; |
5264 |
+ |
5265 |
+ /** |
5266 |
+- * arm_smccc_smc() - make SMC calls |
5267 |
++ * struct arm_smccc_quirk - Contains quirk information |
5268 |
++ * @id: quirk identification |
5269 |
++ * @state: quirk specific information |
5270 |
++ * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 |
5271 |
++ */ |
5272 |
++struct arm_smccc_quirk { |
5273 |
++ int id; |
5274 |
++ union { |
5275 |
++ unsigned long a6; |
5276 |
++ } state; |
5277 |
++}; |
5278 |
++ |
5279 |
++/** |
5280 |
++ * __arm_smccc_smc() - make SMC calls |
5281 |
+ * @a0-a7: arguments passed in registers 0 to 7 |
5282 |
+ * @res: result values from registers 0 to 3 |
5283 |
++ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. |
5284 |
+ * |
5285 |
+ * This function is used to make SMC calls following SMC Calling Convention. |
5286 |
+ * The content of the supplied param are copied to registers 0 to 7 prior |
5287 |
+ * to the SMC instruction. The return values are updated with the content |
5288 |
+- * from register 0 to 3 on return from the SMC instruction. |
5289 |
++ * from register 0 to 3 on return from the SMC instruction. An optional |
5290 |
++ * quirk structure provides vendor specific behavior. |
5291 |
+ */ |
5292 |
+-asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1, |
5293 |
++asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1, |
5294 |
+ unsigned long a2, unsigned long a3, unsigned long a4, |
5295 |
+ unsigned long a5, unsigned long a6, unsigned long a7, |
5296 |
+- struct arm_smccc_res *res); |
5297 |
++ struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); |
5298 |
+ |
5299 |
+ /** |
5300 |
+- * arm_smccc_hvc() - make HVC calls |
5301 |
++ * __arm_smccc_hvc() - make HVC calls |
5302 |
+ * @a0-a7: arguments passed in registers 0 to 7 |
5303 |
+ * @res: result values from registers 0 to 3 |
5304 |
++ * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. |
5305 |
+ * |
5306 |
+ * This function is used to make HVC calls following SMC Calling |
5307 |
+ * Convention. The content of the supplied param are copied to registers 0 |
5308 |
+ * to 7 prior to the HVC instruction. The return values are updated with |
5309 |
+- * the content from register 0 to 3 on return from the HVC instruction. |
5310 |
++ * the content from register 0 to 3 on return from the HVC instruction. An |
5311 |
++ * optional quirk structure provides vendor specific behavior. |
5312 |
+ */ |
5313 |
+-asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1, |
5314 |
++asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, |
5315 |
+ unsigned long a2, unsigned long a3, unsigned long a4, |
5316 |
+ unsigned long a5, unsigned long a6, unsigned long a7, |
5317 |
+- struct arm_smccc_res *res); |
5318 |
++ struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); |
5319 |
++ |
5320 |
++#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL) |
5321 |
++ |
5322 |
++#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__) |
5323 |
++ |
5324 |
++#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL) |
5325 |
++ |
5326 |
++#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) |
5327 |
+ |
5328 |
++#endif /*__ASSEMBLY__*/ |
5329 |
+ #endif /*__LINUX_ARM_SMCCC_H*/ |
5330 |
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h |
5331 |
+index f020ab4079d3..3e5dbbe75f70 100644 |
5332 |
+--- a/include/linux/pci_ids.h |
5333 |
++++ b/include/linux/pci_ids.h |
5334 |
+@@ -2513,6 +2513,8 @@ |
5335 |
+ #define PCI_DEVICE_ID_KORENIX_JETCARDF2 0x1700 |
5336 |
+ #define PCI_DEVICE_ID_KORENIX_JETCARDF3 0x17ff |
5337 |
+ |
5338 |
++#define PCI_VENDOR_ID_HUAWEI 0x19e5 |
5339 |
++ |
5340 |
+ #define PCI_VENDOR_ID_NETRONOME 0x19ee |
5341 |
+ #define PCI_DEVICE_ID_NETRONOME_NFP3200 0x3200 |
5342 |
+ #define PCI_DEVICE_ID_NETRONOME_NFP3240 0x3240 |
5343 |
+diff --git a/include/linux/random.h b/include/linux/random.h |
5344 |
+index 7bd2403e4fef..16ab429735a7 100644 |
5345 |
+--- a/include/linux/random.h |
5346 |
++++ b/include/linux/random.h |
5347 |
+@@ -37,7 +37,6 @@ extern void get_random_bytes(void *buf, int nbytes); |
5348 |
+ extern int add_random_ready_callback(struct random_ready_callback *rdy); |
5349 |
+ extern void del_random_ready_callback(struct random_ready_callback *rdy); |
5350 |
+ extern void get_random_bytes_arch(void *buf, int nbytes); |
5351 |
+-extern int random_int_secret_init(void); |
5352 |
+ |
5353 |
+ #ifndef MODULE |
5354 |
+ extern const struct file_operations random_fops, urandom_fops; |
5355 |
+diff --git a/init/main.c b/init/main.c |
5356 |
+index 2858be732f6d..ae3996ae9bac 100644 |
5357 |
+--- a/init/main.c |
5358 |
++++ b/init/main.c |
5359 |
+@@ -868,7 +868,6 @@ static void __init do_basic_setup(void) |
5360 |
+ do_ctors(); |
5361 |
+ usermodehelper_enable(); |
5362 |
+ do_initcalls(); |
5363 |
+- random_int_secret_init(); |
5364 |
+ } |
5365 |
+ |
5366 |
+ static void __init do_pre_smp_initcalls(void) |
5367 |
+diff --git a/kernel/ptrace.c b/kernel/ptrace.c |
5368 |
+index 49ba7c1ade9d..a5caecef88be 100644 |
5369 |
+--- a/kernel/ptrace.c |
5370 |
++++ b/kernel/ptrace.c |
5371 |
+@@ -181,11 +181,17 @@ static void ptrace_unfreeze_traced(struct task_struct *task) |
5372 |
+ |
5373 |
+ WARN_ON(!task->ptrace || task->parent != current); |
5374 |
+ |
5375 |
++ /* |
5376 |
++ * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely. |
5377 |
++ * Recheck state under the lock to close this race. |
5378 |
++ */ |
5379 |
+ spin_lock_irq(&task->sighand->siglock); |
5380 |
+- if (__fatal_signal_pending(task)) |
5381 |
+- wake_up_state(task, __TASK_TRACED); |
5382 |
+- else |
5383 |
+- task->state = TASK_TRACED; |
5384 |
++ if (task->state == __TASK_TRACED) { |
5385 |
++ if (__fatal_signal_pending(task)) |
5386 |
++ wake_up_state(task, __TASK_TRACED); |
5387 |
++ else |
5388 |
++ task->state = TASK_TRACED; |
5389 |
++ } |
5390 |
+ spin_unlock_irq(&task->sighand->siglock); |
5391 |
+ } |
5392 |
+ |
5393 |
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c |
5394 |
+index 9c143739b8d7..f30847af7310 100644 |
5395 |
+--- a/kernel/trace/ring_buffer.c |
5396 |
++++ b/kernel/trace/ring_buffer.c |
5397 |
+@@ -4870,9 +4870,9 @@ static __init int test_ringbuffer(void) |
5398 |
+ rb_data[cpu].cnt = cpu; |
5399 |
+ rb_threads[cpu] = kthread_create(rb_test, &rb_data[cpu], |
5400 |
+ "rbtester/%d", cpu); |
5401 |
+- if (WARN_ON(!rb_threads[cpu])) { |
5402 |
++ if (WARN_ON(IS_ERR(rb_threads[cpu]))) { |
5403 |
+ pr_cont("FAILED\n"); |
5404 |
+- ret = -1; |
5405 |
++ ret = PTR_ERR(rb_threads[cpu]); |
5406 |
+ goto out_free; |
5407 |
+ } |
5408 |
+ |
5409 |
+@@ -4882,9 +4882,9 @@ static __init int test_ringbuffer(void) |
5410 |
+ |
5411 |
+ /* Now create the rb hammer! */ |
5412 |
+ rb_hammer = kthread_run(rb_hammer_test, NULL, "rbhammer"); |
5413 |
+- if (WARN_ON(!rb_hammer)) { |
5414 |
++ if (WARN_ON(IS_ERR(rb_hammer))) { |
5415 |
+ pr_cont("FAILED\n"); |
5416 |
+- ret = -1; |
5417 |
++ ret = PTR_ERR(rb_hammer); |
5418 |
+ goto out_free; |
5419 |
+ } |
5420 |
+ |
5421 |
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
5422 |
+index f75704717e47..23471526d424 100644 |
5423 |
+--- a/mm/mempolicy.c |
5424 |
++++ b/mm/mempolicy.c |
5425 |
+@@ -1524,7 +1524,6 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, int __user *, policy, |
5426 |
+ COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, |
5427 |
+ compat_ulong_t, maxnode) |
5428 |
+ { |
5429 |
+- long err = 0; |
5430 |
+ unsigned long __user *nm = NULL; |
5431 |
+ unsigned long nr_bits, alloc_size; |
5432 |
+ DECLARE_BITMAP(bm, MAX_NUMNODES); |
5433 |
+@@ -1533,14 +1532,13 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, |
5434 |
+ alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; |
5435 |
+ |
5436 |
+ if (nmask) { |
5437 |
+- err = compat_get_bitmap(bm, nmask, nr_bits); |
5438 |
++ if (compat_get_bitmap(bm, nmask, nr_bits)) |
5439 |
++ return -EFAULT; |
5440 |
+ nm = compat_alloc_user_space(alloc_size); |
5441 |
+- err |= copy_to_user(nm, bm, alloc_size); |
5442 |
++ if (copy_to_user(nm, bm, alloc_size)) |
5443 |
++ return -EFAULT; |
5444 |
+ } |
5445 |
+ |
5446 |
+- if (err) |
5447 |
+- return -EFAULT; |
5448 |
+- |
5449 |
+ return sys_set_mempolicy(mode, nm, nr_bits+1); |
5450 |
+ } |
5451 |
+ |
5452 |
+@@ -1548,7 +1546,6 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, |
5453 |
+ compat_ulong_t, mode, compat_ulong_t __user *, nmask, |
5454 |
+ compat_ulong_t, maxnode, compat_ulong_t, flags) |
5455 |
+ { |
5456 |
+- long err = 0; |
5457 |
+ unsigned long __user *nm = NULL; |
5458 |
+ unsigned long nr_bits, alloc_size; |
5459 |
+ nodemask_t bm; |
5460 |
+@@ -1557,14 +1554,13 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len, |
5461 |
+ alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; |
5462 |
+ |
5463 |
+ if (nmask) { |
5464 |
+- err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits); |
5465 |
++ if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits)) |
5466 |
++ return -EFAULT; |
5467 |
+ nm = compat_alloc_user_space(alloc_size); |
5468 |
+- err |= copy_to_user(nm, nodes_addr(bm), alloc_size); |
5469 |
++ if (copy_to_user(nm, nodes_addr(bm), alloc_size)) |
5470 |
++ return -EFAULT; |
5471 |
+ } |
5472 |
+ |
5473 |
+- if (err) |
5474 |
+- return -EFAULT; |
5475 |
+- |
5476 |
+ return sys_mbind(start, len, mode, nm, nr_bits+1, flags); |
5477 |
+ } |
5478 |
+ |
5479 |
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
5480 |
+index 1460e6ad5e14..e5b159b88e39 100644 |
5481 |
+--- a/mm/page_alloc.c |
5482 |
++++ b/mm/page_alloc.c |
5483 |
+@@ -4345,13 +4345,13 @@ void show_free_areas(unsigned int filter) |
5484 |
+ K(node_page_state(pgdat, NR_FILE_MAPPED)), |
5485 |
+ K(node_page_state(pgdat, NR_FILE_DIRTY)), |
5486 |
+ K(node_page_state(pgdat, NR_WRITEBACK)), |
5487 |
++ K(node_page_state(pgdat, NR_SHMEM)), |
5488 |
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
5489 |
+ K(node_page_state(pgdat, NR_SHMEM_THPS) * HPAGE_PMD_NR), |
5490 |
+ K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) |
5491 |
+ * HPAGE_PMD_NR), |
5492 |
+ K(node_page_state(pgdat, NR_ANON_THPS) * HPAGE_PMD_NR), |
5493 |
+ #endif |
5494 |
+- K(node_page_state(pgdat, NR_SHMEM)), |
5495 |
+ K(node_page_state(pgdat, NR_WRITEBACK_TEMP)), |
5496 |
+ K(node_page_state(pgdat, NR_UNSTABLE_NFS)), |
5497 |
+ node_page_state(pgdat, NR_PAGES_SCANNED), |
5498 |
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c |
5499 |
+index 638ec0759078..8d7747e98fdb 100644 |
5500 |
+--- a/net/mac80211/iface.c |
5501 |
++++ b/net/mac80211/iface.c |
5502 |
+@@ -726,7 +726,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) |
5503 |
+ ieee80211_recalc_ps(local); |
5504 |
+ |
5505 |
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
5506 |
+- sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
5507 |
++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
5508 |
++ local->ops->wake_tx_queue) { |
5509 |
+ /* XXX: for AP_VLAN, actually track AP queues */ |
5510 |
+ netif_tx_start_all_queues(dev); |
5511 |
+ } else if (dev) { |
5512 |
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c |
5513 |
+index 6fdffde28733..153082598522 100644 |
5514 |
+--- a/net/sunrpc/auth_gss/svcauth_gss.c |
5515 |
++++ b/net/sunrpc/auth_gss/svcauth_gss.c |
5516 |
+@@ -1548,7 +1548,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) |
5517 |
+ ret = SVC_COMPLETE; |
5518 |
+ goto out; |
5519 |
+ drop: |
5520 |
+- ret = SVC_DROP; |
5521 |
++ ret = SVC_CLOSE; |
5522 |
+ out: |
5523 |
+ if (rsci) |
5524 |
+ cache_put(&rsci->h, sn->rsc_cache); |
5525 |
+diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c |
5526 |
+index 7c8070ec93c8..75f290bddca1 100644 |
5527 |
+--- a/net/sunrpc/svc.c |
5528 |
++++ b/net/sunrpc/svc.c |
5529 |
+@@ -1155,8 +1155,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) |
5530 |
+ case SVC_DENIED: |
5531 |
+ goto err_bad_auth; |
5532 |
+ case SVC_CLOSE: |
5533 |
+- if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) |
5534 |
+- svc_close_xprt(rqstp->rq_xprt); |
5535 |
++ goto close; |
5536 |
+ case SVC_DROP: |
5537 |
+ goto dropit; |
5538 |
+ case SVC_COMPLETE: |
5539 |
+@@ -1246,7 +1245,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) |
5540 |
+ |
5541 |
+ sendit: |
5542 |
+ if (svc_authorise(rqstp)) |
5543 |
+- goto dropit; |
5544 |
++ goto close; |
5545 |
+ return 1; /* Caller can now send it */ |
5546 |
+ |
5547 |
+ dropit: |
5548 |
+@@ -1254,11 +1253,16 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) |
5549 |
+ dprintk("svc: svc_process dropit\n"); |
5550 |
+ return 0; |
5551 |
+ |
5552 |
++ close: |
5553 |
++ if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) |
5554 |
++ svc_close_xprt(rqstp->rq_xprt); |
5555 |
++ dprintk("svc: svc_process close\n"); |
5556 |
++ return 0; |
5557 |
++ |
5558 |
+ err_short_len: |
5559 |
+ svc_printk(rqstp, "short len %Zd, dropping request\n", |
5560 |
+ argv->iov_len); |
5561 |
+- |
5562 |
+- goto dropit; /* drop request */ |
5563 |
++ goto close; |
5564 |
+ |
5565 |
+ err_bad_rpc: |
5566 |
+ serv->sv_stats->rpcbadfmt++; |
5567 |
+diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c |
5568 |
+index 14b3f007826d..2927d06faa6e 100644 |
5569 |
+--- a/net/wireless/sysfs.c |
5570 |
++++ b/net/wireless/sysfs.c |
5571 |
+@@ -130,12 +130,10 @@ static int wiphy_resume(struct device *dev) |
5572 |
+ /* Age scan results with time spent in suspend */ |
5573 |
+ cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at); |
5574 |
+ |
5575 |
+- if (rdev->ops->resume) { |
5576 |
+- rtnl_lock(); |
5577 |
+- if (rdev->wiphy.registered) |
5578 |
+- ret = rdev_resume(rdev); |
5579 |
+- rtnl_unlock(); |
5580 |
+- } |
5581 |
++ rtnl_lock(); |
5582 |
++ if (rdev->wiphy.registered && rdev->ops->resume) |
5583 |
++ ret = rdev_resume(rdev); |
5584 |
++ rtnl_unlock(); |
5585 |
+ |
5586 |
+ return ret; |
5587 |
+ } |
5588 |
+diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c |
5589 |
+index 49caf1393aeb..fdc14e50d3b9 100644 |
5590 |
+--- a/sound/soc/codecs/rt5670.c |
5591 |
++++ b/sound/soc/codecs/rt5670.c |
5592 |
+@@ -2813,6 +2813,8 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); |
5593 |
+ #ifdef CONFIG_ACPI |
5594 |
+ static const struct acpi_device_id rt5670_acpi_match[] = { |
5595 |
+ { "10EC5670", 0}, |
5596 |
++ { "10EC5672", 0}, |
5597 |
++ { "10EC5640", 0}, /* quirk */ |
5598 |
+ { }, |
5599 |
+ }; |
5600 |
+ MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); |
5601 |
+diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c |
5602 |
+index 0a88537ca58a..0bfa68862460 100644 |
5603 |
+--- a/sound/soc/intel/atom/sst/sst_acpi.c |
5604 |
++++ b/sound/soc/intel/atom/sst/sst_acpi.c |
5605 |
+@@ -400,6 +400,7 @@ static int sst_acpi_remove(struct platform_device *pdev) |
5606 |
+ static unsigned long cht_machine_id; |
5607 |
+ |
5608 |
+ #define CHT_SURFACE_MACH 1 |
5609 |
++#define BYT_THINKPAD_10 2 |
5610 |
+ |
5611 |
+ static int cht_surface_quirk_cb(const struct dmi_system_id *id) |
5612 |
+ { |
5613 |
+@@ -407,6 +408,23 @@ static int cht_surface_quirk_cb(const struct dmi_system_id *id) |
5614 |
+ return 1; |
5615 |
+ } |
5616 |
+ |
5617 |
++static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id) |
5618 |
++{ |
5619 |
++ cht_machine_id = BYT_THINKPAD_10; |
5620 |
++ return 1; |
5621 |
++} |
5622 |
++ |
5623 |
++ |
5624 |
++static const struct dmi_system_id byt_table[] = { |
5625 |
++ { |
5626 |
++ .callback = byt_thinkpad10_quirk_cb, |
5627 |
++ .matches = { |
5628 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
5629 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"), |
5630 |
++ }, |
5631 |
++ }, |
5632 |
++ { } |
5633 |
++}; |
5634 |
+ |
5635 |
+ static const struct dmi_system_id cht_table[] = { |
5636 |
+ { |
5637 |
+@@ -424,6 +442,10 @@ static struct sst_acpi_mach cht_surface_mach = { |
5638 |
+ "10EC5640", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, |
5639 |
+ &chv_platform_data }; |
5640 |
+ |
5641 |
++static struct sst_acpi_mach byt_thinkpad_10 = { |
5642 |
++ "10EC5640", "cht-bsw-rt5672", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, |
5643 |
++ &byt_rvp_platform_data }; |
5644 |
++ |
5645 |
+ static struct sst_acpi_mach *cht_quirk(void *arg) |
5646 |
+ { |
5647 |
+ struct sst_acpi_mach *mach = arg; |
5648 |
+@@ -436,8 +458,21 @@ static struct sst_acpi_mach *cht_quirk(void *arg) |
5649 |
+ return mach; |
5650 |
+ } |
5651 |
+ |
5652 |
++static struct sst_acpi_mach *byt_quirk(void *arg) |
5653 |
++{ |
5654 |
++ struct sst_acpi_mach *mach = arg; |
5655 |
++ |
5656 |
++ dmi_check_system(byt_table); |
5657 |
++ |
5658 |
++ if (cht_machine_id == BYT_THINKPAD_10) |
5659 |
++ return &byt_thinkpad_10; |
5660 |
++ else |
5661 |
++ return mach; |
5662 |
++} |
5663 |
++ |
5664 |
++ |
5665 |
+ static struct sst_acpi_mach sst_acpi_bytcr[] = { |
5666 |
+- {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, |
5667 |
++ {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", byt_quirk, |
5668 |
+ &byt_rvp_platform_data }, |
5669 |
+ {"10EC5642", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, |
5670 |
+ &byt_rvp_platform_data }, |
5671 |
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c |
5672 |
+index bff77a1f27fc..4c8ff298ad26 100644 |
5673 |
+--- a/sound/soc/intel/boards/bytcr_rt5640.c |
5674 |
++++ b/sound/soc/intel/boards/bytcr_rt5640.c |
5675 |
+@@ -57,9 +57,7 @@ struct byt_rt5640_private { |
5676 |
+ struct clk *mclk; |
5677 |
+ }; |
5678 |
+ |
5679 |
+-static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | |
5680 |
+- BYT_RT5640_DMIC_EN | |
5681 |
+- BYT_RT5640_MCLK_EN; |
5682 |
++static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN; |
5683 |
+ |
5684 |
+ static void log_quirks(struct device *dev) |
5685 |
+ { |
5686 |
+@@ -389,6 +387,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { |
5687 |
+ BYT_RT5640_SSP0_AIF1), |
5688 |
+ |
5689 |
+ }, |
5690 |
++ { |
5691 |
++ .callback = byt_rt5640_quirk_cb, |
5692 |
++ .matches = { |
5693 |
++ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), |
5694 |
++ }, |
5695 |
++ .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | |
5696 |
++ BYT_RT5640_MCLK_EN | |
5697 |
++ BYT_RT5640_SSP0_AIF1), |
5698 |
++ |
5699 |
++ }, |
5700 |
+ {} |
5701 |
+ }; |
5702 |
+ |
5703 |
+@@ -738,6 +746,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) |
5704 |
+ if (res_info->acpi_ipc_irq_index == 0) { |
5705 |
+ byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2; |
5706 |
+ } |
5707 |
++ |
5708 |
++ /* change defaults for Baytrail-CR capture */ |
5709 |
++ byt_rt5640_quirk |= BYT_RT5640_IN1_MAP; |
5710 |
++ byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC; |
5711 |
++ } else { |
5712 |
++ byt_rt5640_quirk |= (BYT_RT5640_DMIC1_MAP | |
5713 |
++ BYT_RT5640_DMIC_EN); |
5714 |
+ } |
5715 |
+ |
5716 |
+ /* check quirks before creating card */ |
5717 |
+diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c |
5718 |
+index 16c94c45ce50..90525614c20a 100644 |
5719 |
+--- a/sound/soc/intel/boards/cht_bsw_rt5645.c |
5720 |
++++ b/sound/soc/intel/boards/cht_bsw_rt5645.c |
5721 |
+@@ -24,6 +24,9 @@ |
5722 |
+ #include <linux/acpi.h> |
5723 |
+ #include <linux/platform_device.h> |
5724 |
+ #include <linux/slab.h> |
5725 |
++#include <asm/cpu_device_id.h> |
5726 |
++#include <asm/platform_sst_audio.h> |
5727 |
++#include <linux/clk.h> |
5728 |
+ #include <sound/pcm.h> |
5729 |
+ #include <sound/pcm_params.h> |
5730 |
+ #include <sound/soc.h> |
5731 |
+@@ -45,6 +48,7 @@ struct cht_mc_private { |
5732 |
+ struct snd_soc_jack jack; |
5733 |
+ struct cht_acpi_card *acpi_card; |
5734 |
+ char codec_name[16]; |
5735 |
++ struct clk *mclk; |
5736 |
+ }; |
5737 |
+ |
5738 |
+ static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) |
5739 |
+@@ -65,6 +69,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, |
5740 |
+ struct snd_soc_dapm_context *dapm = w->dapm; |
5741 |
+ struct snd_soc_card *card = dapm->card; |
5742 |
+ struct snd_soc_dai *codec_dai; |
5743 |
++ struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); |
5744 |
+ int ret; |
5745 |
+ |
5746 |
+ codec_dai = cht_get_codec_dai(card); |
5747 |
+@@ -73,19 +78,30 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, |
5748 |
+ return -EIO; |
5749 |
+ } |
5750 |
+ |
5751 |
+- if (!SND_SOC_DAPM_EVENT_OFF(event)) |
5752 |
+- return 0; |
5753 |
++ if (SND_SOC_DAPM_EVENT_ON(event)) { |
5754 |
++ if (ctx->mclk) { |
5755 |
++ ret = clk_prepare_enable(ctx->mclk); |
5756 |
++ if (ret < 0) { |
5757 |
++ dev_err(card->dev, |
5758 |
++ "could not configure MCLK state"); |
5759 |
++ return ret; |
5760 |
++ } |
5761 |
++ } |
5762 |
++ } else { |
5763 |
++ /* Set codec sysclk source to its internal clock because codec PLL will |
5764 |
++ * be off when idle and MCLK will also be off when codec is |
5765 |
++ * runtime suspended. Codec needs clock for jack detection and button |
5766 |
++ * press. MCLK is turned off with clock framework or ACPI. |
5767 |
++ */ |
5768 |
++ ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, |
5769 |
++ 48000 * 512, SND_SOC_CLOCK_IN); |
5770 |
++ if (ret < 0) { |
5771 |
++ dev_err(card->dev, "can't set codec sysclk: %d\n", ret); |
5772 |
++ return ret; |
5773 |
++ } |
5774 |
+ |
5775 |
+- /* Set codec sysclk source to its internal clock because codec PLL will |
5776 |
+- * be off when idle and MCLK will also be off by ACPI when codec is |
5777 |
+- * runtime suspended. Codec needs clock for jack detection and button |
5778 |
+- * press. |
5779 |
+- */ |
5780 |
+- ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, |
5781 |
+- 0, SND_SOC_CLOCK_IN); |
5782 |
+- if (ret < 0) { |
5783 |
+- dev_err(card->dev, "can't set codec sysclk: %d\n", ret); |
5784 |
+- return ret; |
5785 |
++ if (ctx->mclk) |
5786 |
++ clk_disable_unprepare(ctx->mclk); |
5787 |
+ } |
5788 |
+ |
5789 |
+ return 0; |
5790 |
+@@ -97,7 +113,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { |
5791 |
+ SND_SOC_DAPM_MIC("Int Mic", NULL), |
5792 |
+ SND_SOC_DAPM_SPK("Ext Spk", NULL), |
5793 |
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, |
5794 |
+- platform_clock_control, SND_SOC_DAPM_POST_PMD), |
5795 |
++ platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
5796 |
+ }; |
5797 |
+ |
5798 |
+ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { |
5799 |
+@@ -225,6 +241,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) |
5800 |
+ |
5801 |
+ rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); |
5802 |
+ |
5803 |
++ if (ctx->mclk) { |
5804 |
++ /* |
5805 |
++ * The firmware might enable the clock at |
5806 |
++ * boot (this information may or may not |
5807 |
++ * be reflected in the enable clock register). |
5808 |
++ * To change the rate we must disable the clock |
5809 |
++ * first to cover these cases. Due to common |
5810 |
++ * clock framework restrictions that do not allow |
5811 |
++ * to disable a clock that has not been enabled, |
5812 |
++ * we need to enable the clock first. |
5813 |
++ */ |
5814 |
++ ret = clk_prepare_enable(ctx->mclk); |
5815 |
++ if (!ret) |
5816 |
++ clk_disable_unprepare(ctx->mclk); |
5817 |
++ |
5818 |
++ ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); |
5819 |
++ |
5820 |
++ if (ret) |
5821 |
++ dev_err(runtime->dev, "unable to set MCLK rate\n"); |
5822 |
++ } |
5823 |
+ return ret; |
5824 |
+ } |
5825 |
+ |
5826 |
+@@ -349,6 +385,18 @@ static struct cht_acpi_card snd_soc_cards[] = { |
5827 |
+ |
5828 |
+ static char cht_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ |
5829 |
+ |
5830 |
++static bool is_valleyview(void) |
5831 |
++{ |
5832 |
++ static const struct x86_cpu_id cpu_ids[] = { |
5833 |
++ { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ |
5834 |
++ {} |
5835 |
++ }; |
5836 |
++ |
5837 |
++ if (!x86_match_cpu(cpu_ids)) |
5838 |
++ return false; |
5839 |
++ return true; |
5840 |
++} |
5841 |
++ |
5842 |
+ static int snd_cht_mc_probe(struct platform_device *pdev) |
5843 |
+ { |
5844 |
+ int ret_val = 0; |
5845 |
+@@ -358,22 +406,32 @@ static int snd_cht_mc_probe(struct platform_device *pdev) |
5846 |
+ struct sst_acpi_mach *mach; |
5847 |
+ const char *i2c_name = NULL; |
5848 |
+ int dai_index = 0; |
5849 |
++ bool found = false; |
5850 |
+ |
5851 |
+ drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); |
5852 |
+ if (!drv) |
5853 |
+ return -ENOMEM; |
5854 |
+ |
5855 |
++ mach = (&pdev->dev)->platform_data; |
5856 |
++ |
5857 |
+ for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { |
5858 |
+- if (acpi_dev_found(snd_soc_cards[i].codec_id)) { |
5859 |
++ if (acpi_dev_found(snd_soc_cards[i].codec_id) && |
5860 |
++ (!strncmp(snd_soc_cards[i].codec_id, mach->id, 8))) { |
5861 |
+ dev_dbg(&pdev->dev, |
5862 |
+ "found codec %s\n", snd_soc_cards[i].codec_id); |
5863 |
+ card = snd_soc_cards[i].soc_card; |
5864 |
+ drv->acpi_card = &snd_soc_cards[i]; |
5865 |
++ found = true; |
5866 |
+ break; |
5867 |
+ } |
5868 |
+ } |
5869 |
++ |
5870 |
++ if (!found) { |
5871 |
++ dev_err(&pdev->dev, "No matching HID found in supported list\n"); |
5872 |
++ return -ENODEV; |
5873 |
++ } |
5874 |
++ |
5875 |
+ card->dev = &pdev->dev; |
5876 |
+- mach = card->dev->platform_data; |
5877 |
+ sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id); |
5878 |
+ |
5879 |
+ /* set correct codec name */ |
5880 |
+@@ -391,6 +449,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev) |
5881 |
+ cht_dailink[dai_index].codec_name = cht_rt5640_codec_name; |
5882 |
+ } |
5883 |
+ |
5884 |
++ if (is_valleyview()) { |
5885 |
++ drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); |
5886 |
++ if (IS_ERR(drv->mclk)) { |
5887 |
++ dev_err(&pdev->dev, |
5888 |
++ "Failed to get MCLK from pmc_plt_clk_3: %ld\n", |
5889 |
++ PTR_ERR(drv->mclk)); |
5890 |
++ return PTR_ERR(drv->mclk); |
5891 |
++ } |
5892 |
++ } |
5893 |
++ |
5894 |
+ snd_soc_card_set_drvdata(card, drv); |
5895 |
+ ret_val = devm_snd_soc_register_card(&pdev->dev, card); |
5896 |
+ if (ret_val) { |
5897 |
+diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c |
5898 |
+index 687a8f83dbe5..15c92400cea4 100644 |
5899 |
+--- a/sound/soc/sunxi/sun4i-i2s.c |
5900 |
++++ b/sound/soc/sunxi/sun4i-i2s.c |
5901 |
+@@ -14,9 +14,11 @@ |
5902 |
+ #include <linux/clk.h> |
5903 |
+ #include <linux/dmaengine.h> |
5904 |
+ #include <linux/module.h> |
5905 |
++#include <linux/of_device.h> |
5906 |
+ #include <linux/platform_device.h> |
5907 |
+ #include <linux/pm_runtime.h> |
5908 |
+ #include <linux/regmap.h> |
5909 |
++#include <linux/reset.h> |
5910 |
+ |
5911 |
+ #include <sound/dmaengine_pcm.h> |
5912 |
+ #include <sound/pcm_params.h> |
5913 |
+@@ -92,6 +94,7 @@ struct sun4i_i2s { |
5914 |
+ struct clk *bus_clk; |
5915 |
+ struct clk *mod_clk; |
5916 |
+ struct regmap *regmap; |
5917 |
++ struct reset_control *rst; |
5918 |
+ |
5919 |
+ struct snd_dmaengine_dai_dma_data playback_dma_data; |
5920 |
+ }; |
5921 |
+@@ -585,9 +588,22 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) |
5922 |
+ return 0; |
5923 |
+ } |
5924 |
+ |
5925 |
++struct sun4i_i2s_quirks { |
5926 |
++ bool has_reset; |
5927 |
++}; |
5928 |
++ |
5929 |
++static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { |
5930 |
++ .has_reset = false, |
5931 |
++}; |
5932 |
++ |
5933 |
++static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { |
5934 |
++ .has_reset = true, |
5935 |
++}; |
5936 |
++ |
5937 |
+ static int sun4i_i2s_probe(struct platform_device *pdev) |
5938 |
+ { |
5939 |
+ struct sun4i_i2s *i2s; |
5940 |
++ const struct sun4i_i2s_quirks *quirks; |
5941 |
+ struct resource *res; |
5942 |
+ void __iomem *regs; |
5943 |
+ int irq, ret; |
5944 |
+@@ -608,6 +624,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev) |
5945 |
+ return irq; |
5946 |
+ } |
5947 |
+ |
5948 |
++ quirks = of_device_get_match_data(&pdev->dev); |
5949 |
++ if (!quirks) { |
5950 |
++ dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); |
5951 |
++ return -ENODEV; |
5952 |
++ } |
5953 |
++ |
5954 |
+ i2s->bus_clk = devm_clk_get(&pdev->dev, "apb"); |
5955 |
+ if (IS_ERR(i2s->bus_clk)) { |
5956 |
+ dev_err(&pdev->dev, "Can't get our bus clock\n"); |
5957 |
+@@ -626,7 +648,24 @@ static int sun4i_i2s_probe(struct platform_device *pdev) |
5958 |
+ dev_err(&pdev->dev, "Can't get our mod clock\n"); |
5959 |
+ return PTR_ERR(i2s->mod_clk); |
5960 |
+ } |
5961 |
+- |
5962 |
++ |
5963 |
++ if (quirks->has_reset) { |
5964 |
++ i2s->rst = devm_reset_control_get(&pdev->dev, NULL); |
5965 |
++ if (IS_ERR(i2s->rst)) { |
5966 |
++ dev_err(&pdev->dev, "Failed to get reset control\n"); |
5967 |
++ return PTR_ERR(i2s->rst); |
5968 |
++ } |
5969 |
++ } |
5970 |
++ |
5971 |
++ if (!IS_ERR(i2s->rst)) { |
5972 |
++ ret = reset_control_deassert(i2s->rst); |
5973 |
++ if (ret) { |
5974 |
++ dev_err(&pdev->dev, |
5975 |
++ "Failed to deassert the reset control\n"); |
5976 |
++ return -EINVAL; |
5977 |
++ } |
5978 |
++ } |
5979 |
++ |
5980 |
+ i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG; |
5981 |
+ i2s->playback_dma_data.maxburst = 4; |
5982 |
+ |
5983 |
+@@ -658,23 +697,37 @@ static int sun4i_i2s_probe(struct platform_device *pdev) |
5984 |
+ sun4i_i2s_runtime_suspend(&pdev->dev); |
5985 |
+ err_pm_disable: |
5986 |
+ pm_runtime_disable(&pdev->dev); |
5987 |
++ if (!IS_ERR(i2s->rst)) |
5988 |
++ reset_control_assert(i2s->rst); |
5989 |
+ |
5990 |
+ return ret; |
5991 |
+ } |
5992 |
+ |
5993 |
+ static int sun4i_i2s_remove(struct platform_device *pdev) |
5994 |
+ { |
5995 |
++ struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev); |
5996 |
++ |
5997 |
+ snd_dmaengine_pcm_unregister(&pdev->dev); |
5998 |
+ |
5999 |
+ pm_runtime_disable(&pdev->dev); |
6000 |
+ if (!pm_runtime_status_suspended(&pdev->dev)) |
6001 |
+ sun4i_i2s_runtime_suspend(&pdev->dev); |
6002 |
+ |
6003 |
++ if (!IS_ERR(i2s->rst)) |
6004 |
++ reset_control_assert(i2s->rst); |
6005 |
++ |
6006 |
+ return 0; |
6007 |
+ } |
6008 |
+ |
6009 |
+ static const struct of_device_id sun4i_i2s_match[] = { |
6010 |
+- { .compatible = "allwinner,sun4i-a10-i2s", }, |
6011 |
++ { |
6012 |
++ .compatible = "allwinner,sun4i-a10-i2s", |
6013 |
++ .data = &sun4i_a10_i2s_quirks, |
6014 |
++ }, |
6015 |
++ { |
6016 |
++ .compatible = "allwinner,sun6i-a31-i2s", |
6017 |
++ .data = &sun6i_a31_i2s_quirks, |
6018 |
++ }, |
6019 |
+ {} |
6020 |
+ }; |
6021 |
+ MODULE_DEVICE_TABLE(of, sun4i_i2s_match); |
6022 |
+diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c |
6023 |
+index 48afae053c56..cf8459a6fad8 100644 |
6024 |
+--- a/sound/usb/pcm.c |
6025 |
++++ b/sound/usb/pcm.c |
6026 |
+@@ -348,6 +348,16 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, |
6027 |
+ |
6028 |
+ alts = &iface->altsetting[1]; |
6029 |
+ goto add_sync_ep; |
6030 |
++ case USB_ID(0x2466, 0x8003): |
6031 |
++ ep = 0x86; |
6032 |
++ iface = usb_ifnum_to_if(dev, 2); |
6033 |
++ |
6034 |
++ if (!iface || iface->num_altsetting == 0) |
6035 |
++ return -EINVAL; |
6036 |
++ |
6037 |
++ alts = &iface->altsetting[1]; |
6038 |
++ goto add_sync_ep; |
6039 |
++ |
6040 |
+ } |
6041 |
+ if (attr == USB_ENDPOINT_SYNC_ASYNC && |
6042 |
+ altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && |
6043 |
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c |
6044 |
+index 93bb14e7e0f7..eb4b9f7a571e 100644 |
6045 |
+--- a/sound/usb/quirks.c |
6046 |
++++ b/sound/usb/quirks.c |
6047 |
+@@ -1166,6 +1166,18 @@ static bool is_marantz_denon_dac(unsigned int id) |
6048 |
+ return false; |
6049 |
+ } |
6050 |
+ |
6051 |
++/* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch |
6052 |
++ * between PCM/DOP and native DSD mode |
6053 |
++ */ |
6054 |
++static bool is_teac_50X_dac(unsigned int id) |
6055 |
++{ |
6056 |
++ switch (id) { |
6057 |
++ case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ |
6058 |
++ return true; |
6059 |
++ } |
6060 |
++ return false; |
6061 |
++} |
6062 |
++ |
6063 |
+ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, |
6064 |
+ struct audioformat *fmt) |
6065 |
+ { |
6066 |
+@@ -1193,6 +1205,26 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, |
6067 |
+ break; |
6068 |
+ } |
6069 |
+ mdelay(20); |
6070 |
++ } else if (is_teac_50X_dac(subs->stream->chip->usb_id)) { |
6071 |
++ /* Vendor mode switch cmd is required. */ |
6072 |
++ switch (fmt->altsetting) { |
6073 |
++ case 3: /* DSD mode (DSD_U32) requested */ |
6074 |
++ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, |
6075 |
++ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
6076 |
++ 1, 1, NULL, 0); |
6077 |
++ if (err < 0) |
6078 |
++ return err; |
6079 |
++ break; |
6080 |
++ |
6081 |
++ case 2: /* PCM or DOP mode (S32) requested */ |
6082 |
++ case 1: /* PCM mode (S16) requested */ |
6083 |
++ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, |
6084 |
++ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
6085 |
++ 0, 1, NULL, 0); |
6086 |
++ if (err < 0) |
6087 |
++ return err; |
6088 |
++ break; |
6089 |
++ } |
6090 |
+ } |
6091 |
+ return 0; |
6092 |
+ } |
6093 |
+@@ -1338,5 +1370,11 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, |
6094 |
+ return SNDRV_PCM_FMTBIT_DSD_U32_BE; |
6095 |
+ } |
6096 |
+ |
6097 |
++ /* TEAC devices with USB DAC functionality */ |
6098 |
++ if (is_teac_50X_dac(chip->usb_id)) { |
6099 |
++ if (fp->altsetting == 3) |
6100 |
++ return SNDRV_PCM_FMTBIT_DSD_U32_BE; |
6101 |
++ } |
6102 |
++ |
6103 |
+ return 0; |
6104 |
+ } |