1 |
Author: mpagano |
2 |
Date: 2011-11-21 23:58:10 +0000 (Mon, 21 Nov 2011) |
3 |
New Revision: 2014 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/3.0/1009_linux-3.0.10.patch |
7 |
Modified: |
8 |
genpatches-2.6/trunk/3.0/0000_README |
9 |
Log: |
10 |
Linux patch 3.0.10 |
11 |
|
12 |
Modified: genpatches-2.6/trunk/3.0/0000_README |
13 |
=================================================================== |
14 |
--- genpatches-2.6/trunk/3.0/0000_README 2011-11-12 23:48:24 UTC (rev 2013) |
15 |
+++ genpatches-2.6/trunk/3.0/0000_README 2011-11-21 23:58:10 UTC (rev 2014) |
16 |
@@ -75,6 +75,10 @@ |
17 |
From: http://www.kernel.org |
18 |
Desc: Linux 3.0.9 |
19 |
|
20 |
+Patch: 1009_linux-3.0.10.patch |
21 |
+From: http://www.kernel.org |
22 |
+Desc: Linux 3.0.10 |
23 |
+ |
24 |
Patch: 1800_fix-zcache-build.patch |
25 |
From: http://bugs.gentoo.org/show_bug.cgi?id=376325 |
26 |
Desc: Fix zcache build error |
27 |
|
28 |
Added: genpatches-2.6/trunk/3.0/1009_linux-3.0.10.patch |
29 |
=================================================================== |
30 |
--- genpatches-2.6/trunk/3.0/1009_linux-3.0.10.patch (rev 0) |
31 |
+++ genpatches-2.6/trunk/3.0/1009_linux-3.0.10.patch 2011-11-21 23:58:10 UTC (rev 2014) |
32 |
@@ -0,0 +1,893 @@ |
33 |
+diff --git a/Makefile b/Makefile |
34 |
+index 438c11a..36036d1 100644 |
35 |
+--- a/Makefile |
36 |
++++ b/Makefile |
37 |
+@@ -1,6 +1,6 @@ |
38 |
+ VERSION = 3 |
39 |
+ PATCHLEVEL = 0 |
40 |
+-SUBLEVEL = 9 |
41 |
++SUBLEVEL = 10 |
42 |
+ EXTRAVERSION = |
43 |
+ NAME = Sneaky Weasel |
44 |
+ |
45 |
+diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h |
46 |
+index 6fbce72..a0f358d 100644 |
47 |
+--- a/arch/powerpc/include/asm/sections.h |
48 |
++++ b/arch/powerpc/include/asm/sections.h |
49 |
+@@ -8,7 +8,7 @@ |
50 |
+ |
51 |
+ #ifdef __powerpc64__ |
52 |
+ |
53 |
+-extern char _end[]; |
54 |
++extern char __end_interrupts[]; |
55 |
+ |
56 |
+ static inline int in_kernel_text(unsigned long addr) |
57 |
+ { |
58 |
+diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h |
59 |
+index d7cab44..87878c6 100644 |
60 |
+--- a/arch/powerpc/include/asm/synch.h |
61 |
++++ b/arch/powerpc/include/asm/synch.h |
62 |
+@@ -13,6 +13,7 @@ |
63 |
+ extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; |
64 |
+ extern void do_lwsync_fixups(unsigned long value, void *fixup_start, |
65 |
+ void *fixup_end); |
66 |
++extern void do_final_fixups(void); |
67 |
+ |
68 |
+ static inline void eieio(void) |
69 |
+ { |
70 |
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c |
71 |
+index b06bdae..ad892f7 100644 |
72 |
+--- a/arch/powerpc/kernel/kvm.c |
73 |
++++ b/arch/powerpc/kernel/kvm.c |
74 |
+@@ -131,7 +131,6 @@ static void kvm_patch_ins_b(u32 *inst, int addr) |
75 |
+ /* On relocatable kernels interrupts handlers and our code |
76 |
+ can be in different regions, so we don't patch them */ |
77 |
+ |
78 |
+- extern u32 __end_interrupts; |
79 |
+ if ((ulong)inst < (ulong)&__end_interrupts) |
80 |
+ return; |
81 |
+ #endif |
82 |
+diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c |
83 |
+index 620d792..c7e7b8c 100644 |
84 |
+--- a/arch/powerpc/kernel/setup_32.c |
85 |
++++ b/arch/powerpc/kernel/setup_32.c |
86 |
+@@ -107,6 +107,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) |
87 |
+ PTRRELOC(&__start___lwsync_fixup), |
88 |
+ PTRRELOC(&__stop___lwsync_fixup)); |
89 |
+ |
90 |
++ do_final_fixups(); |
91 |
++ |
92 |
+ return KERNELBASE + offset; |
93 |
+ } |
94 |
+ |
95 |
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c |
96 |
+index a88bf27..7867fd1 100644 |
97 |
+--- a/arch/powerpc/kernel/setup_64.c |
98 |
++++ b/arch/powerpc/kernel/setup_64.c |
99 |
+@@ -352,6 +352,7 @@ void __init setup_system(void) |
100 |
+ &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); |
101 |
+ do_lwsync_fixups(cur_cpu_spec->cpu_features, |
102 |
+ &__start___lwsync_fixup, &__stop___lwsync_fixup); |
103 |
++ do_final_fixups(); |
104 |
+ |
105 |
+ /* |
106 |
+ * Unflatten the device-tree passed by prom_init or kexec |
107 |
+diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c |
108 |
+index 0d08d01..7a8a748 100644 |
109 |
+--- a/arch/powerpc/lib/feature-fixups.c |
110 |
++++ b/arch/powerpc/lib/feature-fixups.c |
111 |
+@@ -18,6 +18,8 @@ |
112 |
+ #include <linux/init.h> |
113 |
+ #include <asm/cputable.h> |
114 |
+ #include <asm/code-patching.h> |
115 |
++#include <asm/page.h> |
116 |
++#include <asm/sections.h> |
117 |
+ |
118 |
+ |
119 |
+ struct fixup_entry { |
120 |
+@@ -128,6 +130,27 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) |
121 |
+ } |
122 |
+ } |
123 |
+ |
124 |
++void do_final_fixups(void) |
125 |
++{ |
126 |
++#if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE) |
127 |
++ int *src, *dest; |
128 |
++ unsigned long length; |
129 |
++ |
130 |
++ if (PHYSICAL_START == 0) |
131 |
++ return; |
132 |
++ |
133 |
++ src = (int *)(KERNELBASE + PHYSICAL_START); |
134 |
++ dest = (int *)KERNELBASE; |
135 |
++ length = (__end_interrupts - _stext) / sizeof(int); |
136 |
++ |
137 |
++ while (length--) { |
138 |
++ patch_instruction(dest, *src); |
139 |
++ src++; |
140 |
++ dest++; |
141 |
++ } |
142 |
++#endif |
143 |
++} |
144 |
++ |
145 |
+ #ifdef CONFIG_FTR_FIXUP_SELFTEST |
146 |
+ |
147 |
+ #define check(x) \ |
148 |
+diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c |
149 |
+index 600ed2c..1aa478b 100644 |
150 |
+--- a/arch/powerpc/platforms/ps3/interrupt.c |
151 |
++++ b/arch/powerpc/platforms/ps3/interrupt.c |
152 |
+@@ -88,6 +88,7 @@ struct ps3_private { |
153 |
+ struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); |
154 |
+ u64 ppe_id; |
155 |
+ u64 thread_id; |
156 |
++ unsigned long ipi_mask; |
157 |
+ }; |
158 |
+ |
159 |
+ static DEFINE_PER_CPU(struct ps3_private, ps3_private); |
160 |
+@@ -144,7 +145,11 @@ static void ps3_chip_unmask(struct irq_data *d) |
161 |
+ static void ps3_chip_eoi(struct irq_data *d) |
162 |
+ { |
163 |
+ const struct ps3_private *pd = irq_data_get_irq_chip_data(d); |
164 |
+- lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq); |
165 |
++ |
166 |
++ /* non-IPIs are EOIed here. */ |
167 |
++ |
168 |
++ if (!test_bit(63 - d->irq, &pd->ipi_mask)) |
169 |
++ lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq); |
170 |
+ } |
171 |
+ |
172 |
+ /** |
173 |
+@@ -691,6 +696,16 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) |
174 |
+ cpu, virq, pd->bmp.ipi_debug_brk_mask); |
175 |
+ } |
176 |
+ |
177 |
++void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) |
178 |
++{ |
179 |
++ struct ps3_private *pd = &per_cpu(ps3_private, cpu); |
180 |
++ |
181 |
++ set_bit(63 - virq, &pd->ipi_mask); |
182 |
++ |
183 |
++ DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__, |
184 |
++ cpu, virq, pd->ipi_mask); |
185 |
++} |
186 |
++ |
187 |
+ static unsigned int ps3_get_irq(void) |
188 |
+ { |
189 |
+ struct ps3_private *pd = &__get_cpu_var(ps3_private); |
190 |
+@@ -720,6 +735,12 @@ static unsigned int ps3_get_irq(void) |
191 |
+ BUG(); |
192 |
+ } |
193 |
+ #endif |
194 |
++ |
195 |
++ /* IPIs are EOIed here. */ |
196 |
++ |
197 |
++ if (test_bit(63 - plug, &pd->ipi_mask)) |
198 |
++ lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug); |
199 |
++ |
200 |
+ return plug; |
201 |
+ } |
202 |
+ |
203 |
+diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h |
204 |
+index 9a196a8..1a633ed 100644 |
205 |
+--- a/arch/powerpc/platforms/ps3/platform.h |
206 |
++++ b/arch/powerpc/platforms/ps3/platform.h |
207 |
+@@ -43,6 +43,7 @@ void ps3_mm_shutdown(void); |
208 |
+ void ps3_init_IRQ(void); |
209 |
+ void ps3_shutdown_IRQ(int cpu); |
210 |
+ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); |
211 |
++void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq); |
212 |
+ |
213 |
+ /* smp */ |
214 |
+ |
215 |
+diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c |
216 |
+index 4c44794..f609345 100644 |
217 |
+--- a/arch/powerpc/platforms/ps3/smp.c |
218 |
++++ b/arch/powerpc/platforms/ps3/smp.c |
219 |
+@@ -94,6 +94,8 @@ static void __init ps3_smp_setup_cpu(int cpu) |
220 |
+ |
221 |
+ if (result) |
222 |
+ virqs[i] = NO_IRQ; |
223 |
++ else |
224 |
++ ps3_register_ipi_irq(cpu, virqs[i]); |
225 |
+ } |
226 |
+ |
227 |
+ ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]); |
228 |
+diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h |
229 |
+index 822d608..abcc4dc 100644 |
230 |
+--- a/arch/sh/include/asm/page.h |
231 |
++++ b/arch/sh/include/asm/page.h |
232 |
+@@ -141,8 +141,13 @@ typedef struct page *pgtable_t; |
233 |
+ #endif /* !__ASSEMBLY__ */ |
234 |
+ |
235 |
+ #ifdef CONFIG_UNCACHED_MAPPING |
236 |
++#if defined(CONFIG_29BIT) |
237 |
++#define UNCAC_ADDR(addr) P2SEGADDR(addr) |
238 |
++#define CAC_ADDR(addr) P1SEGADDR(addr) |
239 |
++#else |
240 |
+ #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) |
241 |
+ #define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) |
242 |
++#endif |
243 |
+ #else |
244 |
+ #define UNCAC_ADDR(addr) ((addr)) |
245 |
+ #define CAC_ADDR(addr) ((addr)) |
246 |
+diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c |
247 |
+index 7000e74..fe73276 100644 |
248 |
+--- a/arch/x86/platform/mrst/mrst.c |
249 |
++++ b/arch/x86/platform/mrst/mrst.c |
250 |
+@@ -678,36 +678,40 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) |
251 |
+ pentry = (struct sfi_device_table_entry *)sb->pentry; |
252 |
+ |
253 |
+ for (i = 0; i < num; i++, pentry++) { |
254 |
+- if (pentry->irq != (u8)0xff) { /* native RTE case */ |
255 |
++ int irq = pentry->irq; |
256 |
++ |
257 |
++ if (irq != (u8)0xff) { /* native RTE case */ |
258 |
+ /* these SPI2 devices are not exposed to system as PCI |
259 |
+ * devices, but they have separate RTE entry in IOAPIC |
260 |
+ * so we have to enable them one by one here |
261 |
+ */ |
262 |
+- ioapic = mp_find_ioapic(pentry->irq); |
263 |
++ ioapic = mp_find_ioapic(irq); |
264 |
+ irq_attr.ioapic = ioapic; |
265 |
+- irq_attr.ioapic_pin = pentry->irq; |
266 |
++ irq_attr.ioapic_pin = irq; |
267 |
+ irq_attr.trigger = 1; |
268 |
+ irq_attr.polarity = 1; |
269 |
+- io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr); |
270 |
+- } |
271 |
++ io_apic_set_pci_routing(NULL, irq, &irq_attr); |
272 |
++ } else |
273 |
++ irq = 0; /* No irq */ |
274 |
++ |
275 |
+ switch (pentry->type) { |
276 |
+ case SFI_DEV_TYPE_IPC: |
277 |
+ /* ID as IRQ is a hack that will go away */ |
278 |
+- pdev = platform_device_alloc(pentry->name, pentry->irq); |
279 |
++ pdev = platform_device_alloc(pentry->name, irq); |
280 |
+ if (pdev == NULL) { |
281 |
+ pr_err("out of memory for SFI platform device '%s'.\n", |
282 |
+ pentry->name); |
283 |
+ continue; |
284 |
+ } |
285 |
+- install_irq_resource(pdev, pentry->irq); |
286 |
++ install_irq_resource(pdev, irq); |
287 |
+ pr_debug("info[%2d]: IPC bus, name = %16.16s, " |
288 |
+- "irq = 0x%2x\n", i, pentry->name, pentry->irq); |
289 |
++ "irq = 0x%2x\n", i, pentry->name, irq); |
290 |
+ sfi_handle_ipc_dev(pdev); |
291 |
+ break; |
292 |
+ case SFI_DEV_TYPE_SPI: |
293 |
+ memset(&spi_info, 0, sizeof(spi_info)); |
294 |
+ strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN); |
295 |
+- spi_info.irq = pentry->irq; |
296 |
++ spi_info.irq = irq; |
297 |
+ spi_info.bus_num = pentry->host_num; |
298 |
+ spi_info.chip_select = pentry->addr; |
299 |
+ spi_info.max_speed_hz = pentry->max_freq; |
300 |
+@@ -724,7 +728,7 @@ static int __init sfi_parse_devs(struct sfi_table_header *table) |
301 |
+ memset(&i2c_info, 0, sizeof(i2c_info)); |
302 |
+ bus = pentry->host_num; |
303 |
+ strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN); |
304 |
+- i2c_info.irq = pentry->irq; |
305 |
++ i2c_info.irq = irq; |
306 |
+ i2c_info.addr = pentry->addr; |
307 |
+ pr_debug("info[%2d]: I2C bus = %d, name = %16.16s, " |
308 |
+ "irq = 0x%2x, addr = 0x%x\n", i, bus, |
309 |
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c |
310 |
+index 67d69f1..0fb662a 100644 |
311 |
+--- a/arch/x86/xen/enlighten.c |
312 |
++++ b/arch/x86/xen/enlighten.c |
313 |
+@@ -1337,7 +1337,7 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, |
314 |
+ int cpu = (long)hcpu; |
315 |
+ switch (action) { |
316 |
+ case CPU_UP_PREPARE: |
317 |
+- per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; |
318 |
++ xen_vcpu_setup(cpu); |
319 |
+ if (xen_have_vector_callback) |
320 |
+ xen_init_lock_cpu(cpu); |
321 |
+ break; |
322 |
+@@ -1367,7 +1367,6 @@ static void __init xen_hvm_guest_init(void) |
323 |
+ xen_hvm_smp_init(); |
324 |
+ register_cpu_notifier(&xen_hvm_cpu_notifier); |
325 |
+ xen_unplug_emulated_devices(); |
326 |
+- have_vcpu_info_placement = 0; |
327 |
+ x86_init.irqs.intr_init = xen_init_IRQ; |
328 |
+ xen_hvm_init_time_ops(); |
329 |
+ xen_hvm_init_mmu_ops(); |
330 |
+diff --git a/block/blk-map.c b/block/blk-map.c |
331 |
+index e663ac2..164cd00 100644 |
332 |
+--- a/block/blk-map.c |
333 |
++++ b/block/blk-map.c |
334 |
+@@ -204,10 +204,11 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, |
335 |
+ if (!iov[i].iov_len) |
336 |
+ return -EINVAL; |
337 |
+ |
338 |
+- if (uaddr & queue_dma_alignment(q)) { |
339 |
++ /* |
340 |
++ * Keep going so we check length of all segments |
341 |
++ */ |
342 |
++ if (uaddr & queue_dma_alignment(q)) |
343 |
+ unaligned = 1; |
344 |
+- break; |
345 |
+- } |
346 |
+ } |
347 |
+ |
348 |
+ if (unaligned || (q->dma_pad_mask & len) || map_data) |
349 |
+diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c |
350 |
+index 0a893f7..e36efdc 100644 |
351 |
+--- a/drivers/gpu/drm/i915/i915_debugfs.c |
352 |
++++ b/drivers/gpu/drm/i915/i915_debugfs.c |
353 |
+@@ -865,7 +865,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) |
354 |
+ MEMSTAT_VID_SHIFT); |
355 |
+ seq_printf(m, "Current P-state: %d\n", |
356 |
+ (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); |
357 |
+- } else if (IS_GEN6(dev)) { |
358 |
++ } else if (IS_GEN6(dev) || IS_GEN7(dev)) { |
359 |
+ u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); |
360 |
+ u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); |
361 |
+ u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
362 |
+diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c |
363 |
+index a087e1b..5548593 100644 |
364 |
+--- a/drivers/gpu/drm/i915/i915_gem.c |
365 |
++++ b/drivers/gpu/drm/i915/i915_gem.c |
366 |
+@@ -1475,7 +1475,7 @@ i915_gem_mmap_gtt(struct drm_file *file, |
367 |
+ |
368 |
+ if (obj->base.size > dev_priv->mm.gtt_mappable_end) { |
369 |
+ ret = -E2BIG; |
370 |
+- goto unlock; |
371 |
++ goto out; |
372 |
+ } |
373 |
+ |
374 |
+ if (obj->madv != I915_MADV_WILLNEED) { |
375 |
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
376 |
+index 5609c06..cbf4c4c 100644 |
377 |
+--- a/drivers/gpu/drm/i915/intel_display.c |
378 |
++++ b/drivers/gpu/drm/i915/intel_display.c |
379 |
+@@ -7943,7 +7943,7 @@ void intel_modeset_init(struct drm_device *dev) |
380 |
+ intel_init_emon(dev); |
381 |
+ } |
382 |
+ |
383 |
+- if (IS_GEN6(dev)) |
384 |
++ if (IS_GEN6(dev) || IS_GEN7(dev)) |
385 |
+ gen6_enable_rps(dev_priv); |
386 |
+ |
387 |
+ INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
388 |
+@@ -7985,7 +7985,7 @@ void intel_modeset_cleanup(struct drm_device *dev) |
389 |
+ |
390 |
+ if (IS_IRONLAKE_M(dev)) |
391 |
+ ironlake_disable_drps(dev); |
392 |
+- if (IS_GEN6(dev)) |
393 |
++ if (IS_GEN6(dev) || IS_GEN7(dev)) |
394 |
+ gen6_disable_rps(dev); |
395 |
+ |
396 |
+ if (IS_IRONLAKE_M(dev)) |
397 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c |
398 |
+index a7583a8..d31d355 100644 |
399 |
+--- a/drivers/gpu/drm/nouveau/nouveau_channel.c |
400 |
++++ b/drivers/gpu/drm/nouveau/nouveau_channel.c |
401 |
+@@ -159,6 +159,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, |
402 |
+ INIT_LIST_HEAD(&chan->nvsw.vbl_wait); |
403 |
+ INIT_LIST_HEAD(&chan->nvsw.flip); |
404 |
+ INIT_LIST_HEAD(&chan->fence.pending); |
405 |
++ spin_lock_init(&chan->fence.lock); |
406 |
+ |
407 |
+ /* Allocate DMA push buffer */ |
408 |
+ chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev); |
409 |
+diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c |
410 |
+index 7347075..56f06b0 100644 |
411 |
+--- a/drivers/gpu/drm/nouveau/nouveau_fence.c |
412 |
++++ b/drivers/gpu/drm/nouveau/nouveau_fence.c |
413 |
+@@ -542,8 +542,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) |
414 |
+ return ret; |
415 |
+ } |
416 |
+ |
417 |
+- INIT_LIST_HEAD(&chan->fence.pending); |
418 |
+- spin_lock_init(&chan->fence.lock); |
419 |
+ atomic_set(&chan->fence.last_sequence_irq, 0); |
420 |
+ return 0; |
421 |
+ } |
422 |
+diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c |
423 |
+index b5628ce..3b77ad6 100644 |
424 |
+--- a/drivers/gpu/drm/radeon/atombios_dp.c |
425 |
++++ b/drivers/gpu/drm/radeon/atombios_dp.c |
426 |
+@@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, |
427 |
+ } |
428 |
+ } |
429 |
+ |
430 |
+- DRM_ERROR("aux i2c too many retries, giving up\n"); |
431 |
++ DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); |
432 |
+ return -EREMOTEIO; |
433 |
+ } |
434 |
+ |
435 |
+diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c |
436 |
+index 661b692..6d5628b 100644 |
437 |
+--- a/drivers/leds/led-class.c |
438 |
++++ b/drivers/leds/led-class.c |
439 |
+@@ -270,11 +270,8 @@ void led_blink_set(struct led_classdev *led_cdev, |
440 |
+ del_timer_sync(&led_cdev->blink_timer); |
441 |
+ |
442 |
+ if (led_cdev->blink_set && |
443 |
+- !led_cdev->blink_set(led_cdev, delay_on, delay_off)) { |
444 |
+- led_cdev->blink_delay_on = *delay_on; |
445 |
+- led_cdev->blink_delay_off = *delay_off; |
446 |
++ !led_cdev->blink_set(led_cdev, delay_on, delay_off)) |
447 |
+ return; |
448 |
+- } |
449 |
+ |
450 |
+ /* blink with 1 Hz as default if nothing specified */ |
451 |
+ if (!*delay_on && !*delay_off) |
452 |
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c |
453 |
+index e509147..cbb50d3 100644 |
454 |
+--- a/drivers/md/raid5.c |
455 |
++++ b/drivers/md/raid5.c |
456 |
+@@ -3120,12 +3120,16 @@ static void handle_stripe5(struct stripe_head *sh) |
457 |
+ /* check if the array has lost two devices and, if so, some requests might |
458 |
+ * need to be failed |
459 |
+ */ |
460 |
+- if (s.failed > 1 && s.to_read+s.to_write+s.written) |
461 |
+- handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
462 |
+- if (s.failed > 1 && s.syncing) { |
463 |
+- md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
464 |
+- clear_bit(STRIPE_SYNCING, &sh->state); |
465 |
+- s.syncing = 0; |
466 |
++ if (s.failed > 1) { |
467 |
++ sh->check_state = 0; |
468 |
++ sh->reconstruct_state = 0; |
469 |
++ if (s.to_read+s.to_write+s.written) |
470 |
++ handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
471 |
++ if (s.syncing) { |
472 |
++ md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
473 |
++ clear_bit(STRIPE_SYNCING, &sh->state); |
474 |
++ s.syncing = 0; |
475 |
++ } |
476 |
+ } |
477 |
+ |
478 |
+ /* might be able to return some write requests if the parity block |
479 |
+@@ -3412,12 +3416,16 @@ static void handle_stripe6(struct stripe_head *sh) |
480 |
+ /* check if the array has lost >2 devices and, if so, some requests |
481 |
+ * might need to be failed |
482 |
+ */ |
483 |
+- if (s.failed > 2 && s.to_read+s.to_write+s.written) |
484 |
+- handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
485 |
+- if (s.failed > 2 && s.syncing) { |
486 |
+- md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
487 |
+- clear_bit(STRIPE_SYNCING, &sh->state); |
488 |
+- s.syncing = 0; |
489 |
++ if (s.failed > 2) { |
490 |
++ sh->check_state = 0; |
491 |
++ sh->reconstruct_state = 0; |
492 |
++ if (s.to_read+s.to_write+s.written) |
493 |
++ handle_failed_stripe(conf, sh, &s, disks, &return_bi); |
494 |
++ if (s.syncing) { |
495 |
++ md_done_sync(conf->mddev, STRIPE_SECTORS,0); |
496 |
++ clear_bit(STRIPE_SYNCING, &sh->state); |
497 |
++ s.syncing = 0; |
498 |
++ } |
499 |
+ } |
500 |
+ |
501 |
+ /* |
502 |
+diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c |
503 |
+index b8f2a4e..b9188a2 100644 |
504 |
+--- a/drivers/mfd/twl-core.c |
505 |
++++ b/drivers/mfd/twl-core.c |
506 |
+@@ -109,7 +109,7 @@ |
507 |
+ #define twl_has_watchdog() false |
508 |
+ #endif |
509 |
+ |
510 |
+-#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\ |
511 |
++#if defined(CONFIG_MFD_TWL4030_AUDIO) || defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) ||\ |
512 |
+ defined(CONFIG_SND_SOC_TWL6040) || defined(CONFIG_SND_SOC_TWL6040_MODULE) |
513 |
+ #define twl_has_codec() true |
514 |
+ #else |
515 |
+diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c |
516 |
+index b1fe4fe..7c2e09a 100644 |
517 |
+--- a/drivers/net/wireless/b43/main.c |
518 |
++++ b/drivers/net/wireless/b43/main.c |
519 |
+@@ -2401,6 +2401,13 @@ static int b43_upload_microcode(struct b43_wldev *dev) |
520 |
+ b43_print_fw_helptext(dev->wl, 1); |
521 |
+ err = -EOPNOTSUPP; |
522 |
+ goto error; |
523 |
++ } else if (fwrev >= 598) { |
524 |
++ b43err(dev->wl, "YOUR FIRMWARE IS TOO NEW. Support for " |
525 |
++ "firmware 598 and up requires kernel 3.2 or newer. You " |
526 |
++ "have to install older firmware or upgrade kernel.\n"); |
527 |
++ b43_print_fw_helptext(dev->wl, 1); |
528 |
++ err = -EOPNOTSUPP; |
529 |
++ goto error; |
530 |
+ } |
531 |
+ dev->fw.rev = fwrev; |
532 |
+ dev->fw.patch = fwpatch; |
533 |
+diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c |
534 |
+index 4bcc8b8..ecb9254 100644 |
535 |
+--- a/drivers/virtio/virtio_pci.c |
536 |
++++ b/drivers/virtio/virtio_pci.c |
537 |
+@@ -590,11 +590,11 @@ static struct virtio_config_ops virtio_pci_config_ops = { |
538 |
+ |
539 |
+ static void virtio_pci_release_dev(struct device *_d) |
540 |
+ { |
541 |
+- struct virtio_device *dev = container_of(_d, struct virtio_device, |
542 |
+- dev); |
543 |
+- struct virtio_pci_device *vp_dev = to_vp_device(dev); |
544 |
+- |
545 |
+- kfree(vp_dev); |
546 |
++ /* |
547 |
++ * No need for a release method as we allocate/free |
548 |
++ * all devices together with the pci devices. |
549 |
++ * Provide an empty one to avoid getting a warning from core. |
550 |
++ */ |
551 |
+ } |
552 |
+ |
553 |
+ /* the PCI probing function */ |
554 |
+@@ -682,6 +682,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) |
555 |
+ pci_iounmap(pci_dev, vp_dev->ioaddr); |
556 |
+ pci_release_regions(pci_dev); |
557 |
+ pci_disable_device(pci_dev); |
558 |
++ kfree(vp_dev); |
559 |
+ } |
560 |
+ |
561 |
+ #ifdef CONFIG_PM |
562 |
+diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c |
563 |
+index f6832f4..e1c4c6e 100644 |
564 |
+--- a/drivers/xen/gntalloc.c |
565 |
++++ b/drivers/xen/gntalloc.c |
566 |
+@@ -135,7 +135,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, |
567 |
+ /* Grant foreign access to the page. */ |
568 |
+ gref->gref_id = gnttab_grant_foreign_access(op->domid, |
569 |
+ pfn_to_mfn(page_to_pfn(gref->page)), readonly); |
570 |
+- if (gref->gref_id < 0) { |
571 |
++ if ((int)gref->gref_id < 0) { |
572 |
+ rc = gref->gref_id; |
573 |
+ goto undo; |
574 |
+ } |
575 |
+@@ -280,7 +280,7 @@ static long gntalloc_ioctl_alloc(struct gntalloc_file_private_data *priv, |
576 |
+ goto out; |
577 |
+ } |
578 |
+ |
579 |
+- gref_ids = kzalloc(sizeof(gref_ids[0]) * op.count, GFP_TEMPORARY); |
580 |
++ gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_TEMPORARY); |
581 |
+ if (!gref_ids) { |
582 |
+ rc = -ENOMEM; |
583 |
+ goto out; |
584 |
+diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c |
585 |
+index e673a88..b1ce4c7 100644 |
586 |
+--- a/fs/hfs/trans.c |
587 |
++++ b/fs/hfs/trans.c |
588 |
+@@ -40,6 +40,8 @@ int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in) |
589 |
+ |
590 |
+ src = in->name; |
591 |
+ srclen = in->len; |
592 |
++ if (srclen > HFS_NAMELEN) |
593 |
++ srclen = HFS_NAMELEN; |
594 |
+ dst = out; |
595 |
+ dstlen = HFS_MAX_NAMELEN; |
596 |
+ if (nls_io) { |
597 |
+diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h |
598 |
+index 3d53efd..f81676f 100644 |
599 |
+--- a/include/drm/drm_pciids.h |
600 |
++++ b/include/drm/drm_pciids.h |
601 |
+@@ -4,6 +4,7 @@ |
602 |
+ */ |
603 |
+ #define radeon_PCI_IDS \ |
604 |
+ {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
605 |
++ {0x1002, 0x3151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
606 |
+ {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
607 |
+ {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
608 |
+ {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
609 |
+@@ -55,6 +56,7 @@ |
610 |
+ {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ |
611 |
+ {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ |
612 |
+ {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ |
613 |
++ {0x1002, 0x4C6E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ |
614 |
+ {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
615 |
+ {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
616 |
+ {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
617 |
+diff --git a/mm/backing-dev.c b/mm/backing-dev.c |
618 |
+index e56fe35..b3b122f 100644 |
619 |
+--- a/mm/backing-dev.c |
620 |
++++ b/mm/backing-dev.c |
621 |
+@@ -686,6 +686,14 @@ void bdi_destroy(struct backing_dev_info *bdi) |
622 |
+ |
623 |
+ bdi_unregister(bdi); |
624 |
+ |
625 |
++ /* |
626 |
++ * If bdi_unregister() had already been called earlier, the |
627 |
++ * wakeup_timer could still be armed because bdi_prune_sb() |
628 |
++ * can race with the bdi_wakeup_thread_delayed() calls from |
629 |
++ * __mark_inode_dirty(). |
630 |
++ */ |
631 |
++ del_timer_sync(&bdi->wb.wakeup_timer); |
632 |
++ |
633 |
+ for (i = 0; i < NR_BDI_STAT_ITEMS; i++) |
634 |
+ percpu_counter_destroy(&bdi->bdi_stat[i]); |
635 |
+ |
636 |
+diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c |
637 |
+index 5b366d7..69ff52c 100644 |
638 |
+--- a/security/keys/user_defined.c |
639 |
++++ b/security/keys/user_defined.c |
640 |
+@@ -102,7 +102,8 @@ int user_update(struct key *key, const void *data, size_t datalen) |
641 |
+ key->expiry = 0; |
642 |
+ } |
643 |
+ |
644 |
+- kfree_rcu(zap, rcu); |
645 |
++ if (zap) |
646 |
++ kfree_rcu(zap, rcu); |
647 |
+ |
648 |
+ error: |
649 |
+ return ret; |
650 |
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c |
651 |
+index 45b4a8d..2195851 100644 |
652 |
+--- a/sound/pci/hda/hda_codec.c |
653 |
++++ b/sound/pci/hda/hda_codec.c |
654 |
+@@ -2187,6 +2187,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) |
655 |
+ return 0; |
656 |
+ } |
657 |
+ |
658 |
++typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); |
659 |
++ |
660 |
++/* apply the function to all matching slave ctls in the mixer list */ |
661 |
++static int map_slaves(struct hda_codec *codec, const char * const *slaves, |
662 |
++ map_slave_func_t func, void *data) |
663 |
++{ |
664 |
++ struct hda_nid_item *items; |
665 |
++ const char * const *s; |
666 |
++ int i, err; |
667 |
++ |
668 |
++ items = codec->mixers.list; |
669 |
++ for (i = 0; i < codec->mixers.used; i++) { |
670 |
++ struct snd_kcontrol *sctl = items[i].kctl; |
671 |
++ if (!sctl || !sctl->id.name || |
672 |
++ sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) |
673 |
++ continue; |
674 |
++ for (s = slaves; *s; s++) { |
675 |
++ if (!strcmp(sctl->id.name, *s)) { |
676 |
++ err = func(data, sctl); |
677 |
++ if (err) |
678 |
++ return err; |
679 |
++ break; |
680 |
++ } |
681 |
++ } |
682 |
++ } |
683 |
++ return 0; |
684 |
++} |
685 |
++ |
686 |
++static int check_slave_present(void *data, struct snd_kcontrol *sctl) |
687 |
++{ |
688 |
++ return 1; |
689 |
++} |
690 |
++ |
691 |
+ /** |
692 |
+ * snd_hda_add_vmaster - create a virtual master control and add slaves |
693 |
+ * @codec: HD-audio codec |
694 |
+@@ -2207,12 +2240,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
695 |
+ unsigned int *tlv, const char * const *slaves) |
696 |
+ { |
697 |
+ struct snd_kcontrol *kctl; |
698 |
+- const char * const *s; |
699 |
+ int err; |
700 |
+ |
701 |
+- for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) |
702 |
+- ; |
703 |
+- if (!*s) { |
704 |
++ err = map_slaves(codec, slaves, check_slave_present, NULL); |
705 |
++ if (err != 1) { |
706 |
+ snd_printdd("No slave found for %s\n", name); |
707 |
+ return 0; |
708 |
+ } |
709 |
+@@ -2223,23 +2254,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
710 |
+ if (err < 0) |
711 |
+ return err; |
712 |
+ |
713 |
+- for (s = slaves; *s; s++) { |
714 |
+- struct snd_kcontrol *sctl; |
715 |
+- int i = 0; |
716 |
+- for (;;) { |
717 |
+- sctl = _snd_hda_find_mixer_ctl(codec, *s, i); |
718 |
+- if (!sctl) { |
719 |
+- if (!i) |
720 |
+- snd_printdd("Cannot find slave %s, " |
721 |
+- "skipped\n", *s); |
722 |
+- break; |
723 |
+- } |
724 |
+- err = snd_ctl_add_slave(kctl, sctl); |
725 |
+- if (err < 0) |
726 |
+- return err; |
727 |
+- i++; |
728 |
+- } |
729 |
+- } |
730 |
++ err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, |
731 |
++ kctl); |
732 |
++ if (err < 0) |
733 |
++ return err; |
734 |
+ return 0; |
735 |
+ } |
736 |
+ EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); |
737 |
+diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c |
738 |
+index fb9f08a..2194912 100644 |
739 |
+--- a/sound/soc/codecs/wm8994.c |
740 |
++++ b/sound/soc/codecs/wm8994.c |
741 |
+@@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = { |
742 |
+ static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) |
743 |
+ { |
744 |
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
745 |
+- struct wm8994 *control = wm8994->control_data; |
746 |
++ struct wm8994 *control = codec->control_data; |
747 |
+ |
748 |
+ switch (reg) { |
749 |
+ case WM8994_GPIO_1: |
750 |
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
751 |
+index cdd19d7..0de7cbd 100644 |
752 |
+--- a/sound/usb/mixer.c |
753 |
++++ b/sound/usb/mixer.c |
754 |
+@@ -765,10 +765,60 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) |
755 |
+ * interface to ALSA control for feature/mixer units |
756 |
+ */ |
757 |
+ |
758 |
++/* volume control quirks */ |
759 |
++static void volume_control_quirks(struct usb_mixer_elem_info *cval, |
760 |
++ struct snd_kcontrol *kctl) |
761 |
++{ |
762 |
++ switch (cval->mixer->chip->usb_id) { |
763 |
++ case USB_ID(0x0471, 0x0101): |
764 |
++ case USB_ID(0x0471, 0x0104): |
765 |
++ case USB_ID(0x0471, 0x0105): |
766 |
++ case USB_ID(0x0672, 0x1041): |
767 |
++ /* quirk for UDA1321/N101. |
768 |
++ * note that detection between firmware 2.1.1.7 (N101) |
769 |
++ * and later 2.1.1.21 is not very clear from datasheets. |
770 |
++ * I hope that the min value is -15360 for newer firmware --jk |
771 |
++ */ |
772 |
++ if (!strcmp(kctl->id.name, "PCM Playback Volume") && |
773 |
++ cval->min == -15616) { |
774 |
++ snd_printk(KERN_INFO |
775 |
++ "set volume quirk for UDA1321/N101 chip\n"); |
776 |
++ cval->max = -256; |
777 |
++ } |
778 |
++ break; |
779 |
++ |
780 |
++ case USB_ID(0x046d, 0x09a4): |
781 |
++ if (!strcmp(kctl->id.name, "Mic Capture Volume")) { |
782 |
++ snd_printk(KERN_INFO |
783 |
++ "set volume quirk for QuickCam E3500\n"); |
784 |
++ cval->min = 6080; |
785 |
++ cval->max = 8768; |
786 |
++ cval->res = 192; |
787 |
++ } |
788 |
++ break; |
789 |
++ |
790 |
++ case USB_ID(0x046d, 0x0808): |
791 |
++ case USB_ID(0x046d, 0x0809): |
792 |
++ case USB_ID(0x046d, 0x0991): |
793 |
++ /* Most audio usb devices lie about volume resolution. |
794 |
++ * Most Logitech webcams have res = 384. |
795 |
++ * Proboly there is some logitech magic behind this number --fishor |
796 |
++ */ |
797 |
++ if (!strcmp(kctl->id.name, "Mic Capture Volume")) { |
798 |
++ snd_printk(KERN_INFO |
799 |
++ "set resolution quirk: cval->res = 384\n"); |
800 |
++ cval->res = 384; |
801 |
++ } |
802 |
++ break; |
803 |
++ |
804 |
++ } |
805 |
++} |
806 |
++ |
807 |
+ /* |
808 |
+ * retrieve the minimum and maximum values for the specified control |
809 |
+ */ |
810 |
+-static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) |
811 |
++static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, |
812 |
++ int default_min, struct snd_kcontrol *kctl) |
813 |
+ { |
814 |
+ /* for failsafe */ |
815 |
+ cval->min = default_min; |
816 |
+@@ -844,6 +894,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) |
817 |
+ cval->initialized = 1; |
818 |
+ } |
819 |
+ |
820 |
++ if (kctl) |
821 |
++ volume_control_quirks(cval, kctl); |
822 |
++ |
823 |
+ /* USB descriptions contain the dB scale in 1/256 dB unit |
824 |
+ * while ALSA TLV contains in 1/100 dB unit |
825 |
+ */ |
826 |
+@@ -864,6 +917,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) |
827 |
+ return 0; |
828 |
+ } |
829 |
+ |
830 |
++#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) |
831 |
+ |
832 |
+ /* get a feature/mixer unit info */ |
833 |
+ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
834 |
+@@ -881,8 +935,17 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ |
835 |
+ uinfo->value.integer.min = 0; |
836 |
+ uinfo->value.integer.max = 1; |
837 |
+ } else { |
838 |
+- if (! cval->initialized) |
839 |
+- get_min_max(cval, 0); |
840 |
++ if (!cval->initialized) { |
841 |
++ get_min_max_with_quirks(cval, 0, kcontrol); |
842 |
++ if (cval->initialized && cval->dBmin >= cval->dBmax) { |
843 |
++ kcontrol->vd[0].access &= |
844 |
++ ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
845 |
++ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); |
846 |
++ snd_ctl_notify(cval->mixer->chip->card, |
847 |
++ SNDRV_CTL_EVENT_MASK_INFO, |
848 |
++ &kcontrol->id); |
849 |
++ } |
850 |
++ } |
851 |
+ uinfo->value.integer.min = 0; |
852 |
+ uinfo->value.integer.max = |
853 |
+ (cval->max - cval->min + cval->res - 1) / cval->res; |
854 |
+@@ -1036,9 +1099,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
855 |
+ cval->ch_readonly = readonly_mask; |
856 |
+ } |
857 |
+ |
858 |
+- /* get min/max values */ |
859 |
+- get_min_max(cval, 0); |
860 |
+- |
861 |
+ /* if all channels in the mask are marked read-only, make the control |
862 |
+ * read-only. set_cur_mix_value() will check the mask again and won't |
863 |
+ * issue write commands to read-only channels. */ |
864 |
+@@ -1060,6 +1120,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
865 |
+ len = snd_usb_copy_string_desc(state, nameid, |
866 |
+ kctl->id.name, sizeof(kctl->id.name)); |
867 |
+ |
868 |
++ /* get min/max values */ |
869 |
++ get_min_max_with_quirks(cval, 0, kctl); |
870 |
++ |
871 |
+ switch (control) { |
872 |
+ case UAC_FU_MUTE: |
873 |
+ case UAC_FU_VOLUME: |
874 |
+@@ -1109,51 +1172,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
875 |
+ break; |
876 |
+ } |
877 |
+ |
878 |
+- /* volume control quirks */ |
879 |
+- switch (state->chip->usb_id) { |
880 |
+- case USB_ID(0x0471, 0x0101): |
881 |
+- case USB_ID(0x0471, 0x0104): |
882 |
+- case USB_ID(0x0471, 0x0105): |
883 |
+- case USB_ID(0x0672, 0x1041): |
884 |
+- /* quirk for UDA1321/N101. |
885 |
+- * note that detection between firmware 2.1.1.7 (N101) |
886 |
+- * and later 2.1.1.21 is not very clear from datasheets. |
887 |
+- * I hope that the min value is -15360 for newer firmware --jk |
888 |
+- */ |
889 |
+- if (!strcmp(kctl->id.name, "PCM Playback Volume") && |
890 |
+- cval->min == -15616) { |
891 |
+- snd_printk(KERN_INFO |
892 |
+- "set volume quirk for UDA1321/N101 chip\n"); |
893 |
+- cval->max = -256; |
894 |
+- } |
895 |
+- break; |
896 |
+- |
897 |
+- case USB_ID(0x046d, 0x09a4): |
898 |
+- if (!strcmp(kctl->id.name, "Mic Capture Volume")) { |
899 |
+- snd_printk(KERN_INFO |
900 |
+- "set volume quirk for QuickCam E3500\n"); |
901 |
+- cval->min = 6080; |
902 |
+- cval->max = 8768; |
903 |
+- cval->res = 192; |
904 |
+- } |
905 |
+- break; |
906 |
+- |
907 |
+- case USB_ID(0x046d, 0x0808): |
908 |
+- case USB_ID(0x046d, 0x0809): |
909 |
+- case USB_ID(0x046d, 0x0991): |
910 |
+- /* Most audio usb devices lie about volume resolution. |
911 |
+- * Most Logitech webcams have res = 384. |
912 |
+- * Proboly there is some logitech magic behind this number --fishor |
913 |
+- */ |
914 |
+- if (!strcmp(kctl->id.name, "Mic Capture Volume")) { |
915 |
+- snd_printk(KERN_INFO |
916 |
+- "set resolution quirk: cval->res = 384\n"); |
917 |
+- cval->res = 384; |
918 |
+- } |
919 |
+- break; |
920 |
+- |
921 |
+- } |
922 |
+- |
923 |
+ range = (cval->max - cval->min) / cval->res; |
924 |
+ /* Are there devices with volume range more than 255? I use a bit more |
925 |
+ * to be sure. 384 is a resolution magic number found on Logitech |