diff options
300 files changed, 5407 insertions, 1924 deletions
diff --git a/Documentation/devicetree/bindings/mips/cpu_irq.txt b/Documentation/devicetree/bindings/mips/cpu_irq.txt new file mode 100644 index 000000000000..13aa4b62c62a --- /dev/null +++ b/Documentation/devicetree/bindings/mips/cpu_irq.txt | |||
@@ -0,0 +1,47 @@ | |||
1 | MIPS CPU interrupt controller | ||
2 | |||
3 | On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU | ||
4 | IRQs from a devicetree file and create a irq_domain for IRQ controller. | ||
5 | |||
6 | With the irq_domain in place we can describe how the 8 IRQs are wired to the | ||
7 | platforms internal interrupt controller cascade. | ||
8 | |||
9 | Below is an example of a platform describing the cascade inside the devicetree | ||
10 | and the code used to load it inside arch_init_irq(). | ||
11 | |||
12 | Required properties: | ||
13 | - compatible : Should be "mti,cpu-interrupt-controller" | ||
14 | |||
15 | Example devicetree: | ||
16 | cpu-irq: cpu-irq@0 { | ||
17 | #address-cells = <0>; | ||
18 | |||
19 | interrupt-controller; | ||
20 | #interrupt-cells = <1>; | ||
21 | |||
22 | compatible = "mti,cpu-interrupt-controller"; | ||
23 | }; | ||
24 | |||
25 | intc: intc@200 { | ||
26 | compatible = "ralink,rt2880-intc"; | ||
27 | reg = <0x200 0x100>; | ||
28 | |||
29 | interrupt-controller; | ||
30 | #interrupt-cells = <1>; | ||
31 | |||
32 | interrupt-parent = <&cpu-irq>; | ||
33 | interrupts = <2>; | ||
34 | }; | ||
35 | |||
36 | |||
37 | Example platform irq.c: | ||
38 | static struct of_device_id __initdata of_irq_ids[] = { | ||
39 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, | ||
40 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, | ||
41 | {}, | ||
42 | }; | ||
43 | |||
44 | void __init arch_init_irq(void) | ||
45 | { | ||
46 | of_irq_init(of_irq_ids); | ||
47 | } | ||
diff --git a/Documentation/devicetree/bindings/serial/lantiq_asc.txt b/Documentation/devicetree/bindings/serial/lantiq_asc.txt new file mode 100644 index 000000000000..5b78591aaa46 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/lantiq_asc.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | Lantiq SoC ASC serial controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Should be "lantiq,asc" | ||
5 | - reg : Address and length of the register set for the device | ||
6 | - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier | ||
7 | depends on the interrupt-parent interrupt controller. | ||
8 | |||
9 | Example: | ||
10 | |||
11 | asc1: serial@E100C00 { | ||
12 | compatible = "lantiq,asc"; | ||
13 | reg = <0xE100C00 0x400>; | ||
14 | interrupt-parent = <&icu0>; | ||
15 | interrupts = <112 113 114>; | ||
16 | }; | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 363e348bff9b..6c723811c0a0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2438,7 +2438,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2438 | real-time workloads. It can also improve energy | 2438 | real-time workloads. It can also improve energy |
2439 | efficiency for asymmetric multiprocessors. | 2439 | efficiency for asymmetric multiprocessors. |
2440 | 2440 | ||
2441 | rcu_nocbs_poll [KNL,BOOT] | 2441 | rcu_nocb_poll [KNL,BOOT] |
2442 | Rather than requiring that offloaded CPUs | 2442 | Rather than requiring that offloaded CPUs |
2443 | (specified by rcu_nocbs= above) explicitly | 2443 | (specified by rcu_nocbs= above) explicitly |
2444 | awaken the corresponding "rcuoN" kthreads, | 2444 | awaken the corresponding "rcuoN" kthreads, |
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index 3edb4c2887a1..e540fd67f767 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt | |||
@@ -57,7 +57,7 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment | |||
57 | Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover | 57 | Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover |
58 | protocol entry point. | 58 | protocol entry point. |
59 | 59 | ||
60 | Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields | 60 | Protocol 2.12: (Kernel 3.8) Added the xloadflags field and extension fields |
61 | to struct boot_params for for loading bzImage and ramdisk | 61 | to struct boot_params for for loading bzImage and ramdisk |
62 | above 4G in 64bit. | 62 | above 4G in 64bit. |
63 | 63 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 212c255b9347..35a56bcd5e75 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1489,7 +1489,7 @@ AVR32 ARCHITECTURE | |||
1489 | M: Haavard Skinnemoen <hskinnemoen@gmail.com> | 1489 | M: Haavard Skinnemoen <hskinnemoen@gmail.com> |
1490 | M: Hans-Christian Egtvedt <egtvedt@samfundet.no> | 1490 | M: Hans-Christian Egtvedt <egtvedt@samfundet.no> |
1491 | W: http://www.atmel.com/products/AVR32/ | 1491 | W: http://www.atmel.com/products/AVR32/ |
1492 | W: http://avr32linux.org/ | 1492 | W: http://mirror.egtvedt.no/avr32linux.org/ |
1493 | W: http://avrfreaks.net/ | 1493 | W: http://avrfreaks.net/ |
1494 | S: Maintained | 1494 | S: Maintained |
1495 | F: arch/avr32/ | 1495 | F: arch/avr32/ |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 8 | 2 | PATCHLEVEL = 8 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc6 | 4 | EXTRAVERSION = -rc7 |
5 | NAME = Unicycling Gorilla | 5 | NAME = Unicycling Gorilla |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 36ae03a3f5d1..87dfa9026c5b 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -351,6 +351,25 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) | |||
351 | irq_set_chained_handler(irq, gic_handle_cascade_irq); | 351 | irq_set_chained_handler(irq, gic_handle_cascade_irq); |
352 | } | 352 | } |
353 | 353 | ||
354 | static u8 gic_get_cpumask(struct gic_chip_data *gic) | ||
355 | { | ||
356 | void __iomem *base = gic_data_dist_base(gic); | ||
357 | u32 mask, i; | ||
358 | |||
359 | for (i = mask = 0; i < 32; i += 4) { | ||
360 | mask = readl_relaxed(base + GIC_DIST_TARGET + i); | ||
361 | mask |= mask >> 16; | ||
362 | mask |= mask >> 8; | ||
363 | if (mask) | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | if (!mask) | ||
368 | pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); | ||
369 | |||
370 | return mask; | ||
371 | } | ||
372 | |||
354 | static void __init gic_dist_init(struct gic_chip_data *gic) | 373 | static void __init gic_dist_init(struct gic_chip_data *gic) |
355 | { | 374 | { |
356 | unsigned int i; | 375 | unsigned int i; |
@@ -369,7 +388,9 @@ static void __init gic_dist_init(struct gic_chip_data *gic) | |||
369 | /* | 388 | /* |
370 | * Set all global interrupts to this CPU only. | 389 | * Set all global interrupts to this CPU only. |
371 | */ | 390 | */ |
372 | cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0); | 391 | cpumask = gic_get_cpumask(gic); |
392 | cpumask |= cpumask << 8; | ||
393 | cpumask |= cpumask << 16; | ||
373 | for (i = 32; i < gic_irqs; i += 4) | 394 | for (i = 32; i < gic_irqs; i += 4) |
374 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); | 395 | writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); |
375 | 396 | ||
@@ -400,7 +421,7 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | |||
400 | * Get what the GIC says our CPU mask is. | 421 | * Get what the GIC says our CPU mask is. |
401 | */ | 422 | */ |
402 | BUG_ON(cpu >= NR_GIC_CPU_IF); | 423 | BUG_ON(cpu >= NR_GIC_CPU_IF); |
403 | cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0); | 424 | cpu_mask = gic_get_cpumask(gic); |
404 | gic_cpu_map[cpu] = cpu_mask; | 425 | gic_cpu_map[cpu] = cpu_mask; |
405 | 426 | ||
406 | /* | 427 | /* |
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 73cf03aa981e..1c4df27f9332 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
@@ -37,7 +37,7 @@ | |||
37 | */ | 37 | */ |
38 | #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) | 38 | #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) |
39 | #define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000)) | 39 | #define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000)) |
40 | #define TASK_UNMAPPED_BASE (UL(CONFIG_PAGE_OFFSET) / 3) | 40 | #define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * The maximum size of a 26-bit user space task. | 43 | * The maximum size of a 26-bit user space task. |
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index e103c290bc9e..85afb031b676 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig | |||
@@ -414,7 +414,7 @@ config MACH_EXYNOS4_DT | |||
414 | select CPU_EXYNOS4210 | 414 | select CPU_EXYNOS4210 |
415 | select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD | 415 | select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD |
416 | select PINCTRL | 416 | select PINCTRL |
417 | select PINCTRL_EXYNOS4 | 417 | select PINCTRL_EXYNOS |
418 | select USE_OF | 418 | select USE_OF |
419 | help | 419 | help |
420 | Machine support for Samsung Exynos4 machine with device tree enabled. | 420 | Machine support for Samsung Exynos4 machine with device tree enabled. |
diff --git a/arch/arm/mach-realview/include/mach/irqs-eb.h b/arch/arm/mach-realview/include/mach/irqs-eb.h index d6b5073692d2..44754230fdcc 100644 --- a/arch/arm/mach-realview/include/mach/irqs-eb.h +++ b/arch/arm/mach-realview/include/mach/irqs-eb.h | |||
@@ -115,7 +115,7 @@ | |||
115 | /* | 115 | /* |
116 | * Only define NR_IRQS if less than NR_IRQS_EB | 116 | * Only define NR_IRQS if less than NR_IRQS_EB |
117 | */ | 117 | */ |
118 | #define NR_IRQS_EB (IRQ_EB_GIC_START + 96) | 118 | #define NR_IRQS_EB (IRQ_EB_GIC_START + 128) |
119 | 119 | ||
120 | #if defined(CONFIG_MACH_REALVIEW_EB) \ | 120 | #if defined(CONFIG_MACH_REALVIEW_EB) \ |
121 | && (!defined(NR_IRQS) || (NR_IRQS < NR_IRQS_EB)) | 121 | && (!defined(NR_IRQS) || (NR_IRQS < NR_IRQS_EB)) |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 076c26d43864..dda3904dc64c 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -640,7 +640,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, | |||
640 | 640 | ||
641 | if (is_coherent || nommu()) | 641 | if (is_coherent || nommu()) |
642 | addr = __alloc_simple_buffer(dev, size, gfp, &page); | 642 | addr = __alloc_simple_buffer(dev, size, gfp, &page); |
643 | else if (gfp & GFP_ATOMIC) | 643 | else if (!(gfp & __GFP_WAIT)) |
644 | addr = __alloc_from_pool(size, &page); | 644 | addr = __alloc_from_pool(size, &page); |
645 | else if (!IS_ENABLED(CONFIG_CMA)) | 645 | else if (!IS_ENABLED(CONFIG_CMA)) |
646 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); | 646 | addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); |
diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h index aaf5199d8fcb..b3d18f9f3e8d 100644 --- a/arch/avr32/include/asm/dma-mapping.h +++ b/arch/avr32/include/asm/dma-mapping.h | |||
@@ -336,4 +336,14 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, | |||
336 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 336 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
337 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 337 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
338 | 338 | ||
339 | /* drivers/base/dma-mapping.c */ | ||
340 | extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, | ||
341 | void *cpu_addr, dma_addr_t dma_addr, size_t size); | ||
342 | extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
343 | void *cpu_addr, dma_addr_t dma_addr, | ||
344 | size_t size); | ||
345 | |||
346 | #define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s) | ||
347 | #define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s) | ||
348 | |||
339 | #endif /* __ASM_AVR32_DMA_MAPPING_H */ | 349 | #endif /* __ASM_AVR32_DMA_MAPPING_H */ |
diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h index bbf461076a0a..054d9ec57d9d 100644 --- a/arch/blackfin/include/asm/dma-mapping.h +++ b/arch/blackfin/include/asm/dma-mapping.h | |||
@@ -154,4 +154,14 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
154 | _dma_sync((dma_addr_t)vaddr, size, dir); | 154 | _dma_sync((dma_addr_t)vaddr, size, dir); |
155 | } | 155 | } |
156 | 156 | ||
157 | /* drivers/base/dma-mapping.c */ | ||
158 | extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, | ||
159 | void *cpu_addr, dma_addr_t dma_addr, size_t size); | ||
160 | extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
161 | void *cpu_addr, dma_addr_t dma_addr, | ||
162 | size_t size); | ||
163 | |||
164 | #define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s) | ||
165 | #define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s) | ||
166 | |||
157 | #endif /* _BLACKFIN_DMA_MAPPING_H */ | 167 | #endif /* _BLACKFIN_DMA_MAPPING_H */ |
diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h index 3c694065030f..88bd0d899bdb 100644 --- a/arch/c6x/include/asm/dma-mapping.h +++ b/arch/c6x/include/asm/dma-mapping.h | |||
@@ -89,4 +89,19 @@ extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); | |||
89 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) | 89 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) |
90 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h)) | 90 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h)) |
91 | 91 | ||
92 | /* Not supported for now */ | ||
93 | static inline int dma_mmap_coherent(struct device *dev, | ||
94 | struct vm_area_struct *vma, void *cpu_addr, | ||
95 | dma_addr_t dma_addr, size_t size) | ||
96 | { | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
101 | void *cpu_addr, dma_addr_t dma_addr, | ||
102 | size_t size) | ||
103 | { | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | |||
92 | #endif /* _ASM_C6X_DMA_MAPPING_H */ | 107 | #endif /* _ASM_C6X_DMA_MAPPING_H */ |
diff --git a/arch/cris/include/asm/dma-mapping.h b/arch/cris/include/asm/dma-mapping.h index 8588b2ccf854..2f0f654f1b44 100644 --- a/arch/cris/include/asm/dma-mapping.h +++ b/arch/cris/include/asm/dma-mapping.h | |||
@@ -158,5 +158,15 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
158 | { | 158 | { |
159 | } | 159 | } |
160 | 160 | ||
161 | /* drivers/base/dma-mapping.c */ | ||
162 | extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, | ||
163 | void *cpu_addr, dma_addr_t dma_addr, size_t size); | ||
164 | extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
165 | void *cpu_addr, dma_addr_t dma_addr, | ||
166 | size_t size); | ||
167 | |||
168 | #define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s) | ||
169 | #define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s) | ||
170 | |||
161 | 171 | ||
162 | #endif | 172 | #endif |
diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h index dfb811002c64..1746a2b8e6e7 100644 --- a/arch/frv/include/asm/dma-mapping.h +++ b/arch/frv/include/asm/dma-mapping.h | |||
@@ -132,4 +132,19 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
132 | flush_write_buffers(); | 132 | flush_write_buffers(); |
133 | } | 133 | } |
134 | 134 | ||
135 | /* Not supported for now */ | ||
136 | static inline int dma_mmap_coherent(struct device *dev, | ||
137 | struct vm_area_struct *vma, void *cpu_addr, | ||
138 | dma_addr_t dma_addr, size_t size) | ||
139 | { | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
144 | void *cpu_addr, dma_addr_t dma_addr, | ||
145 | size_t size) | ||
146 | { | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | |||
135 | #endif /* _ASM_DMA_MAPPING_H */ | 150 | #endif /* _ASM_DMA_MAPPING_H */ |
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h index 3e6b8445af6a..292805f0762e 100644 --- a/arch/m68k/include/asm/dma-mapping.h +++ b/arch/m68k/include/asm/dma-mapping.h | |||
@@ -115,4 +115,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) | |||
115 | #include <asm-generic/dma-mapping-broken.h> | 115 | #include <asm-generic/dma-mapping-broken.h> |
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | /* drivers/base/dma-mapping.c */ | ||
119 | extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, | ||
120 | void *cpu_addr, dma_addr_t dma_addr, size_t size); | ||
121 | extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
122 | void *cpu_addr, dma_addr_t dma_addr, | ||
123 | size_t size); | ||
124 | |||
125 | #define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s) | ||
126 | #define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s) | ||
127 | |||
118 | #endif /* _M68K_DMA_MAPPING_H */ | 128 | #endif /* _M68K_DMA_MAPPING_H */ |
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 5c088494e046..4b597d91a8d5 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms | |||
@@ -21,6 +21,7 @@ platforms += netlogic | |||
21 | platforms += pmcs-msp71xx | 21 | platforms += pmcs-msp71xx |
22 | platforms += pnx833x | 22 | platforms += pnx833x |
23 | platforms += powertv | 23 | platforms += powertv |
24 | platforms += ralink | ||
24 | platforms += rb532 | 25 | platforms += rb532 |
25 | platforms += sgi-ip22 | 26 | platforms += sgi-ip22 |
26 | platforms += sgi-ip27 | 27 | platforms += sgi-ip27 |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index af4e04fde0b4..6fe9a188c49f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -107,12 +107,14 @@ config ATH79 | |||
107 | config BCM47XX | 107 | config BCM47XX |
108 | bool "Broadcom BCM47XX based boards" | 108 | bool "Broadcom BCM47XX based boards" |
109 | select ARCH_WANT_OPTIONAL_GPIOLIB | 109 | select ARCH_WANT_OPTIONAL_GPIOLIB |
110 | select BOOT_RAW | ||
110 | select CEVT_R4K | 111 | select CEVT_R4K |
111 | select CSRC_R4K | 112 | select CSRC_R4K |
112 | select DMA_NONCOHERENT | 113 | select DMA_NONCOHERENT |
113 | select FW_CFE | 114 | select FW_CFE |
114 | select HW_HAS_PCI | 115 | select HW_HAS_PCI |
115 | select IRQ_CPU | 116 | select IRQ_CPU |
117 | select NO_EXCEPT_FILL | ||
116 | select SYS_SUPPORTS_32BIT_KERNEL | 118 | select SYS_SUPPORTS_32BIT_KERNEL |
117 | select SYS_SUPPORTS_LITTLE_ENDIAN | 119 | select SYS_SUPPORTS_LITTLE_ENDIAN |
118 | select SYS_HAS_EARLY_PRINTK | 120 | select SYS_HAS_EARLY_PRINTK |
@@ -294,6 +296,7 @@ config MIPS_MALTA | |||
294 | select BOOT_RAW | 296 | select BOOT_RAW |
295 | select CEVT_R4K | 297 | select CEVT_R4K |
296 | select CSRC_R4K | 298 | select CSRC_R4K |
299 | select CSRC_GIC | ||
297 | select DMA_NONCOHERENT | 300 | select DMA_NONCOHERENT |
298 | select GENERIC_ISA_DMA | 301 | select GENERIC_ISA_DMA |
299 | select HAVE_PCSPKR_PLATFORM | 302 | select HAVE_PCSPKR_PLATFORM |
@@ -425,6 +428,22 @@ config POWERTV | |||
425 | help | 428 | help |
426 | This enables support for the Cisco PowerTV Platform. | 429 | This enables support for the Cisco PowerTV Platform. |
427 | 430 | ||
431 | config RALINK | ||
432 | bool "Ralink based machines" | ||
433 | select CEVT_R4K | ||
434 | select CSRC_R4K | ||
435 | select BOOT_RAW | ||
436 | select DMA_NONCOHERENT | ||
437 | select IRQ_CPU | ||
438 | select USE_OF | ||
439 | select SYS_HAS_CPU_MIPS32_R1 | ||
440 | select SYS_HAS_CPU_MIPS32_R2 | ||
441 | select SYS_SUPPORTS_32BIT_KERNEL | ||
442 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
443 | select SYS_HAS_EARLY_PRINTK | ||
444 | select HAVE_MACH_CLKDEV | ||
445 | select CLKDEV_LOOKUP | ||
446 | |||
428 | config SGI_IP22 | 447 | config SGI_IP22 |
429 | bool "SGI IP22 (Indy/Indigo2)" | 448 | bool "SGI IP22 (Indy/Indigo2)" |
430 | select FW_ARC | 449 | select FW_ARC |
@@ -837,6 +856,7 @@ source "arch/mips/lantiq/Kconfig" | |||
837 | source "arch/mips/lasat/Kconfig" | 856 | source "arch/mips/lasat/Kconfig" |
838 | source "arch/mips/pmcs-msp71xx/Kconfig" | 857 | source "arch/mips/pmcs-msp71xx/Kconfig" |
839 | source "arch/mips/powertv/Kconfig" | 858 | source "arch/mips/powertv/Kconfig" |
859 | source "arch/mips/ralink/Kconfig" | ||
840 | source "arch/mips/sgi-ip27/Kconfig" | 860 | source "arch/mips/sgi-ip27/Kconfig" |
841 | source "arch/mips/sibyte/Kconfig" | 861 | source "arch/mips/sibyte/Kconfig" |
842 | source "arch/mips/txx9/Kconfig" | 862 | source "arch/mips/txx9/Kconfig" |
@@ -917,6 +937,9 @@ config CSRC_POWERTV | |||
917 | config CSRC_R4K | 937 | config CSRC_R4K |
918 | bool | 938 | bool |
919 | 939 | ||
940 | config CSRC_GIC | ||
941 | bool | ||
942 | |||
920 | config CSRC_SB1250 | 943 | config CSRC_SB1250 |
921 | bool | 944 | bool |
922 | 945 | ||
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index f44feee2d67f..3995e31a73e2 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig | |||
@@ -14,6 +14,18 @@ config ATH79_MACH_AP121 | |||
14 | Say 'Y' here if you want your kernel to support the | 14 | Say 'Y' here if you want your kernel to support the |
15 | Atheros AP121 reference board. | 15 | Atheros AP121 reference board. |
16 | 16 | ||
17 | config ATH79_MACH_AP136 | ||
18 | bool "Atheros AP136 reference board" | ||
19 | select SOC_QCA955X | ||
20 | select ATH79_DEV_GPIO_BUTTONS | ||
21 | select ATH79_DEV_LEDS_GPIO | ||
22 | select ATH79_DEV_SPI | ||
23 | select ATH79_DEV_USB | ||
24 | select ATH79_DEV_WMAC | ||
25 | help | ||
26 | Say 'Y' here if you want your kernel to support the | ||
27 | Atheros AP136 reference board. | ||
28 | |||
17 | config ATH79_MACH_AP81 | 29 | config ATH79_MACH_AP81 |
18 | bool "Atheros AP81 reference board" | 30 | bool "Atheros AP81 reference board" |
19 | select SOC_AR913X | 31 | select SOC_AR913X |
@@ -88,6 +100,12 @@ config SOC_AR934X | |||
88 | select PCI_AR724X if PCI | 100 | select PCI_AR724X if PCI |
89 | def_bool n | 101 | def_bool n |
90 | 102 | ||
103 | config SOC_QCA955X | ||
104 | select USB_ARCH_HAS_EHCI | ||
105 | select HW_HAS_PCI | ||
106 | select PCI_AR724X if PCI | ||
107 | def_bool n | ||
108 | |||
91 | config PCI_AR724X | 109 | config PCI_AR724X |
92 | def_bool n | 110 | def_bool n |
93 | 111 | ||
@@ -104,7 +122,7 @@ config ATH79_DEV_USB | |||
104 | def_bool n | 122 | def_bool n |
105 | 123 | ||
106 | config ATH79_DEV_WMAC | 124 | config ATH79_DEV_WMAC |
107 | depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X) | 125 | depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X) |
108 | def_bool n | 126 | def_bool n |
109 | 127 | ||
110 | endif | 128 | endif |
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile index 2b54d98263f3..5c9ff692ff3c 100644 --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile | |||
@@ -27,6 +27,7 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o | |||
27 | # Machines | 27 | # Machines |
28 | # | 28 | # |
29 | obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o | 29 | obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o |
30 | obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o | ||
30 | obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o | 31 | obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o |
31 | obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o | 32 | obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o |
32 | obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o | 33 | obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o |
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 8c1b8bf9b32f..765ef30e3e1c 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c | |||
@@ -295,6 +295,82 @@ static void __init ar934x_clocks_init(void) | |||
295 | iounmap(dpll_base); | 295 | iounmap(dpll_base); |
296 | } | 296 | } |
297 | 297 | ||
298 | static void __init qca955x_clocks_init(void) | ||
299 | { | ||
300 | u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; | ||
301 | u32 cpu_pll, ddr_pll; | ||
302 | u32 bootstrap; | ||
303 | |||
304 | bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); | ||
305 | if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) | ||
306 | ath79_ref_clk.rate = 40 * 1000 * 1000; | ||
307 | else | ||
308 | ath79_ref_clk.rate = 25 * 1000 * 1000; | ||
309 | |||
310 | pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); | ||
311 | out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
312 | QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
313 | ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
314 | QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
315 | nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & | ||
316 | QCA955X_PLL_CPU_CONFIG_NINT_MASK; | ||
317 | frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & | ||
318 | QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; | ||
319 | |||
320 | cpu_pll = nint * ath79_ref_clk.rate / ref_div; | ||
321 | cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6)); | ||
322 | cpu_pll /= (1 << out_div); | ||
323 | |||
324 | pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); | ||
325 | out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||
326 | QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||
327 | ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||
328 | QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; | ||
329 | nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & | ||
330 | QCA955X_PLL_DDR_CONFIG_NINT_MASK; | ||
331 | frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & | ||
332 | QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; | ||
333 | |||
334 | ddr_pll = nint * ath79_ref_clk.rate / ref_div; | ||
335 | ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10)); | ||
336 | ddr_pll /= (1 << out_div); | ||
337 | |||
338 | clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); | ||
339 | |||
340 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||
341 | QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||
342 | |||
343 | if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) | ||
344 | ath79_cpu_clk.rate = ath79_ref_clk.rate; | ||
345 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) | ||
346 | ath79_cpu_clk.rate = ddr_pll / (postdiv + 1); | ||
347 | else | ||
348 | ath79_cpu_clk.rate = cpu_pll / (postdiv + 1); | ||
349 | |||
350 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & | ||
351 | QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; | ||
352 | |||
353 | if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) | ||
354 | ath79_ddr_clk.rate = ath79_ref_clk.rate; | ||
355 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) | ||
356 | ath79_ddr_clk.rate = cpu_pll / (postdiv + 1); | ||
357 | else | ||
358 | ath79_ddr_clk.rate = ddr_pll / (postdiv + 1); | ||
359 | |||
360 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & | ||
361 | QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; | ||
362 | |||
363 | if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) | ||
364 | ath79_ahb_clk.rate = ath79_ref_clk.rate; | ||
365 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) | ||
366 | ath79_ahb_clk.rate = ddr_pll / (postdiv + 1); | ||
367 | else | ||
368 | ath79_ahb_clk.rate = cpu_pll / (postdiv + 1); | ||
369 | |||
370 | ath79_wdt_clk.rate = ath79_ref_clk.rate; | ||
371 | ath79_uart_clk.rate = ath79_ref_clk.rate; | ||
372 | } | ||
373 | |||
298 | void __init ath79_clocks_init(void) | 374 | void __init ath79_clocks_init(void) |
299 | { | 375 | { |
300 | if (soc_is_ar71xx()) | 376 | if (soc_is_ar71xx()) |
@@ -307,6 +383,8 @@ void __init ath79_clocks_init(void) | |||
307 | ar933x_clocks_init(); | 383 | ar933x_clocks_init(); |
308 | else if (soc_is_ar934x()) | 384 | else if (soc_is_ar934x()) |
309 | ar934x_clocks_init(); | 385 | ar934x_clocks_init(); |
386 | else if (soc_is_qca955x()) | ||
387 | qca955x_clocks_init(); | ||
310 | else | 388 | else |
311 | BUG(); | 389 | BUG(); |
312 | 390 | ||
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index 5a4adfc9d79d..eb3966cd8cfc 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c | |||
@@ -72,6 +72,8 @@ void ath79_device_reset_set(u32 mask) | |||
72 | reg = AR933X_RESET_REG_RESET_MODULE; | 72 | reg = AR933X_RESET_REG_RESET_MODULE; |
73 | else if (soc_is_ar934x()) | 73 | else if (soc_is_ar934x()) |
74 | reg = AR934X_RESET_REG_RESET_MODULE; | 74 | reg = AR934X_RESET_REG_RESET_MODULE; |
75 | else if (soc_is_qca955x()) | ||
76 | reg = QCA955X_RESET_REG_RESET_MODULE; | ||
75 | else | 77 | else |
76 | BUG(); | 78 | BUG(); |
77 | 79 | ||
@@ -98,6 +100,8 @@ void ath79_device_reset_clear(u32 mask) | |||
98 | reg = AR933X_RESET_REG_RESET_MODULE; | 100 | reg = AR933X_RESET_REG_RESET_MODULE; |
99 | else if (soc_is_ar934x()) | 101 | else if (soc_is_ar934x()) |
100 | reg = AR934X_RESET_REG_RESET_MODULE; | 102 | reg = AR934X_RESET_REG_RESET_MODULE; |
103 | else if (soc_is_qca955x()) | ||
104 | reg = QCA955X_RESET_REG_RESET_MODULE; | ||
101 | else | 105 | else |
102 | BUG(); | 106 | BUG(); |
103 | 107 | ||
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index 45efc63b08b6..9516aab27139 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c | |||
@@ -36,7 +36,7 @@ static struct resource ath79_uart_resources[] = { | |||
36 | static struct plat_serial8250_port ath79_uart_data[] = { | 36 | static struct plat_serial8250_port ath79_uart_data[] = { |
37 | { | 37 | { |
38 | .mapbase = AR71XX_UART_BASE, | 38 | .mapbase = AR71XX_UART_BASE, |
39 | .irq = ATH79_MISC_IRQ_UART, | 39 | .irq = ATH79_MISC_IRQ(3), |
40 | .flags = AR71XX_UART_FLAGS, | 40 | .flags = AR71XX_UART_FLAGS, |
41 | .iotype = UPIO_MEM32, | 41 | .iotype = UPIO_MEM32, |
42 | .regshift = 2, | 42 | .regshift = 2, |
@@ -62,8 +62,8 @@ static struct resource ar933x_uart_resources[] = { | |||
62 | .flags = IORESOURCE_MEM, | 62 | .flags = IORESOURCE_MEM, |
63 | }, | 63 | }, |
64 | { | 64 | { |
65 | .start = ATH79_MISC_IRQ_UART, | 65 | .start = ATH79_MISC_IRQ(3), |
66 | .end = ATH79_MISC_IRQ_UART, | 66 | .end = ATH79_MISC_IRQ(3), |
67 | .flags = IORESOURCE_IRQ, | 67 | .flags = IORESOURCE_IRQ, |
68 | }, | 68 | }, |
69 | }; | 69 | }; |
@@ -90,7 +90,8 @@ void __init ath79_register_uart(void) | |||
90 | if (soc_is_ar71xx() || | 90 | if (soc_is_ar71xx() || |
91 | soc_is_ar724x() || | 91 | soc_is_ar724x() || |
92 | soc_is_ar913x() || | 92 | soc_is_ar913x() || |
93 | soc_is_ar934x()) { | 93 | soc_is_ar934x() || |
94 | soc_is_qca955x()) { | ||
94 | ath79_uart_data[0].uartclk = clk_get_rate(clk); | 95 | ath79_uart_data[0].uartclk = clk_get_rate(clk); |
95 | platform_device_register(&ath79_uart_device); | 96 | platform_device_register(&ath79_uart_device); |
96 | } else if (soc_is_ar933x()) { | 97 | } else if (soc_is_ar933x()) { |
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index bd2bc108e1b5..8227265bcc2d 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c | |||
@@ -25,29 +25,11 @@ | |||
25 | #include "common.h" | 25 | #include "common.h" |
26 | #include "dev-usb.h" | 26 | #include "dev-usb.h" |
27 | 27 | ||
28 | static struct resource ath79_ohci_resources[2]; | 28 | static u64 ath79_usb_dmamask = DMA_BIT_MASK(32); |
29 | |||
30 | static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); | ||
31 | 29 | ||
32 | static struct usb_ohci_pdata ath79_ohci_pdata = { | 30 | static struct usb_ohci_pdata ath79_ohci_pdata = { |
33 | }; | 31 | }; |
34 | 32 | ||
35 | static struct platform_device ath79_ohci_device = { | ||
36 | .name = "ohci-platform", | ||
37 | .id = -1, | ||
38 | .resource = ath79_ohci_resources, | ||
39 | .num_resources = ARRAY_SIZE(ath79_ohci_resources), | ||
40 | .dev = { | ||
41 | .dma_mask = &ath79_ohci_dmamask, | ||
42 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
43 | .platform_data = &ath79_ohci_pdata, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | static struct resource ath79_ehci_resources[2]; | ||
48 | |||
49 | static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); | ||
50 | |||
51 | static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { | 33 | static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { |
52 | .has_synopsys_hc_bug = 1, | 34 | .has_synopsys_hc_bug = 1, |
53 | }; | 35 | }; |
@@ -57,22 +39,16 @@ static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { | |||
57 | .has_tt = 1, | 39 | .has_tt = 1, |
58 | }; | 40 | }; |
59 | 41 | ||
60 | static struct platform_device ath79_ehci_device = { | 42 | static void __init ath79_usb_register(const char *name, int id, |
61 | .name = "ehci-platform", | 43 | unsigned long base, unsigned long size, |
62 | .id = -1, | 44 | int irq, const void *data, |
63 | .resource = ath79_ehci_resources, | 45 | size_t data_size) |
64 | .num_resources = ARRAY_SIZE(ath79_ehci_resources), | ||
65 | .dev = { | ||
66 | .dma_mask = &ath79_ehci_dmamask, | ||
67 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
68 | }, | ||
69 | }; | ||
70 | |||
71 | static void __init ath79_usb_init_resource(struct resource res[2], | ||
72 | unsigned long base, | ||
73 | unsigned long size, | ||
74 | int irq) | ||
75 | { | 46 | { |
47 | struct resource res[2]; | ||
48 | struct platform_device *pdev; | ||
49 | |||
50 | memset(res, 0, sizeof(res)); | ||
51 | |||
76 | res[0].flags = IORESOURCE_MEM; | 52 | res[0].flags = IORESOURCE_MEM; |
77 | res[0].start = base; | 53 | res[0].start = base; |
78 | res[0].end = base + size - 1; | 54 | res[0].end = base + size - 1; |
@@ -80,6 +56,19 @@ static void __init ath79_usb_init_resource(struct resource res[2], | |||
80 | res[1].flags = IORESOURCE_IRQ; | 56 | res[1].flags = IORESOURCE_IRQ; |
81 | res[1].start = irq; | 57 | res[1].start = irq; |
82 | res[1].end = irq; | 58 | res[1].end = irq; |
59 | |||
60 | pdev = platform_device_register_resndata(NULL, name, id, | ||
61 | res, ARRAY_SIZE(res), | ||
62 | data, data_size); | ||
63 | |||
64 | if (IS_ERR(pdev)) { | ||
65 | pr_err("ath79: unable to register USB at %08lx, err=%d\n", | ||
66 | base, (int) PTR_ERR(pdev)); | ||
67 | return; | ||
68 | } | ||
69 | |||
70 | pdev->dev.dma_mask = &ath79_usb_dmamask; | ||
71 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
83 | } | 72 | } |
84 | 73 | ||
85 | #define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ | 74 | #define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ |
@@ -106,14 +95,15 @@ static void __init ath79_usb_setup(void) | |||
106 | 95 | ||
107 | mdelay(900); | 96 | mdelay(900); |
108 | 97 | ||
109 | ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE, | 98 | ath79_usb_register("ohci-platform", -1, |
110 | AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI); | 99 | AR71XX_OHCI_BASE, AR71XX_OHCI_SIZE, |
111 | platform_device_register(&ath79_ohci_device); | 100 | ATH79_MISC_IRQ(6), |
101 | &ath79_ohci_pdata, sizeof(ath79_ohci_pdata)); | ||
112 | 102 | ||
113 | ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE, | 103 | ath79_usb_register("ehci-platform", -1, |
114 | AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB); | 104 | AR71XX_EHCI_BASE, AR71XX_EHCI_SIZE, |
115 | ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; | 105 | ATH79_CPU_IRQ(3), |
116 | platform_device_register(&ath79_ehci_device); | 106 | &ath79_ehci_pdata_v1, sizeof(ath79_ehci_pdata_v1)); |
117 | } | 107 | } |
118 | 108 | ||
119 | static void __init ar7240_usb_setup(void) | 109 | static void __init ar7240_usb_setup(void) |
@@ -135,9 +125,10 @@ static void __init ar7240_usb_setup(void) | |||
135 | 125 | ||
136 | iounmap(usb_ctrl_base); | 126 | iounmap(usb_ctrl_base); |
137 | 127 | ||
138 | ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE, | 128 | ath79_usb_register("ohci-platform", -1, |
139 | AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB); | 129 | AR7240_OHCI_BASE, AR7240_OHCI_SIZE, |
140 | platform_device_register(&ath79_ohci_device); | 130 | ATH79_CPU_IRQ(3), |
131 | &ath79_ohci_pdata, sizeof(ath79_ohci_pdata)); | ||
141 | } | 132 | } |
142 | 133 | ||
143 | static void __init ar724x_usb_setup(void) | 134 | static void __init ar724x_usb_setup(void) |
@@ -151,10 +142,10 @@ static void __init ar724x_usb_setup(void) | |||
151 | ath79_device_reset_clear(AR724X_RESET_USB_PHY); | 142 | ath79_device_reset_clear(AR724X_RESET_USB_PHY); |
152 | mdelay(10); | 143 | mdelay(10); |
153 | 144 | ||
154 | ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE, | 145 | ath79_usb_register("ehci-platform", -1, |
155 | AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB); | 146 | AR724X_EHCI_BASE, AR724X_EHCI_SIZE, |
156 | ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; | 147 | ATH79_CPU_IRQ(3), |
157 | platform_device_register(&ath79_ehci_device); | 148 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); |
158 | } | 149 | } |
159 | 150 | ||
160 | static void __init ar913x_usb_setup(void) | 151 | static void __init ar913x_usb_setup(void) |
@@ -168,10 +159,10 @@ static void __init ar913x_usb_setup(void) | |||
168 | ath79_device_reset_clear(AR913X_RESET_USB_PHY); | 159 | ath79_device_reset_clear(AR913X_RESET_USB_PHY); |
169 | mdelay(10); | 160 | mdelay(10); |
170 | 161 | ||
171 | ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE, | 162 | ath79_usb_register("ehci-platform", -1, |
172 | AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB); | 163 | AR913X_EHCI_BASE, AR913X_EHCI_SIZE, |
173 | ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; | 164 | ATH79_CPU_IRQ(3), |
174 | platform_device_register(&ath79_ehci_device); | 165 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); |
175 | } | 166 | } |
176 | 167 | ||
177 | static void __init ar933x_usb_setup(void) | 168 | static void __init ar933x_usb_setup(void) |
@@ -185,10 +176,10 @@ static void __init ar933x_usb_setup(void) | |||
185 | ath79_device_reset_clear(AR933X_RESET_USB_PHY); | 176 | ath79_device_reset_clear(AR933X_RESET_USB_PHY); |
186 | mdelay(10); | 177 | mdelay(10); |
187 | 178 | ||
188 | ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE, | 179 | ath79_usb_register("ehci-platform", -1, |
189 | AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB); | 180 | AR933X_EHCI_BASE, AR933X_EHCI_SIZE, |
190 | ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; | 181 | ATH79_CPU_IRQ(3), |
191 | platform_device_register(&ath79_ehci_device); | 182 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); |
192 | } | 183 | } |
193 | 184 | ||
194 | static void __init ar934x_usb_setup(void) | 185 | static void __init ar934x_usb_setup(void) |
@@ -211,10 +202,23 @@ static void __init ar934x_usb_setup(void) | |||
211 | ath79_device_reset_clear(AR934X_RESET_USB_HOST); | 202 | ath79_device_reset_clear(AR934X_RESET_USB_HOST); |
212 | udelay(1000); | 203 | udelay(1000); |
213 | 204 | ||
214 | ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE, | 205 | ath79_usb_register("ehci-platform", -1, |
215 | AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB); | 206 | AR934X_EHCI_BASE, AR934X_EHCI_SIZE, |
216 | ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; | 207 | ATH79_CPU_IRQ(3), |
217 | platform_device_register(&ath79_ehci_device); | 208 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); |
209 | } | ||
210 | |||
211 | static void __init qca955x_usb_setup(void) | ||
212 | { | ||
213 | ath79_usb_register("ehci-platform", 0, | ||
214 | QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, | ||
215 | ATH79_IP3_IRQ(0), | ||
216 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
217 | |||
218 | ath79_usb_register("ehci-platform", 1, | ||
219 | QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE, | ||
220 | ATH79_IP3_IRQ(1), | ||
221 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
218 | } | 222 | } |
219 | 223 | ||
220 | void __init ath79_register_usb(void) | 224 | void __init ath79_register_usb(void) |
@@ -231,6 +235,8 @@ void __init ath79_register_usb(void) | |||
231 | ar933x_usb_setup(); | 235 | ar933x_usb_setup(); |
232 | else if (soc_is_ar934x()) | 236 | else if (soc_is_ar934x()) |
233 | ar934x_usb_setup(); | 237 | ar934x_usb_setup(); |
238 | else if (soc_is_qca955x()) | ||
239 | qca955x_usb_setup(); | ||
234 | else | 240 | else |
235 | BUG(); | 241 | BUG(); |
236 | } | 242 | } |
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c index d6d893c16ad4..da190b1b87ce 100644 --- a/arch/mips/ath79/dev-wmac.c +++ b/arch/mips/ath79/dev-wmac.c | |||
@@ -55,8 +55,8 @@ static void __init ar913x_wmac_setup(void) | |||
55 | 55 | ||
56 | ath79_wmac_resources[0].start = AR913X_WMAC_BASE; | 56 | ath79_wmac_resources[0].start = AR913X_WMAC_BASE; |
57 | ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; | 57 | ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; |
58 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; | 58 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); |
59 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; | 59 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); |
60 | } | 60 | } |
61 | 61 | ||
62 | 62 | ||
@@ -83,8 +83,8 @@ static void __init ar933x_wmac_setup(void) | |||
83 | 83 | ||
84 | ath79_wmac_resources[0].start = AR933X_WMAC_BASE; | 84 | ath79_wmac_resources[0].start = AR933X_WMAC_BASE; |
85 | ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; | 85 | ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; |
86 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; | 86 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); |
87 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; | 87 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); |
88 | 88 | ||
89 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | 89 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); |
90 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | 90 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) |
@@ -107,7 +107,7 @@ static void ar934x_wmac_setup(void) | |||
107 | ath79_wmac_resources[0].start = AR934X_WMAC_BASE; | 107 | ath79_wmac_resources[0].start = AR934X_WMAC_BASE; |
108 | ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; | 108 | ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; |
109 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | 109 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); |
110 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | 110 | ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); |
111 | 111 | ||
112 | t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | 112 | t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); |
113 | if (t & AR934X_BOOTSTRAP_REF_CLK_40) | 113 | if (t & AR934X_BOOTSTRAP_REF_CLK_40) |
@@ -116,6 +116,24 @@ static void ar934x_wmac_setup(void) | |||
116 | ath79_wmac_data.is_clk_25mhz = true; | 116 | ath79_wmac_data.is_clk_25mhz = true; |
117 | } | 117 | } |
118 | 118 | ||
119 | static void qca955x_wmac_setup(void) | ||
120 | { | ||
121 | u32 t; | ||
122 | |||
123 | ath79_wmac_device.name = "qca955x_wmac"; | ||
124 | |||
125 | ath79_wmac_resources[0].start = QCA955X_WMAC_BASE; | ||
126 | ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1; | ||
127 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||
128 | ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); | ||
129 | |||
130 | t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); | ||
131 | if (t & QCA955X_BOOTSTRAP_REF_CLK_40) | ||
132 | ath79_wmac_data.is_clk_25mhz = false; | ||
133 | else | ||
134 | ath79_wmac_data.is_clk_25mhz = true; | ||
135 | } | ||
136 | |||
119 | void __init ath79_register_wmac(u8 *cal_data) | 137 | void __init ath79_register_wmac(u8 *cal_data) |
120 | { | 138 | { |
121 | if (soc_is_ar913x()) | 139 | if (soc_is_ar913x()) |
@@ -124,6 +142,8 @@ void __init ath79_register_wmac(u8 *cal_data) | |||
124 | ar933x_wmac_setup(); | 142 | ar933x_wmac_setup(); |
125 | else if (soc_is_ar934x()) | 143 | else if (soc_is_ar934x()) |
126 | ar934x_wmac_setup(); | 144 | ar934x_wmac_setup(); |
145 | else if (soc_is_qca955x()) | ||
146 | qca955x_wmac_setup(); | ||
127 | else | 147 | else |
128 | BUG(); | 148 | BUG(); |
129 | 149 | ||
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c index dc938cb2ba58..b955fafc58ba 100644 --- a/arch/mips/ath79/early_printk.c +++ b/arch/mips/ath79/early_printk.c | |||
@@ -74,6 +74,8 @@ static void prom_putchar_init(void) | |||
74 | case REV_ID_MAJOR_AR9341: | 74 | case REV_ID_MAJOR_AR9341: |
75 | case REV_ID_MAJOR_AR9342: | 75 | case REV_ID_MAJOR_AR9342: |
76 | case REV_ID_MAJOR_AR9344: | 76 | case REV_ID_MAJOR_AR9344: |
77 | case REV_ID_MAJOR_QCA9556: | ||
78 | case REV_ID_MAJOR_QCA9558: | ||
77 | _prom_putchar = prom_putchar_ar71xx; | 79 | _prom_putchar = prom_putchar_ar71xx; |
78 | break; | 80 | break; |
79 | 81 | ||
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index 48fe762d2526..8d025b028bb1 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c | |||
@@ -137,49 +137,45 @@ static struct gpio_chip ath79_gpio_chip = { | |||
137 | .base = 0, | 137 | .base = 0, |
138 | }; | 138 | }; |
139 | 139 | ||
140 | void ath79_gpio_function_enable(u32 mask) | 140 | static void __iomem *ath79_gpio_get_function_reg(void) |
141 | { | 141 | { |
142 | void __iomem *base = ath79_gpio_base; | 142 | u32 reg = 0; |
143 | unsigned long flags; | ||
144 | 143 | ||
145 | spin_lock_irqsave(&ath79_gpio_lock, flags); | 144 | if (soc_is_ar71xx() || |
146 | 145 | soc_is_ar724x() || | |
147 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask, | 146 | soc_is_ar913x() || |
148 | base + AR71XX_GPIO_REG_FUNC); | 147 | soc_is_ar933x()) |
149 | /* flush write */ | 148 | reg = AR71XX_GPIO_REG_FUNC; |
150 | __raw_readl(base + AR71XX_GPIO_REG_FUNC); | 149 | else if (soc_is_ar934x()) |
150 | reg = AR934X_GPIO_REG_FUNC; | ||
151 | else | ||
152 | BUG(); | ||
151 | 153 | ||
152 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | 154 | return ath79_gpio_base + reg; |
153 | } | 155 | } |
154 | 156 | ||
155 | void ath79_gpio_function_disable(u32 mask) | 157 | void ath79_gpio_function_setup(u32 set, u32 clear) |
156 | { | 158 | { |
157 | void __iomem *base = ath79_gpio_base; | 159 | void __iomem *reg = ath79_gpio_get_function_reg(); |
158 | unsigned long flags; | 160 | unsigned long flags; |
159 | 161 | ||
160 | spin_lock_irqsave(&ath79_gpio_lock, flags); | 162 | spin_lock_irqsave(&ath79_gpio_lock, flags); |
161 | 163 | ||
162 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask, | 164 | __raw_writel((__raw_readl(reg) & ~clear) | set, reg); |
163 | base + AR71XX_GPIO_REG_FUNC); | ||
164 | /* flush write */ | 165 | /* flush write */ |
165 | __raw_readl(base + AR71XX_GPIO_REG_FUNC); | 166 | __raw_readl(reg); |
166 | 167 | ||
167 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | 168 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); |
168 | } | 169 | } |
169 | 170 | ||
170 | void ath79_gpio_function_setup(u32 set, u32 clear) | 171 | void ath79_gpio_function_enable(u32 mask) |
171 | { | 172 | { |
172 | void __iomem *base = ath79_gpio_base; | 173 | ath79_gpio_function_setup(mask, 0); |
173 | unsigned long flags; | 174 | } |
174 | |||
175 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
176 | |||
177 | __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set, | ||
178 | base + AR71XX_GPIO_REG_FUNC); | ||
179 | /* flush write */ | ||
180 | __raw_readl(base + AR71XX_GPIO_REG_FUNC); | ||
181 | 175 | ||
182 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | 176 | void ath79_gpio_function_disable(u32 mask) |
177 | { | ||
178 | ath79_gpio_function_setup(0, mask); | ||
183 | } | 179 | } |
184 | 180 | ||
185 | void __init ath79_gpio_init(void) | 181 | void __init ath79_gpio_init(void) |
@@ -198,12 +194,14 @@ void __init ath79_gpio_init(void) | |||
198 | ath79_gpio_count = AR933X_GPIO_COUNT; | 194 | ath79_gpio_count = AR933X_GPIO_COUNT; |
199 | else if (soc_is_ar934x()) | 195 | else if (soc_is_ar934x()) |
200 | ath79_gpio_count = AR934X_GPIO_COUNT; | 196 | ath79_gpio_count = AR934X_GPIO_COUNT; |
197 | else if (soc_is_qca955x()) | ||
198 | ath79_gpio_count = QCA955X_GPIO_COUNT; | ||
201 | else | 199 | else |
202 | BUG(); | 200 | BUG(); |
203 | 201 | ||
204 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); | 202 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); |
205 | ath79_gpio_chip.ngpio = ath79_gpio_count; | 203 | ath79_gpio_chip.ngpio = ath79_gpio_count; |
206 | if (soc_is_ar934x()) { | 204 | if (soc_is_ar934x() || soc_is_qca955x()) { |
207 | ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; | 205 | ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; |
208 | ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; | 206 | ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; |
209 | } | 207 | } |
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 90d09fc15398..9c0e1761773f 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -35,44 +35,17 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
35 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & | 35 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & |
36 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | 36 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); |
37 | 37 | ||
38 | if (pending & MISC_INT_UART) | 38 | if (!pending) { |
39 | generic_handle_irq(ATH79_MISC_IRQ_UART); | 39 | spurious_interrupt(); |
40 | 40 | return; | |
41 | else if (pending & MISC_INT_DMA) | 41 | } |
42 | generic_handle_irq(ATH79_MISC_IRQ_DMA); | ||
43 | |||
44 | else if (pending & MISC_INT_PERFC) | ||
45 | generic_handle_irq(ATH79_MISC_IRQ_PERFC); | ||
46 | |||
47 | else if (pending & MISC_INT_TIMER) | ||
48 | generic_handle_irq(ATH79_MISC_IRQ_TIMER); | ||
49 | |||
50 | else if (pending & MISC_INT_TIMER2) | ||
51 | generic_handle_irq(ATH79_MISC_IRQ_TIMER2); | ||
52 | |||
53 | else if (pending & MISC_INT_TIMER3) | ||
54 | generic_handle_irq(ATH79_MISC_IRQ_TIMER3); | ||
55 | |||
56 | else if (pending & MISC_INT_TIMER4) | ||
57 | generic_handle_irq(ATH79_MISC_IRQ_TIMER4); | ||
58 | |||
59 | else if (pending & MISC_INT_OHCI) | ||
60 | generic_handle_irq(ATH79_MISC_IRQ_OHCI); | ||
61 | |||
62 | else if (pending & MISC_INT_ERROR) | ||
63 | generic_handle_irq(ATH79_MISC_IRQ_ERROR); | ||
64 | |||
65 | else if (pending & MISC_INT_GPIO) | ||
66 | generic_handle_irq(ATH79_MISC_IRQ_GPIO); | ||
67 | |||
68 | else if (pending & MISC_INT_WDOG) | ||
69 | generic_handle_irq(ATH79_MISC_IRQ_WDOG); | ||
70 | 42 | ||
71 | else if (pending & MISC_INT_ETHSW) | 43 | while (pending) { |
72 | generic_handle_irq(ATH79_MISC_IRQ_ETHSW); | 44 | int bit = __ffs(pending); |
73 | 45 | ||
74 | else | 46 | generic_handle_irq(ATH79_MISC_IRQ(bit)); |
75 | spurious_interrupt(); | 47 | pending &= ~BIT(bit); |
48 | } | ||
76 | } | 49 | } |
77 | 50 | ||
78 | static void ar71xx_misc_irq_unmask(struct irq_data *d) | 51 | static void ar71xx_misc_irq_unmask(struct irq_data *d) |
@@ -130,7 +103,10 @@ static void __init ath79_misc_irq_init(void) | |||
130 | 103 | ||
131 | if (soc_is_ar71xx() || soc_is_ar913x()) | 104 | if (soc_is_ar71xx() || soc_is_ar913x()) |
132 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; | 105 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; |
133 | else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x()) | 106 | else if (soc_is_ar724x() || |
107 | soc_is_ar933x() || | ||
108 | soc_is_ar934x() || | ||
109 | soc_is_qca955x()) | ||
134 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; | 110 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; |
135 | else | 111 | else |
136 | BUG(); | 112 | BUG(); |
@@ -141,7 +117,7 @@ static void __init ath79_misc_irq_init(void) | |||
141 | handle_level_irq); | 117 | handle_level_irq); |
142 | } | 118 | } |
143 | 119 | ||
144 | irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); | 120 | irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler); |
145 | } | 121 | } |
146 | 122 | ||
147 | static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) | 123 | static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) |
@@ -174,7 +150,89 @@ static void ar934x_ip2_irq_init(void) | |||
174 | irq_set_chip_and_handler(i, &dummy_irq_chip, | 150 | irq_set_chip_and_handler(i, &dummy_irq_chip, |
175 | handle_level_irq); | 151 | handle_level_irq); |
176 | 152 | ||
177 | irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); | 153 | irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); |
154 | } | ||
155 | |||
156 | static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) | ||
157 | { | ||
158 | u32 status; | ||
159 | |||
160 | disable_irq_nosync(irq); | ||
161 | |||
162 | status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); | ||
163 | status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL; | ||
164 | |||
165 | if (status == 0) { | ||
166 | spurious_interrupt(); | ||
167 | goto enable; | ||
168 | } | ||
169 | |||
170 | if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { | ||
171 | /* TODO: flush DDR? */ | ||
172 | generic_handle_irq(ATH79_IP2_IRQ(0)); | ||
173 | } | ||
174 | |||
175 | if (status & QCA955X_EXT_INT_WMAC_ALL) { | ||
176 | /* TODO: flush DDR? */ | ||
177 | generic_handle_irq(ATH79_IP2_IRQ(1)); | ||
178 | } | ||
179 | |||
180 | enable: | ||
181 | enable_irq(irq); | ||
182 | } | ||
183 | |||
184 | static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) | ||
185 | { | ||
186 | u32 status; | ||
187 | |||
188 | disable_irq_nosync(irq); | ||
189 | |||
190 | status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); | ||
191 | status &= QCA955X_EXT_INT_PCIE_RC2_ALL | | ||
192 | QCA955X_EXT_INT_USB1 | | ||
193 | QCA955X_EXT_INT_USB2; | ||
194 | |||
195 | if (status == 0) { | ||
196 | spurious_interrupt(); | ||
197 | goto enable; | ||
198 | } | ||
199 | |||
200 | if (status & QCA955X_EXT_INT_USB1) { | ||
201 | /* TODO: flush DDR? */ | ||
202 | generic_handle_irq(ATH79_IP3_IRQ(0)); | ||
203 | } | ||
204 | |||
205 | if (status & QCA955X_EXT_INT_USB2) { | ||
206 | /* TODO: flush DDR? */ | ||
207 | generic_handle_irq(ATH79_IP3_IRQ(1)); | ||
208 | } | ||
209 | |||
210 | if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { | ||
211 | /* TODO: flush DDR? */ | ||
212 | generic_handle_irq(ATH79_IP3_IRQ(2)); | ||
213 | } | ||
214 | |||
215 | enable: | ||
216 | enable_irq(irq); | ||
217 | } | ||
218 | |||
219 | static void qca955x_irq_init(void) | ||
220 | { | ||
221 | int i; | ||
222 | |||
223 | for (i = ATH79_IP2_IRQ_BASE; | ||
224 | i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||
225 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
226 | handle_level_irq); | ||
227 | |||
228 | irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch); | ||
229 | |||
230 | for (i = ATH79_IP3_IRQ_BASE; | ||
231 | i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) | ||
232 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
233 | handle_level_irq); | ||
234 | |||
235 | irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); | ||
178 | } | 236 | } |
179 | 237 | ||
180 | asmlinkage void plat_irq_dispatch(void) | 238 | asmlinkage void plat_irq_dispatch(void) |
@@ -184,22 +242,22 @@ asmlinkage void plat_irq_dispatch(void) | |||
184 | pending = read_c0_status() & read_c0_cause() & ST0_IM; | 242 | pending = read_c0_status() & read_c0_cause() & ST0_IM; |
185 | 243 | ||
186 | if (pending & STATUSF_IP7) | 244 | if (pending & STATUSF_IP7) |
187 | do_IRQ(ATH79_CPU_IRQ_TIMER); | 245 | do_IRQ(ATH79_CPU_IRQ(7)); |
188 | 246 | ||
189 | else if (pending & STATUSF_IP2) | 247 | else if (pending & STATUSF_IP2) |
190 | ath79_ip2_handler(); | 248 | ath79_ip2_handler(); |
191 | 249 | ||
192 | else if (pending & STATUSF_IP4) | 250 | else if (pending & STATUSF_IP4) |
193 | do_IRQ(ATH79_CPU_IRQ_GE0); | 251 | do_IRQ(ATH79_CPU_IRQ(4)); |
194 | 252 | ||
195 | else if (pending & STATUSF_IP5) | 253 | else if (pending & STATUSF_IP5) |
196 | do_IRQ(ATH79_CPU_IRQ_GE1); | 254 | do_IRQ(ATH79_CPU_IRQ(5)); |
197 | 255 | ||
198 | else if (pending & STATUSF_IP3) | 256 | else if (pending & STATUSF_IP3) |
199 | ath79_ip3_handler(); | 257 | ath79_ip3_handler(); |
200 | 258 | ||
201 | else if (pending & STATUSF_IP6) | 259 | else if (pending & STATUSF_IP6) |
202 | do_IRQ(ATH79_CPU_IRQ_MISC); | 260 | do_IRQ(ATH79_CPU_IRQ(6)); |
203 | 261 | ||
204 | else | 262 | else |
205 | spurious_interrupt(); | 263 | spurious_interrupt(); |
@@ -212,63 +270,69 @@ asmlinkage void plat_irq_dispatch(void) | |||
212 | * Issue a flush in the handlers to ensure that the driver sees | 270 | * Issue a flush in the handlers to ensure that the driver sees |
213 | * the update. | 271 | * the update. |
214 | */ | 272 | */ |
273 | |||
274 | static void ath79_default_ip2_handler(void) | ||
275 | { | ||
276 | do_IRQ(ATH79_CPU_IRQ(2)); | ||
277 | } | ||
278 | |||
279 | static void ath79_default_ip3_handler(void) | ||
280 | { | ||
281 | do_IRQ(ATH79_CPU_IRQ(3)); | ||
282 | } | ||
283 | |||
215 | static void ar71xx_ip2_handler(void) | 284 | static void ar71xx_ip2_handler(void) |
216 | { | 285 | { |
217 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); | 286 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); |
218 | do_IRQ(ATH79_CPU_IRQ_IP2); | 287 | do_IRQ(ATH79_CPU_IRQ(2)); |
219 | } | 288 | } |
220 | 289 | ||
221 | static void ar724x_ip2_handler(void) | 290 | static void ar724x_ip2_handler(void) |
222 | { | 291 | { |
223 | ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); | 292 | ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); |
224 | do_IRQ(ATH79_CPU_IRQ_IP2); | 293 | do_IRQ(ATH79_CPU_IRQ(2)); |
225 | } | 294 | } |
226 | 295 | ||
227 | static void ar913x_ip2_handler(void) | 296 | static void ar913x_ip2_handler(void) |
228 | { | 297 | { |
229 | ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); | 298 | ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); |
230 | do_IRQ(ATH79_CPU_IRQ_IP2); | 299 | do_IRQ(ATH79_CPU_IRQ(2)); |
231 | } | 300 | } |
232 | 301 | ||
233 | static void ar933x_ip2_handler(void) | 302 | static void ar933x_ip2_handler(void) |
234 | { | 303 | { |
235 | ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); | 304 | ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); |
236 | do_IRQ(ATH79_CPU_IRQ_IP2); | 305 | do_IRQ(ATH79_CPU_IRQ(2)); |
237 | } | ||
238 | |||
239 | static void ar934x_ip2_handler(void) | ||
240 | { | ||
241 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
242 | } | 306 | } |
243 | 307 | ||
244 | static void ar71xx_ip3_handler(void) | 308 | static void ar71xx_ip3_handler(void) |
245 | { | 309 | { |
246 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); | 310 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); |
247 | do_IRQ(ATH79_CPU_IRQ_USB); | 311 | do_IRQ(ATH79_CPU_IRQ(3)); |
248 | } | 312 | } |
249 | 313 | ||
250 | static void ar724x_ip3_handler(void) | 314 | static void ar724x_ip3_handler(void) |
251 | { | 315 | { |
252 | ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); | 316 | ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); |
253 | do_IRQ(ATH79_CPU_IRQ_USB); | 317 | do_IRQ(ATH79_CPU_IRQ(3)); |
254 | } | 318 | } |
255 | 319 | ||
256 | static void ar913x_ip3_handler(void) | 320 | static void ar913x_ip3_handler(void) |
257 | { | 321 | { |
258 | ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); | 322 | ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); |
259 | do_IRQ(ATH79_CPU_IRQ_USB); | 323 | do_IRQ(ATH79_CPU_IRQ(3)); |
260 | } | 324 | } |
261 | 325 | ||
262 | static void ar933x_ip3_handler(void) | 326 | static void ar933x_ip3_handler(void) |
263 | { | 327 | { |
264 | ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); | 328 | ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); |
265 | do_IRQ(ATH79_CPU_IRQ_USB); | 329 | do_IRQ(ATH79_CPU_IRQ(3)); |
266 | } | 330 | } |
267 | 331 | ||
268 | static void ar934x_ip3_handler(void) | 332 | static void ar934x_ip3_handler(void) |
269 | { | 333 | { |
270 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); | 334 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); |
271 | do_IRQ(ATH79_CPU_IRQ_USB); | 335 | do_IRQ(ATH79_CPU_IRQ(3)); |
272 | } | 336 | } |
273 | 337 | ||
274 | void __init arch_init_irq(void) | 338 | void __init arch_init_irq(void) |
@@ -286,16 +350,21 @@ void __init arch_init_irq(void) | |||
286 | ath79_ip2_handler = ar933x_ip2_handler; | 350 | ath79_ip2_handler = ar933x_ip2_handler; |
287 | ath79_ip3_handler = ar933x_ip3_handler; | 351 | ath79_ip3_handler = ar933x_ip3_handler; |
288 | } else if (soc_is_ar934x()) { | 352 | } else if (soc_is_ar934x()) { |
289 | ath79_ip2_handler = ar934x_ip2_handler; | 353 | ath79_ip2_handler = ath79_default_ip2_handler; |
290 | ath79_ip3_handler = ar934x_ip3_handler; | 354 | ath79_ip3_handler = ar934x_ip3_handler; |
355 | } else if (soc_is_qca955x()) { | ||
356 | ath79_ip2_handler = ath79_default_ip2_handler; | ||
357 | ath79_ip3_handler = ath79_default_ip3_handler; | ||
291 | } else { | 358 | } else { |
292 | BUG(); | 359 | BUG(); |
293 | } | 360 | } |
294 | 361 | ||
295 | cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; | 362 | cp0_perfcount_irq = ATH79_MISC_IRQ(5); |
296 | mips_cpu_irq_init(); | 363 | mips_cpu_irq_init(); |
297 | ath79_misc_irq_init(); | 364 | ath79_misc_irq_init(); |
298 | 365 | ||
299 | if (soc_is_ar934x()) | 366 | if (soc_is_ar934x()) |
300 | ar934x_ip2_irq_init(); | 367 | ar934x_ip2_irq_init(); |
368 | else if (soc_is_qca955x()) | ||
369 | qca955x_irq_init(); | ||
301 | } | 370 | } |
diff --git a/arch/mips/ath79/mach-ap136.c b/arch/mips/ath79/mach-ap136.c new file mode 100644 index 000000000000..479dd4b1d0d2 --- /dev/null +++ b/arch/mips/ath79/mach-ap136.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * Qualcomm Atheros AP136 reference board support | ||
3 | * | ||
4 | * Copyright (c) 2012 Qualcomm Atheros | ||
5 | * Copyright (c) 2012-2013 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * | ||
7 | * Permission to use, copy, modify, and/or distribute this software for any | ||
8 | * purpose with or without fee is hereby granted, provided that the above | ||
9 | * copyright notice and this permission notice appear in all copies. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include <linux/ath9k_platform.h> | ||
23 | |||
24 | #include "machtypes.h" | ||
25 | #include "dev-gpio-buttons.h" | ||
26 | #include "dev-leds-gpio.h" | ||
27 | #include "dev-spi.h" | ||
28 | #include "dev-usb.h" | ||
29 | #include "dev-wmac.h" | ||
30 | #include "pci.h" | ||
31 | |||
32 | #define AP136_GPIO_LED_STATUS_RED 14 | ||
33 | #define AP136_GPIO_LED_STATUS_GREEN 19 | ||
34 | #define AP136_GPIO_LED_USB 4 | ||
35 | #define AP136_GPIO_LED_WLAN_2G 13 | ||
36 | #define AP136_GPIO_LED_WLAN_5G 12 | ||
37 | #define AP136_GPIO_LED_WPS_RED 15 | ||
38 | #define AP136_GPIO_LED_WPS_GREEN 20 | ||
39 | |||
40 | #define AP136_GPIO_BTN_WPS 16 | ||
41 | #define AP136_GPIO_BTN_RFKILL 21 | ||
42 | |||
43 | #define AP136_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
44 | #define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL) | ||
45 | |||
46 | #define AP136_WMAC_CALDATA_OFFSET 0x1000 | ||
47 | #define AP136_PCIE_CALDATA_OFFSET 0x5000 | ||
48 | |||
49 | static struct gpio_led ap136_leds_gpio[] __initdata = { | ||
50 | { | ||
51 | .name = "qca:green:status", | ||
52 | .gpio = AP136_GPIO_LED_STATUS_GREEN, | ||
53 | .active_low = 1, | ||
54 | }, | ||
55 | { | ||
56 | .name = "qca:red:status", | ||
57 | .gpio = AP136_GPIO_LED_STATUS_RED, | ||
58 | .active_low = 1, | ||
59 | }, | ||
60 | { | ||
61 | .name = "qca:green:wps", | ||
62 | .gpio = AP136_GPIO_LED_WPS_GREEN, | ||
63 | .active_low = 1, | ||
64 | }, | ||
65 | { | ||
66 | .name = "qca:red:wps", | ||
67 | .gpio = AP136_GPIO_LED_WPS_RED, | ||
68 | .active_low = 1, | ||
69 | }, | ||
70 | { | ||
71 | .name = "qca:red:wlan-2g", | ||
72 | .gpio = AP136_GPIO_LED_WLAN_2G, | ||
73 | .active_low = 1, | ||
74 | }, | ||
75 | { | ||
76 | .name = "qca:red:usb", | ||
77 | .gpio = AP136_GPIO_LED_USB, | ||
78 | .active_low = 1, | ||
79 | } | ||
80 | }; | ||
81 | |||
82 | static struct gpio_keys_button ap136_gpio_keys[] __initdata = { | ||
83 | { | ||
84 | .desc = "WPS button", | ||
85 | .type = EV_KEY, | ||
86 | .code = KEY_WPS_BUTTON, | ||
87 | .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL, | ||
88 | .gpio = AP136_GPIO_BTN_WPS, | ||
89 | .active_low = 1, | ||
90 | }, | ||
91 | { | ||
92 | .desc = "RFKILL button", | ||
93 | .type = EV_KEY, | ||
94 | .code = KEY_RFKILL, | ||
95 | .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL, | ||
96 | .gpio = AP136_GPIO_BTN_RFKILL, | ||
97 | .active_low = 1, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | static struct spi_board_info ap136_spi_info[] = { | ||
102 | { | ||
103 | .bus_num = 0, | ||
104 | .chip_select = 0, | ||
105 | .max_speed_hz = 25000000, | ||
106 | .modalias = "mx25l6405d", | ||
107 | } | ||
108 | }; | ||
109 | |||
110 | static struct ath79_spi_platform_data ap136_spi_data = { | ||
111 | .bus_num = 0, | ||
112 | .num_chipselect = 1, | ||
113 | }; | ||
114 | |||
115 | #ifdef CONFIG_PCI | ||
116 | static struct ath9k_platform_data ap136_ath9k_data; | ||
117 | |||
118 | static int ap136_pci_plat_dev_init(struct pci_dev *dev) | ||
119 | { | ||
120 | if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0) | ||
121 | dev->dev.platform_data = &ap136_ath9k_data; | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static void __init ap136_pci_init(u8 *eeprom) | ||
127 | { | ||
128 | memcpy(ap136_ath9k_data.eeprom_data, eeprom, | ||
129 | sizeof(ap136_ath9k_data.eeprom_data)); | ||
130 | |||
131 | ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init); | ||
132 | ath79_register_pci(); | ||
133 | } | ||
134 | #else | ||
135 | static inline void ap136_pci_init(void) {} | ||
136 | #endif /* CONFIG_PCI */ | ||
137 | |||
138 | static void __init ap136_setup(void) | ||
139 | { | ||
140 | u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); | ||
141 | |||
142 | ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio), | ||
143 | ap136_leds_gpio); | ||
144 | ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL, | ||
145 | ARRAY_SIZE(ap136_gpio_keys), | ||
146 | ap136_gpio_keys); | ||
147 | ath79_register_spi(&ap136_spi_data, ap136_spi_info, | ||
148 | ARRAY_SIZE(ap136_spi_info)); | ||
149 | ath79_register_usb(); | ||
150 | ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET); | ||
151 | ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET); | ||
152 | } | ||
153 | |||
154 | MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010", | ||
155 | "Atheros AP136-010 reference board", | ||
156 | ap136_setup); | ||
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h index af92e5c30d66..26254058c545 100644 --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h | |||
@@ -17,6 +17,7 @@ | |||
17 | enum ath79_mach_type { | 17 | enum ath79_mach_type { |
18 | ATH79_MACH_GENERIC = 0, | 18 | ATH79_MACH_GENERIC = 0, |
19 | ATH79_MACH_AP121, /* Atheros AP121 reference board */ | 19 | ATH79_MACH_AP121, /* Atheros AP121 reference board */ |
20 | ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */ | ||
20 | ATH79_MACH_AP81, /* Atheros AP81 reference board */ | 21 | ATH79_MACH_AP81, /* Atheros AP81 reference board */ |
21 | ATH79_MACH_DB120, /* Atheros DB120 reference board */ | 22 | ATH79_MACH_DB120, /* Atheros DB120 reference board */ |
22 | ATH79_MACH_PB44, /* Atheros PB44 reference board */ | 23 | ATH79_MACH_PB44, /* Atheros PB44 reference board */ |
diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index ca83abd9d31e..730c0b03060d 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c | |||
@@ -14,10 +14,11 @@ | |||
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <linux/resource.h> | ||
18 | #include <linux/platform_device.h> | ||
17 | #include <asm/mach-ath79/ar71xx_regs.h> | 19 | #include <asm/mach-ath79/ar71xx_regs.h> |
18 | #include <asm/mach-ath79/ath79.h> | 20 | #include <asm/mach-ath79/ath79.h> |
19 | #include <asm/mach-ath79/irq.h> | 21 | #include <asm/mach-ath79/irq.h> |
20 | #include <asm/mach-ath79/pci.h> | ||
21 | #include "pci.h" | 22 | #include "pci.h" |
22 | 23 | ||
23 | static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); | 24 | static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); |
@@ -48,6 +49,21 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { | |||
48 | } | 49 | } |
49 | }; | 50 | }; |
50 | 51 | ||
52 | static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { | ||
53 | { | ||
54 | .bus = 0, | ||
55 | .slot = 0, | ||
56 | .pin = 1, | ||
57 | .irq = ATH79_PCI_IRQ(0), | ||
58 | }, | ||
59 | { | ||
60 | .bus = 1, | ||
61 | .slot = 0, | ||
62 | .pin = 1, | ||
63 | .irq = ATH79_PCI_IRQ(1), | ||
64 | }, | ||
65 | }; | ||
66 | |||
51 | int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | 67 | int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) |
52 | { | 68 | { |
53 | int irq = -1; | 69 | int irq = -1; |
@@ -63,6 +79,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | |||
63 | soc_is_ar9344()) { | 79 | soc_is_ar9344()) { |
64 | ath79_pci_irq_map = ar724x_pci_irq_map; | 80 | ath79_pci_irq_map = ar724x_pci_irq_map; |
65 | ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); | 81 | ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); |
82 | } else if (soc_is_qca955x()) { | ||
83 | ath79_pci_irq_map = qca955x_pci_irq_map; | ||
84 | ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); | ||
66 | } else { | 85 | } else { |
67 | pr_crit("pci %s: invalid irq map\n", | 86 | pr_crit("pci %s: invalid irq map\n", |
68 | pci_name((struct pci_dev *) dev)); | 87 | pci_name((struct pci_dev *) dev)); |
@@ -74,7 +93,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | |||
74 | const struct ath79_pci_irq *entry; | 93 | const struct ath79_pci_irq *entry; |
75 | 94 | ||
76 | entry = &ath79_pci_irq_map[i]; | 95 | entry = &ath79_pci_irq_map[i]; |
77 | if (entry->slot == slot && entry->pin == pin) { | 96 | if (entry->bus == dev->bus->number && |
97 | entry->slot == slot && | ||
98 | entry->pin == pin) { | ||
78 | irq = entry->irq; | 99 | irq = entry->irq; |
79 | break; | 100 | break; |
80 | } | 101 | } |
@@ -110,21 +131,143 @@ void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) | |||
110 | ath79_pci_plat_dev_init = func; | 131 | ath79_pci_plat_dev_init = func; |
111 | } | 132 | } |
112 | 133 | ||
113 | int __init ath79_register_pci(void) | 134 | static struct platform_device * |
135 | ath79_register_pci_ar71xx(void) | ||
136 | { | ||
137 | struct platform_device *pdev; | ||
138 | struct resource res[4]; | ||
139 | |||
140 | memset(res, 0, sizeof(res)); | ||
141 | |||
142 | res[0].name = "cfg_base"; | ||
143 | res[0].flags = IORESOURCE_MEM; | ||
144 | res[0].start = AR71XX_PCI_CFG_BASE; | ||
145 | res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1; | ||
146 | |||
147 | res[1].flags = IORESOURCE_IRQ; | ||
148 | res[1].start = ATH79_CPU_IRQ(2); | ||
149 | res[1].end = ATH79_CPU_IRQ(2); | ||
150 | |||
151 | res[2].name = "io_base"; | ||
152 | res[2].flags = IORESOURCE_IO; | ||
153 | res[2].start = 0; | ||
154 | res[2].end = 0; | ||
155 | |||
156 | res[3].name = "mem_base"; | ||
157 | res[3].flags = IORESOURCE_MEM; | ||
158 | res[3].start = AR71XX_PCI_MEM_BASE; | ||
159 | res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1; | ||
160 | |||
161 | pdev = platform_device_register_simple("ar71xx-pci", -1, | ||
162 | res, ARRAY_SIZE(res)); | ||
163 | return pdev; | ||
164 | } | ||
165 | |||
166 | static struct platform_device * | ||
167 | ath79_register_pci_ar724x(int id, | ||
168 | unsigned long cfg_base, | ||
169 | unsigned long ctrl_base, | ||
170 | unsigned long crp_base, | ||
171 | unsigned long mem_base, | ||
172 | unsigned long mem_size, | ||
173 | unsigned long io_base, | ||
174 | int irq) | ||
114 | { | 175 | { |
115 | if (soc_is_ar71xx()) | 176 | struct platform_device *pdev; |
116 | return ar71xx_pcibios_init(); | 177 | struct resource res[6]; |
178 | |||
179 | memset(res, 0, sizeof(res)); | ||
180 | |||
181 | res[0].name = "cfg_base"; | ||
182 | res[0].flags = IORESOURCE_MEM; | ||
183 | res[0].start = cfg_base; | ||
184 | res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1; | ||
185 | |||
186 | res[1].name = "ctrl_base"; | ||
187 | res[1].flags = IORESOURCE_MEM; | ||
188 | res[1].start = ctrl_base; | ||
189 | res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1; | ||
190 | |||
191 | res[2].flags = IORESOURCE_IRQ; | ||
192 | res[2].start = irq; | ||
193 | res[2].end = irq; | ||
194 | |||
195 | res[3].name = "mem_base"; | ||
196 | res[3].flags = IORESOURCE_MEM; | ||
197 | res[3].start = mem_base; | ||
198 | res[3].end = mem_base + mem_size - 1; | ||
199 | |||
200 | res[4].name = "io_base"; | ||
201 | res[4].flags = IORESOURCE_IO; | ||
202 | res[4].start = io_base; | ||
203 | res[4].end = io_base; | ||
117 | 204 | ||
118 | if (soc_is_ar724x()) | 205 | res[5].name = "crp_base"; |
119 | return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); | 206 | res[5].flags = IORESOURCE_MEM; |
207 | res[5].start = crp_base; | ||
208 | res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1; | ||
120 | 209 | ||
121 | if (soc_is_ar9342() || soc_is_ar9344()) { | 210 | pdev = platform_device_register_simple("ar724x-pci", id, |
211 | res, ARRAY_SIZE(res)); | ||
212 | return pdev; | ||
213 | } | ||
214 | |||
215 | int __init ath79_register_pci(void) | ||
216 | { | ||
217 | struct platform_device *pdev = NULL; | ||
218 | |||
219 | if (soc_is_ar71xx()) { | ||
220 | pdev = ath79_register_pci_ar71xx(); | ||
221 | } else if (soc_is_ar724x()) { | ||
222 | pdev = ath79_register_pci_ar724x(-1, | ||
223 | AR724X_PCI_CFG_BASE, | ||
224 | AR724X_PCI_CTRL_BASE, | ||
225 | AR724X_PCI_CRP_BASE, | ||
226 | AR724X_PCI_MEM_BASE, | ||
227 | AR724X_PCI_MEM_SIZE, | ||
228 | 0, | ||
229 | ATH79_CPU_IRQ(2)); | ||
230 | } else if (soc_is_ar9342() || | ||
231 | soc_is_ar9344()) { | ||
122 | u32 bootstrap; | 232 | u32 bootstrap; |
123 | 233 | ||
124 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | 234 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); |
125 | if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC) | 235 | if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0) |
126 | return ar724x_pcibios_init(ATH79_IP2_IRQ(0)); | 236 | return -ENODEV; |
237 | |||
238 | pdev = ath79_register_pci_ar724x(-1, | ||
239 | AR724X_PCI_CFG_BASE, | ||
240 | AR724X_PCI_CTRL_BASE, | ||
241 | AR724X_PCI_CRP_BASE, | ||
242 | AR724X_PCI_MEM_BASE, | ||
243 | AR724X_PCI_MEM_SIZE, | ||
244 | 0, | ||
245 | ATH79_IP2_IRQ(0)); | ||
246 | } else if (soc_is_qca9558()) { | ||
247 | pdev = ath79_register_pci_ar724x(0, | ||
248 | QCA955X_PCI_CFG_BASE0, | ||
249 | QCA955X_PCI_CTRL_BASE0, | ||
250 | QCA955X_PCI_CRP_BASE0, | ||
251 | QCA955X_PCI_MEM_BASE0, | ||
252 | QCA955X_PCI_MEM_SIZE, | ||
253 | 0, | ||
254 | ATH79_IP2_IRQ(0)); | ||
255 | |||
256 | pdev = ath79_register_pci_ar724x(1, | ||
257 | QCA955X_PCI_CFG_BASE1, | ||
258 | QCA955X_PCI_CTRL_BASE1, | ||
259 | QCA955X_PCI_CRP_BASE1, | ||
260 | QCA955X_PCI_MEM_BASE1, | ||
261 | QCA955X_PCI_MEM_SIZE, | ||
262 | 1, | ||
263 | ATH79_IP3_IRQ(2)); | ||
264 | } else { | ||
265 | /* No PCI support */ | ||
266 | return -ENODEV; | ||
127 | } | 267 | } |
128 | 268 | ||
129 | return -ENODEV; | 269 | if (!pdev) |
270 | pr_err("unable to register PCI controller device\n"); | ||
271 | |||
272 | return pdev ? 0 : -ENODEV; | ||
130 | } | 273 | } |
diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h index 51c6625dcc6d..1d00a3803c37 100644 --- a/arch/mips/ath79/pci.h +++ b/arch/mips/ath79/pci.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define _ATH79_PCI_H | 14 | #define _ATH79_PCI_H |
15 | 15 | ||
16 | struct ath79_pci_irq { | 16 | struct ath79_pci_irq { |
17 | int bus; | ||
17 | u8 slot; | 18 | u8 slot; |
18 | u8 pin; | 19 | u8 pin; |
19 | int irq; | 20 | int irq; |
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 60d212ef8629..d5b3c9057018 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
@@ -164,13 +164,29 @@ static void __init ath79_detect_sys_type(void) | |||
164 | rev = id & AR934X_REV_ID_REVISION_MASK; | 164 | rev = id & AR934X_REV_ID_REVISION_MASK; |
165 | break; | 165 | break; |
166 | 166 | ||
167 | case REV_ID_MAJOR_QCA9556: | ||
168 | ath79_soc = ATH79_SOC_QCA9556; | ||
169 | chip = "9556"; | ||
170 | rev = id & QCA955X_REV_ID_REVISION_MASK; | ||
171 | break; | ||
172 | |||
173 | case REV_ID_MAJOR_QCA9558: | ||
174 | ath79_soc = ATH79_SOC_QCA9558; | ||
175 | chip = "9558"; | ||
176 | rev = id & QCA955X_REV_ID_REVISION_MASK; | ||
177 | break; | ||
178 | |||
167 | default: | 179 | default: |
168 | panic("ath79: unknown SoC, id:0x%08x", id); | 180 | panic("ath79: unknown SoC, id:0x%08x", id); |
169 | } | 181 | } |
170 | 182 | ||
171 | ath79_soc_rev = rev; | 183 | ath79_soc_rev = rev; |
172 | 184 | ||
173 | sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); | 185 | if (soc_is_qca955x()) |
186 | sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u", | ||
187 | chip, rev); | ||
188 | else | ||
189 | sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); | ||
174 | pr_info("SoC: %s\n", ath79_sys_type); | 190 | pr_info("SoC: %s\n", ath79_sys_type); |
175 | } | 191 | } |
176 | 192 | ||
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index c37419c11c92..cc40b74940f5 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2005 Broadcom Corporation | 4 | * Copyright (C) 2005 Broadcom Corporation |
5 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | 5 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> |
6 | * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> | 6 | * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -18,83 +18,160 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <asm/addrspace.h> | 20 | #include <asm/addrspace.h> |
21 | #include <asm/mach-bcm47xx/nvram.h> | 21 | #include <bcm47xx_nvram.h> |
22 | #include <asm/mach-bcm47xx/bcm47xx.h> | 22 | #include <asm/mach-bcm47xx/bcm47xx.h> |
23 | 23 | ||
24 | static char nvram_buf[NVRAM_SPACE]; | 24 | static char nvram_buf[NVRAM_SPACE]; |
25 | 25 | ||
26 | static u32 find_nvram_size(u32 end) | ||
27 | { | ||
28 | struct nvram_header *header; | ||
29 | u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; | ||
30 | int i; | ||
31 | |||
32 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | ||
33 | header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); | ||
34 | if (header->magic == NVRAM_HEADER) | ||
35 | return nvram_sizes[i]; | ||
36 | } | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | |||
26 | /* Probe for NVRAM header */ | 41 | /* Probe for NVRAM header */ |
27 | static void early_nvram_init(void) | 42 | static int nvram_find_and_copy(u32 base, u32 lim) |
28 | { | 43 | { |
29 | #ifdef CONFIG_BCM47XX_SSB | ||
30 | struct ssb_mipscore *mcore_ssb; | ||
31 | #endif | ||
32 | #ifdef CONFIG_BCM47XX_BCMA | ||
33 | struct bcma_drv_cc *bcma_cc; | ||
34 | #endif | ||
35 | struct nvram_header *header; | 44 | struct nvram_header *header; |
36 | int i; | 45 | int i; |
37 | u32 base = 0; | ||
38 | u32 lim = 0; | ||
39 | u32 off; | 46 | u32 off; |
40 | u32 *src, *dst; | 47 | u32 *src, *dst; |
48 | u32 size; | ||
41 | 49 | ||
42 | switch (bcm47xx_bus_type) { | 50 | /* TODO: when nvram is on nand flash check for bad blocks first. */ |
43 | #ifdef CONFIG_BCM47XX_SSB | ||
44 | case BCM47XX_BUS_TYPE_SSB: | ||
45 | mcore_ssb = &bcm47xx_bus.ssb.mipscore; | ||
46 | base = mcore_ssb->pflash.window; | ||
47 | lim = mcore_ssb->pflash.window_size; | ||
48 | break; | ||
49 | #endif | ||
50 | #ifdef CONFIG_BCM47XX_BCMA | ||
51 | case BCM47XX_BUS_TYPE_BCMA: | ||
52 | bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc; | ||
53 | base = bcma_cc->pflash.window; | ||
54 | lim = bcma_cc->pflash.window_size; | ||
55 | break; | ||
56 | #endif | ||
57 | } | ||
58 | |||
59 | off = FLASH_MIN; | 51 | off = FLASH_MIN; |
60 | while (off <= lim) { | 52 | while (off <= lim) { |
61 | /* Windowed flash access */ | 53 | /* Windowed flash access */ |
62 | header = (struct nvram_header *) | 54 | size = find_nvram_size(base + off); |
63 | KSEG1ADDR(base + off - NVRAM_SPACE); | 55 | if (size) { |
64 | if (header->magic == NVRAM_HEADER) | 56 | header = (struct nvram_header *)KSEG1ADDR(base + off - |
57 | size); | ||
65 | goto found; | 58 | goto found; |
59 | } | ||
66 | off <<= 1; | 60 | off <<= 1; |
67 | } | 61 | } |
68 | 62 | ||
69 | /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ | 63 | /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ |
70 | header = (struct nvram_header *) KSEG1ADDR(base + 4096); | 64 | header = (struct nvram_header *) KSEG1ADDR(base + 4096); |
71 | if (header->magic == NVRAM_HEADER) | 65 | if (header->magic == NVRAM_HEADER) { |
66 | size = NVRAM_SPACE; | ||
72 | goto found; | 67 | goto found; |
68 | } | ||
73 | 69 | ||
74 | header = (struct nvram_header *) KSEG1ADDR(base + 1024); | 70 | header = (struct nvram_header *) KSEG1ADDR(base + 1024); |
75 | if (header->magic == NVRAM_HEADER) | 71 | if (header->magic == NVRAM_HEADER) { |
72 | size = NVRAM_SPACE; | ||
76 | goto found; | 73 | goto found; |
74 | } | ||
77 | 75 | ||
78 | return; | 76 | pr_err("no nvram found\n"); |
77 | return -ENXIO; | ||
79 | 78 | ||
80 | found: | 79 | found: |
80 | |||
81 | if (header->len > size) | ||
82 | pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n"); | ||
83 | if (header->len > NVRAM_SPACE) | ||
84 | pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", | ||
85 | header->len, NVRAM_SPACE); | ||
86 | |||
81 | src = (u32 *) header; | 87 | src = (u32 *) header; |
82 | dst = (u32 *) nvram_buf; | 88 | dst = (u32 *) nvram_buf; |
83 | for (i = 0; i < sizeof(struct nvram_header); i += 4) | 89 | for (i = 0; i < sizeof(struct nvram_header); i += 4) |
84 | *dst++ = *src++; | 90 | *dst++ = *src++; |
85 | for (; i < header->len && i < NVRAM_SPACE; i += 4) | 91 | for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4) |
86 | *dst++ = le32_to_cpu(*src++); | 92 | *dst++ = le32_to_cpu(*src++); |
93 | memset(dst, 0x0, NVRAM_SPACE - i); | ||
94 | |||
95 | return 0; | ||
87 | } | 96 | } |
88 | 97 | ||
89 | int nvram_getenv(char *name, char *val, size_t val_len) | 98 | #ifdef CONFIG_BCM47XX_SSB |
99 | static int nvram_init_ssb(void) | ||
100 | { | ||
101 | struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; | ||
102 | u32 base; | ||
103 | u32 lim; | ||
104 | |||
105 | if (mcore->pflash.present) { | ||
106 | base = mcore->pflash.window; | ||
107 | lim = mcore->pflash.window_size; | ||
108 | } else { | ||
109 | pr_err("Couldn't find supported flash memory\n"); | ||
110 | return -ENXIO; | ||
111 | } | ||
112 | |||
113 | return nvram_find_and_copy(base, lim); | ||
114 | } | ||
115 | #endif | ||
116 | |||
117 | #ifdef CONFIG_BCM47XX_BCMA | ||
118 | static int nvram_init_bcma(void) | ||
119 | { | ||
120 | struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; | ||
121 | u32 base; | ||
122 | u32 lim; | ||
123 | |||
124 | #ifdef CONFIG_BCMA_NFLASH | ||
125 | if (cc->nflash.boot) { | ||
126 | base = BCMA_SOC_FLASH1; | ||
127 | lim = BCMA_SOC_FLASH1_SZ; | ||
128 | } else | ||
129 | #endif | ||
130 | if (cc->pflash.present) { | ||
131 | base = cc->pflash.window; | ||
132 | lim = cc->pflash.window_size; | ||
133 | #ifdef CONFIG_BCMA_SFLASH | ||
134 | } else if (cc->sflash.present) { | ||
135 | base = cc->sflash.window; | ||
136 | lim = cc->sflash.size; | ||
137 | #endif | ||
138 | } else { | ||
139 | pr_err("Couldn't find supported flash memory\n"); | ||
140 | return -ENXIO; | ||
141 | } | ||
142 | |||
143 | return nvram_find_and_copy(base, lim); | ||
144 | } | ||
145 | #endif | ||
146 | |||
147 | static int nvram_init(void) | ||
148 | { | ||
149 | switch (bcm47xx_bus_type) { | ||
150 | #ifdef CONFIG_BCM47XX_SSB | ||
151 | case BCM47XX_BUS_TYPE_SSB: | ||
152 | return nvram_init_ssb(); | ||
153 | #endif | ||
154 | #ifdef CONFIG_BCM47XX_BCMA | ||
155 | case BCM47XX_BUS_TYPE_BCMA: | ||
156 | return nvram_init_bcma(); | ||
157 | #endif | ||
158 | } | ||
159 | return -ENXIO; | ||
160 | } | ||
161 | |||
162 | int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) | ||
90 | { | 163 | { |
91 | char *var, *value, *end, *eq; | 164 | char *var, *value, *end, *eq; |
165 | int err; | ||
92 | 166 | ||
93 | if (!name) | 167 | if (!name) |
94 | return NVRAM_ERR_INV_PARAM; | 168 | return -EINVAL; |
95 | 169 | ||
96 | if (!nvram_buf[0]) | 170 | if (!nvram_buf[0]) { |
97 | early_nvram_init(); | 171 | err = nvram_init(); |
172 | if (err) | ||
173 | return err; | ||
174 | } | ||
98 | 175 | ||
99 | /* Look for name=value and return value */ | 176 | /* Look for name=value and return value */ |
100 | var = &nvram_buf[sizeof(struct nvram_header)]; | 177 | var = &nvram_buf[sizeof(struct nvram_header)]; |
@@ -110,6 +187,6 @@ int nvram_getenv(char *name, char *val, size_t val_len) | |||
110 | return snprintf(val, val_len, "%s", value); | 187 | return snprintf(val, val_len, "%s", value); |
111 | } | 188 | } |
112 | } | 189 | } |
113 | return NVRAM_ERR_ENVNOTFOUND; | 190 | return -ENOENT; |
114 | } | 191 | } |
115 | EXPORT_SYMBOL(nvram_getenv); | 192 | EXPORT_SYMBOL(bcm47xx_nvram_getenv); |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 4d54b58dbd32..b2246cd9ca12 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <asm/reboot.h> | 35 | #include <asm/reboot.h> |
36 | #include <asm/time.h> | 36 | #include <asm/time.h> |
37 | #include <bcm47xx.h> | 37 | #include <bcm47xx.h> |
38 | #include <asm/mach-bcm47xx/nvram.h> | 38 | #include <bcm47xx_nvram.h> |
39 | 39 | ||
40 | union bcm47xx_bus bcm47xx_bus; | 40 | union bcm47xx_bus bcm47xx_bus; |
41 | EXPORT_SYMBOL(bcm47xx_bus); | 41 | EXPORT_SYMBOL(bcm47xx_bus); |
@@ -115,7 +115,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, | |||
115 | memset(&iv->sprom, 0, sizeof(struct ssb_sprom)); | 115 | memset(&iv->sprom, 0, sizeof(struct ssb_sprom)); |
116 | bcm47xx_fill_sprom(&iv->sprom, NULL, false); | 116 | bcm47xx_fill_sprom(&iv->sprom, NULL, false); |
117 | 117 | ||
118 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) | 118 | if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) |
119 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); | 119 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); |
120 | 120 | ||
121 | return 0; | 121 | return 0; |
@@ -138,7 +138,7 @@ static void __init bcm47xx_register_ssb(void) | |||
138 | panic("Failed to initialize SSB bus (err %d)", err); | 138 | panic("Failed to initialize SSB bus (err %d)", err); |
139 | 139 | ||
140 | mcore = &bcm47xx_bus.ssb.mipscore; | 140 | mcore = &bcm47xx_bus.ssb.mipscore; |
141 | if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { | 141 | if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { |
142 | if (strstr(buf, "console=ttyS1")) { | 142 | if (strstr(buf, "console=ttyS1")) { |
143 | struct ssb_serial_port port; | 143 | struct ssb_serial_port port; |
144 | 144 | ||
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index b2a7c251e471..ad03c931b905 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <bcm47xx.h> | 29 | #include <bcm47xx.h> |
30 | #include <nvram.h> | 30 | #include <bcm47xx_nvram.h> |
31 | 31 | ||
32 | static void create_key(const char *prefix, const char *postfix, | 32 | static void create_key(const char *prefix, const char *postfix, |
33 | const char *name, char *buf, int len) | 33 | const char *name, char *buf, int len) |
@@ -50,10 +50,10 @@ static int get_nvram_var(const char *prefix, const char *postfix, | |||
50 | 50 | ||
51 | create_key(prefix, postfix, name, key, sizeof(key)); | 51 | create_key(prefix, postfix, name, key, sizeof(key)); |
52 | 52 | ||
53 | err = nvram_getenv(key, buf, len); | 53 | err = bcm47xx_nvram_getenv(key, buf, len); |
54 | if (fallback && err == NVRAM_ERR_ENVNOTFOUND && prefix) { | 54 | if (fallback && err == -ENOENT && prefix) { |
55 | create_key(NULL, postfix, name, key, sizeof(key)); | 55 | create_key(NULL, postfix, name, key, sizeof(key)); |
56 | err = nvram_getenv(key, buf, len); | 56 | err = bcm47xx_nvram_getenv(key, buf, len); |
57 | } | 57 | } |
58 | return err; | 58 | return err; |
59 | } | 59 | } |
@@ -71,7 +71,7 @@ static void nvram_read_ ## type (const char *prefix, \ | |||
71 | fallback); \ | 71 | fallback); \ |
72 | if (err < 0) \ | 72 | if (err < 0) \ |
73 | return; \ | 73 | return; \ |
74 | err = kstrto ## type (buf, 0, &var); \ | 74 | err = kstrto ## type(strim(buf), 0, &var); \ |
75 | if (err) { \ | 75 | if (err) { \ |
76 | pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \ | 76 | pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \ |
77 | prefix, name, postfix, buf, err); \ | 77 | prefix, name, postfix, buf, err); \ |
@@ -99,7 +99,7 @@ static void nvram_read_u32_2(const char *prefix, const char *name, | |||
99 | err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); | 99 | err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); |
100 | if (err < 0) | 100 | if (err < 0) |
101 | return; | 101 | return; |
102 | err = kstrtou32(buf, 0, &val); | 102 | err = kstrtou32(strim(buf), 0, &val); |
103 | if (err) { | 103 | if (err) { |
104 | pr_warn("can not parse nvram name %s%s with value %s got %i\n", | 104 | pr_warn("can not parse nvram name %s%s with value %s got %i\n", |
105 | prefix, name, buf, err); | 105 | prefix, name, buf, err); |
@@ -120,7 +120,7 @@ static void nvram_read_leddc(const char *prefix, const char *name, | |||
120 | err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); | 120 | err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); |
121 | if (err < 0) | 121 | if (err < 0) |
122 | return; | 122 | return; |
123 | err = kstrtou32(buf, 0, &val); | 123 | err = kstrtou32(strim(buf), 0, &val); |
124 | if (err) { | 124 | if (err) { |
125 | pr_warn("can not parse nvram name %s%s with value %s got %i\n", | 125 | pr_warn("can not parse nvram name %s%s with value %s got %i\n", |
126 | prefix, name, buf, err); | 126 | prefix, name, buf, err); |
@@ -144,7 +144,7 @@ static void nvram_read_macaddr(const char *prefix, const char *name, | |||
144 | if (err < 0) | 144 | if (err < 0) |
145 | return; | 145 | return; |
146 | 146 | ||
147 | nvram_parse_macaddr(buf, *val); | 147 | bcm47xx_nvram_parse_macaddr(buf, *val); |
148 | } | 148 | } |
149 | 149 | ||
150 | static void nvram_read_alpha2(const char *prefix, const char *name, | 150 | static void nvram_read_alpha2(const char *prefix, const char *name, |
@@ -652,12 +652,10 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, | |||
652 | static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, | 652 | static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, |
653 | bool fallback) | 653 | bool fallback) |
654 | { | 654 | { |
655 | nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, | 655 | nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, true); |
656 | fallback); | ||
657 | nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0, | 656 | nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0, |
658 | fallback); | 657 | fallback); |
659 | nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, | 658 | nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, true); |
660 | fallback); | ||
661 | nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, | 659 | nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, |
662 | &sprom->boardflags_hi, fallback); | 660 | &sprom->boardflags_hi, fallback); |
663 | nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, | 661 | nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, |
diff --git a/arch/mips/bcm63xx/early_printk.c b/arch/mips/bcm63xx/early_printk.c index bf353c937df2..aa8f7f9cc7a4 100644 --- a/arch/mips/bcm63xx/early_printk.c +++ b/arch/mips/bcm63xx/early_printk.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <bcm63xx_io.h> | 10 | #include <bcm63xx_io.h> |
11 | #include <bcm63xx_regs.h> | 11 | #include <bcm63xx_regs.h> |
12 | 12 | ||
13 | static void __init wait_xfered(void) | 13 | static void wait_xfered(void) |
14 | { | 14 | { |
15 | unsigned int val; | 15 | unsigned int val; |
16 | 16 | ||
@@ -22,7 +22,7 @@ static void __init wait_xfered(void) | |||
22 | } while (1); | 22 | } while (1); |
23 | } | 23 | } |
24 | 24 | ||
25 | void __init prom_putchar(char c) | 25 | void prom_putchar(char c) |
26 | { | 26 | { |
27 | wait_xfered(); | 27 | wait_xfered(); |
28 | bcm_uart0_writel(c, UART_FIFO_REG); | 28 | bcm_uart0_writel(c, UART_FIFO_REG); |
diff --git a/arch/mips/configs/ath79_defconfig b/arch/mips/configs/ath79_defconfig index ea87d43ba607..e3a3836508ec 100644 --- a/arch/mips/configs/ath79_defconfig +++ b/arch/mips/configs/ath79_defconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | CONFIG_ATH79=y | 1 | CONFIG_ATH79=y |
2 | CONFIG_ATH79_MACH_AP121=y | 2 | CONFIG_ATH79_MACH_AP121=y |
3 | CONFIG_ATH79_MACH_AP136=y | ||
3 | CONFIG_ATH79_MACH_AP81=y | 4 | CONFIG_ATH79_MACH_AP81=y |
4 | CONFIG_ATH79_MACH_DB120=y | 5 | CONFIG_ATH79_MACH_DB120=y |
5 | CONFIG_ATH79_MACH_PB44=y | 6 | CONFIG_ATH79_MACH_PB44=y |
diff --git a/arch/mips/configs/rt305x_defconfig b/arch/mips/configs/rt305x_defconfig new file mode 100644 index 000000000000..d1741bcf8949 --- /dev/null +++ b/arch/mips/configs/rt305x_defconfig | |||
@@ -0,0 +1,167 @@ | |||
1 | CONFIG_RALINK=y | ||
2 | CONFIG_DTB_RT305X_EVAL=y | ||
3 | CONFIG_CPU_MIPS32_R2=y | ||
4 | # CONFIG_COMPACTION is not set | ||
5 | # CONFIG_CROSS_MEMORY_ATTACH is not set | ||
6 | CONFIG_HZ_100=y | ||
7 | # CONFIG_SECCOMP is not set | ||
8 | CONFIG_EXPERIMENTAL=y | ||
9 | # CONFIG_LOCALVERSION_AUTO is not set | ||
10 | CONFIG_SYSVIPC=y | ||
11 | CONFIG_HIGH_RES_TIMERS=y | ||
12 | CONFIG_BLK_DEV_INITRD=y | ||
13 | CONFIG_INITRAMFS_SOURCE="" | ||
14 | CONFIG_INITRAMFS_ROOT_UID=1000 | ||
15 | CONFIG_INITRAMFS_ROOT_GID=1000 | ||
16 | # CONFIG_RD_GZIP is not set | ||
17 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
18 | CONFIG_KALLSYMS_ALL=y | ||
19 | # CONFIG_AIO is not set | ||
20 | CONFIG_EMBEDDED=y | ||
21 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
22 | # CONFIG_SLUB_DEBUG is not set | ||
23 | # CONFIG_COMPAT_BRK is not set | ||
24 | CONFIG_MODULES=y | ||
25 | CONFIG_MODULE_UNLOAD=y | ||
26 | # CONFIG_BLK_DEV_BSG is not set | ||
27 | CONFIG_PARTITION_ADVANCED=y | ||
28 | # CONFIG_IOSCHED_CFQ is not set | ||
29 | # CONFIG_COREDUMP is not set | ||
30 | # CONFIG_SUSPEND is not set | ||
31 | CONFIG_NET=y | ||
32 | CONFIG_PACKET=y | ||
33 | CONFIG_UNIX=y | ||
34 | CONFIG_INET=y | ||
35 | CONFIG_IP_MULTICAST=y | ||
36 | CONFIG_IP_ADVANCED_ROUTER=y | ||
37 | CONFIG_IP_MULTIPLE_TABLES=y | ||
38 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
39 | CONFIG_IP_ROUTE_VERBOSE=y | ||
40 | CONFIG_IP_MROUTE=y | ||
41 | CONFIG_IP_MROUTE_MULTIPLE_TABLES=y | ||
42 | CONFIG_ARPD=y | ||
43 | CONFIG_SYN_COOKIES=y | ||
44 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
45 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
46 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
47 | # CONFIG_INET_LRO is not set | ||
48 | # CONFIG_INET_DIAG is not set | ||
49 | CONFIG_TCP_CONG_ADVANCED=y | ||
50 | # CONFIG_TCP_CONG_BIC is not set | ||
51 | # CONFIG_TCP_CONG_WESTWOOD is not set | ||
52 | # CONFIG_TCP_CONG_HTCP is not set | ||
53 | # CONFIG_IPV6 is not set | ||
54 | CONFIG_NETFILTER=y | ||
55 | # CONFIG_BRIDGE_NETFILTER is not set | ||
56 | CONFIG_NF_CONNTRACK=m | ||
57 | CONFIG_NF_CONNTRACK_FTP=m | ||
58 | CONFIG_NF_CONNTRACK_IRC=m | ||
59 | CONFIG_NETFILTER_XT_TARGET_CT=m | ||
60 | CONFIG_NETFILTER_XT_TARGET_LOG=m | ||
61 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m | ||
62 | CONFIG_NETFILTER_XT_MATCH_COMMENT=m | ||
63 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | ||
64 | CONFIG_NETFILTER_XT_MATCH_LIMIT=m | ||
65 | CONFIG_NETFILTER_XT_MATCH_MAC=m | ||
66 | CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m | ||
67 | CONFIG_NETFILTER_XT_MATCH_STATE=m | ||
68 | CONFIG_NF_CONNTRACK_IPV4=m | ||
69 | # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set | ||
70 | CONFIG_IP_NF_IPTABLES=m | ||
71 | CONFIG_IP_NF_FILTER=m | ||
72 | CONFIG_IP_NF_TARGET_REJECT=m | ||
73 | CONFIG_IP_NF_MANGLE=m | ||
74 | CONFIG_IP_NF_RAW=m | ||
75 | CONFIG_BRIDGE=y | ||
76 | # CONFIG_BRIDGE_IGMP_SNOOPING is not set | ||
77 | CONFIG_VLAN_8021Q=y | ||
78 | CONFIG_NET_SCHED=y | ||
79 | CONFIG_HAMRADIO=y | ||
80 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
81 | # CONFIG_FIRMWARE_IN_KERNEL is not set | ||
82 | CONFIG_MTD=y | ||
83 | CONFIG_MTD_CMDLINE_PARTS=y | ||
84 | CONFIG_MTD_CHAR=y | ||
85 | CONFIG_MTD_BLOCK=y | ||
86 | CONFIG_MTD_CFI=y | ||
87 | CONFIG_MTD_CFI_AMDSTD=y | ||
88 | CONFIG_MTD_COMPLEX_MAPPINGS=y | ||
89 | CONFIG_MTD_PHYSMAP=y | ||
90 | CONFIG_MTD_PHYSMAP_OF=y | ||
91 | CONFIG_MTD_M25P80=y | ||
92 | CONFIG_EEPROM_93CX6=m | ||
93 | CONFIG_SCSI=y | ||
94 | CONFIG_BLK_DEV_SD=y | ||
95 | CONFIG_NETDEVICES=y | ||
96 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
97 | CONFIG_PHYLIB=y | ||
98 | CONFIG_PPP=m | ||
99 | CONFIG_PPP_FILTER=y | ||
100 | CONFIG_PPP_MULTILINK=y | ||
101 | CONFIG_PPPOE=m | ||
102 | CONFIG_PPP_ASYNC=m | ||
103 | CONFIG_ISDN=y | ||
104 | CONFIG_INPUT=m | ||
105 | CONFIG_INPUT_POLLDEV=m | ||
106 | # CONFIG_INPUT_MOUSEDEV is not set | ||
107 | # CONFIG_KEYBOARD_ATKBD is not set | ||
108 | # CONFIG_INPUT_MOUSE is not set | ||
109 | CONFIG_INPUT_MISC=y | ||
110 | # CONFIG_SERIO is not set | ||
111 | # CONFIG_VT is not set | ||
112 | # CONFIG_LEGACY_PTYS is not set | ||
113 | # CONFIG_DEVKMEM is not set | ||
114 | CONFIG_SERIAL_8250=y | ||
115 | CONFIG_SERIAL_8250_CONSOLE=y | ||
116 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
117 | CONFIG_SERIAL_OF_PLATFORM=y | ||
118 | CONFIG_SPI=y | ||
119 | # CONFIG_HWMON is not set | ||
120 | CONFIG_WATCHDOG=y | ||
121 | # CONFIG_HID is not set | ||
122 | # CONFIG_USB_HID is not set | ||
123 | CONFIG_USB=y | ||
124 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | ||
125 | CONFIG_USB_STORAGE=y | ||
126 | CONFIG_USB_STORAGE_DEBUG=y | ||
127 | CONFIG_NEW_LEDS=y | ||
128 | CONFIG_LEDS_CLASS=y | ||
129 | CONFIG_LEDS_TRIGGERS=y | ||
130 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
131 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
132 | CONFIG_STAGING=y | ||
133 | # CONFIG_IOMMU_SUPPORT is not set | ||
134 | # CONFIG_DNOTIFY is not set | ||
135 | # CONFIG_PROC_PAGE_MONITOR is not set | ||
136 | CONFIG_TMPFS=y | ||
137 | CONFIG_TMPFS_XATTR=y | ||
138 | CONFIG_JFFS2_FS=y | ||
139 | CONFIG_JFFS2_SUMMARY=y | ||
140 | CONFIG_JFFS2_FS_XATTR=y | ||
141 | # CONFIG_JFFS2_FS_POSIX_ACL is not set | ||
142 | # CONFIG_JFFS2_FS_SECURITY is not set | ||
143 | CONFIG_JFFS2_COMPRESSION_OPTIONS=y | ||
144 | # CONFIG_JFFS2_ZLIB is not set | ||
145 | CONFIG_SQUASHFS=y | ||
146 | # CONFIG_SQUASHFS_ZLIB is not set | ||
147 | CONFIG_SQUASHFS_XZ=y | ||
148 | CONFIG_PRINTK_TIME=y | ||
149 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
150 | CONFIG_MAGIC_SYSRQ=y | ||
151 | CONFIG_STRIP_ASM_SYMS=y | ||
152 | CONFIG_DEBUG_FS=y | ||
153 | # CONFIG_SCHED_DEBUG is not set | ||
154 | # CONFIG_FTRACE is not set | ||
155 | CONFIG_CMDLINE_BOOL=y | ||
156 | CONFIG_CRYPTO_MANAGER=m | ||
157 | CONFIG_CRYPTO_ARC4=m | ||
158 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
159 | CONFIG_CRC_ITU_T=m | ||
160 | CONFIG_CRC32_SARWATE=y | ||
161 | # CONFIG_XZ_DEC_X86 is not set | ||
162 | # CONFIG_XZ_DEC_POWERPC is not set | ||
163 | # CONFIG_XZ_DEC_IA64 is not set | ||
164 | # CONFIG_XZ_DEC_ARM is not set | ||
165 | # CONFIG_XZ_DEC_ARMTHUMB is not set | ||
166 | # CONFIG_XZ_DEC_SPARC is not set | ||
167 | CONFIG_AVERAGE=y | ||
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 1e83b24fa461..1a57e8b4d092 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -98,6 +98,9 @@ | |||
98 | #ifndef cpu_has_rixi | 98 | #ifndef cpu_has_rixi |
99 | #define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) | 99 | #define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) |
100 | #endif | 100 | #endif |
101 | #ifndef cpu_has_mmips | ||
102 | #define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS) | ||
103 | #endif | ||
101 | #ifndef cpu_has_vtag_icache | 104 | #ifndef cpu_has_vtag_icache |
102 | #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) | 105 | #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) |
103 | #endif | 106 | #endif |
@@ -273,4 +276,8 @@ | |||
273 | #define cpu_has_perf_cntr_intr_bit (cpu_data[0].options & MIPS_CPU_PCI) | 276 | #define cpu_has_perf_cntr_intr_bit (cpu_data[0].options & MIPS_CPU_PCI) |
274 | #endif | 277 | #endif |
275 | 278 | ||
279 | #ifndef cpu_has_vz | ||
280 | #define cpu_has_vz (cpu_data[0].ases & MIPS_ASE_VZ) | ||
281 | #endif | ||
282 | |||
276 | #endif /* __ASM_CPU_FEATURES_H */ | 283 | #endif /* __ASM_CPU_FEATURES_H */ |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 9904697bd792..dd86ab205483 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -96,6 +96,7 @@ | |||
96 | #define PRID_IMP_1004K 0x9900 | 96 | #define PRID_IMP_1004K 0x9900 |
97 | #define PRID_IMP_1074K 0x9a00 | 97 | #define PRID_IMP_1074K 0x9a00 |
98 | #define PRID_IMP_M14KC 0x9c00 | 98 | #define PRID_IMP_M14KC 0x9c00 |
99 | #define PRID_IMP_M14KEC 0x9e00 | ||
99 | 100 | ||
100 | /* | 101 | /* |
101 | * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE | 102 | * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE |
@@ -264,6 +265,7 @@ enum cpu_type_enum { | |||
264 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, | 265 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, |
265 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, | 266 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, |
266 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, | 267 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, |
268 | CPU_M14KEC, | ||
267 | 269 | ||
268 | /* | 270 | /* |
269 | * MIPS64 class processors | 271 | * MIPS64 class processors |
@@ -322,6 +324,7 @@ enum cpu_type_enum { | |||
322 | #define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */ | 324 | #define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */ |
323 | #define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */ | 325 | #define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */ |
324 | #define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */ | 326 | #define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */ |
327 | #define MIPS_CPU_MICROMIPS 0x01000000 /* CPU has microMIPS capability */ | ||
325 | 328 | ||
326 | /* | 329 | /* |
327 | * CPU ASE encodings | 330 | * CPU ASE encodings |
@@ -333,6 +336,6 @@ enum cpu_type_enum { | |||
333 | #define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */ | 336 | #define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */ |
334 | #define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */ | 337 | #define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */ |
335 | #define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */ | 338 | #define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */ |
336 | 339 | #define MIPS_ASE_VZ 0x00000080 /* Virtualization ASE */ | |
337 | 340 | ||
338 | #endif /* _ASM_CPU_H */ | 341 | #endif /* _ASM_CPU_H */ |
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 61b06d7e7de1..bdc9786ab5a7 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -359,6 +359,7 @@ struct gic_shared_intr_map { | |||
359 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ | 359 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ |
360 | #define GIC_PIN_TO_VEC_OFFSET (1) | 360 | #define GIC_PIN_TO_VEC_OFFSET (1) |
361 | 361 | ||
362 | extern int gic_present; | ||
362 | extern unsigned long _gic_base; | 363 | extern unsigned long _gic_base; |
363 | extern unsigned int gic_irq_base; | 364 | extern unsigned int gic_irq_base; |
364 | extern unsigned int gic_irq_flags[]; | 365 | extern unsigned int gic_irq_flags[]; |
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h index 568544b6e856..44d6a5bde4a1 100644 --- a/arch/mips/include/asm/hazards.h +++ b/arch/mips/include/asm/hazards.h | |||
@@ -141,7 +141,7 @@ do { \ | |||
141 | 141 | ||
142 | #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ | 142 | #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ |
143 | defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \ | 143 | defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \ |
144 | defined(CONFIG_CPU_R5500) | 144 | defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR) |
145 | 145 | ||
146 | /* | 146 | /* |
147 | * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. | 147 | * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. |
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h index ef6a07cddb23..3f11fdb3ed8c 100644 --- a/arch/mips/include/asm/irq_cpu.h +++ b/arch/mips/include/asm/irq_cpu.h | |||
@@ -17,4 +17,10 @@ extern void mips_cpu_irq_init(void); | |||
17 | extern void rm7k_cpu_irq_init(void); | 17 | extern void rm7k_cpu_irq_init(void); |
18 | extern void rm9k_cpu_irq_init(void); | 18 | extern void rm9k_cpu_irq_init(void); |
19 | 19 | ||
20 | #ifdef CONFIG_IRQ_DOMAIN | ||
21 | struct device_node; | ||
22 | extern int mips_cpu_intc_init(struct device_node *of_node, | ||
23 | struct device_node *parent); | ||
24 | #endif | ||
25 | |||
20 | #endif /* _ASM_IRQ_CPU_H */ | 26 | #endif /* _ASM_IRQ_CPU_H */ |
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index 8dec938af115..b86a1253a5bf 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h | |||
@@ -41,11 +41,37 @@ | |||
41 | #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) | 41 | #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) |
42 | #define AR71XX_RESET_SIZE 0x100 | 42 | #define AR71XX_RESET_SIZE 0x100 |
43 | 43 | ||
44 | #define AR71XX_PCI_MEM_BASE 0x10000000 | ||
45 | #define AR71XX_PCI_MEM_SIZE 0x07000000 | ||
46 | |||
47 | #define AR71XX_PCI_WIN0_OFFS 0x10000000 | ||
48 | #define AR71XX_PCI_WIN1_OFFS 0x11000000 | ||
49 | #define AR71XX_PCI_WIN2_OFFS 0x12000000 | ||
50 | #define AR71XX_PCI_WIN3_OFFS 0x13000000 | ||
51 | #define AR71XX_PCI_WIN4_OFFS 0x14000000 | ||
52 | #define AR71XX_PCI_WIN5_OFFS 0x15000000 | ||
53 | #define AR71XX_PCI_WIN6_OFFS 0x16000000 | ||
54 | #define AR71XX_PCI_WIN7_OFFS 0x07000000 | ||
55 | |||
56 | #define AR71XX_PCI_CFG_BASE \ | ||
57 | (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) | ||
58 | #define AR71XX_PCI_CFG_SIZE 0x100 | ||
59 | |||
44 | #define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) | 60 | #define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) |
45 | #define AR7240_USB_CTRL_SIZE 0x100 | 61 | #define AR7240_USB_CTRL_SIZE 0x100 |
46 | #define AR7240_OHCI_BASE 0x1b000000 | 62 | #define AR7240_OHCI_BASE 0x1b000000 |
47 | #define AR7240_OHCI_SIZE 0x1000 | 63 | #define AR7240_OHCI_SIZE 0x1000 |
48 | 64 | ||
65 | #define AR724X_PCI_MEM_BASE 0x10000000 | ||
66 | #define AR724X_PCI_MEM_SIZE 0x04000000 | ||
67 | |||
68 | #define AR724X_PCI_CFG_BASE 0x14000000 | ||
69 | #define AR724X_PCI_CFG_SIZE 0x1000 | ||
70 | #define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000c0000) | ||
71 | #define AR724X_PCI_CRP_SIZE 0x1000 | ||
72 | #define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) | ||
73 | #define AR724X_PCI_CTRL_SIZE 0x100 | ||
74 | |||
49 | #define AR724X_EHCI_BASE 0x1b000000 | 75 | #define AR724X_EHCI_BASE 0x1b000000 |
50 | #define AR724X_EHCI_SIZE 0x1000 | 76 | #define AR724X_EHCI_SIZE 0x1000 |
51 | 77 | ||
@@ -68,6 +94,25 @@ | |||
68 | #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) | 94 | #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) |
69 | #define AR934X_SRIF_SIZE 0x1000 | 95 | #define AR934X_SRIF_SIZE 0x1000 |
70 | 96 | ||
97 | #define QCA955X_PCI_MEM_BASE0 0x10000000 | ||
98 | #define QCA955X_PCI_MEM_BASE1 0x12000000 | ||
99 | #define QCA955X_PCI_MEM_SIZE 0x02000000 | ||
100 | #define QCA955X_PCI_CFG_BASE0 0x14000000 | ||
101 | #define QCA955X_PCI_CFG_BASE1 0x16000000 | ||
102 | #define QCA955X_PCI_CFG_SIZE 0x1000 | ||
103 | #define QCA955X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000) | ||
104 | #define QCA955X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000) | ||
105 | #define QCA955X_PCI_CRP_SIZE 0x1000 | ||
106 | #define QCA955X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000) | ||
107 | #define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) | ||
108 | #define QCA955X_PCI_CTRL_SIZE 0x100 | ||
109 | |||
110 | #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) | ||
111 | #define QCA955X_WMAC_SIZE 0x20000 | ||
112 | #define QCA955X_EHCI0_BASE 0x1b000000 | ||
113 | #define QCA955X_EHCI1_BASE 0x1b400000 | ||
114 | #define QCA955X_EHCI_SIZE 0x1000 | ||
115 | |||
71 | /* | 116 | /* |
72 | * DDR_CTRL block | 117 | * DDR_CTRL block |
73 | */ | 118 | */ |
@@ -199,6 +244,41 @@ | |||
199 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) | 244 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) |
200 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) | 245 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) |
201 | 246 | ||
247 | #define QCA955X_PLL_CPU_CONFIG_REG 0x00 | ||
248 | #define QCA955X_PLL_DDR_CONFIG_REG 0x04 | ||
249 | #define QCA955X_PLL_CLK_CTRL_REG 0x08 | ||
250 | |||
251 | #define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 | ||
252 | #define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f | ||
253 | #define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6 | ||
254 | #define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f | ||
255 | #define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 | ||
256 | #define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f | ||
257 | #define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 | ||
258 | #define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 | ||
259 | |||
260 | #define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 | ||
261 | #define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff | ||
262 | #define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10 | ||
263 | #define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f | ||
264 | #define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 | ||
265 | #define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f | ||
266 | #define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 | ||
267 | #define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 | ||
268 | |||
269 | #define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2) | ||
270 | #define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3) | ||
271 | #define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4) | ||
272 | #define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5 | ||
273 | #define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f | ||
274 | #define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10 | ||
275 | #define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f | ||
276 | #define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15 | ||
277 | #define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f | ||
278 | #define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) | ||
279 | #define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) | ||
280 | #define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) | ||
281 | |||
202 | /* | 282 | /* |
203 | * USB_CONFIG block | 283 | * USB_CONFIG block |
204 | */ | 284 | */ |
@@ -238,6 +318,10 @@ | |||
238 | #define AR934X_RESET_REG_BOOTSTRAP 0xb0 | 318 | #define AR934X_RESET_REG_BOOTSTRAP 0xb0 |
239 | #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac | 319 | #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac |
240 | 320 | ||
321 | #define QCA955X_RESET_REG_RESET_MODULE 0x1c | ||
322 | #define QCA955X_RESET_REG_BOOTSTRAP 0xb0 | ||
323 | #define QCA955X_RESET_REG_EXT_INT_STATUS 0xac | ||
324 | |||
241 | #define MISC_INT_ETHSW BIT(12) | 325 | #define MISC_INT_ETHSW BIT(12) |
242 | #define MISC_INT_TIMER4 BIT(10) | 326 | #define MISC_INT_TIMER4 BIT(10) |
243 | #define MISC_INT_TIMER3 BIT(9) | 327 | #define MISC_INT_TIMER3 BIT(9) |
@@ -315,6 +399,8 @@ | |||
315 | #define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) | 399 | #define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) |
316 | #define AR934X_BOOTSTRAP_DDR1 BIT(0) | 400 | #define AR934X_BOOTSTRAP_DDR1 BIT(0) |
317 | 401 | ||
402 | #define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4) | ||
403 | |||
318 | #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) | 404 | #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) |
319 | #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) | 405 | #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) |
320 | #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) | 406 | #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) |
@@ -333,6 +419,37 @@ | |||
333 | AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ | 419 | AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ |
334 | AR934X_PCIE_WMAC_INT_PCIE_RC3) | 420 | AR934X_PCIE_WMAC_INT_PCIE_RC3) |
335 | 421 | ||
422 | #define QCA955X_EXT_INT_WMAC_MISC BIT(0) | ||
423 | #define QCA955X_EXT_INT_WMAC_TX BIT(1) | ||
424 | #define QCA955X_EXT_INT_WMAC_RXLP BIT(2) | ||
425 | #define QCA955X_EXT_INT_WMAC_RXHP BIT(3) | ||
426 | #define QCA955X_EXT_INT_PCIE_RC1 BIT(4) | ||
427 | #define QCA955X_EXT_INT_PCIE_RC1_INT0 BIT(5) | ||
428 | #define QCA955X_EXT_INT_PCIE_RC1_INT1 BIT(6) | ||
429 | #define QCA955X_EXT_INT_PCIE_RC1_INT2 BIT(7) | ||
430 | #define QCA955X_EXT_INT_PCIE_RC1_INT3 BIT(8) | ||
431 | #define QCA955X_EXT_INT_PCIE_RC2 BIT(12) | ||
432 | #define QCA955X_EXT_INT_PCIE_RC2_INT0 BIT(13) | ||
433 | #define QCA955X_EXT_INT_PCIE_RC2_INT1 BIT(14) | ||
434 | #define QCA955X_EXT_INT_PCIE_RC2_INT2 BIT(15) | ||
435 | #define QCA955X_EXT_INT_PCIE_RC2_INT3 BIT(16) | ||
436 | #define QCA955X_EXT_INT_USB1 BIT(24) | ||
437 | #define QCA955X_EXT_INT_USB2 BIT(28) | ||
438 | |||
439 | #define QCA955X_EXT_INT_WMAC_ALL \ | ||
440 | (QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \ | ||
441 | QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP) | ||
442 | |||
443 | #define QCA955X_EXT_INT_PCIE_RC1_ALL \ | ||
444 | (QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \ | ||
445 | QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \ | ||
446 | QCA955X_EXT_INT_PCIE_RC1_INT3) | ||
447 | |||
448 | #define QCA955X_EXT_INT_PCIE_RC2_ALL \ | ||
449 | (QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \ | ||
450 | QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \ | ||
451 | QCA955X_EXT_INT_PCIE_RC2_INT3) | ||
452 | |||
336 | #define REV_ID_MAJOR_MASK 0xfff0 | 453 | #define REV_ID_MAJOR_MASK 0xfff0 |
337 | #define REV_ID_MAJOR_AR71XX 0x00a0 | 454 | #define REV_ID_MAJOR_AR71XX 0x00a0 |
338 | #define REV_ID_MAJOR_AR913X 0x00b0 | 455 | #define REV_ID_MAJOR_AR913X 0x00b0 |
@@ -344,6 +461,8 @@ | |||
344 | #define REV_ID_MAJOR_AR9341 0x0120 | 461 | #define REV_ID_MAJOR_AR9341 0x0120 |
345 | #define REV_ID_MAJOR_AR9342 0x1120 | 462 | #define REV_ID_MAJOR_AR9342 0x1120 |
346 | #define REV_ID_MAJOR_AR9344 0x2120 | 463 | #define REV_ID_MAJOR_AR9344 0x2120 |
464 | #define REV_ID_MAJOR_QCA9556 0x0130 | ||
465 | #define REV_ID_MAJOR_QCA9558 0x1130 | ||
347 | 466 | ||
348 | #define AR71XX_REV_ID_MINOR_MASK 0x3 | 467 | #define AR71XX_REV_ID_MINOR_MASK 0x3 |
349 | #define AR71XX_REV_ID_MINOR_AR7130 0x0 | 468 | #define AR71XX_REV_ID_MINOR_AR7130 0x0 |
@@ -364,6 +483,8 @@ | |||
364 | 483 | ||
365 | #define AR934X_REV_ID_REVISION_MASK 0xf | 484 | #define AR934X_REV_ID_REVISION_MASK 0xf |
366 | 485 | ||
486 | #define QCA955X_REV_ID_REVISION_MASK 0xf | ||
487 | |||
367 | /* | 488 | /* |
368 | * SPI block | 489 | * SPI block |
369 | */ | 490 | */ |
@@ -401,12 +522,15 @@ | |||
401 | #define AR71XX_GPIO_REG_INT_ENABLE 0x24 | 522 | #define AR71XX_GPIO_REG_INT_ENABLE 0x24 |
402 | #define AR71XX_GPIO_REG_FUNC 0x28 | 523 | #define AR71XX_GPIO_REG_FUNC 0x28 |
403 | 524 | ||
525 | #define AR934X_GPIO_REG_FUNC 0x6c | ||
526 | |||
404 | #define AR71XX_GPIO_COUNT 16 | 527 | #define AR71XX_GPIO_COUNT 16 |
405 | #define AR7240_GPIO_COUNT 18 | 528 | #define AR7240_GPIO_COUNT 18 |
406 | #define AR7241_GPIO_COUNT 20 | 529 | #define AR7241_GPIO_COUNT 20 |
407 | #define AR913X_GPIO_COUNT 22 | 530 | #define AR913X_GPIO_COUNT 22 |
408 | #define AR933X_GPIO_COUNT 30 | 531 | #define AR933X_GPIO_COUNT 30 |
409 | #define AR934X_GPIO_COUNT 23 | 532 | #define AR934X_GPIO_COUNT 23 |
533 | #define QCA955X_GPIO_COUNT 24 | ||
410 | 534 | ||
411 | /* | 535 | /* |
412 | * SRIF block | 536 | * SRIF block |
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h index 4f248c3d7b23..1557934aaca9 100644 --- a/arch/mips/include/asm/mach-ath79/ath79.h +++ b/arch/mips/include/asm/mach-ath79/ath79.h | |||
@@ -32,6 +32,8 @@ enum ath79_soc_type { | |||
32 | ATH79_SOC_AR9341, | 32 | ATH79_SOC_AR9341, |
33 | ATH79_SOC_AR9342, | 33 | ATH79_SOC_AR9342, |
34 | ATH79_SOC_AR9344, | 34 | ATH79_SOC_AR9344, |
35 | ATH79_SOC_QCA9556, | ||
36 | ATH79_SOC_QCA9558, | ||
35 | }; | 37 | }; |
36 | 38 | ||
37 | extern enum ath79_soc_type ath79_soc; | 39 | extern enum ath79_soc_type ath79_soc; |
@@ -98,6 +100,21 @@ static inline int soc_is_ar934x(void) | |||
98 | return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344(); | 100 | return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344(); |
99 | } | 101 | } |
100 | 102 | ||
103 | static inline int soc_is_qca9556(void) | ||
104 | { | ||
105 | return ath79_soc == ATH79_SOC_QCA9556; | ||
106 | } | ||
107 | |||
108 | static inline int soc_is_qca9558(void) | ||
109 | { | ||
110 | return ath79_soc == ATH79_SOC_QCA9558; | ||
111 | } | ||
112 | |||
113 | static inline int soc_is_qca955x(void) | ||
114 | { | ||
115 | return soc_is_qca9556() || soc_is_qca9558(); | ||
116 | } | ||
117 | |||
101 | extern void __iomem *ath79_ddr_base; | 118 | extern void __iomem *ath79_ddr_base; |
102 | extern void __iomem *ath79_pll_base; | 119 | extern void __iomem *ath79_pll_base; |
103 | extern void __iomem *ath79_reset_base; | 120 | extern void __iomem *ath79_reset_base; |
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h index 0968f69e2018..5c9ca76a7ebf 100644 --- a/arch/mips/include/asm/mach-ath79/irq.h +++ b/arch/mips/include/asm/mach-ath79/irq.h | |||
@@ -10,10 +10,13 @@ | |||
10 | #define __ASM_MACH_ATH79_IRQ_H | 10 | #define __ASM_MACH_ATH79_IRQ_H |
11 | 11 | ||
12 | #define MIPS_CPU_IRQ_BASE 0 | 12 | #define MIPS_CPU_IRQ_BASE 0 |
13 | #define NR_IRQS 48 | 13 | #define NR_IRQS 51 |
14 | |||
15 | #define ATH79_CPU_IRQ(_x) (MIPS_CPU_IRQ_BASE + (_x)) | ||
14 | 16 | ||
15 | #define ATH79_MISC_IRQ_BASE 8 | 17 | #define ATH79_MISC_IRQ_BASE 8 |
16 | #define ATH79_MISC_IRQ_COUNT 32 | 18 | #define ATH79_MISC_IRQ_COUNT 32 |
19 | #define ATH79_MISC_IRQ(_x) (ATH79_MISC_IRQ_BASE + (_x)) | ||
17 | 20 | ||
18 | #define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT) | 21 | #define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT) |
19 | #define ATH79_PCI_IRQ_COUNT 6 | 22 | #define ATH79_PCI_IRQ_COUNT 6 |
@@ -23,25 +26,9 @@ | |||
23 | #define ATH79_IP2_IRQ_COUNT 2 | 26 | #define ATH79_IP2_IRQ_COUNT 2 |
24 | #define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) | 27 | #define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) |
25 | 28 | ||
26 | #define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) | 29 | #define ATH79_IP3_IRQ_BASE (ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT) |
27 | #define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) | 30 | #define ATH79_IP3_IRQ_COUNT 3 |
28 | #define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) | 31 | #define ATH79_IP3_IRQ(_x) (ATH79_IP3_IRQ_BASE + (_x)) |
29 | #define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5) | ||
30 | #define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) | ||
31 | #define ATH79_CPU_IRQ_TIMER (MIPS_CPU_IRQ_BASE + 7) | ||
32 | |||
33 | #define ATH79_MISC_IRQ_TIMER (ATH79_MISC_IRQ_BASE + 0) | ||
34 | #define ATH79_MISC_IRQ_ERROR (ATH79_MISC_IRQ_BASE + 1) | ||
35 | #define ATH79_MISC_IRQ_GPIO (ATH79_MISC_IRQ_BASE + 2) | ||
36 | #define ATH79_MISC_IRQ_UART (ATH79_MISC_IRQ_BASE + 3) | ||
37 | #define ATH79_MISC_IRQ_WDOG (ATH79_MISC_IRQ_BASE + 4) | ||
38 | #define ATH79_MISC_IRQ_PERFC (ATH79_MISC_IRQ_BASE + 5) | ||
39 | #define ATH79_MISC_IRQ_OHCI (ATH79_MISC_IRQ_BASE + 6) | ||
40 | #define ATH79_MISC_IRQ_DMA (ATH79_MISC_IRQ_BASE + 7) | ||
41 | #define ATH79_MISC_IRQ_TIMER2 (ATH79_MISC_IRQ_BASE + 8) | ||
42 | #define ATH79_MISC_IRQ_TIMER3 (ATH79_MISC_IRQ_BASE + 9) | ||
43 | #define ATH79_MISC_IRQ_TIMER4 (ATH79_MISC_IRQ_BASE + 10) | ||
44 | #define ATH79_MISC_IRQ_ETHSW (ATH79_MISC_IRQ_BASE + 12) | ||
45 | 32 | ||
46 | #include_next <irq.h> | 33 | #include_next <irq.h> |
47 | 34 | ||
diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h deleted file mode 100644 index 7868f7fa028f..000000000000 --- a/arch/mips/include/asm/mach-ath79/pci.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X PCI support | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_MACH_ATH79_PCI_H | ||
14 | #define __ASM_MACH_ATH79_PCI_H | ||
15 | |||
16 | #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX) | ||
17 | int ar71xx_pcibios_init(void); | ||
18 | #else | ||
19 | static inline int ar71xx_pcibios_init(void) { return 0; } | ||
20 | #endif | ||
21 | |||
22 | #if defined(CONFIG_PCI_AR724X) | ||
23 | int ar724x_pcibios_init(int irq); | ||
24 | #else | ||
25 | static inline int ar724x_pcibios_init(int irq) { return 0; } | ||
26 | #endif | ||
27 | |||
28 | #endif /* __ASM_MACH_ATH79_PCI_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h index 69ef3efe06e7..b8e7be8f34dd 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | |||
@@ -8,8 +8,8 @@ | |||
8 | * option) any later version. | 8 | * option) any later version. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef __NVRAM_H | 11 | #ifndef __BCM47XX_NVRAM_H |
12 | #define __NVRAM_H | 12 | #define __BCM47XX_NVRAM_H |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
@@ -32,12 +32,9 @@ struct nvram_header { | |||
32 | #define NVRAM_MAX_VALUE_LEN 255 | 32 | #define NVRAM_MAX_VALUE_LEN 255 |
33 | #define NVRAM_MAX_PARAM_LEN 64 | 33 | #define NVRAM_MAX_PARAM_LEN 64 |
34 | 34 | ||
35 | #define NVRAM_ERR_INV_PARAM -8 | 35 | extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); |
36 | #define NVRAM_ERR_ENVNOTFOUND -9 | ||
37 | 36 | ||
38 | extern int nvram_getenv(char *name, char *val, size_t val_len); | 37 | static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) |
39 | |||
40 | static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||
41 | { | 38 | { |
42 | if (strchr(buf, ':')) | 39 | if (strchr(buf, ':')) |
43 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | 40 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], |
@@ -51,4 +48,4 @@ static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6]) | |||
51 | printk(KERN_WARNING "Can not parse mac address: %s\n", buf); | 48 | printk(KERN_WARNING "Can not parse mac address: %s\n", buf); |
52 | } | 49 | } |
53 | 50 | ||
54 | #endif | 51 | #endif /* __BCM47XX_NVRAM_H */ |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index 5e8a6e965756..f196cceb7322 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h | |||
@@ -34,6 +34,7 @@ extern spinlock_t ebu_lock; | |||
34 | extern void ltq_disable_irq(struct irq_data *data); | 34 | extern void ltq_disable_irq(struct irq_data *data); |
35 | extern void ltq_mask_and_ack_irq(struct irq_data *data); | 35 | extern void ltq_mask_and_ack_irq(struct irq_data *data); |
36 | extern void ltq_enable_irq(struct irq_data *data); | 36 | extern void ltq_enable_irq(struct irq_data *data); |
37 | extern int ltq_eiu_get_irq(int exin); | ||
37 | 38 | ||
38 | /* clock handling */ | 39 | /* clock handling */ |
39 | extern int clk_activate(struct clk *clk); | 40 | extern int clk_activate(struct clk *clk); |
@@ -41,6 +42,7 @@ extern void clk_deactivate(struct clk *clk); | |||
41 | extern struct clk *clk_get_cpu(void); | 42 | extern struct clk *clk_get_cpu(void); |
42 | extern struct clk *clk_get_fpi(void); | 43 | extern struct clk *clk_get_fpi(void); |
43 | extern struct clk *clk_get_io(void); | 44 | extern struct clk *clk_get_io(void); |
45 | extern struct clk *clk_get_ppe(void); | ||
44 | 46 | ||
45 | /* find out what bootsource we have */ | 47 | /* find out what bootsource we have */ |
46 | extern unsigned char ltq_boot_select(void); | 48 | extern unsigned char ltq_boot_select(void); |
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h new file mode 100644 index 000000000000..5a508f9f9432 --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Ralink SoC register definitions | ||
3 | * | ||
4 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
5 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef _RALINK_REGS_H_ | ||
14 | #define _RALINK_REGS_H_ | ||
15 | |||
16 | extern __iomem void *rt_sysc_membase; | ||
17 | extern __iomem void *rt_memc_membase; | ||
18 | |||
19 | static inline void rt_sysc_w32(u32 val, unsigned reg) | ||
20 | { | ||
21 | __raw_writel(val, rt_sysc_membase + reg); | ||
22 | } | ||
23 | |||
24 | static inline u32 rt_sysc_r32(unsigned reg) | ||
25 | { | ||
26 | return __raw_readl(rt_sysc_membase + reg); | ||
27 | } | ||
28 | |||
29 | static inline void rt_memc_w32(u32 val, unsigned reg) | ||
30 | { | ||
31 | __raw_writel(val, rt_memc_membase + reg); | ||
32 | } | ||
33 | |||
34 | static inline u32 rt_memc_r32(unsigned reg) | ||
35 | { | ||
36 | return __raw_readl(rt_memc_membase + reg); | ||
37 | } | ||
38 | |||
39 | #endif /* _RALINK_REGS_H_ */ | ||
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h new file mode 100644 index 000000000000..7d344f2d7d0a --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/rt305x.h | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Parts of this file are based on Ralink's 2.6.21 BSP | ||
7 | * | ||
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
11 | */ | ||
12 | |||
13 | #ifndef _RT305X_REGS_H_ | ||
14 | #define _RT305X_REGS_H_ | ||
15 | |||
16 | enum rt305x_soc_type { | ||
17 | RT305X_SOC_UNKNOWN = 0, | ||
18 | RT305X_SOC_RT3050, | ||
19 | RT305X_SOC_RT3052, | ||
20 | RT305X_SOC_RT3350, | ||
21 | RT305X_SOC_RT3352, | ||
22 | RT305X_SOC_RT5350, | ||
23 | }; | ||
24 | |||
25 | extern enum rt305x_soc_type rt305x_soc; | ||
26 | |||
27 | static inline int soc_is_rt3050(void) | ||
28 | { | ||
29 | return rt305x_soc == RT305X_SOC_RT3050; | ||
30 | } | ||
31 | |||
32 | static inline int soc_is_rt3052(void) | ||
33 | { | ||
34 | return rt305x_soc == RT305X_SOC_RT3052; | ||
35 | } | ||
36 | |||
37 | static inline int soc_is_rt305x(void) | ||
38 | { | ||
39 | return soc_is_rt3050() || soc_is_rt3052(); | ||
40 | } | ||
41 | |||
42 | static inline int soc_is_rt3350(void) | ||
43 | { | ||
44 | return rt305x_soc == RT305X_SOC_RT3350; | ||
45 | } | ||
46 | |||
47 | static inline int soc_is_rt3352(void) | ||
48 | { | ||
49 | return rt305x_soc == RT305X_SOC_RT3352; | ||
50 | } | ||
51 | |||
52 | static inline int soc_is_rt5350(void) | ||
53 | { | ||
54 | return rt305x_soc == RT305X_SOC_RT5350; | ||
55 | } | ||
56 | |||
57 | #define RT305X_SYSC_BASE 0x10000000 | ||
58 | |||
59 | #define SYSC_REG_CHIP_NAME0 0x00 | ||
60 | #define SYSC_REG_CHIP_NAME1 0x04 | ||
61 | #define SYSC_REG_CHIP_ID 0x0c | ||
62 | #define SYSC_REG_SYSTEM_CONFIG 0x10 | ||
63 | |||
64 | #define RT3052_CHIP_NAME0 0x30335452 | ||
65 | #define RT3052_CHIP_NAME1 0x20203235 | ||
66 | |||
67 | #define RT3350_CHIP_NAME0 0x33335452 | ||
68 | #define RT3350_CHIP_NAME1 0x20203035 | ||
69 | |||
70 | #define RT3352_CHIP_NAME0 0x33335452 | ||
71 | #define RT3352_CHIP_NAME1 0x20203235 | ||
72 | |||
73 | #define RT5350_CHIP_NAME0 0x33355452 | ||
74 | #define RT5350_CHIP_NAME1 0x20203035 | ||
75 | |||
76 | #define CHIP_ID_ID_MASK 0xff | ||
77 | #define CHIP_ID_ID_SHIFT 8 | ||
78 | #define CHIP_ID_REV_MASK 0xff | ||
79 | |||
80 | #define RT305X_SYSCFG_CPUCLK_SHIFT 18 | ||
81 | #define RT305X_SYSCFG_CPUCLK_MASK 0x1 | ||
82 | #define RT305X_SYSCFG_CPUCLK_LOW 0x0 | ||
83 | #define RT305X_SYSCFG_CPUCLK_HIGH 0x1 | ||
84 | |||
85 | #define RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT 2 | ||
86 | #define RT305X_SYSCFG_CPUCLK_MASK 0x1 | ||
87 | #define RT305X_SYSCFG_SRAM_CS0_MODE_WDT 0x1 | ||
88 | |||
89 | #define RT3352_SYSCFG0_CPUCLK_SHIFT 8 | ||
90 | #define RT3352_SYSCFG0_CPUCLK_MASK 0x1 | ||
91 | #define RT3352_SYSCFG0_CPUCLK_LOW 0x0 | ||
92 | #define RT3352_SYSCFG0_CPUCLK_HIGH 0x1 | ||
93 | |||
94 | #define RT5350_SYSCFG0_CPUCLK_SHIFT 8 | ||
95 | #define RT5350_SYSCFG0_CPUCLK_MASK 0x3 | ||
96 | #define RT5350_SYSCFG0_CPUCLK_360 0x0 | ||
97 | #define RT5350_SYSCFG0_CPUCLK_320 0x2 | ||
98 | #define RT5350_SYSCFG0_CPUCLK_300 0x3 | ||
99 | |||
100 | /* multi function gpio pins */ | ||
101 | #define RT305X_GPIO_I2C_SD 1 | ||
102 | #define RT305X_GPIO_I2C_SCLK 2 | ||
103 | #define RT305X_GPIO_SPI_EN 3 | ||
104 | #define RT305X_GPIO_SPI_CLK 4 | ||
105 | /* GPIO 7-14 is shared between UART0, PCM and I2S interfaces */ | ||
106 | #define RT305X_GPIO_7 7 | ||
107 | #define RT305X_GPIO_10 10 | ||
108 | #define RT305X_GPIO_14 14 | ||
109 | #define RT305X_GPIO_UART1_TXD 15 | ||
110 | #define RT305X_GPIO_UART1_RXD 16 | ||
111 | #define RT305X_GPIO_JTAG_TDO 17 | ||
112 | #define RT305X_GPIO_JTAG_TDI 18 | ||
113 | #define RT305X_GPIO_MDIO_MDC 22 | ||
114 | #define RT305X_GPIO_MDIO_MDIO 23 | ||
115 | #define RT305X_GPIO_SDRAM_MD16 24 | ||
116 | #define RT305X_GPIO_SDRAM_MD31 39 | ||
117 | #define RT305X_GPIO_GE0_TXD0 40 | ||
118 | #define RT305X_GPIO_GE0_RXCLK 51 | ||
119 | |||
120 | #define RT305X_GPIO_MODE_I2C BIT(0) | ||
121 | #define RT305X_GPIO_MODE_SPI BIT(1) | ||
122 | #define RT305X_GPIO_MODE_UART0_SHIFT 2 | ||
123 | #define RT305X_GPIO_MODE_UART0_MASK 0x7 | ||
124 | #define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) | ||
125 | #define RT305X_GPIO_MODE_UARTF 0x0 | ||
126 | #define RT305X_GPIO_MODE_PCM_UARTF 0x1 | ||
127 | #define RT305X_GPIO_MODE_PCM_I2S 0x2 | ||
128 | #define RT305X_GPIO_MODE_I2S_UARTF 0x3 | ||
129 | #define RT305X_GPIO_MODE_PCM_GPIO 0x4 | ||
130 | #define RT305X_GPIO_MODE_GPIO_UARTF 0x5 | ||
131 | #define RT305X_GPIO_MODE_GPIO_I2S 0x6 | ||
132 | #define RT305X_GPIO_MODE_GPIO 0x7 | ||
133 | #define RT305X_GPIO_MODE_UART1 BIT(5) | ||
134 | #define RT305X_GPIO_MODE_JTAG BIT(6) | ||
135 | #define RT305X_GPIO_MODE_MDIO BIT(7) | ||
136 | #define RT305X_GPIO_MODE_SDRAM BIT(8) | ||
137 | #define RT305X_GPIO_MODE_RGMII BIT(9) | ||
138 | |||
139 | #endif | ||
diff --git a/arch/mips/include/asm/mach-ralink/war.h b/arch/mips/include/asm/mach-ralink/war.h new file mode 100644 index 000000000000..a7b712cf2d28 --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/war.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | ||
7 | */ | ||
8 | #ifndef __ASM_MACH_RALINK_WAR_H | ||
9 | #define __ASM_MACH_RALINK_WAR_H | ||
10 | |||
11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
13 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
14 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
15 | #define BCM1250_M3_WAR 0 | ||
16 | #define SIBYTE_1956_WAR 0 | ||
17 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
18 | #define MIPS_CACHE_SYNC_WAR 0 | ||
19 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
20 | #define RM9000_CDEX_SMP_WAR 0 | ||
21 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
22 | #define R10000_LLSC_WAR 0 | ||
23 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
24 | |||
25 | #endif /* __ASM_MACH_RALINK_WAR_H */ | ||
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h index 1465b1193b12..44a09a64160a 100644 --- a/arch/mips/include/asm/mips-boards/generic.h +++ b/arch/mips/include/asm/mips-boards/generic.h | |||
@@ -1,21 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | 4 | * for more details. |
13 | * | 5 | * |
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Defines of the MIPS boards specific address-MAP, registers, etc. | 6 | * Defines of the MIPS boards specific address-MAP, registers, etc. |
7 | * | ||
8 | * Copyright (C) 2000,2012 MIPS Technologies, Inc. | ||
9 | * All rights reserved. | ||
10 | * Authors: Carsten Langgaard <carstenl@mips.com> | ||
11 | * Steven J. Hill <sjhill@mips.com> | ||
19 | */ | 12 | */ |
20 | #ifndef __ASM_MIPS_BOARDS_GENERIC_H | 13 | #ifndef __ASM_MIPS_BOARDS_GENERIC_H |
21 | #define __ASM_MIPS_BOARDS_GENERIC_H | 14 | #define __ASM_MIPS_BOARDS_GENERIC_H |
@@ -30,13 +23,6 @@ | |||
30 | #define ASCII_DISPLAY_WORD_BASE 0x1f000410 | 23 | #define ASCII_DISPLAY_WORD_BASE 0x1f000410 |
31 | #define ASCII_DISPLAY_POS_BASE 0x1f000418 | 24 | #define ASCII_DISPLAY_POS_BASE 0x1f000418 |
32 | 25 | ||
33 | |||
34 | /* | ||
35 | * Yamon Prom print address. | ||
36 | */ | ||
37 | #define YAMON_PROM_PRINT_ADDR 0x1fc00504 | ||
38 | |||
39 | |||
40 | /* | 26 | /* |
41 | * Reset register. | 27 | * Reset register. |
42 | */ | 28 | */ |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 2145162674b9..12b70c25906a 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -595,6 +595,8 @@ | |||
595 | #define MIPS_CONF3_DSP2P (_ULCAST_(1) << 11) | 595 | #define MIPS_CONF3_DSP2P (_ULCAST_(1) << 11) |
596 | #define MIPS_CONF3_RXI (_ULCAST_(1) << 12) | 596 | #define MIPS_CONF3_RXI (_ULCAST_(1) << 12) |
597 | #define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) | 597 | #define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) |
598 | #define MIPS_CONF3_ISA (_ULCAST_(3) << 14) | ||
599 | #define MIPS_CONF3_VZ (_ULCAST_(1) << 23) | ||
598 | 600 | ||
599 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) | 601 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) |
600 | #define MIPS_CONF4_MMUEXTDEF (_ULCAST_(3) << 14) | 602 | #define MIPS_CONF4_MMUEXTDEF (_ULCAST_(3) << 14) |
@@ -1158,36 +1160,26 @@ do { \ | |||
1158 | __res; \ | 1160 | __res; \ |
1159 | }) | 1161 | }) |
1160 | 1162 | ||
1163 | #ifdef HAVE_AS_DSP | ||
1161 | #define rddsp(mask) \ | 1164 | #define rddsp(mask) \ |
1162 | ({ \ | 1165 | ({ \ |
1163 | unsigned int __res; \ | 1166 | unsigned int __dspctl; \ |
1164 | \ | 1167 | \ |
1165 | __asm__ __volatile__( \ | 1168 | __asm__ __volatile__( \ |
1166 | " .set push \n" \ | 1169 | " rddsp %0, %x1 \n" \ |
1167 | " .set noat \n" \ | 1170 | : "=r" (__dspctl) \ |
1168 | " # rddsp $1, %x1 \n" \ | ||
1169 | " .word 0x7c000cb8 | (%x1 << 16) \n" \ | ||
1170 | " move %0, $1 \n" \ | ||
1171 | " .set pop \n" \ | ||
1172 | : "=r" (__res) \ | ||
1173 | : "i" (mask)); \ | 1171 | : "i" (mask)); \ |
1174 | __res; \ | 1172 | __dspctl; \ |
1175 | }) | 1173 | }) |
1176 | 1174 | ||
1177 | #define wrdsp(val, mask) \ | 1175 | #define wrdsp(val, mask) \ |
1178 | do { \ | 1176 | do { \ |
1179 | __asm__ __volatile__( \ | 1177 | __asm__ __volatile__( \ |
1180 | " .set push \n" \ | 1178 | " wrdsp %0, %x1 \n" \ |
1181 | " .set noat \n" \ | ||
1182 | " move $1, %0 \n" \ | ||
1183 | " # wrdsp $1, %x1 \n" \ | ||
1184 | " .word 0x7c2004f8 | (%x1 << 11) \n" \ | ||
1185 | " .set pop \n" \ | ||
1186 | : \ | 1179 | : \ |
1187 | : "r" (val), "i" (mask)); \ | 1180 | : "r" (val), "i" (mask)); \ |
1188 | } while (0) | 1181 | } while (0) |
1189 | 1182 | ||
1190 | #if 0 /* Need DSP ASE capable assembler ... */ | ||
1191 | #define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) | 1183 | #define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) |
1192 | #define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) | 1184 | #define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) |
1193 | #define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) | 1185 | #define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) |
@@ -1210,230 +1202,177 @@ do { \ | |||
1210 | 1202 | ||
1211 | #else | 1203 | #else |
1212 | 1204 | ||
1213 | #define mfhi0() \ | 1205 | #ifdef CONFIG_CPU_MICROMIPS |
1214 | ({ \ | 1206 | #define rddsp(mask) \ |
1215 | unsigned long __treg; \ | ||
1216 | \ | ||
1217 | __asm__ __volatile__( \ | ||
1218 | " .set push \n" \ | ||
1219 | " .set noat \n" \ | ||
1220 | " # mfhi %0, $ac0 \n" \ | ||
1221 | " .word 0x00000810 \n" \ | ||
1222 | " move %0, $1 \n" \ | ||
1223 | " .set pop \n" \ | ||
1224 | : "=r" (__treg)); \ | ||
1225 | __treg; \ | ||
1226 | }) | ||
1227 | |||
1228 | #define mfhi1() \ | ||
1229 | ({ \ | ||
1230 | unsigned long __treg; \ | ||
1231 | \ | ||
1232 | __asm__ __volatile__( \ | ||
1233 | " .set push \n" \ | ||
1234 | " .set noat \n" \ | ||
1235 | " # mfhi %0, $ac1 \n" \ | ||
1236 | " .word 0x00200810 \n" \ | ||
1237 | " move %0, $1 \n" \ | ||
1238 | " .set pop \n" \ | ||
1239 | : "=r" (__treg)); \ | ||
1240 | __treg; \ | ||
1241 | }) | ||
1242 | |||
1243 | #define mfhi2() \ | ||
1244 | ({ \ | ||
1245 | unsigned long __treg; \ | ||
1246 | \ | ||
1247 | __asm__ __volatile__( \ | ||
1248 | " .set push \n" \ | ||
1249 | " .set noat \n" \ | ||
1250 | " # mfhi %0, $ac2 \n" \ | ||
1251 | " .word 0x00400810 \n" \ | ||
1252 | " move %0, $1 \n" \ | ||
1253 | " .set pop \n" \ | ||
1254 | : "=r" (__treg)); \ | ||
1255 | __treg; \ | ||
1256 | }) | ||
1257 | |||
1258 | #define mfhi3() \ | ||
1259 | ({ \ | ||
1260 | unsigned long __treg; \ | ||
1261 | \ | ||
1262 | __asm__ __volatile__( \ | ||
1263 | " .set push \n" \ | ||
1264 | " .set noat \n" \ | ||
1265 | " # mfhi %0, $ac3 \n" \ | ||
1266 | " .word 0x00600810 \n" \ | ||
1267 | " move %0, $1 \n" \ | ||
1268 | " .set pop \n" \ | ||
1269 | : "=r" (__treg)); \ | ||
1270 | __treg; \ | ||
1271 | }) | ||
1272 | |||
1273 | #define mflo0() \ | ||
1274 | ({ \ | ||
1275 | unsigned long __treg; \ | ||
1276 | \ | ||
1277 | __asm__ __volatile__( \ | ||
1278 | " .set push \n" \ | ||
1279 | " .set noat \n" \ | ||
1280 | " # mflo %0, $ac0 \n" \ | ||
1281 | " .word 0x00000812 \n" \ | ||
1282 | " move %0, $1 \n" \ | ||
1283 | " .set pop \n" \ | ||
1284 | : "=r" (__treg)); \ | ||
1285 | __treg; \ | ||
1286 | }) | ||
1287 | |||
1288 | #define mflo1() \ | ||
1289 | ({ \ | ||
1290 | unsigned long __treg; \ | ||
1291 | \ | ||
1292 | __asm__ __volatile__( \ | ||
1293 | " .set push \n" \ | ||
1294 | " .set noat \n" \ | ||
1295 | " # mflo %0, $ac1 \n" \ | ||
1296 | " .word 0x00200812 \n" \ | ||
1297 | " move %0, $1 \n" \ | ||
1298 | " .set pop \n" \ | ||
1299 | : "=r" (__treg)); \ | ||
1300 | __treg; \ | ||
1301 | }) | ||
1302 | |||
1303 | #define mflo2() \ | ||
1304 | ({ \ | ||
1305 | unsigned long __treg; \ | ||
1306 | \ | ||
1307 | __asm__ __volatile__( \ | ||
1308 | " .set push \n" \ | ||
1309 | " .set noat \n" \ | ||
1310 | " # mflo %0, $ac2 \n" \ | ||
1311 | " .word 0x00400812 \n" \ | ||
1312 | " move %0, $1 \n" \ | ||
1313 | " .set pop \n" \ | ||
1314 | : "=r" (__treg)); \ | ||
1315 | __treg; \ | ||
1316 | }) | ||
1317 | |||
1318 | #define mflo3() \ | ||
1319 | ({ \ | 1207 | ({ \ |
1320 | unsigned long __treg; \ | 1208 | unsigned int __res; \ |
1321 | \ | 1209 | \ |
1322 | __asm__ __volatile__( \ | 1210 | __asm__ __volatile__( \ |
1323 | " .set push \n" \ | ||
1324 | " .set noat \n" \ | ||
1325 | " # mflo %0, $ac3 \n" \ | ||
1326 | " .word 0x00600812 \n" \ | ||
1327 | " move %0, $1 \n" \ | ||
1328 | " .set pop \n" \ | ||
1329 | : "=r" (__treg)); \ | ||
1330 | __treg; \ | ||
1331 | }) | ||
1332 | |||
1333 | #define mthi0(x) \ | ||
1334 | do { \ | ||
1335 | __asm__ __volatile__( \ | ||
1336 | " .set push \n" \ | 1211 | " .set push \n" \ |
1337 | " .set noat \n" \ | 1212 | " .set noat \n" \ |
1338 | " move $1, %0 \n" \ | 1213 | " # rddsp $1, %x1 \n" \ |
1339 | " # mthi $1, $ac0 \n" \ | 1214 | " .hword ((0x0020067c | (%x1 << 14)) >> 16) \n" \ |
1340 | " .word 0x00200011 \n" \ | 1215 | " .hword ((0x0020067c | (%x1 << 14)) & 0xffff) \n" \ |
1216 | " move %0, $1 \n" \ | ||
1341 | " .set pop \n" \ | 1217 | " .set pop \n" \ |
1342 | : \ | 1218 | : "=r" (__res) \ |
1343 | : "r" (x)); \ | 1219 | : "i" (mask)); \ |
1344 | } while (0) | 1220 | __res; \ |
1221 | }) | ||
1345 | 1222 | ||
1346 | #define mthi1(x) \ | 1223 | #define wrdsp(val, mask) \ |
1347 | do { \ | 1224 | do { \ |
1348 | __asm__ __volatile__( \ | 1225 | __asm__ __volatile__( \ |
1349 | " .set push \n" \ | 1226 | " .set push \n" \ |
1350 | " .set noat \n" \ | 1227 | " .set noat \n" \ |
1351 | " move $1, %0 \n" \ | 1228 | " move $1, %0 \n" \ |
1352 | " # mthi $1, $ac1 \n" \ | 1229 | " # wrdsp $1, %x1 \n" \ |
1353 | " .word 0x00200811 \n" \ | 1230 | " .hword ((0x0020167c | (%x1 << 14)) >> 16) \n" \ |
1231 | " .hword ((0x0020167c | (%x1 << 14)) & 0xffff) \n" \ | ||
1354 | " .set pop \n" \ | 1232 | " .set pop \n" \ |
1355 | : \ | 1233 | : \ |
1356 | : "r" (x)); \ | 1234 | : "r" (val), "i" (mask)); \ |
1357 | } while (0) | 1235 | } while (0) |
1358 | 1236 | ||
1359 | #define mthi2(x) \ | 1237 | #define _umips_dsp_mfxxx(ins) \ |
1360 | do { \ | 1238 | ({ \ |
1239 | unsigned long __treg; \ | ||
1240 | \ | ||
1361 | __asm__ __volatile__( \ | 1241 | __asm__ __volatile__( \ |
1362 | " .set push \n" \ | 1242 | " .set push \n" \ |
1363 | " .set noat \n" \ | 1243 | " .set noat \n" \ |
1364 | " move $1, %0 \n" \ | 1244 | " .hword 0x0001 \n" \ |
1365 | " # mthi $1, $ac2 \n" \ | 1245 | " .hword %x1 \n" \ |
1366 | " .word 0x00201011 \n" \ | 1246 | " move %0, $1 \n" \ |
1367 | " .set pop \n" \ | 1247 | " .set pop \n" \ |
1368 | : \ | 1248 | : "=r" (__treg) \ |
1369 | : "r" (x)); \ | 1249 | : "i" (ins)); \ |
1370 | } while (0) | 1250 | __treg; \ |
1251 | }) | ||
1371 | 1252 | ||
1372 | #define mthi3(x) \ | 1253 | #define _umips_dsp_mtxxx(val, ins) \ |
1373 | do { \ | 1254 | do { \ |
1374 | __asm__ __volatile__( \ | 1255 | __asm__ __volatile__( \ |
1375 | " .set push \n" \ | 1256 | " .set push \n" \ |
1376 | " .set noat \n" \ | 1257 | " .set noat \n" \ |
1377 | " move $1, %0 \n" \ | 1258 | " move $1, %0 \n" \ |
1378 | " # mthi $1, $ac3 \n" \ | 1259 | " .hword 0x0001 \n" \ |
1379 | " .word 0x00201811 \n" \ | 1260 | " .hword %x1 \n" \ |
1380 | " .set pop \n" \ | 1261 | " .set pop \n" \ |
1381 | : \ | 1262 | : \ |
1382 | : "r" (x)); \ | 1263 | : "r" (val), "i" (ins)); \ |
1383 | } while (0) | 1264 | } while (0) |
1384 | 1265 | ||
1385 | #define mtlo0(x) \ | 1266 | #define _umips_dsp_mflo(reg) _umips_dsp_mfxxx((reg << 14) | 0x107c) |
1386 | do { \ | 1267 | #define _umips_dsp_mfhi(reg) _umips_dsp_mfxxx((reg << 14) | 0x007c) |
1268 | |||
1269 | #define _umips_dsp_mtlo(val, reg) _umips_dsp_mtxxx(val, ((reg << 14) | 0x307c)) | ||
1270 | #define _umips_dsp_mthi(val, reg) _umips_dsp_mtxxx(val, ((reg << 14) | 0x207c)) | ||
1271 | |||
1272 | #define mflo0() _umips_dsp_mflo(0) | ||
1273 | #define mflo1() _umips_dsp_mflo(1) | ||
1274 | #define mflo2() _umips_dsp_mflo(2) | ||
1275 | #define mflo3() _umips_dsp_mflo(3) | ||
1276 | |||
1277 | #define mfhi0() _umips_dsp_mfhi(0) | ||
1278 | #define mfhi1() _umips_dsp_mfhi(1) | ||
1279 | #define mfhi2() _umips_dsp_mfhi(2) | ||
1280 | #define mfhi3() _umips_dsp_mfhi(3) | ||
1281 | |||
1282 | #define mtlo0(x) _umips_dsp_mtlo(x, 0) | ||
1283 | #define mtlo1(x) _umips_dsp_mtlo(x, 1) | ||
1284 | #define mtlo2(x) _umips_dsp_mtlo(x, 2) | ||
1285 | #define mtlo3(x) _umips_dsp_mtlo(x, 3) | ||
1286 | |||
1287 | #define mthi0(x) _umips_dsp_mthi(x, 0) | ||
1288 | #define mthi1(x) _umips_dsp_mthi(x, 1) | ||
1289 | #define mthi2(x) _umips_dsp_mthi(x, 2) | ||
1290 | #define mthi3(x) _umips_dsp_mthi(x, 3) | ||
1291 | |||
1292 | #else /* !CONFIG_CPU_MICROMIPS */ | ||
1293 | #define rddsp(mask) \ | ||
1294 | ({ \ | ||
1295 | unsigned int __res; \ | ||
1296 | \ | ||
1387 | __asm__ __volatile__( \ | 1297 | __asm__ __volatile__( \ |
1388 | " .set push \n" \ | 1298 | " .set push \n" \ |
1389 | " .set noat \n" \ | 1299 | " .set noat \n" \ |
1390 | " move $1, %0 \n" \ | 1300 | " # rddsp $1, %x1 \n" \ |
1391 | " # mtlo $1, $ac0 \n" \ | 1301 | " .word 0x7c000cb8 | (%x1 << 16) \n" \ |
1392 | " .word 0x00200013 \n" \ | 1302 | " move %0, $1 \n" \ |
1393 | " .set pop \n" \ | 1303 | " .set pop \n" \ |
1394 | : \ | 1304 | : "=r" (__res) \ |
1395 | : "r" (x)); \ | 1305 | : "i" (mask)); \ |
1396 | } while (0) | 1306 | __res; \ |
1307 | }) | ||
1397 | 1308 | ||
1398 | #define mtlo1(x) \ | 1309 | #define wrdsp(val, mask) \ |
1399 | do { \ | 1310 | do { \ |
1400 | __asm__ __volatile__( \ | 1311 | __asm__ __volatile__( \ |
1401 | " .set push \n" \ | 1312 | " .set push \n" \ |
1402 | " .set noat \n" \ | 1313 | " .set noat \n" \ |
1403 | " move $1, %0 \n" \ | 1314 | " move $1, %0 \n" \ |
1404 | " # mtlo $1, $ac1 \n" \ | 1315 | " # wrdsp $1, %x1 \n" \ |
1405 | " .word 0x00200813 \n" \ | 1316 | " .word 0x7c2004f8 | (%x1 << 11) \n" \ |
1406 | " .set pop \n" \ | 1317 | " .set pop \n" \ |
1407 | : \ | 1318 | : \ |
1408 | : "r" (x)); \ | 1319 | : "r" (val), "i" (mask)); \ |
1409 | } while (0) | 1320 | } while (0) |
1410 | 1321 | ||
1411 | #define mtlo2(x) \ | 1322 | #define _dsp_mfxxx(ins) \ |
1412 | do { \ | 1323 | ({ \ |
1324 | unsigned long __treg; \ | ||
1325 | \ | ||
1413 | __asm__ __volatile__( \ | 1326 | __asm__ __volatile__( \ |
1414 | " .set push \n" \ | 1327 | " .set push \n" \ |
1415 | " .set noat \n" \ | 1328 | " .set noat \n" \ |
1416 | " move $1, %0 \n" \ | 1329 | " .word (0x00000810 | %1) \n" \ |
1417 | " # mtlo $1, $ac2 \n" \ | 1330 | " move %0, $1 \n" \ |
1418 | " .word 0x00201013 \n" \ | ||
1419 | " .set pop \n" \ | 1331 | " .set pop \n" \ |
1420 | : \ | 1332 | : "=r" (__treg) \ |
1421 | : "r" (x)); \ | 1333 | : "i" (ins)); \ |
1422 | } while (0) | 1334 | __treg; \ |
1335 | }) | ||
1423 | 1336 | ||
1424 | #define mtlo3(x) \ | 1337 | #define _dsp_mtxxx(val, ins) \ |
1425 | do { \ | 1338 | do { \ |
1426 | __asm__ __volatile__( \ | 1339 | __asm__ __volatile__( \ |
1427 | " .set push \n" \ | 1340 | " .set push \n" \ |
1428 | " .set noat \n" \ | 1341 | " .set noat \n" \ |
1429 | " move $1, %0 \n" \ | 1342 | " move $1, %0 \n" \ |
1430 | " # mtlo $1, $ac3 \n" \ | 1343 | " .word (0x00200011 | %1) \n" \ |
1431 | " .word 0x00201813 \n" \ | ||
1432 | " .set pop \n" \ | 1344 | " .set pop \n" \ |
1433 | : \ | 1345 | : \ |
1434 | : "r" (x)); \ | 1346 | : "r" (val), "i" (ins)); \ |
1435 | } while (0) | 1347 | } while (0) |
1436 | 1348 | ||
1349 | #define _dsp_mflo(reg) _dsp_mfxxx((reg << 21) | 0x0002) | ||
1350 | #define _dsp_mfhi(reg) _dsp_mfxxx((reg << 21) | 0x0000) | ||
1351 | |||
1352 | #define _dsp_mtlo(val, reg) _dsp_mtxxx(val, ((reg << 11) | 0x0002)) | ||
1353 | #define _dsp_mthi(val, reg) _dsp_mtxxx(val, ((reg << 11) | 0x0000)) | ||
1354 | |||
1355 | #define mflo0() _dsp_mflo(0) | ||
1356 | #define mflo1() _dsp_mflo(1) | ||
1357 | #define mflo2() _dsp_mflo(2) | ||
1358 | #define mflo3() _dsp_mflo(3) | ||
1359 | |||
1360 | #define mfhi0() _dsp_mfhi(0) | ||
1361 | #define mfhi1() _dsp_mfhi(1) | ||
1362 | #define mfhi2() _dsp_mfhi(2) | ||
1363 | #define mfhi3() _dsp_mfhi(3) | ||
1364 | |||
1365 | #define mtlo0(x) _dsp_mtlo(x, 0) | ||
1366 | #define mtlo1(x) _dsp_mtlo(x, 1) | ||
1367 | #define mtlo2(x) _dsp_mtlo(x, 2) | ||
1368 | #define mtlo3(x) _dsp_mtlo(x, 3) | ||
1369 | |||
1370 | #define mthi0(x) _dsp_mthi(x, 0) | ||
1371 | #define mthi1(x) _dsp_mthi(x, 1) | ||
1372 | #define mthi2(x) _dsp_mthi(x, 2) | ||
1373 | #define mthi3(x) _dsp_mthi(x, 3) | ||
1374 | |||
1375 | #endif /* CONFIG_CPU_MICROMIPS */ | ||
1437 | #endif | 1376 | #endif |
1438 | 1377 | ||
1439 | /* | 1378 | /* |
diff --git a/arch/mips/include/asm/netlogic/mips-extns.h b/arch/mips/include/asm/netlogic/mips-extns.h index 8ffae43107e6..8ad2e0f81719 100644 --- a/arch/mips/include/asm/netlogic/mips-extns.h +++ b/arch/mips/include/asm/netlogic/mips-extns.h | |||
@@ -68,6 +68,85 @@ do { \ | |||
68 | __write_64bit_c0_register($9, 7, (val)); \ | 68 | __write_64bit_c0_register($9, 7, (val)); \ |
69 | } while (0) | 69 | } while (0) |
70 | 70 | ||
71 | /* | ||
72 | * Handling the 64 bit EIMR and EIRR registers in 32-bit mode with | ||
73 | * standard functions will be very inefficient. This provides | ||
74 | * optimized functions for the normal operations on the registers. | ||
75 | * | ||
76 | * Call with interrupts disabled. | ||
77 | */ | ||
78 | static inline void ack_c0_eirr(int irq) | ||
79 | { | ||
80 | __asm__ __volatile__( | ||
81 | ".set push\n\t" | ||
82 | ".set mips64\n\t" | ||
83 | ".set noat\n\t" | ||
84 | "li $1, 1\n\t" | ||
85 | "dsllv $1, $1, %0\n\t" | ||
86 | "dmtc0 $1, $9, 6\n\t" | ||
87 | ".set pop" | ||
88 | : : "r" (irq)); | ||
89 | } | ||
90 | |||
91 | static inline void set_c0_eimr(int irq) | ||
92 | { | ||
93 | __asm__ __volatile__( | ||
94 | ".set push\n\t" | ||
95 | ".set mips64\n\t" | ||
96 | ".set noat\n\t" | ||
97 | "li $1, 1\n\t" | ||
98 | "dsllv %0, $1, %0\n\t" | ||
99 | "dmfc0 $1, $9, 7\n\t" | ||
100 | "or $1, %0\n\t" | ||
101 | "dmtc0 $1, $9, 7\n\t" | ||
102 | ".set pop" | ||
103 | : "+r" (irq)); | ||
104 | } | ||
105 | |||
106 | static inline void clear_c0_eimr(int irq) | ||
107 | { | ||
108 | __asm__ __volatile__( | ||
109 | ".set push\n\t" | ||
110 | ".set mips64\n\t" | ||
111 | ".set noat\n\t" | ||
112 | "li $1, 1\n\t" | ||
113 | "dsllv %0, $1, %0\n\t" | ||
114 | "dmfc0 $1, $9, 7\n\t" | ||
115 | "or $1, %0\n\t" | ||
116 | "xor $1, %0\n\t" | ||
117 | "dmtc0 $1, $9, 7\n\t" | ||
118 | ".set pop" | ||
119 | : "+r" (irq)); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Read c0 eimr and c0 eirr, do AND of the two values, the result is | ||
124 | * the interrupts which are raised and are not masked. | ||
125 | */ | ||
126 | static inline uint64_t read_c0_eirr_and_eimr(void) | ||
127 | { | ||
128 | uint64_t val; | ||
129 | |||
130 | #ifdef CONFIG_64BIT | ||
131 | val = read_c0_eimr() & read_c0_eirr(); | ||
132 | #else | ||
133 | __asm__ __volatile__( | ||
134 | ".set push\n\t" | ||
135 | ".set mips64\n\t" | ||
136 | ".set noat\n\t" | ||
137 | "dmfc0 %M0, $9, 6\n\t" | ||
138 | "dmfc0 %L0, $9, 7\n\t" | ||
139 | "and %M0, %L0\n\t" | ||
140 | "dsll %L0, %M0, 32\n\t" | ||
141 | "dsra %M0, %M0, 32\n\t" | ||
142 | "dsra %L0, %L0, 32\n\t" | ||
143 | ".set pop" | ||
144 | : "=r" (val)); | ||
145 | #endif | ||
146 | |||
147 | return val; | ||
148 | } | ||
149 | |||
71 | static inline int hard_smp_processor_id(void) | 150 | static inline int hard_smp_processor_id(void) |
72 | { | 151 | { |
73 | return __read_32bit_c0_register($15, 1) & 0x3ff; | 152 | return __read_32bit_c0_register($15, 1) & 0x3ff; |
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h index 7b63a6b722a0..6d2e58a9a542 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h | |||
@@ -46,6 +46,8 @@ | |||
46 | #define CPU_BLOCKID_FPU 9 | 46 | #define CPU_BLOCKID_FPU 9 |
47 | #define CPU_BLOCKID_MAP 10 | 47 | #define CPU_BLOCKID_MAP 10 |
48 | 48 | ||
49 | #define ICU_DEFEATURE 0x100 | ||
50 | |||
49 | #define LSU_DEFEATURE 0x304 | 51 | #define LSU_DEFEATURE 0x304 |
50 | #define LSU_DEBUG_ADDR 0x305 | 52 | #define LSU_DEBUG_ADDR 0x305 |
51 | #define LSU_DEBUG_DATA0 0x306 | 53 | #define LSU_DEBUG_DATA0 0x306 |
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h index 46ace0ca26d8..3df53017fe51 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h | |||
@@ -261,6 +261,8 @@ | |||
261 | #define PIC_LOCAL_SCHEDULING 1 | 261 | #define PIC_LOCAL_SCHEDULING 1 |
262 | #define PIC_GLOBAL_SCHEDULING 0 | 262 | #define PIC_GLOBAL_SCHEDULING 0 |
263 | 263 | ||
264 | #define PIC_CLK_HZ 133333333 | ||
265 | |||
264 | #define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r) | 266 | #define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r) |
265 | #define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v) | 267 | #define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v) |
266 | #define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node)) | 268 | #define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node)) |
@@ -315,6 +317,12 @@ nlm_pic_read_timer(uint64_t base, int timer) | |||
315 | return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer)); | 317 | return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer)); |
316 | } | 318 | } |
317 | 319 | ||
320 | static inline uint32_t | ||
321 | nlm_pic_read_timer32(uint64_t base, int timer) | ||
322 | { | ||
323 | return (uint32_t)nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer)); | ||
324 | } | ||
325 | |||
318 | static inline void | 326 | static inline void |
319 | nlm_pic_write_timer(uint64_t base, int timer, uint64_t value) | 327 | nlm_pic_write_timer(uint64_t base, int timer, uint64_t value) |
320 | { | 328 | { |
@@ -376,9 +384,9 @@ nlm_pic_ack(uint64_t base, int irt_num) | |||
376 | } | 384 | } |
377 | 385 | ||
378 | static inline void | 386 | static inline void |
379 | nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt) | 387 | nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt, int en) |
380 | { | 388 | { |
381 | nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt); | 389 | nlm_pic_write_irt_direct(base, irt, en, 0, 0, irq, hwt); |
382 | } | 390 | } |
383 | 391 | ||
384 | int nlm_irq_to_irt(int irq); | 392 | int nlm_irq_to_irt(int irq); |
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h index 2f549453585e..63c99176dffe 100644 --- a/arch/mips/include/asm/netlogic/xlr/pic.h +++ b/arch/mips/include/asm/netlogic/xlr/pic.h | |||
@@ -35,10 +35,11 @@ | |||
35 | #ifndef _ASM_NLM_XLR_PIC_H | 35 | #ifndef _ASM_NLM_XLR_PIC_H |
36 | #define _ASM_NLM_XLR_PIC_H | 36 | #define _ASM_NLM_XLR_PIC_H |
37 | 37 | ||
38 | #define PIC_CLKS_PER_SEC 66666666ULL | 38 | #define PIC_CLK_HZ 66666666 |
39 | /* PIC hardware interrupt numbers */ | 39 | /* PIC hardware interrupt numbers */ |
40 | #define PIC_IRT_WD_INDEX 0 | 40 | #define PIC_IRT_WD_INDEX 0 |
41 | #define PIC_IRT_TIMER_0_INDEX 1 | 41 | #define PIC_IRT_TIMER_0_INDEX 1 |
42 | #define PIC_IRT_TIMER_INDEX(i) ((i) + PIC_IRT_TIMER_0_INDEX) | ||
42 | #define PIC_IRT_TIMER_1_INDEX 2 | 43 | #define PIC_IRT_TIMER_1_INDEX 2 |
43 | #define PIC_IRT_TIMER_2_INDEX 3 | 44 | #define PIC_IRT_TIMER_2_INDEX 3 |
44 | #define PIC_IRT_TIMER_3_INDEX 4 | 45 | #define PIC_IRT_TIMER_3_INDEX 4 |
@@ -99,6 +100,7 @@ | |||
99 | 100 | ||
100 | /* PIC Registers */ | 101 | /* PIC Registers */ |
101 | #define PIC_CTRL 0x00 | 102 | #define PIC_CTRL 0x00 |
103 | #define PIC_CTRL_STE 8 /* timer enable start bit */ | ||
102 | #define PIC_IPI 0x04 | 104 | #define PIC_IPI 0x04 |
103 | #define PIC_INT_ACK 0x06 | 105 | #define PIC_INT_ACK 0x06 |
104 | 106 | ||
@@ -251,12 +253,52 @@ nlm_pic_ack(uint64_t base, int irt) | |||
251 | } | 253 | } |
252 | 254 | ||
253 | static inline void | 255 | static inline void |
254 | nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt) | 256 | nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt, int en) |
255 | { | 257 | { |
256 | nlm_write_reg(base, PIC_IRT_0(irt), (1u << hwt)); | 258 | nlm_write_reg(base, PIC_IRT_0(irt), (1u << hwt)); |
257 | /* local scheduling, invalid, level by default */ | 259 | /* local scheduling, invalid, level by default */ |
258 | nlm_write_reg(base, PIC_IRT_1(irt), | 260 | nlm_write_reg(base, PIC_IRT_1(irt), |
259 | (1 << 30) | (1 << 6) | irq); | 261 | (en << 30) | (1 << 6) | irq); |
262 | } | ||
263 | |||
264 | static inline uint64_t | ||
265 | nlm_pic_read_timer(uint64_t base, int timer) | ||
266 | { | ||
267 | uint32_t up1, up2, low; | ||
268 | |||
269 | up1 = nlm_read_reg(base, PIC_TIMER_COUNT_1(timer)); | ||
270 | low = nlm_read_reg(base, PIC_TIMER_COUNT_0(timer)); | ||
271 | up2 = nlm_read_reg(base, PIC_TIMER_COUNT_1(timer)); | ||
272 | |||
273 | if (up1 != up2) /* wrapped, get the new low */ | ||
274 | low = nlm_read_reg(base, PIC_TIMER_COUNT_0(timer)); | ||
275 | return ((uint64_t)up2 << 32) | low; | ||
276 | |||
277 | } | ||
278 | |||
279 | static inline uint32_t | ||
280 | nlm_pic_read_timer32(uint64_t base, int timer) | ||
281 | { | ||
282 | return nlm_read_reg(base, PIC_TIMER_COUNT_0(timer)); | ||
283 | } | ||
284 | |||
285 | static inline void | ||
286 | nlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu) | ||
287 | { | ||
288 | uint32_t up, low; | ||
289 | uint64_t pic_ctrl = nlm_read_reg(base, PIC_CTRL); | ||
290 | int en; | ||
291 | |||
292 | en = (irq > 0); | ||
293 | up = value >> 32; | ||
294 | low = value & 0xFFFFFFFF; | ||
295 | nlm_write_reg(base, PIC_TIMER_MAXVAL_0(timer), low); | ||
296 | nlm_write_reg(base, PIC_TIMER_MAXVAL_1(timer), up); | ||
297 | nlm_pic_init_irt(base, PIC_IRT_TIMER_INDEX(timer), irq, cpu, 0); | ||
298 | |||
299 | /* enable the timer */ | ||
300 | pic_ctrl |= (1 << (PIC_CTRL_STE + timer)); | ||
301 | nlm_write_reg(base, PIC_CTRL, pic_ctrl); | ||
260 | } | 302 | } |
261 | #endif | 303 | #endif |
262 | #endif /* _ASM_NLM_XLR_PIC_H */ | 304 | #endif /* _ASM_NLM_XLR_PIC_H */ |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index e224876cc344..b8e24fd4cbc5 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -144,8 +144,13 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
144 | 144 | ||
145 | extern char * (*pcibios_plat_setup)(char *str); | 145 | extern char * (*pcibios_plat_setup)(char *str); |
146 | 146 | ||
147 | #ifdef CONFIG_OF | ||
147 | /* this function parses memory ranges from a device node */ | 148 | /* this function parses memory ranges from a device node */ |
148 | extern void pci_load_of_ranges(struct pci_controller *hose, | 149 | extern void pci_load_of_ranges(struct pci_controller *hose, |
149 | struct device_node *node); | 150 | struct device_node *node); |
151 | #else | ||
152 | static inline void pci_load_of_ranges(struct pci_controller *hose, | ||
153 | struct device_node *node) {} | ||
154 | #endif | ||
150 | 155 | ||
151 | #endif /* _ASM_PCI_H */ | 156 | #endif /* _ASM_PCI_H */ |
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 96353075cc60..debc8009bd58 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h | |||
@@ -75,7 +75,7 @@ extern int init_r4k_clocksource(void); | |||
75 | 75 | ||
76 | static inline int init_mips_clocksource(void) | 76 | static inline int init_mips_clocksource(void) |
77 | { | 77 | { |
78 | #ifdef CONFIG_CSRC_R4K | 78 | #if defined(CONFIG_CSRC_R4K) && !defined(CONFIG_CSRC_GIC) |
79 | return init_r4k_clocksource(); | 79 | return init_r4k_clocksource(); |
80 | #else | 80 | #else |
81 | return 0; | 81 | return 0; |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index c48ed923fd55..f81d98f6184c 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -27,6 +27,7 @@ obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o | |||
27 | obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o | 27 | obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o |
28 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o | 28 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o |
29 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o | 29 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o |
30 | obj-$(CONFIG_CSRC_GIC) += csrc-gic.o | ||
30 | obj-$(CONFIG_SYNC_R4K) += sync-r4k.o | 31 | obj-$(CONFIG_SYNC_R4K) += sync-r4k.o |
31 | 32 | ||
32 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 33 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
@@ -98,4 +99,35 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o | |||
98 | 99 | ||
99 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 100 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
100 | 101 | ||
102 | # | ||
103 | # DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is safe | ||
104 | # to enable DSP assembler support here even if the MIPS Release 2 CPU we | ||
105 | # are targetting does not support DSP because all code-paths making use of | ||
106 | # it properly check that the running CPU *actually does* support these | ||
107 | # instructions. | ||
108 | # | ||
109 | ifeq ($(CONFIG_CPU_MIPSR2), y) | ||
110 | CFLAGS_DSP = -DHAVE_AS_DSP | ||
111 | |||
112 | # | ||
113 | # Check if assembler supports DSP ASE | ||
114 | # | ||
115 | ifeq ($(call cc-option-yn,-mdsp), y) | ||
116 | CFLAGS_DSP += -mdsp | ||
117 | endif | ||
118 | |||
119 | # | ||
120 | # Check if assembler supports DSP ASE Rev2 | ||
121 | # | ||
122 | ifeq ($(call cc-option-yn,-mdspr2), y) | ||
123 | CFLAGS_DSP += -mdspr2 | ||
124 | endif | ||
125 | |||
126 | CFLAGS_signal.o = $(CFLAGS_DSP) | ||
127 | CFLAGS_signal32.o = $(CFLAGS_DSP) | ||
128 | CFLAGS_process.o = $(CFLAGS_DSP) | ||
129 | CFLAGS_branch.o = $(CFLAGS_DSP) | ||
130 | CFLAGS_ptrace.o = $(CFLAGS_DSP) | ||
131 | endif | ||
132 | |||
101 | CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) | 133 | CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS) |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 2656c898e337..6bfccc227a95 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -201,6 +201,7 @@ void __init check_wait(void) | |||
201 | break; | 201 | break; |
202 | 202 | ||
203 | case CPU_M14KC: | 203 | case CPU_M14KC: |
204 | case CPU_M14KEC: | ||
204 | case CPU_24K: | 205 | case CPU_24K: |
205 | case CPU_34K: | 206 | case CPU_34K: |
206 | case CPU_1004K: | 207 | case CPU_1004K: |
@@ -467,6 +468,10 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
467 | c->ases |= MIPS_ASE_MIPSMT; | 468 | c->ases |= MIPS_ASE_MIPSMT; |
468 | if (config3 & MIPS_CONF3_ULRI) | 469 | if (config3 & MIPS_CONF3_ULRI) |
469 | c->options |= MIPS_CPU_ULRI; | 470 | c->options |= MIPS_CPU_ULRI; |
471 | if (config3 & MIPS_CONF3_ISA) | ||
472 | c->options |= MIPS_CPU_MICROMIPS; | ||
473 | if (config3 & MIPS_CONF3_VZ) | ||
474 | c->ases |= MIPS_ASE_VZ; | ||
470 | 475 | ||
471 | return config3 & MIPS_CONF_M; | 476 | return config3 & MIPS_CONF_M; |
472 | } | 477 | } |
@@ -866,10 +871,13 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
866 | __cpu_name[cpu] = "MIPS 20Kc"; | 871 | __cpu_name[cpu] = "MIPS 20Kc"; |
867 | break; | 872 | break; |
868 | case PRID_IMP_24K: | 873 | case PRID_IMP_24K: |
869 | case PRID_IMP_24KE: | ||
870 | c->cputype = CPU_24K; | 874 | c->cputype = CPU_24K; |
871 | __cpu_name[cpu] = "MIPS 24Kc"; | 875 | __cpu_name[cpu] = "MIPS 24Kc"; |
872 | break; | 876 | break; |
877 | case PRID_IMP_24KE: | ||
878 | c->cputype = CPU_24K; | ||
879 | __cpu_name[cpu] = "MIPS 24KEc"; | ||
880 | break; | ||
873 | case PRID_IMP_25KF: | 881 | case PRID_IMP_25KF: |
874 | c->cputype = CPU_25KF; | 882 | c->cputype = CPU_25KF; |
875 | __cpu_name[cpu] = "MIPS 25Kc"; | 883 | __cpu_name[cpu] = "MIPS 25Kc"; |
@@ -886,6 +894,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
886 | c->cputype = CPU_M14KC; | 894 | c->cputype = CPU_M14KC; |
887 | __cpu_name[cpu] = "MIPS M14Kc"; | 895 | __cpu_name[cpu] = "MIPS M14Kc"; |
888 | break; | 896 | break; |
897 | case PRID_IMP_M14KEC: | ||
898 | c->cputype = CPU_M14KEC; | ||
899 | __cpu_name[cpu] = "MIPS M14KEc"; | ||
900 | break; | ||
889 | case PRID_IMP_1004K: | 901 | case PRID_IMP_1004K: |
890 | c->cputype = CPU_1004K; | 902 | c->cputype = CPU_1004K; |
891 | __cpu_name[cpu] = "MIPS 1004Kc"; | 903 | __cpu_name[cpu] = "MIPS 1004Kc"; |
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c new file mode 100644 index 000000000000..5dca24bce51b --- /dev/null +++ b/arch/mips/kernel/csrc-gic.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | */ | ||
8 | #include <linux/clocksource.h> | ||
9 | #include <linux/init.h> | ||
10 | |||
11 | #include <asm/time.h> | ||
12 | #include <asm/gic.h> | ||
13 | |||
14 | static cycle_t gic_hpt_read(struct clocksource *cs) | ||
15 | { | ||
16 | unsigned int hi, hi2, lo; | ||
17 | |||
18 | do { | ||
19 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); | ||
20 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); | ||
21 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); | ||
22 | } while (hi2 != hi); | ||
23 | |||
24 | return (((cycle_t) hi) << 32) + lo; | ||
25 | } | ||
26 | |||
27 | static struct clocksource gic_clocksource = { | ||
28 | .name = "GIC", | ||
29 | .read = gic_hpt_read, | ||
30 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
31 | }; | ||
32 | |||
33 | void __init gic_clocksource_init(unsigned int frequency) | ||
34 | { | ||
35 | unsigned int config, bits; | ||
36 | |||
37 | /* Calculate the clocksource mask. */ | ||
38 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); | ||
39 | bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> | ||
40 | (GIC_SH_CONFIG_COUNTBITS_SHF - 2)); | ||
41 | |||
42 | /* Set clocksource mask. */ | ||
43 | gic_clocksource.mask = CLOCKSOURCE_MASK(bits); | ||
44 | |||
45 | /* Calculate a somewhat reasonable rating value. */ | ||
46 | gic_clocksource.rating = 200 + frequency / 10000000; | ||
47 | |||
48 | clocksource_register_hz(&gic_clocksource, frequency); | ||
49 | } | ||
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c index 9ae813eb782e..9e6440eaa455 100644 --- a/arch/mips/kernel/early_printk.c +++ b/arch/mips/kernel/early_printk.c | |||
@@ -14,8 +14,7 @@ | |||
14 | 14 | ||
15 | extern void prom_putchar(char); | 15 | extern void prom_putchar(char); |
16 | 16 | ||
17 | static void __init | 17 | static void early_console_write(struct console *con, const char *s, unsigned n) |
18 | early_console_write(struct console *con, const char *s, unsigned n) | ||
19 | { | 18 | { |
20 | while (n-- && *s) { | 19 | while (n-- && *s) { |
21 | if (*s == '\n') | 20 | if (*s == '\n') |
@@ -25,7 +24,7 @@ early_console_write(struct console *con, const char *s, unsigned n) | |||
25 | } | 24 | } |
26 | } | 25 | } |
27 | 26 | ||
28 | static struct console early_console __initdata = { | 27 | static struct console early_console = { |
29 | .name = "early", | 28 | .name = "early", |
30 | .write = early_console_write, | 29 | .write = early_console_write, |
31 | .flags = CON_PRINTBUFFER | CON_BOOT, | 30 | .flags = CON_PRINTBUFFER | CON_BOOT, |
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 0207a44917bf..72ef2d25cbf2 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/irqdomain.h> | ||
34 | 35 | ||
35 | #include <asm/irq_cpu.h> | 36 | #include <asm/irq_cpu.h> |
36 | #include <asm/mipsregs.h> | 37 | #include <asm/mipsregs.h> |
@@ -113,3 +114,44 @@ void __init mips_cpu_irq_init(void) | |||
113 | irq_set_chip_and_handler(i, &mips_cpu_irq_controller, | 114 | irq_set_chip_and_handler(i, &mips_cpu_irq_controller, |
114 | handle_percpu_irq); | 115 | handle_percpu_irq); |
115 | } | 116 | } |
117 | |||
118 | #ifdef CONFIG_IRQ_DOMAIN | ||
119 | static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, | ||
120 | irq_hw_number_t hw) | ||
121 | { | ||
122 | static struct irq_chip *chip; | ||
123 | |||
124 | if (hw < 2 && cpu_has_mipsmt) { | ||
125 | /* Software interrupts are used for MT/CMT IPI */ | ||
126 | chip = &mips_mt_cpu_irq_controller; | ||
127 | } else { | ||
128 | chip = &mips_cpu_irq_controller; | ||
129 | } | ||
130 | |||
131 | irq_set_chip_and_handler(irq, chip, handle_percpu_irq); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = { | ||
137 | .map = mips_cpu_intc_map, | ||
138 | .xlate = irq_domain_xlate_onecell, | ||
139 | }; | ||
140 | |||
141 | int __init mips_cpu_intc_init(struct device_node *of_node, | ||
142 | struct device_node *parent) | ||
143 | { | ||
144 | struct irq_domain *domain; | ||
145 | |||
146 | /* Mask interrupts. */ | ||
147 | clear_c0_status(ST0_IM); | ||
148 | clear_c0_cause(CAUSEF_IP); | ||
149 | |||
150 | domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0, | ||
151 | &mips_cpu_intc_irq_domain_ops, NULL); | ||
152 | if (!domain) | ||
153 | panic("Failed to add irqdomain for MIPS CPU\n"); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | #endif /* CONFIG_IRQ_DOMAIN */ | ||
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 79d4b8edbd76..135c4aadccbe 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -95,6 +95,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
95 | if (cpu_has_dsp) seq_printf(m, "%s", " dsp"); | 95 | if (cpu_has_dsp) seq_printf(m, "%s", " dsp"); |
96 | if (cpu_has_dsp2) seq_printf(m, "%s", " dsp2"); | 96 | if (cpu_has_dsp2) seq_printf(m, "%s", " dsp2"); |
97 | if (cpu_has_mipsmt) seq_printf(m, "%s", " mt"); | 97 | if (cpu_has_mipsmt) seq_printf(m, "%s", " mt"); |
98 | if (cpu_has_mmips) seq_printf(m, "%s", " micromips"); | ||
99 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); | ||
98 | seq_printf(m, "\n"); | 100 | seq_printf(m, "\n"); |
99 | 101 | ||
100 | seq_printf(m, "shadow register sets\t: %d\n", | 102 | seq_printf(m, "shadow register sets\t: %d\n", |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 653197e151d5..4c774d5d5087 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -480,34 +480,75 @@ static int __init early_parse_mem(char *p) | |||
480 | } | 480 | } |
481 | early_param("mem", early_parse_mem); | 481 | early_param("mem", early_parse_mem); |
482 | 482 | ||
483 | static void __init arch_mem_init(char **cmdline_p) | 483 | #ifdef CONFIG_PROC_VMCORE |
484 | unsigned long setup_elfcorehdr, setup_elfcorehdr_size; | ||
485 | static int __init early_parse_elfcorehdr(char *p) | ||
486 | { | ||
487 | int i; | ||
488 | |||
489 | setup_elfcorehdr = memparse(p, &p); | ||
490 | |||
491 | for (i = 0; i < boot_mem_map.nr_map; i++) { | ||
492 | unsigned long start = boot_mem_map.map[i].addr; | ||
493 | unsigned long end = (boot_mem_map.map[i].addr + | ||
494 | boot_mem_map.map[i].size); | ||
495 | if (setup_elfcorehdr >= start && setup_elfcorehdr < end) { | ||
496 | /* | ||
497 | * Reserve from the elf core header to the end of | ||
498 | * the memory segment, that should all be kdump | ||
499 | * reserved memory. | ||
500 | */ | ||
501 | setup_elfcorehdr_size = end - setup_elfcorehdr; | ||
502 | break; | ||
503 | } | ||
504 | } | ||
505 | /* | ||
506 | * If we don't find it in the memory map, then we shouldn't | ||
507 | * have to worry about it, as the new kernel won't use it. | ||
508 | */ | ||
509 | return 0; | ||
510 | } | ||
511 | early_param("elfcorehdr", early_parse_elfcorehdr); | ||
512 | #endif | ||
513 | |||
514 | static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) | ||
484 | { | 515 | { |
485 | phys_t init_mem, init_end, init_size; | 516 | phys_t size; |
517 | int i; | ||
486 | 518 | ||
519 | size = end - mem; | ||
520 | if (!size) | ||
521 | return; | ||
522 | |||
523 | /* Make sure it is in the boot_mem_map */ | ||
524 | for (i = 0; i < boot_mem_map.nr_map; i++) { | ||
525 | if (mem >= boot_mem_map.map[i].addr && | ||
526 | mem < (boot_mem_map.map[i].addr + | ||
527 | boot_mem_map.map[i].size)) | ||
528 | return; | ||
529 | } | ||
530 | add_memory_region(mem, size, type); | ||
531 | } | ||
532 | |||
533 | static void __init arch_mem_init(char **cmdline_p) | ||
534 | { | ||
487 | extern void plat_mem_setup(void); | 535 | extern void plat_mem_setup(void); |
488 | 536 | ||
489 | /* call board setup routine */ | 537 | /* call board setup routine */ |
490 | plat_mem_setup(); | 538 | plat_mem_setup(); |
491 | 539 | ||
492 | init_mem = PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT; | 540 | /* |
493 | init_end = PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT; | 541 | * Make sure all kernel memory is in the maps. The "UP" and |
494 | init_size = init_end - init_mem; | 542 | * "DOWN" are opposite for initdata since if it crosses over |
495 | if (init_size) { | 543 | * into another memory section you don't want that to be |
496 | /* Make sure it is in the boot_mem_map */ | 544 | * freed when the initdata is freed. |
497 | int i, found; | 545 | */ |
498 | found = 0; | 546 | arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, |
499 | for (i = 0; i < boot_mem_map.nr_map; i++) { | 547 | PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, |
500 | if (init_mem >= boot_mem_map.map[i].addr && | 548 | BOOT_MEM_RAM); |
501 | init_mem < (boot_mem_map.map[i].addr + | 549 | arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, |
502 | boot_mem_map.map[i].size)) { | 550 | PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, |
503 | found = 1; | 551 | BOOT_MEM_INIT_RAM); |
504 | break; | ||
505 | } | ||
506 | } | ||
507 | if (!found) | ||
508 | add_memory_region(init_mem, init_size, | ||
509 | BOOT_MEM_INIT_RAM); | ||
510 | } | ||
511 | 552 | ||
512 | pr_info("Determined physical RAM map:\n"); | 553 | pr_info("Determined physical RAM map:\n"); |
513 | print_memory_map(); | 554 | print_memory_map(); |
@@ -537,6 +578,14 @@ static void __init arch_mem_init(char **cmdline_p) | |||
537 | } | 578 | } |
538 | 579 | ||
539 | bootmem_init(); | 580 | bootmem_init(); |
581 | #ifdef CONFIG_PROC_VMCORE | ||
582 | if (setup_elfcorehdr && setup_elfcorehdr_size) { | ||
583 | printk(KERN_INFO "kdump reserved memory at %lx-%lx\n", | ||
584 | setup_elfcorehdr, setup_elfcorehdr_size); | ||
585 | reserve_bootmem(setup_elfcorehdr, setup_elfcorehdr_size, | ||
586 | BOOTMEM_DEFAULT); | ||
587 | } | ||
588 | #endif | ||
540 | #ifdef CONFIG_KEXEC | 589 | #ifdef CONFIG_KEXEC |
541 | if (crashk_res.start != crashk_res.end) | 590 | if (crashk_res.start != crashk_res.end) |
542 | reserve_bootmem(crashk_res.start, | 591 | reserve_bootmem(crashk_res.start, |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 1c152a93dc7b..7186222dc5bb 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/addrspace.h> | 41 | #include <asm/addrspace.h> |
42 | #include <asm/smtc.h> | 42 | #include <asm/smtc.h> |
43 | #include <asm/smtc_proc.h> | 43 | #include <asm/smtc_proc.h> |
44 | #include <asm/setup.h> | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * SMTC Kernel needs to manipulate low-level CPU interrupt mask | 47 | * SMTC Kernel needs to manipulate low-level CPU interrupt mask |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 32fc5d4a22e5..b4c01522edde 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -697,18 +697,7 @@ static int vpe_run(struct vpe * v) | |||
697 | dmt_flag = dmt(); | 697 | dmt_flag = dmt(); |
698 | vpeflags = dvpe(); | 698 | vpeflags = dvpe(); |
699 | 699 | ||
700 | if (!list_empty(&v->tc)) { | 700 | if (list_empty(&v->tc)) { |
701 | if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) { | ||
702 | evpe(vpeflags); | ||
703 | emt(dmt_flag); | ||
704 | local_irq_restore(flags); | ||
705 | |||
706 | printk(KERN_WARNING | ||
707 | "VPE loader: TC %d is already in use.\n", | ||
708 | v->tc->index); | ||
709 | return -ENOEXEC; | ||
710 | } | ||
711 | } else { | ||
712 | evpe(vpeflags); | 701 | evpe(vpeflags); |
713 | emt(dmt_flag); | 702 | emt(dmt_flag); |
714 | local_irq_restore(flags); | 703 | local_irq_restore(flags); |
@@ -720,6 +709,8 @@ static int vpe_run(struct vpe * v) | |||
720 | return -ENOEXEC; | 709 | return -ENOEXEC; |
721 | } | 710 | } |
722 | 711 | ||
712 | t = list_first_entry(&v->tc, struct tc, tc); | ||
713 | |||
723 | /* Put MVPE's into 'configuration state' */ | 714 | /* Put MVPE's into 'configuration state' */ |
724 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 715 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
725 | 716 | ||
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index 186fd3e44242..3fc2e6d70c77 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c | |||
@@ -26,13 +26,15 @@ | |||
26 | #include "prom.h" | 26 | #include "prom.h" |
27 | 27 | ||
28 | /* lantiq socs have 3 static clocks */ | 28 | /* lantiq socs have 3 static clocks */ |
29 | static struct clk cpu_clk_generic[3]; | 29 | static struct clk cpu_clk_generic[4]; |
30 | 30 | ||
31 | void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io) | 31 | void clkdev_add_static(unsigned long cpu, unsigned long fpi, |
32 | unsigned long io, unsigned long ppe) | ||
32 | { | 33 | { |
33 | cpu_clk_generic[0].rate = cpu; | 34 | cpu_clk_generic[0].rate = cpu; |
34 | cpu_clk_generic[1].rate = fpi; | 35 | cpu_clk_generic[1].rate = fpi; |
35 | cpu_clk_generic[2].rate = io; | 36 | cpu_clk_generic[2].rate = io; |
37 | cpu_clk_generic[3].rate = ppe; | ||
36 | } | 38 | } |
37 | 39 | ||
38 | struct clk *clk_get_cpu(void) | 40 | struct clk *clk_get_cpu(void) |
@@ -51,6 +53,12 @@ struct clk *clk_get_io(void) | |||
51 | return &cpu_clk_generic[2]; | 53 | return &cpu_clk_generic[2]; |
52 | } | 54 | } |
53 | 55 | ||
56 | struct clk *clk_get_ppe(void) | ||
57 | { | ||
58 | return &cpu_clk_generic[3]; | ||
59 | } | ||
60 | EXPORT_SYMBOL_GPL(clk_get_ppe); | ||
61 | |||
54 | static inline int clk_good(struct clk *clk) | 62 | static inline int clk_good(struct clk *clk) |
55 | { | 63 | { |
56 | return clk && !IS_ERR(clk); | 64 | return clk && !IS_ERR(clk); |
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h index fa670602b91b..77e4bdb1fe8c 100644 --- a/arch/mips/lantiq/clk.h +++ b/arch/mips/lantiq/clk.h | |||
@@ -27,12 +27,15 @@ | |||
27 | #define CLOCK_167M 166666667 | 27 | #define CLOCK_167M 166666667 |
28 | #define CLOCK_196_608M 196608000 | 28 | #define CLOCK_196_608M 196608000 |
29 | #define CLOCK_200M 200000000 | 29 | #define CLOCK_200M 200000000 |
30 | #define CLOCK_222M 222000000 | ||
31 | #define CLOCK_240M 240000000 | ||
30 | #define CLOCK_250M 250000000 | 32 | #define CLOCK_250M 250000000 |
31 | #define CLOCK_266M 266666666 | 33 | #define CLOCK_266M 266666666 |
32 | #define CLOCK_300M 300000000 | 34 | #define CLOCK_300M 300000000 |
33 | #define CLOCK_333M 333333333 | 35 | #define CLOCK_333M 333333333 |
34 | #define CLOCK_393M 393215332 | 36 | #define CLOCK_393M 393215332 |
35 | #define CLOCK_400M 400000000 | 37 | #define CLOCK_400M 400000000 |
38 | #define CLOCK_450M 450000000 | ||
36 | #define CLOCK_500M 500000000 | 39 | #define CLOCK_500M 500000000 |
37 | #define CLOCK_600M 600000000 | 40 | #define CLOCK_600M 600000000 |
38 | 41 | ||
@@ -64,15 +67,17 @@ struct clk { | |||
64 | }; | 67 | }; |
65 | 68 | ||
66 | extern void clkdev_add_static(unsigned long cpu, unsigned long fpi, | 69 | extern void clkdev_add_static(unsigned long cpu, unsigned long fpi, |
67 | unsigned long io); | 70 | unsigned long io, unsigned long ppe); |
68 | 71 | ||
69 | extern unsigned long ltq_danube_cpu_hz(void); | 72 | extern unsigned long ltq_danube_cpu_hz(void); |
70 | extern unsigned long ltq_danube_fpi_hz(void); | 73 | extern unsigned long ltq_danube_fpi_hz(void); |
74 | extern unsigned long ltq_danube_pp32_hz(void); | ||
71 | 75 | ||
72 | extern unsigned long ltq_ar9_cpu_hz(void); | 76 | extern unsigned long ltq_ar9_cpu_hz(void); |
73 | extern unsigned long ltq_ar9_fpi_hz(void); | 77 | extern unsigned long ltq_ar9_fpi_hz(void); |
74 | 78 | ||
75 | extern unsigned long ltq_vr9_cpu_hz(void); | 79 | extern unsigned long ltq_vr9_cpu_hz(void); |
76 | extern unsigned long ltq_vr9_fpi_hz(void); | 80 | extern unsigned long ltq_vr9_fpi_hz(void); |
81 | extern unsigned long ltq_vr9_pp32_hz(void); | ||
77 | 82 | ||
78 | #endif | 83 | #endif |
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 2d4ced332b37..ff4894a833ee 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c | |||
@@ -241,9 +241,9 @@ void __init ltq_soc_init(void) | |||
241 | 241 | ||
242 | /* get our 3 static rates for cpu, fpi and io clocks */ | 242 | /* get our 3 static rates for cpu, fpi and io clocks */ |
243 | if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV) | 243 | if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV) |
244 | clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M); | 244 | clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M, 0); |
245 | else | 245 | else |
246 | clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M); | 246 | clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M, 0); |
247 | 247 | ||
248 | /* add our clock domains */ | 248 | /* add our clock domains */ |
249 | clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0); | 249 | clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0); |
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 5323308aab3f..51194875f158 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c | |||
@@ -33,17 +33,10 @@ | |||
33 | /* register definitions - external irqs */ | 33 | /* register definitions - external irqs */ |
34 | #define LTQ_EIU_EXIN_C 0x0000 | 34 | #define LTQ_EIU_EXIN_C 0x0000 |
35 | #define LTQ_EIU_EXIN_INIC 0x0004 | 35 | #define LTQ_EIU_EXIN_INIC 0x0004 |
36 | #define LTQ_EIU_EXIN_INC 0x0008 | ||
36 | #define LTQ_EIU_EXIN_INEN 0x000C | 37 | #define LTQ_EIU_EXIN_INEN 0x000C |
37 | 38 | ||
38 | /* irq numbers used by the external interrupt unit (EIU) */ | 39 | /* number of external interrupts */ |
39 | #define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30) | ||
40 | #define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31) | ||
41 | #define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26) | ||
42 | #define LTQ_EIU_IR3 INT_NUM_IM1_IRL0 | ||
43 | #define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) | ||
44 | #define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) | ||
45 | #define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) | ||
46 | #define XWAY_EXIN_COUNT 3 | ||
47 | #define MAX_EIU 6 | 40 | #define MAX_EIU 6 |
48 | 41 | ||
49 | /* the performance counter */ | 42 | /* the performance counter */ |
@@ -72,20 +65,19 @@ | |||
72 | int gic_present; | 65 | int gic_present; |
73 | #endif | 66 | #endif |
74 | 67 | ||
75 | static unsigned short ltq_eiu_irq[MAX_EIU] = { | ||
76 | LTQ_EIU_IR0, | ||
77 | LTQ_EIU_IR1, | ||
78 | LTQ_EIU_IR2, | ||
79 | LTQ_EIU_IR3, | ||
80 | LTQ_EIU_IR4, | ||
81 | LTQ_EIU_IR5, | ||
82 | }; | ||
83 | |||
84 | static int exin_avail; | 68 | static int exin_avail; |
69 | static struct resource ltq_eiu_irq[MAX_EIU]; | ||
85 | static void __iomem *ltq_icu_membase[MAX_IM]; | 70 | static void __iomem *ltq_icu_membase[MAX_IM]; |
86 | static void __iomem *ltq_eiu_membase; | 71 | static void __iomem *ltq_eiu_membase; |
87 | static struct irq_domain *ltq_domain; | 72 | static struct irq_domain *ltq_domain; |
88 | 73 | ||
74 | int ltq_eiu_get_irq(int exin) | ||
75 | { | ||
76 | if (exin < exin_avail) | ||
77 | return ltq_eiu_irq[exin].start; | ||
78 | return -1; | ||
79 | } | ||
80 | |||
89 | void ltq_disable_irq(struct irq_data *d) | 81 | void ltq_disable_irq(struct irq_data *d) |
90 | { | 82 | { |
91 | u32 ier = LTQ_ICU_IM0_IER; | 83 | u32 ier = LTQ_ICU_IM0_IER; |
@@ -128,19 +120,65 @@ void ltq_enable_irq(struct irq_data *d) | |||
128 | ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier); | 120 | ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier); |
129 | } | 121 | } |
130 | 122 | ||
123 | static int ltq_eiu_settype(struct irq_data *d, unsigned int type) | ||
124 | { | ||
125 | int i; | ||
126 | |||
127 | for (i = 0; i < MAX_EIU; i++) { | ||
128 | if (d->hwirq == ltq_eiu_irq[i].start) { | ||
129 | int val = 0; | ||
130 | int edge = 0; | ||
131 | |||
132 | switch (type) { | ||
133 | case IRQF_TRIGGER_NONE: | ||
134 | break; | ||
135 | case IRQF_TRIGGER_RISING: | ||
136 | val = 1; | ||
137 | edge = 1; | ||
138 | break; | ||
139 | case IRQF_TRIGGER_FALLING: | ||
140 | val = 2; | ||
141 | edge = 1; | ||
142 | break; | ||
143 | case IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING: | ||
144 | val = 3; | ||
145 | edge = 1; | ||
146 | break; | ||
147 | case IRQF_TRIGGER_HIGH: | ||
148 | val = 5; | ||
149 | break; | ||
150 | case IRQF_TRIGGER_LOW: | ||
151 | val = 6; | ||
152 | break; | ||
153 | default: | ||
154 | pr_err("invalid type %d for irq %ld\n", | ||
155 | type, d->hwirq); | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | if (edge) | ||
160 | irq_set_handler(d->hwirq, handle_edge_irq); | ||
161 | |||
162 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | | ||
163 | (val << (i * 4)), LTQ_EIU_EXIN_C); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
131 | static unsigned int ltq_startup_eiu_irq(struct irq_data *d) | 170 | static unsigned int ltq_startup_eiu_irq(struct irq_data *d) |
132 | { | 171 | { |
133 | int i; | 172 | int i; |
134 | 173 | ||
135 | ltq_enable_irq(d); | 174 | ltq_enable_irq(d); |
136 | for (i = 0; i < MAX_EIU; i++) { | 175 | for (i = 0; i < MAX_EIU; i++) { |
137 | if (d->hwirq == ltq_eiu_irq[i]) { | 176 | if (d->hwirq == ltq_eiu_irq[i].start) { |
138 | /* low level - we should really handle set_type */ | 177 | /* by default we are low level triggered */ |
139 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | | 178 | ltq_eiu_settype(d, IRQF_TRIGGER_LOW); |
140 | (0x6 << (i * 4)), LTQ_EIU_EXIN_C); | ||
141 | /* clear all pending */ | 179 | /* clear all pending */ |
142 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i), | 180 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INC) & ~BIT(i), |
143 | LTQ_EIU_EXIN_INIC); | 181 | LTQ_EIU_EXIN_INC); |
144 | /* enable */ | 182 | /* enable */ |
145 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i), | 183 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i), |
146 | LTQ_EIU_EXIN_INEN); | 184 | LTQ_EIU_EXIN_INEN); |
@@ -157,7 +195,7 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d) | |||
157 | 195 | ||
158 | ltq_disable_irq(d); | 196 | ltq_disable_irq(d); |
159 | for (i = 0; i < MAX_EIU; i++) { | 197 | for (i = 0; i < MAX_EIU; i++) { |
160 | if (d->hwirq == ltq_eiu_irq[i]) { | 198 | if (d->hwirq == ltq_eiu_irq[i].start) { |
161 | /* disable */ | 199 | /* disable */ |
162 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i), | 200 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i), |
163 | LTQ_EIU_EXIN_INEN); | 201 | LTQ_EIU_EXIN_INEN); |
@@ -186,6 +224,7 @@ static struct irq_chip ltq_eiu_type = { | |||
186 | .irq_ack = ltq_ack_irq, | 224 | .irq_ack = ltq_ack_irq, |
187 | .irq_mask = ltq_disable_irq, | 225 | .irq_mask = ltq_disable_irq, |
188 | .irq_mask_ack = ltq_mask_and_ack_irq, | 226 | .irq_mask_ack = ltq_mask_and_ack_irq, |
227 | .irq_set_type = ltq_eiu_settype, | ||
189 | }; | 228 | }; |
190 | 229 | ||
191 | static void ltq_hw_irqdispatch(int module) | 230 | static void ltq_hw_irqdispatch(int module) |
@@ -301,7 +340,7 @@ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | |||
301 | return 0; | 340 | return 0; |
302 | 341 | ||
303 | for (i = 0; i < exin_avail; i++) | 342 | for (i = 0; i < exin_avail; i++) |
304 | if (hw == ltq_eiu_irq[i]) | 343 | if (hw == ltq_eiu_irq[i].start) |
305 | chip = <q_eiu_type; | 344 | chip = <q_eiu_type; |
306 | 345 | ||
307 | irq_set_chip_and_handler(hw, chip, handle_level_irq); | 346 | irq_set_chip_and_handler(hw, chip, handle_level_irq); |
@@ -323,7 +362,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
323 | { | 362 | { |
324 | struct device_node *eiu_node; | 363 | struct device_node *eiu_node; |
325 | struct resource res; | 364 | struct resource res; |
326 | int i; | 365 | int i, ret; |
327 | 366 | ||
328 | for (i = 0; i < MAX_IM; i++) { | 367 | for (i = 0; i < MAX_IM; i++) { |
329 | if (of_address_to_resource(node, i, &res)) | 368 | if (of_address_to_resource(node, i, &res)) |
@@ -340,17 +379,19 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
340 | } | 379 | } |
341 | 380 | ||
342 | /* the external interrupts are optional and xway only */ | 381 | /* the external interrupts are optional and xway only */ |
343 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu"); | 382 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); |
344 | if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { | 383 | if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { |
345 | /* find out how many external irq sources we have */ | 384 | /* find out how many external irq sources we have */ |
346 | const __be32 *count = of_get_property(node, | 385 | exin_avail = of_irq_count(eiu_node); |
347 | "lantiq,count", NULL); | ||
348 | 386 | ||
349 | if (count) | ||
350 | exin_avail = *count; | ||
351 | if (exin_avail > MAX_EIU) | 387 | if (exin_avail > MAX_EIU) |
352 | exin_avail = MAX_EIU; | 388 | exin_avail = MAX_EIU; |
353 | 389 | ||
390 | ret = of_irq_to_resource_table(eiu_node, | ||
391 | ltq_eiu_irq, exin_avail); | ||
392 | if (ret != exin_avail) | ||
393 | panic("failed to load external irq resources\n"); | ||
394 | |||
354 | if (request_mem_region(res.start, resource_size(&res), | 395 | if (request_mem_region(res.start, resource_size(&res), |
355 | res.name) < 0) | 396 | res.name) < 0) |
356 | pr_err("Failed to request eiu memory"); | 397 | pr_err("Failed to request eiu memory"); |
diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c index 9aa17f79a742..1ab576dc9bd1 100644 --- a/arch/mips/lantiq/xway/clk.c +++ b/arch/mips/lantiq/xway/clk.c | |||
@@ -53,6 +53,29 @@ unsigned long ltq_danube_cpu_hz(void) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | unsigned long ltq_danube_pp32_hz(void) | ||
57 | { | ||
58 | unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 7) & 3; | ||
59 | unsigned long clk; | ||
60 | |||
61 | switch (clksys) { | ||
62 | case 1: | ||
63 | clk = CLOCK_240M; | ||
64 | break; | ||
65 | case 2: | ||
66 | clk = CLOCK_222M; | ||
67 | break; | ||
68 | case 3: | ||
69 | clk = CLOCK_133M; | ||
70 | break; | ||
71 | default: | ||
72 | clk = CLOCK_266M; | ||
73 | break; | ||
74 | } | ||
75 | |||
76 | return clk; | ||
77 | } | ||
78 | |||
56 | unsigned long ltq_ar9_sys_hz(void) | 79 | unsigned long ltq_ar9_sys_hz(void) |
57 | { | 80 | { |
58 | if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) | 81 | if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) |
@@ -149,3 +172,23 @@ unsigned long ltq_vr9_fpi_hz(void) | |||
149 | 172 | ||
150 | return clk; | 173 | return clk; |
151 | } | 174 | } |
175 | |||
176 | unsigned long ltq_vr9_pp32_hz(void) | ||
177 | { | ||
178 | unsigned int clksys = (ltq_cgu_r32(CGU_SYS) >> 16) & 3; | ||
179 | unsigned long clk; | ||
180 | |||
181 | switch (clksys) { | ||
182 | case 1: | ||
183 | clk = CLOCK_450M; | ||
184 | break; | ||
185 | case 2: | ||
186 | clk = CLOCK_300M; | ||
187 | break; | ||
188 | default: | ||
189 | clk = CLOCK_500M; | ||
190 | break; | ||
191 | } | ||
192 | |||
193 | return clk; | ||
194 | } | ||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 544dbb7fb421..1fa0f175357e 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c | |||
@@ -78,10 +78,19 @@ static struct ltq_xrx200_gphy_reset { | |||
78 | /* reset and boot a gphy. these phys only exist on xrx200 SoC */ | 78 | /* reset and boot a gphy. these phys only exist on xrx200 SoC */ |
79 | int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) | 79 | int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) |
80 | { | 80 | { |
81 | struct clk *clk; | ||
82 | |||
81 | if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) { | 83 | if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) { |
82 | dev_err(dev, "this SoC has no GPHY\n"); | 84 | dev_err(dev, "this SoC has no GPHY\n"); |
83 | return -EINVAL; | 85 | return -EINVAL; |
84 | } | 86 | } |
87 | |||
88 | clk = clk_get_sys("1f203000.rcu", "gphy"); | ||
89 | if (IS_ERR(clk)) | ||
90 | return PTR_ERR(clk); | ||
91 | |||
92 | clk_enable(clk); | ||
93 | |||
85 | if (id > 1) { | 94 | if (id > 1) { |
86 | dev_err(dev, "%u is an invalid gphy id\n", id); | 95 | dev_err(dev, "%u is an invalid gphy id\n", id); |
87 | return -EINVAL; | 96 | return -EINVAL; |
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 3925e6609acc..c24924fe087d 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c | |||
@@ -305,7 +305,7 @@ void __init ltq_soc_init(void) | |||
305 | 305 | ||
306 | /* check if all the core register ranges are available */ | 306 | /* check if all the core register ranges are available */ |
307 | if (!np_pmu || !np_cgu || !np_ebu) | 307 | if (!np_pmu || !np_cgu || !np_ebu) |
308 | panic("Failed to load core nodess from devicetree"); | 308 | panic("Failed to load core nodes from devicetree"); |
309 | 309 | ||
310 | if (of_address_to_resource(np_pmu, 0, &res_pmu) || | 310 | if (of_address_to_resource(np_pmu, 0, &res_pmu) || |
311 | of_address_to_resource(np_cgu, 0, &res_cgu) || | 311 | of_address_to_resource(np_cgu, 0, &res_cgu) || |
@@ -356,14 +356,16 @@ void __init ltq_soc_init(void) | |||
356 | 356 | ||
357 | if (of_machine_is_compatible("lantiq,ase")) { | 357 | if (of_machine_is_compatible("lantiq,ase")) { |
358 | if (ltq_cgu_r32(CGU_SYS) & (1 << 5)) | 358 | if (ltq_cgu_r32(CGU_SYS) & (1 << 5)) |
359 | clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M); | 359 | clkdev_add_static(CLOCK_266M, CLOCK_133M, |
360 | CLOCK_133M, CLOCK_266M); | ||
360 | else | 361 | else |
361 | clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M); | 362 | clkdev_add_static(CLOCK_133M, CLOCK_133M, |
363 | CLOCK_133M, CLOCK_133M); | ||
362 | clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY), | 364 | clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY), |
363 | clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY); | 365 | clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY); |
364 | } else if (of_machine_is_compatible("lantiq,vr9")) { | 366 | } else if (of_machine_is_compatible("lantiq,vr9")) { |
365 | clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), | 367 | clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), |
366 | ltq_vr9_fpi_hz()); | 368 | ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz()); |
367 | clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY); | 369 | clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY); |
368 | clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK); | 370 | clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK); |
369 | clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI); | 371 | clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI); |
@@ -374,12 +376,13 @@ void __init ltq_soc_init(void) | |||
374 | PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | | 376 | PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | |
375 | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | | 377 | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | |
376 | PMU_PPE_QSB | PMU_PPE_TOP); | 378 | PMU_PPE_QSB | PMU_PPE_TOP); |
379 | clkdev_add_pmu("1f203000.rcu", "gphy", 0, PMU_GPHY); | ||
377 | } else if (of_machine_is_compatible("lantiq,ar9")) { | 380 | } else if (of_machine_is_compatible("lantiq,ar9")) { |
378 | clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), | 381 | clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), |
379 | ltq_ar9_fpi_hz()); | 382 | ltq_ar9_fpi_hz(), CLOCK_250M); |
380 | clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH); | 383 | clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH); |
381 | } else { | 384 | } else { |
382 | clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), | 385 | clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), |
383 | ltq_danube_fpi_hz()); | 386 | ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); |
384 | } | 387 | } |
385 | } | 388 | } |
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c index 2dd9c5648d79..2a47af5a55c3 100644 --- a/arch/mips/loongson1/common/prom.c +++ b/arch/mips/loongson1/common/prom.c | |||
@@ -73,7 +73,7 @@ void __init prom_free_prom_memory(void) | |||
73 | 73 | ||
74 | #define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) | 74 | #define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) |
75 | 75 | ||
76 | void __init prom_putchar(char c) | 76 | void prom_putchar(char c) |
77 | { | 77 | { |
78 | int timeout; | 78 | int timeout; |
79 | 79 | ||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index d45f8e28b470..ecca559b8d7b 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -1057,6 +1057,7 @@ static void __cpuinit probe_pcache(void) | |||
1057 | break; | 1057 | break; |
1058 | 1058 | ||
1059 | case CPU_M14KC: | 1059 | case CPU_M14KC: |
1060 | case CPU_M14KEC: | ||
1060 | case CPU_24K: | 1061 | case CPU_24K: |
1061 | case CPU_34K: | 1062 | case CPU_34K: |
1062 | case CPU_74K: | 1063 | case CPU_74K: |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 36b9bd89c799..820e6612d744 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -581,6 +581,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, | |||
581 | case CPU_4KC: | 581 | case CPU_4KC: |
582 | case CPU_4KEC: | 582 | case CPU_4KEC: |
583 | case CPU_M14KC: | 583 | case CPU_M14KC: |
584 | case CPU_M14KEC: | ||
584 | case CPU_SB1: | 585 | case CPU_SB1: |
585 | case CPU_SB1A: | 586 | case CPU_SB1A: |
586 | case CPU_4KSC: | 587 | case CPU_4KSC: |
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 8607b0dd29f6..a144b89cf9ba 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
@@ -17,7 +17,6 @@ | |||
17 | * | 17 | * |
18 | * Setting up the clock on the MIPS boards. | 18 | * Setting up the clock on the MIPS boards. |
19 | */ | 19 | */ |
20 | |||
21 | #include <linux/types.h> | 20 | #include <linux/types.h> |
22 | #include <linux/i8253.h> | 21 | #include <linux/i8253.h> |
23 | #include <linux/init.h> | 22 | #include <linux/init.h> |
@@ -25,7 +24,6 @@ | |||
25 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
26 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
27 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
28 | #include <linux/time.h> | ||
29 | #include <linux/timex.h> | 27 | #include <linux/timex.h> |
30 | #include <linux/mc146818rtc.h> | 28 | #include <linux/mc146818rtc.h> |
31 | 29 | ||
@@ -34,11 +32,11 @@ | |||
34 | #include <asm/hardirq.h> | 32 | #include <asm/hardirq.h> |
35 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
36 | #include <asm/div64.h> | 34 | #include <asm/div64.h> |
37 | #include <asm/cpu.h> | ||
38 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
39 | #include <asm/time.h> | 36 | #include <asm/time.h> |
40 | #include <asm/mc146818-time.h> | 37 | #include <asm/mc146818-time.h> |
41 | #include <asm/msc01_ic.h> | 38 | #include <asm/msc01_ic.h> |
39 | #include <asm/gic.h> | ||
42 | 40 | ||
43 | #include <asm/mips-boards/generic.h> | 41 | #include <asm/mips-boards/generic.h> |
44 | #include <asm/mips-boards/prom.h> | 42 | #include <asm/mips-boards/prom.h> |
@@ -46,6 +44,7 @@ | |||
46 | #include <asm/mips-boards/maltaint.h> | 44 | #include <asm/mips-boards/maltaint.h> |
47 | 45 | ||
48 | unsigned long cpu_khz; | 46 | unsigned long cpu_khz; |
47 | int gic_frequency; | ||
49 | 48 | ||
50 | static int mips_cpu_timer_irq; | 49 | static int mips_cpu_timer_irq; |
51 | static int mips_cpu_perf_irq; | 50 | static int mips_cpu_perf_irq; |
@@ -61,44 +60,50 @@ static void mips_perf_dispatch(void) | |||
61 | do_IRQ(mips_cpu_perf_irq); | 60 | do_IRQ(mips_cpu_perf_irq); |
62 | } | 61 | } |
63 | 62 | ||
63 | static unsigned int freqround(unsigned int freq, unsigned int amount) | ||
64 | { | ||
65 | freq += amount; | ||
66 | freq -= freq % (amount*2); | ||
67 | return freq; | ||
68 | } | ||
69 | |||
64 | /* | 70 | /* |
65 | * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect | 71 | * Estimate CPU and GIC frequencies. |
66 | */ | 72 | */ |
67 | static unsigned int __init estimate_cpu_frequency(void) | 73 | static void __init estimate_frequencies(void) |
68 | { | 74 | { |
69 | unsigned int prid = read_c0_prid() & 0xffff00; | ||
70 | unsigned int count; | ||
71 | |||
72 | unsigned long flags; | 75 | unsigned long flags; |
73 | unsigned int start; | 76 | unsigned int count, start; |
77 | unsigned int giccount = 0, gicstart = 0; | ||
74 | 78 | ||
75 | local_irq_save(flags); | 79 | local_irq_save(flags); |
76 | 80 | ||
77 | /* Start counter exactly on falling edge of update flag */ | 81 | /* Start counter exactly on falling edge of update flag. */ |
78 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 82 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
79 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 83 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
80 | 84 | ||
81 | /* Start r4k counter. */ | 85 | /* Initialize counters. */ |
82 | start = read_c0_count(); | 86 | start = read_c0_count(); |
87 | if (gic_present) | ||
88 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); | ||
83 | 89 | ||
84 | /* Read counter exactly on falling edge of update flag */ | 90 | /* Read counter exactly on falling edge of update flag. */ |
85 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 91 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
86 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 92 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
87 | 93 | ||
88 | count = read_c0_count() - start; | 94 | count = read_c0_count(); |
95 | if (gic_present) | ||
96 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); | ||
89 | 97 | ||
90 | /* restore interrupts */ | ||
91 | local_irq_restore(flags); | 98 | local_irq_restore(flags); |
92 | 99 | ||
93 | mips_hpt_frequency = count; | 100 | count -= start; |
94 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | 101 | if (gic_present) |
95 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | 102 | giccount -= gicstart; |
96 | count *= 2; | ||
97 | |||
98 | count += 5000; /* round */ | ||
99 | count -= count%10000; | ||
100 | 103 | ||
101 | return count; | 104 | mips_hpt_frequency = count; |
105 | if (gic_present) | ||
106 | gic_frequency = giccount; | ||
102 | } | 107 | } |
103 | 108 | ||
104 | void read_persistent_clock(struct timespec *ts) | 109 | void read_persistent_clock(struct timespec *ts) |
@@ -144,22 +149,34 @@ unsigned int __cpuinit get_c0_compare_int(void) | |||
144 | 149 | ||
145 | void __init plat_time_init(void) | 150 | void __init plat_time_init(void) |
146 | { | 151 | { |
147 | unsigned int est_freq; | 152 | unsigned int prid = read_c0_prid() & 0xffff00; |
148 | 153 | unsigned int freq; | |
149 | /* Set Data mode - binary. */ | ||
150 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
151 | |||
152 | est_freq = estimate_cpu_frequency(); | ||
153 | 154 | ||
154 | printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, | 155 | estimate_frequencies(); |
155 | (est_freq%1000000)*100/1000000); | ||
156 | 156 | ||
157 | cpu_khz = est_freq / 1000; | 157 | freq = mips_hpt_frequency; |
158 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | ||
159 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
160 | freq *= 2; | ||
161 | freq = freqround(freq, 5000); | ||
162 | pr_debug("CPU frequency %d.%02d MHz\n", freq/1000000, | ||
163 | (freq%1000000)*100/1000000); | ||
164 | cpu_khz = freq / 1000; | ||
165 | |||
166 | if (gic_present) { | ||
167 | freq = freqround(gic_frequency, 5000); | ||
168 | pr_debug("GIC frequency %d.%02d MHz\n", freq/1000000, | ||
169 | (freq%1000000)*100/1000000); | ||
170 | gic_clocksource_init(gic_frequency); | ||
171 | } else | ||
172 | init_r4k_clocksource(); | ||
158 | 173 | ||
159 | mips_scroll_message(); | 174 | #ifdef CONFIG_I8253 |
160 | #ifdef CONFIG_I8253 /* Only Malta has a PIT */ | 175 | /* Only Malta has a PIT. */ |
161 | setup_pit_timer(); | 176 | setup_pit_timer(); |
162 | #endif | 177 | #endif |
163 | 178 | ||
179 | mips_scroll_message(); | ||
180 | |||
164 | plat_perf_setup(); | 181 | plat_perf_setup(); |
165 | } | 182 | } |
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c index 780832e391ff..9f84c60bf535 100644 --- a/arch/mips/netlogic/common/irq.c +++ b/arch/mips/netlogic/common/irq.c | |||
@@ -105,21 +105,23 @@ static void xlp_pic_disable(struct irq_data *d) | |||
105 | static void xlp_pic_mask_ack(struct irq_data *d) | 105 | static void xlp_pic_mask_ack(struct irq_data *d) |
106 | { | 106 | { |
107 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); | 107 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); |
108 | uint64_t mask = 1ull << pd->picirq; | ||
109 | 108 | ||
110 | write_c0_eirr(mask); /* ack by writing EIRR */ | 109 | clear_c0_eimr(pd->picirq); |
110 | ack_c0_eirr(pd->picirq); | ||
111 | } | 111 | } |
112 | 112 | ||
113 | static void xlp_pic_unmask(struct irq_data *d) | 113 | static void xlp_pic_unmask(struct irq_data *d) |
114 | { | 114 | { |
115 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); | 115 | struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); |
116 | 116 | ||
117 | if (!pd) | 117 | BUG_ON(!pd); |
118 | return; | ||
119 | 118 | ||
120 | if (pd->extra_ack) | 119 | if (pd->extra_ack) |
121 | pd->extra_ack(d); | 120 | pd->extra_ack(d); |
122 | 121 | ||
122 | /* re-enable the intr on this cpu */ | ||
123 | set_c0_eimr(pd->picirq); | ||
124 | |||
123 | /* Ack is a single write, no need to lock */ | 125 | /* Ack is a single write, no need to lock */ |
124 | nlm_pic_ack(pd->node->picbase, pd->irt); | 126 | nlm_pic_ack(pd->node->picbase, pd->irt); |
125 | } | 127 | } |
@@ -134,32 +136,17 @@ static struct irq_chip xlp_pic = { | |||
134 | 136 | ||
135 | static void cpuintr_disable(struct irq_data *d) | 137 | static void cpuintr_disable(struct irq_data *d) |
136 | { | 138 | { |
137 | uint64_t eimr; | 139 | clear_c0_eimr(d->irq); |
138 | uint64_t mask = 1ull << d->irq; | ||
139 | |||
140 | eimr = read_c0_eimr(); | ||
141 | write_c0_eimr(eimr & ~mask); | ||
142 | } | 140 | } |
143 | 141 | ||
144 | static void cpuintr_enable(struct irq_data *d) | 142 | static void cpuintr_enable(struct irq_data *d) |
145 | { | 143 | { |
146 | uint64_t eimr; | 144 | set_c0_eimr(d->irq); |
147 | uint64_t mask = 1ull << d->irq; | ||
148 | |||
149 | eimr = read_c0_eimr(); | ||
150 | write_c0_eimr(eimr | mask); | ||
151 | } | 145 | } |
152 | 146 | ||
153 | static void cpuintr_ack(struct irq_data *d) | 147 | static void cpuintr_ack(struct irq_data *d) |
154 | { | 148 | { |
155 | uint64_t mask = 1ull << d->irq; | 149 | ack_c0_eirr(d->irq); |
156 | |||
157 | write_c0_eirr(mask); | ||
158 | } | ||
159 | |||
160 | static void cpuintr_nop(struct irq_data *d) | ||
161 | { | ||
162 | WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq); | ||
163 | } | 150 | } |
164 | 151 | ||
165 | /* | 152 | /* |
@@ -170,9 +157,9 @@ struct irq_chip nlm_cpu_intr = { | |||
170 | .name = "XLP-CPU-INTR", | 157 | .name = "XLP-CPU-INTR", |
171 | .irq_enable = cpuintr_enable, | 158 | .irq_enable = cpuintr_enable, |
172 | .irq_disable = cpuintr_disable, | 159 | .irq_disable = cpuintr_disable, |
173 | .irq_mask = cpuintr_nop, | 160 | .irq_mask = cpuintr_disable, |
174 | .irq_ack = cpuintr_nop, | 161 | .irq_ack = cpuintr_ack, |
175 | .irq_eoi = cpuintr_ack, | 162 | .irq_eoi = cpuintr_enable, |
176 | }; | 163 | }; |
177 | 164 | ||
178 | static void __init nlm_init_percpu_irqs(void) | 165 | static void __init nlm_init_percpu_irqs(void) |
@@ -230,7 +217,7 @@ static void nlm_init_node_irqs(int node) | |||
230 | nlm_setup_pic_irq(node, i, i, irt); | 217 | nlm_setup_pic_irq(node, i, i, irt); |
231 | /* set interrupts to first cpu in node */ | 218 | /* set interrupts to first cpu in node */ |
232 | nlm_pic_init_irt(nodep->picbase, irt, i, | 219 | nlm_pic_init_irt(nodep->picbase, irt, i, |
233 | node * NLM_CPUS_PER_NODE); | 220 | node * NLM_CPUS_PER_NODE, 0); |
234 | irqmask |= (1ull << i); | 221 | irqmask |= (1ull << i); |
235 | } | 222 | } |
236 | nodep->irqmask = irqmask; | 223 | nodep->irqmask = irqmask; |
@@ -265,7 +252,7 @@ asmlinkage void plat_irq_dispatch(void) | |||
265 | int i, node; | 252 | int i, node; |
266 | 253 | ||
267 | node = nlm_nodeid(); | 254 | node = nlm_nodeid(); |
268 | eirr = read_c0_eirr() & read_c0_eimr(); | 255 | eirr = read_c0_eirr_and_eimr(); |
269 | 256 | ||
270 | i = __ilog2_u64(eirr); | 257 | i = __ilog2_u64(eirr); |
271 | if (i == -1) | 258 | if (i == -1) |
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index a080d9ee3cd7..2bb95dcfe20a 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c | |||
@@ -84,15 +84,19 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
84 | /* IRQ_IPI_SMP_FUNCTION Handler */ | 84 | /* IRQ_IPI_SMP_FUNCTION Handler */ |
85 | void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) | 85 | void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) |
86 | { | 86 | { |
87 | write_c0_eirr(1ull << irq); | 87 | clear_c0_eimr(irq); |
88 | ack_c0_eirr(irq); | ||
88 | smp_call_function_interrupt(); | 89 | smp_call_function_interrupt(); |
90 | set_c0_eimr(irq); | ||
89 | } | 91 | } |
90 | 92 | ||
91 | /* IRQ_IPI_SMP_RESCHEDULE handler */ | 93 | /* IRQ_IPI_SMP_RESCHEDULE handler */ |
92 | void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) | 94 | void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) |
93 | { | 95 | { |
94 | write_c0_eirr(1ull << irq); | 96 | clear_c0_eimr(irq); |
97 | ack_c0_eirr(irq); | ||
95 | scheduler_ipi(); | 98 | scheduler_ipi(); |
99 | set_c0_eimr(irq); | ||
96 | } | 100 | } |
97 | 101 | ||
98 | /* | 102 | /* |
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S index 280ff5855ef7..026517488584 100644 --- a/arch/mips/netlogic/common/smpboot.S +++ b/arch/mips/netlogic/common/smpboot.S | |||
@@ -69,6 +69,12 @@ | |||
69 | #endif | 69 | #endif |
70 | mtcr t1, t0 | 70 | mtcr t1, t0 |
71 | 71 | ||
72 | li t0, ICU_DEFEATURE | ||
73 | mfcr t1, t0 | ||
74 | ori t1, 0x1000 /* Enable Icache partitioning */ | ||
75 | mtcr t1, t0 | ||
76 | |||
77 | |||
72 | #ifdef XLP_AX_WORKAROUND | 78 | #ifdef XLP_AX_WORKAROUND |
73 | li t0, SCHED_DEFEATURE | 79 | li t0, SCHED_DEFEATURE |
74 | lui t1, 0x0100 /* Disable BRU accepting ALU ops */ | 80 | lui t1, 0x0100 /* Disable BRU accepting ALU ops */ |
diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c index bd3e498157ff..5c56555380bb 100644 --- a/arch/mips/netlogic/common/time.c +++ b/arch/mips/netlogic/common/time.c | |||
@@ -35,17 +35,73 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | 36 | ||
37 | #include <asm/time.h> | 37 | #include <asm/time.h> |
38 | #include <asm/cpu-features.h> | ||
39 | |||
38 | #include <asm/netlogic/interrupt.h> | 40 | #include <asm/netlogic/interrupt.h> |
39 | #include <asm/netlogic/common.h> | 41 | #include <asm/netlogic/common.h> |
42 | #include <asm/netlogic/haldefs.h> | ||
43 | #include <asm/netlogic/common.h> | ||
44 | |||
45 | #if defined(CONFIG_CPU_XLP) | ||
46 | #include <asm/netlogic/xlp-hal/iomap.h> | ||
47 | #include <asm/netlogic/xlp-hal/xlp.h> | ||
48 | #include <asm/netlogic/xlp-hal/pic.h> | ||
49 | #elif defined(CONFIG_CPU_XLR) | ||
50 | #include <asm/netlogic/xlr/iomap.h> | ||
51 | #include <asm/netlogic/xlr/pic.h> | ||
52 | #include <asm/netlogic/xlr/xlr.h> | ||
53 | #else | ||
54 | #error "Unknown CPU" | ||
55 | #endif | ||
40 | 56 | ||
41 | unsigned int __cpuinit get_c0_compare_int(void) | 57 | unsigned int __cpuinit get_c0_compare_int(void) |
42 | { | 58 | { |
43 | return IRQ_TIMER; | 59 | return IRQ_TIMER; |
44 | } | 60 | } |
45 | 61 | ||
62 | static cycle_t nlm_get_pic_timer(struct clocksource *cs) | ||
63 | { | ||
64 | uint64_t picbase = nlm_get_node(0)->picbase; | ||
65 | |||
66 | return ~nlm_pic_read_timer(picbase, PIC_CLOCK_TIMER); | ||
67 | } | ||
68 | |||
69 | static cycle_t nlm_get_pic_timer32(struct clocksource *cs) | ||
70 | { | ||
71 | uint64_t picbase = nlm_get_node(0)->picbase; | ||
72 | |||
73 | return ~nlm_pic_read_timer32(picbase, PIC_CLOCK_TIMER); | ||
74 | } | ||
75 | |||
76 | static struct clocksource csrc_pic = { | ||
77 | .name = "PIC", | ||
78 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
79 | }; | ||
80 | |||
81 | static void nlm_init_pic_timer(void) | ||
82 | { | ||
83 | uint64_t picbase = nlm_get_node(0)->picbase; | ||
84 | |||
85 | nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0); | ||
86 | if (current_cpu_data.cputype == CPU_XLR) { | ||
87 | csrc_pic.mask = CLOCKSOURCE_MASK(32); | ||
88 | csrc_pic.read = nlm_get_pic_timer32; | ||
89 | } else { | ||
90 | csrc_pic.mask = CLOCKSOURCE_MASK(64); | ||
91 | csrc_pic.read = nlm_get_pic_timer; | ||
92 | } | ||
93 | csrc_pic.rating = 1000; | ||
94 | clocksource_register_hz(&csrc_pic, PIC_CLK_HZ); | ||
95 | } | ||
96 | |||
46 | void __init plat_time_init(void) | 97 | void __init plat_time_init(void) |
47 | { | 98 | { |
99 | nlm_init_pic_timer(); | ||
48 | mips_hpt_frequency = nlm_get_cpu_frequency(); | 100 | mips_hpt_frequency = nlm_get_cpu_frequency(); |
101 | if (current_cpu_type() == CPU_XLR) | ||
102 | preset_lpj = mips_hpt_frequency / (3 * HZ); | ||
103 | else | ||
104 | preset_lpj = mips_hpt_frequency / (2 * HZ); | ||
49 | pr_info("MIPS counter frequency [%ld]\n", | 105 | pr_info("MIPS counter frequency [%ld]\n", |
50 | (unsigned long)mips_hpt_frequency); | 106 | (unsigned long)mips_hpt_frequency); |
51 | } | 107 | } |
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index cb9010642ac3..abb3e08cc052 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <asm/netlogic/xlp-hal/xlp.h> | 51 | #include <asm/netlogic/xlp-hal/xlp.h> |
52 | #include <asm/netlogic/xlp-hal/sys.h> | 52 | #include <asm/netlogic/xlp-hal/sys.h> |
53 | 53 | ||
54 | static int xlp_wakeup_core(uint64_t sysbase, int core) | 54 | static int xlp_wakeup_core(uint64_t sysbase, int node, int core) |
55 | { | 55 | { |
56 | uint32_t coremask, value; | 56 | uint32_t coremask, value; |
57 | int count; | 57 | int count; |
@@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) | |||
82 | struct nlm_soc_info *nodep; | 82 | struct nlm_soc_info *nodep; |
83 | uint64_t syspcibase; | 83 | uint64_t syspcibase; |
84 | uint32_t syscoremask; | 84 | uint32_t syscoremask; |
85 | int core, n, cpu; | 85 | int core, n, cpu, count, val; |
86 | 86 | ||
87 | for (n = 0; n < NLM_NR_NODES; n++) { | 87 | for (n = 0; n < NLM_NR_NODES; n++) { |
88 | syspcibase = nlm_get_sys_pcibase(n); | 88 | syspcibase = nlm_get_sys_pcibase(n); |
89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) | 89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) |
90 | break; | 90 | break; |
91 | 91 | ||
92 | /* read cores in reset from SYS and account for boot cpu */ | 92 | /* read cores in reset from SYS */ |
93 | nlm_node_init(n); | 93 | if (n != 0) |
94 | nlm_node_init(n); | ||
94 | nodep = nlm_get_node(n); | 95 | nodep = nlm_get_node(n); |
95 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); | 96 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); |
96 | if (n == 0) | 97 | /* The boot cpu */ |
98 | if (n == 0) { | ||
97 | syscoremask |= 1; | 99 | syscoremask |= 1; |
100 | nodep->coremask = 1; | ||
101 | } | ||
98 | 102 | ||
99 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { | 103 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { |
104 | /* we will be on node 0 core 0 */ | ||
105 | if (n == 0 && core == 0) | ||
106 | continue; | ||
107 | |||
100 | /* see if the core exists */ | 108 | /* see if the core exists */ |
101 | if ((syscoremask & (1 << core)) == 0) | 109 | if ((syscoremask & (1 << core)) == 0) |
102 | continue; | 110 | continue; |
103 | 111 | ||
104 | /* see if at least the first thread is enabled */ | 112 | /* see if at least the first hw thread is enabled */ |
105 | cpu = (n * NLM_CORES_PER_NODE + core) | 113 | cpu = (n * NLM_CORES_PER_NODE + core) |
106 | * NLM_THREADS_PER_CORE; | 114 | * NLM_THREADS_PER_CORE; |
107 | if (!cpumask_test_cpu(cpu, wakeup_mask)) | 115 | if (!cpumask_test_cpu(cpu, wakeup_mask)) |
108 | continue; | 116 | continue; |
109 | 117 | ||
110 | /* wake up the core */ | 118 | /* wake up the core */ |
111 | if (xlp_wakeup_core(nodep->sysbase, core)) | 119 | if (!xlp_wakeup_core(nodep->sysbase, n, core)) |
112 | nodep->coremask |= 1u << core; | 120 | continue; |
113 | else | 121 | |
114 | pr_err("Failed to enable core %d\n", core); | 122 | /* core is up */ |
123 | nodep->coremask |= 1u << core; | ||
124 | |||
125 | /* spin until the first hw thread sets its ready */ | ||
126 | count = 0x20000000; | ||
127 | do { | ||
128 | val = *(volatile int *)&nlm_cpu_ready[cpu]; | ||
129 | } while (val == 0 && --count > 0); | ||
115 | } | 130 | } |
116 | } | 131 | } |
117 | } | 132 | } |
diff --git a/arch/mips/netlogic/xlr/fmn-config.c b/arch/mips/netlogic/xlr/fmn-config.c index f5bddf95bf24..ed3bf0e3f309 100644 --- a/arch/mips/netlogic/xlr/fmn-config.c +++ b/arch/mips/netlogic/xlr/fmn-config.c | |||
@@ -216,6 +216,8 @@ void xlr_board_info_setup(void) | |||
216 | case PRID_IMP_NETLOGIC_XLS404B: | 216 | case PRID_IMP_NETLOGIC_XLS404B: |
217 | case PRID_IMP_NETLOGIC_XLS408B: | 217 | case PRID_IMP_NETLOGIC_XLS408B: |
218 | case PRID_IMP_NETLOGIC_XLS416B: | 218 | case PRID_IMP_NETLOGIC_XLS416B: |
219 | case PRID_IMP_NETLOGIC_XLS608B: | ||
220 | case PRID_IMP_NETLOGIC_XLS616B: | ||
219 | setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, | 221 | setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, |
220 | FMN_STNID_GMAC0_TX3, 8, 8, 32); | 222 | FMN_STNID_GMAC0_TX3, 8, 8, 32); |
221 | setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, | 223 | setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, |
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c index e287277d32b0..7b96a91f4773 100644 --- a/arch/mips/netlogic/xlr/platform.c +++ b/arch/mips/netlogic/xlr/platform.c | |||
@@ -64,7 +64,7 @@ void nlm_xlr_uart_out(struct uart_port *p, int offset, int value) | |||
64 | .iotype = UPIO_MEM32, \ | 64 | .iotype = UPIO_MEM32, \ |
65 | .flags = (UPF_SKIP_TEST | \ | 65 | .flags = (UPF_SKIP_TEST | \ |
66 | UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\ | 66 | UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\ |
67 | .uartclk = PIC_CLKS_PER_SEC, \ | 67 | .uartclk = PIC_CLK_HZ, \ |
68 | .type = PORT_16550A, \ | 68 | .type = PORT_16550A, \ |
69 | .serial_in = nlm_xlr_uart_in, \ | 69 | .serial_in = nlm_xlr_uart_in, \ |
70 | .serial_out = nlm_xlr_uart_out, \ | 70 | .serial_out = nlm_xlr_uart_out, \ |
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index f088efb8fe4c..e3e094100e3e 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c | |||
@@ -70,7 +70,7 @@ static void __init nlm_early_serial_setup(void) | |||
70 | s.iotype = UPIO_MEM32; | 70 | s.iotype = UPIO_MEM32; |
71 | s.regshift = 2; | 71 | s.regshift = 2; |
72 | s.irq = PIC_UART_0_IRQ; | 72 | s.irq = PIC_UART_0_IRQ; |
73 | s.uartclk = PIC_CLKS_PER_SEC; | 73 | s.uartclk = PIC_CLK_HZ; |
74 | s.serial_in = nlm_xlr_uart_in; | 74 | s.serial_in = nlm_xlr_uart_in; |
75 | s.serial_out = nlm_xlr_uart_out; | 75 | s.serial_out = nlm_xlr_uart_out; |
76 | s.mapbase = uart_base; | 76 | s.mapbase = uart_base; |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 56f2cf221c7d..af763e838fdd 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -78,6 +78,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
78 | switch (current_cpu_type()) { | 78 | switch (current_cpu_type()) { |
79 | case CPU_5KC: | 79 | case CPU_5KC: |
80 | case CPU_M14KC: | 80 | case CPU_M14KC: |
81 | case CPU_M14KEC: | ||
81 | case CPU_20KC: | 82 | case CPU_20KC: |
82 | case CPU_24K: | 83 | case CPU_24K: |
83 | case CPU_25KF: | 84 | case CPU_25KF: |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 1cfab95755b9..1fd361462c03 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -351,6 +351,10 @@ static int __init mipsxx_init(void) | |||
351 | op_model_mipsxx_ops.cpu_type = "mips/M14Kc"; | 351 | op_model_mipsxx_ops.cpu_type = "mips/M14Kc"; |
352 | break; | 352 | break; |
353 | 353 | ||
354 | case CPU_M14KEC: | ||
355 | op_model_mipsxx_ops.cpu_type = "mips/M14KEc"; | ||
356 | break; | ||
357 | |||
354 | case CPU_20KC: | 358 | case CPU_20KC: |
355 | op_model_mipsxx_ops.cpu_type = "mips/20K"; | 359 | op_model_mipsxx_ops.cpu_type = "mips/20K"; |
356 | break; | 360 | break; |
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 6eaa4f2d0e38..412ec025cf55 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c | |||
@@ -18,26 +18,11 @@ | |||
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/pci_regs.h> | 19 | #include <linux/pci_regs.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
21 | 23 | ||
22 | #include <asm/mach-ath79/ar71xx_regs.h> | 24 | #include <asm/mach-ath79/ar71xx_regs.h> |
23 | #include <asm/mach-ath79/ath79.h> | 25 | #include <asm/mach-ath79/ath79.h> |
24 | #include <asm/mach-ath79/pci.h> | ||
25 | |||
26 | #define AR71XX_PCI_MEM_BASE 0x10000000 | ||
27 | #define AR71XX_PCI_MEM_SIZE 0x07000000 | ||
28 | |||
29 | #define AR71XX_PCI_WIN0_OFFS 0x10000000 | ||
30 | #define AR71XX_PCI_WIN1_OFFS 0x11000000 | ||
31 | #define AR71XX_PCI_WIN2_OFFS 0x12000000 | ||
32 | #define AR71XX_PCI_WIN3_OFFS 0x13000000 | ||
33 | #define AR71XX_PCI_WIN4_OFFS 0x14000000 | ||
34 | #define AR71XX_PCI_WIN5_OFFS 0x15000000 | ||
35 | #define AR71XX_PCI_WIN6_OFFS 0x16000000 | ||
36 | #define AR71XX_PCI_WIN7_OFFS 0x07000000 | ||
37 | |||
38 | #define AR71XX_PCI_CFG_BASE \ | ||
39 | (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) | ||
40 | #define AR71XX_PCI_CFG_SIZE 0x100 | ||
41 | 26 | ||
42 | #define AR71XX_PCI_REG_CRP_AD_CBE 0x00 | 27 | #define AR71XX_PCI_REG_CRP_AD_CBE 0x00 |
43 | #define AR71XX_PCI_REG_CRP_WRDATA 0x04 | 28 | #define AR71XX_PCI_REG_CRP_WRDATA 0x04 |
@@ -63,8 +48,15 @@ | |||
63 | 48 | ||
64 | #define AR71XX_PCI_IRQ_COUNT 5 | 49 | #define AR71XX_PCI_IRQ_COUNT 5 |
65 | 50 | ||
66 | static DEFINE_SPINLOCK(ar71xx_pci_lock); | 51 | struct ar71xx_pci_controller { |
67 | static void __iomem *ar71xx_pcicfg_base; | 52 | void __iomem *cfg_base; |
53 | spinlock_t lock; | ||
54 | int irq; | ||
55 | int irq_base; | ||
56 | struct pci_controller pci_ctrl; | ||
57 | struct resource io_res; | ||
58 | struct resource mem_res; | ||
59 | }; | ||
68 | 60 | ||
69 | /* Byte lane enable bits */ | 61 | /* Byte lane enable bits */ |
70 | static const u8 ar71xx_pci_ble_table[4][4] = { | 62 | static const u8 ar71xx_pci_ble_table[4][4] = { |
@@ -107,9 +99,18 @@ static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, | |||
107 | return ret; | 99 | return ret; |
108 | } | 100 | } |
109 | 101 | ||
110 | static int ar71xx_pci_check_error(int quiet) | 102 | static inline struct ar71xx_pci_controller * |
103 | pci_bus_to_ar71xx_controller(struct pci_bus *bus) | ||
111 | { | 104 | { |
112 | void __iomem *base = ar71xx_pcicfg_base; | 105 | struct pci_controller *hose; |
106 | |||
107 | hose = (struct pci_controller *) bus->sysdata; | ||
108 | return container_of(hose, struct ar71xx_pci_controller, pci_ctrl); | ||
109 | } | ||
110 | |||
111 | static int ar71xx_pci_check_error(struct ar71xx_pci_controller *apc, int quiet) | ||
112 | { | ||
113 | void __iomem *base = apc->cfg_base; | ||
113 | u32 pci_err; | 114 | u32 pci_err; |
114 | u32 ahb_err; | 115 | u32 ahb_err; |
115 | 116 | ||
@@ -144,9 +145,10 @@ static int ar71xx_pci_check_error(int quiet) | |||
144 | return !!(ahb_err | pci_err); | 145 | return !!(ahb_err | pci_err); |
145 | } | 146 | } |
146 | 147 | ||
147 | static inline void ar71xx_pci_local_write(int where, int size, u32 value) | 148 | static inline void ar71xx_pci_local_write(struct ar71xx_pci_controller *apc, |
149 | int where, int size, u32 value) | ||
148 | { | 150 | { |
149 | void __iomem *base = ar71xx_pcicfg_base; | 151 | void __iomem *base = apc->cfg_base; |
150 | u32 ad_cbe; | 152 | u32 ad_cbe; |
151 | 153 | ||
152 | value = value << (8 * (where & 3)); | 154 | value = value << (8 * (where & 3)); |
@@ -162,7 +164,8 @@ static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, | |||
162 | unsigned int devfn, | 164 | unsigned int devfn, |
163 | int where, int size, u32 cmd) | 165 | int where, int size, u32 cmd) |
164 | { | 166 | { |
165 | void __iomem *base = ar71xx_pcicfg_base; | 167 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
168 | void __iomem *base = apc->cfg_base; | ||
166 | u32 addr; | 169 | u32 addr; |
167 | 170 | ||
168 | addr = ar71xx_pci_bus_addr(bus, devfn, where); | 171 | addr = ar71xx_pci_bus_addr(bus, devfn, where); |
@@ -171,13 +174,14 @@ static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, | |||
171 | __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), | 174 | __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), |
172 | base + AR71XX_PCI_REG_CFG_CBE); | 175 | base + AR71XX_PCI_REG_CFG_CBE); |
173 | 176 | ||
174 | return ar71xx_pci_check_error(1); | 177 | return ar71xx_pci_check_error(apc, 1); |
175 | } | 178 | } |
176 | 179 | ||
177 | static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 180 | static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, |
178 | int where, int size, u32 *value) | 181 | int where, int size, u32 *value) |
179 | { | 182 | { |
180 | void __iomem *base = ar71xx_pcicfg_base; | 183 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
184 | void __iomem *base = apc->cfg_base; | ||
181 | unsigned long flags; | 185 | unsigned long flags; |
182 | u32 data; | 186 | u32 data; |
183 | int err; | 187 | int err; |
@@ -186,7 +190,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
186 | ret = PCIBIOS_SUCCESSFUL; | 190 | ret = PCIBIOS_SUCCESSFUL; |
187 | data = ~0; | 191 | data = ~0; |
188 | 192 | ||
189 | spin_lock_irqsave(&ar71xx_pci_lock, flags); | 193 | spin_lock_irqsave(&apc->lock, flags); |
190 | 194 | ||
191 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | 195 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, |
192 | AR71XX_PCI_CFG_CMD_READ); | 196 | AR71XX_PCI_CFG_CMD_READ); |
@@ -195,7 +199,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
195 | else | 199 | else |
196 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); | 200 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); |
197 | 201 | ||
198 | spin_unlock_irqrestore(&ar71xx_pci_lock, flags); | 202 | spin_unlock_irqrestore(&apc->lock, flags); |
199 | 203 | ||
200 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; | 204 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; |
201 | 205 | ||
@@ -205,7 +209,8 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
205 | static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | 209 | static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, |
206 | int where, int size, u32 value) | 210 | int where, int size, u32 value) |
207 | { | 211 | { |
208 | void __iomem *base = ar71xx_pcicfg_base; | 212 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
213 | void __iomem *base = apc->cfg_base; | ||
209 | unsigned long flags; | 214 | unsigned long flags; |
210 | int err; | 215 | int err; |
211 | int ret; | 216 | int ret; |
@@ -213,7 +218,7 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
213 | value = value << (8 * (where & 3)); | 218 | value = value << (8 * (where & 3)); |
214 | ret = PCIBIOS_SUCCESSFUL; | 219 | ret = PCIBIOS_SUCCESSFUL; |
215 | 220 | ||
216 | spin_lock_irqsave(&ar71xx_pci_lock, flags); | 221 | spin_lock_irqsave(&apc->lock, flags); |
217 | 222 | ||
218 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | 223 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, |
219 | AR71XX_PCI_CFG_CMD_WRITE); | 224 | AR71XX_PCI_CFG_CMD_WRITE); |
@@ -222,7 +227,7 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
222 | else | 227 | else |
223 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); | 228 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); |
224 | 229 | ||
225 | spin_unlock_irqrestore(&ar71xx_pci_lock, flags); | 230 | spin_unlock_irqrestore(&apc->lock, flags); |
226 | 231 | ||
227 | return ret; | 232 | return ret; |
228 | } | 233 | } |
@@ -232,45 +237,28 @@ static struct pci_ops ar71xx_pci_ops = { | |||
232 | .write = ar71xx_pci_write_config, | 237 | .write = ar71xx_pci_write_config, |
233 | }; | 238 | }; |
234 | 239 | ||
235 | static struct resource ar71xx_pci_io_resource = { | ||
236 | .name = "PCI IO space", | ||
237 | .start = 0, | ||
238 | .end = 0, | ||
239 | .flags = IORESOURCE_IO, | ||
240 | }; | ||
241 | |||
242 | static struct resource ar71xx_pci_mem_resource = { | ||
243 | .name = "PCI memory space", | ||
244 | .start = AR71XX_PCI_MEM_BASE, | ||
245 | .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, | ||
246 | .flags = IORESOURCE_MEM | ||
247 | }; | ||
248 | |||
249 | static struct pci_controller ar71xx_pci_controller = { | ||
250 | .pci_ops = &ar71xx_pci_ops, | ||
251 | .mem_resource = &ar71xx_pci_mem_resource, | ||
252 | .io_resource = &ar71xx_pci_io_resource, | ||
253 | }; | ||
254 | |||
255 | static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | 240 | static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) |
256 | { | 241 | { |
242 | struct ar71xx_pci_controller *apc; | ||
257 | void __iomem *base = ath79_reset_base; | 243 | void __iomem *base = ath79_reset_base; |
258 | u32 pending; | 244 | u32 pending; |
259 | 245 | ||
246 | apc = irq_get_handler_data(irq); | ||
247 | |||
260 | pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & | 248 | pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & |
261 | __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | 249 | __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); |
262 | 250 | ||
263 | if (pending & AR71XX_PCI_INT_DEV0) | 251 | if (pending & AR71XX_PCI_INT_DEV0) |
264 | generic_handle_irq(ATH79_PCI_IRQ(0)); | 252 | generic_handle_irq(apc->irq_base + 0); |
265 | 253 | ||
266 | else if (pending & AR71XX_PCI_INT_DEV1) | 254 | else if (pending & AR71XX_PCI_INT_DEV1) |
267 | generic_handle_irq(ATH79_PCI_IRQ(1)); | 255 | generic_handle_irq(apc->irq_base + 1); |
268 | 256 | ||
269 | else if (pending & AR71XX_PCI_INT_DEV2) | 257 | else if (pending & AR71XX_PCI_INT_DEV2) |
270 | generic_handle_irq(ATH79_PCI_IRQ(2)); | 258 | generic_handle_irq(apc->irq_base + 2); |
271 | 259 | ||
272 | else if (pending & AR71XX_PCI_INT_CORE) | 260 | else if (pending & AR71XX_PCI_INT_CORE) |
273 | generic_handle_irq(ATH79_PCI_IRQ(4)); | 261 | generic_handle_irq(apc->irq_base + 4); |
274 | 262 | ||
275 | else | 263 | else |
276 | spurious_interrupt(); | 264 | spurious_interrupt(); |
@@ -278,10 +266,14 @@ static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
278 | 266 | ||
279 | static void ar71xx_pci_irq_unmask(struct irq_data *d) | 267 | static void ar71xx_pci_irq_unmask(struct irq_data *d) |
280 | { | 268 | { |
281 | unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE; | 269 | struct ar71xx_pci_controller *apc; |
270 | unsigned int irq; | ||
282 | void __iomem *base = ath79_reset_base; | 271 | void __iomem *base = ath79_reset_base; |
283 | u32 t; | 272 | u32 t; |
284 | 273 | ||
274 | apc = irq_data_get_irq_chip_data(d); | ||
275 | irq = d->irq - apc->irq_base; | ||
276 | |||
285 | t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | 277 | t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); |
286 | __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); | 278 | __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); |
287 | 279 | ||
@@ -291,10 +283,14 @@ static void ar71xx_pci_irq_unmask(struct irq_data *d) | |||
291 | 283 | ||
292 | static void ar71xx_pci_irq_mask(struct irq_data *d) | 284 | static void ar71xx_pci_irq_mask(struct irq_data *d) |
293 | { | 285 | { |
294 | unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE; | 286 | struct ar71xx_pci_controller *apc; |
287 | unsigned int irq; | ||
295 | void __iomem *base = ath79_reset_base; | 288 | void __iomem *base = ath79_reset_base; |
296 | u32 t; | 289 | u32 t; |
297 | 290 | ||
291 | apc = irq_data_get_irq_chip_data(d); | ||
292 | irq = d->irq - apc->irq_base; | ||
293 | |||
298 | t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | 294 | t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); |
299 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); | 295 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); |
300 | 296 | ||
@@ -309,7 +305,7 @@ static struct irq_chip ar71xx_pci_irq_chip = { | |||
309 | .irq_mask_ack = ar71xx_pci_irq_mask, | 305 | .irq_mask_ack = ar71xx_pci_irq_mask, |
310 | }; | 306 | }; |
311 | 307 | ||
312 | static __init void ar71xx_pci_irq_init(void) | 308 | static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc) |
313 | { | 309 | { |
314 | void __iomem *base = ath79_reset_base; | 310 | void __iomem *base = ath79_reset_base; |
315 | int i; | 311 | int i; |
@@ -319,15 +315,19 @@ static __init void ar71xx_pci_irq_init(void) | |||
319 | 315 | ||
320 | BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT); | 316 | BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT); |
321 | 317 | ||
322 | for (i = ATH79_PCI_IRQ_BASE; | 318 | apc->irq_base = ATH79_PCI_IRQ_BASE; |
323 | i < ATH79_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) | 319 | for (i = apc->irq_base; |
320 | i < apc->irq_base + AR71XX_PCI_IRQ_COUNT; i++) { | ||
324 | irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, | 321 | irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, |
325 | handle_level_irq); | 322 | handle_level_irq); |
323 | irq_set_chip_data(i, apc); | ||
324 | } | ||
326 | 325 | ||
327 | irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler); | 326 | irq_set_handler_data(apc->irq, apc); |
327 | irq_set_chained_handler(apc->irq, ar71xx_pci_irq_handler); | ||
328 | } | 328 | } |
329 | 329 | ||
330 | static __init void ar71xx_pci_reset(void) | 330 | static void ar71xx_pci_reset(void) |
331 | { | 331 | { |
332 | void __iomem *ddr_base = ath79_ddr_base; | 332 | void __iomem *ddr_base = ath79_ddr_base; |
333 | 333 | ||
@@ -349,27 +349,83 @@ static __init void ar71xx_pci_reset(void) | |||
349 | mdelay(100); | 349 | mdelay(100); |
350 | } | 350 | } |
351 | 351 | ||
352 | __init int ar71xx_pcibios_init(void) | 352 | static int ar71xx_pci_probe(struct platform_device *pdev) |
353 | { | 353 | { |
354 | struct ar71xx_pci_controller *apc; | ||
355 | struct resource *res; | ||
354 | u32 t; | 356 | u32 t; |
355 | 357 | ||
356 | ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE); | 358 | apc = devm_kzalloc(&pdev->dev, sizeof(struct ar71xx_pci_controller), |
357 | if (ar71xx_pcicfg_base == NULL) | 359 | GFP_KERNEL); |
360 | if (!apc) | ||
361 | return -ENOMEM; | ||
362 | |||
363 | spin_lock_init(&apc->lock); | ||
364 | |||
365 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); | ||
366 | if (!res) | ||
367 | return -EINVAL; | ||
368 | |||
369 | apc->cfg_base = devm_request_and_ioremap(&pdev->dev, res); | ||
370 | if (!apc->cfg_base) | ||
358 | return -ENOMEM; | 371 | return -ENOMEM; |
359 | 372 | ||
373 | apc->irq = platform_get_irq(pdev, 0); | ||
374 | if (apc->irq < 0) | ||
375 | return -EINVAL; | ||
376 | |||
377 | res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); | ||
378 | if (!res) | ||
379 | return -EINVAL; | ||
380 | |||
381 | apc->io_res.parent = res; | ||
382 | apc->io_res.name = "PCI IO space"; | ||
383 | apc->io_res.start = res->start; | ||
384 | apc->io_res.end = res->end; | ||
385 | apc->io_res.flags = IORESOURCE_IO; | ||
386 | |||
387 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base"); | ||
388 | if (!res) | ||
389 | return -EINVAL; | ||
390 | |||
391 | apc->mem_res.parent = res; | ||
392 | apc->mem_res.name = "PCI memory space"; | ||
393 | apc->mem_res.start = res->start; | ||
394 | apc->mem_res.end = res->end; | ||
395 | apc->mem_res.flags = IORESOURCE_MEM; | ||
396 | |||
360 | ar71xx_pci_reset(); | 397 | ar71xx_pci_reset(); |
361 | 398 | ||
362 | /* setup COMMAND register */ | 399 | /* setup COMMAND register */ |
363 | t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | 400 | t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE |
364 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; | 401 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; |
365 | ar71xx_pci_local_write(PCI_COMMAND, 4, t); | 402 | ar71xx_pci_local_write(apc, PCI_COMMAND, 4, t); |
366 | 403 | ||
367 | /* clear bus errors */ | 404 | /* clear bus errors */ |
368 | ar71xx_pci_check_error(1); | 405 | ar71xx_pci_check_error(apc, 1); |
406 | |||
407 | ar71xx_pci_irq_init(apc); | ||
369 | 408 | ||
370 | ar71xx_pci_irq_init(); | 409 | apc->pci_ctrl.pci_ops = &ar71xx_pci_ops; |
410 | apc->pci_ctrl.mem_resource = &apc->mem_res; | ||
411 | apc->pci_ctrl.io_resource = &apc->io_res; | ||
371 | 412 | ||
372 | register_pci_controller(&ar71xx_pci_controller); | 413 | register_pci_controller(&apc->pci_ctrl); |
373 | 414 | ||
374 | return 0; | 415 | return 0; |
375 | } | 416 | } |
417 | |||
418 | static struct platform_driver ar71xx_pci_driver = { | ||
419 | .probe = ar71xx_pci_probe, | ||
420 | .driver = { | ||
421 | .name = "ar71xx-pci", | ||
422 | .owner = THIS_MODULE, | ||
423 | }, | ||
424 | }; | ||
425 | |||
426 | static int __init ar71xx_pci_init(void) | ||
427 | { | ||
428 | return platform_driver_register(&ar71xx_pci_driver); | ||
429 | } | ||
430 | |||
431 | postcore_initcall(ar71xx_pci_init); | ||
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 279585d6eca0..8a0700d448fe 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c | |||
@@ -9,19 +9,13 @@ | |||
9 | * by the Free Software Foundation. | 9 | * by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/spinlock.h> | ||
12 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
13 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
14 | #include <asm/mach-ath79/ath79.h> | 17 | #include <asm/mach-ath79/ath79.h> |
15 | #include <asm/mach-ath79/ar71xx_regs.h> | 18 | #include <asm/mach-ath79/ar71xx_regs.h> |
16 | #include <asm/mach-ath79/pci.h> | ||
17 | |||
18 | #define AR724X_PCI_CFG_BASE 0x14000000 | ||
19 | #define AR724X_PCI_CFG_SIZE 0x1000 | ||
20 | #define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) | ||
21 | #define AR724X_PCI_CTRL_SIZE 0x100 | ||
22 | |||
23 | #define AR724X_PCI_MEM_BASE 0x10000000 | ||
24 | #define AR724X_PCI_MEM_SIZE 0x04000000 | ||
25 | 19 | ||
26 | #define AR724X_PCI_REG_RESET 0x18 | 20 | #define AR724X_PCI_REG_RESET 0x18 |
27 | #define AR724X_PCI_REG_INT_STATUS 0x4c | 21 | #define AR724X_PCI_REG_INT_STATUS 0x4c |
@@ -35,38 +29,112 @@ | |||
35 | 29 | ||
36 | #define AR7240_BAR0_WAR_VALUE 0xffff | 30 | #define AR7240_BAR0_WAR_VALUE 0xffff |
37 | 31 | ||
38 | static DEFINE_SPINLOCK(ar724x_pci_lock); | 32 | #define AR724X_PCI_CMD_INIT (PCI_COMMAND_MEMORY | \ |
39 | static void __iomem *ar724x_pci_devcfg_base; | 33 | PCI_COMMAND_MASTER | \ |
40 | static void __iomem *ar724x_pci_ctrl_base; | 34 | PCI_COMMAND_INVALIDATE | \ |
35 | PCI_COMMAND_PARITY | \ | ||
36 | PCI_COMMAND_SERR | \ | ||
37 | PCI_COMMAND_FAST_BACK) | ||
38 | |||
39 | struct ar724x_pci_controller { | ||
40 | void __iomem *devcfg_base; | ||
41 | void __iomem *ctrl_base; | ||
42 | void __iomem *crp_base; | ||
43 | |||
44 | int irq; | ||
45 | int irq_base; | ||
46 | |||
47 | bool link_up; | ||
48 | bool bar0_is_cached; | ||
49 | u32 bar0_value; | ||
41 | 50 | ||
42 | static u32 ar724x_pci_bar0_value; | 51 | spinlock_t lock; |
43 | static bool ar724x_pci_bar0_is_cached; | ||
44 | static bool ar724x_pci_link_up; | ||
45 | 52 | ||
46 | static inline bool ar724x_pci_check_link(void) | 53 | struct pci_controller pci_controller; |
54 | struct resource io_res; | ||
55 | struct resource mem_res; | ||
56 | }; | ||
57 | |||
58 | static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc) | ||
47 | { | 59 | { |
48 | u32 reset; | 60 | u32 reset; |
49 | 61 | ||
50 | reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); | 62 | reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET); |
51 | return reset & AR724X_PCI_RESET_LINK_UP; | 63 | return reset & AR724X_PCI_RESET_LINK_UP; |
52 | } | 64 | } |
53 | 65 | ||
66 | static inline struct ar724x_pci_controller * | ||
67 | pci_bus_to_ar724x_controller(struct pci_bus *bus) | ||
68 | { | ||
69 | struct pci_controller *hose; | ||
70 | |||
71 | hose = (struct pci_controller *) bus->sysdata; | ||
72 | return container_of(hose, struct ar724x_pci_controller, pci_controller); | ||
73 | } | ||
74 | |||
75 | static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | ||
76 | int where, int size, u32 value) | ||
77 | { | ||
78 | unsigned long flags; | ||
79 | void __iomem *base; | ||
80 | u32 data; | ||
81 | int s; | ||
82 | |||
83 | WARN_ON(where & (size - 1)); | ||
84 | |||
85 | if (!apc->link_up) | ||
86 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
87 | |||
88 | base = apc->crp_base; | ||
89 | |||
90 | spin_lock_irqsave(&apc->lock, flags); | ||
91 | data = __raw_readl(base + (where & ~3)); | ||
92 | |||
93 | switch (size) { | ||
94 | case 1: | ||
95 | s = ((where & 3) * 8); | ||
96 | data &= ~(0xff << s); | ||
97 | data |= ((value & 0xff) << s); | ||
98 | break; | ||
99 | case 2: | ||
100 | s = ((where & 2) * 8); | ||
101 | data &= ~(0xffff << s); | ||
102 | data |= ((value & 0xffff) << s); | ||
103 | break; | ||
104 | case 4: | ||
105 | data = value; | ||
106 | break; | ||
107 | default: | ||
108 | spin_unlock_irqrestore(&apc->lock, flags); | ||
109 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
110 | } | ||
111 | |||
112 | __raw_writel(data, base + (where & ~3)); | ||
113 | /* flush write */ | ||
114 | __raw_readl(base + (where & ~3)); | ||
115 | spin_unlock_irqrestore(&apc->lock, flags); | ||
116 | |||
117 | return PCIBIOS_SUCCESSFUL; | ||
118 | } | ||
119 | |||
54 | static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | 120 | static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
55 | int size, uint32_t *value) | 121 | int size, uint32_t *value) |
56 | { | 122 | { |
123 | struct ar724x_pci_controller *apc; | ||
57 | unsigned long flags; | 124 | unsigned long flags; |
58 | void __iomem *base; | 125 | void __iomem *base; |
59 | u32 data; | 126 | u32 data; |
60 | 127 | ||
61 | if (!ar724x_pci_link_up) | 128 | apc = pci_bus_to_ar724x_controller(bus); |
129 | if (!apc->link_up) | ||
62 | return PCIBIOS_DEVICE_NOT_FOUND; | 130 | return PCIBIOS_DEVICE_NOT_FOUND; |
63 | 131 | ||
64 | if (devfn) | 132 | if (devfn) |
65 | return PCIBIOS_DEVICE_NOT_FOUND; | 133 | return PCIBIOS_DEVICE_NOT_FOUND; |
66 | 134 | ||
67 | base = ar724x_pci_devcfg_base; | 135 | base = apc->devcfg_base; |
68 | 136 | ||
69 | spin_lock_irqsave(&ar724x_pci_lock, flags); | 137 | spin_lock_irqsave(&apc->lock, flags); |
70 | data = __raw_readl(base + (where & ~3)); | 138 | data = __raw_readl(base + (where & ~3)); |
71 | 139 | ||
72 | switch (size) { | 140 | switch (size) { |
@@ -85,17 +153,17 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
85 | case 4: | 153 | case 4: |
86 | break; | 154 | break; |
87 | default: | 155 | default: |
88 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | 156 | spin_unlock_irqrestore(&apc->lock, flags); |
89 | 157 | ||
90 | return PCIBIOS_BAD_REGISTER_NUMBER; | 158 | return PCIBIOS_BAD_REGISTER_NUMBER; |
91 | } | 159 | } |
92 | 160 | ||
93 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | 161 | spin_unlock_irqrestore(&apc->lock, flags); |
94 | 162 | ||
95 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && | 163 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && |
96 | ar724x_pci_bar0_is_cached) { | 164 | apc->bar0_is_cached) { |
97 | /* use the cached value */ | 165 | /* use the cached value */ |
98 | *value = ar724x_pci_bar0_value; | 166 | *value = apc->bar0_value; |
99 | } else { | 167 | } else { |
100 | *value = data; | 168 | *value = data; |
101 | } | 169 | } |
@@ -106,12 +174,14 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
106 | static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | 174 | static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, |
107 | int size, uint32_t value) | 175 | int size, uint32_t value) |
108 | { | 176 | { |
177 | struct ar724x_pci_controller *apc; | ||
109 | unsigned long flags; | 178 | unsigned long flags; |
110 | void __iomem *base; | 179 | void __iomem *base; |
111 | u32 data; | 180 | u32 data; |
112 | int s; | 181 | int s; |
113 | 182 | ||
114 | if (!ar724x_pci_link_up) | 183 | apc = pci_bus_to_ar724x_controller(bus); |
184 | if (!apc->link_up) | ||
115 | return PCIBIOS_DEVICE_NOT_FOUND; | 185 | return PCIBIOS_DEVICE_NOT_FOUND; |
116 | 186 | ||
117 | if (devfn) | 187 | if (devfn) |
@@ -129,18 +199,18 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
129 | * BAR0 register in order to make the device memory | 199 | * BAR0 register in order to make the device memory |
130 | * accessible. | 200 | * accessible. |
131 | */ | 201 | */ |
132 | ar724x_pci_bar0_is_cached = true; | 202 | apc->bar0_is_cached = true; |
133 | ar724x_pci_bar0_value = value; | 203 | apc->bar0_value = value; |
134 | 204 | ||
135 | value = AR7240_BAR0_WAR_VALUE; | 205 | value = AR7240_BAR0_WAR_VALUE; |
136 | } else { | 206 | } else { |
137 | ar724x_pci_bar0_is_cached = false; | 207 | apc->bar0_is_cached = false; |
138 | } | 208 | } |
139 | } | 209 | } |
140 | 210 | ||
141 | base = ar724x_pci_devcfg_base; | 211 | base = apc->devcfg_base; |
142 | 212 | ||
143 | spin_lock_irqsave(&ar724x_pci_lock, flags); | 213 | spin_lock_irqsave(&apc->lock, flags); |
144 | data = __raw_readl(base + (where & ~3)); | 214 | data = __raw_readl(base + (where & ~3)); |
145 | 215 | ||
146 | switch (size) { | 216 | switch (size) { |
@@ -158,7 +228,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
158 | data = value; | 228 | data = value; |
159 | break; | 229 | break; |
160 | default: | 230 | default: |
161 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | 231 | spin_unlock_irqrestore(&apc->lock, flags); |
162 | 232 | ||
163 | return PCIBIOS_BAD_REGISTER_NUMBER; | 233 | return PCIBIOS_BAD_REGISTER_NUMBER; |
164 | } | 234 | } |
@@ -166,7 +236,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
166 | __raw_writel(data, base + (where & ~3)); | 236 | __raw_writel(data, base + (where & ~3)); |
167 | /* flush write */ | 237 | /* flush write */ |
168 | __raw_readl(base + (where & ~3)); | 238 | __raw_readl(base + (where & ~3)); |
169 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | 239 | spin_unlock_irqrestore(&apc->lock, flags); |
170 | 240 | ||
171 | return PCIBIOS_SUCCESSFUL; | 241 | return PCIBIOS_SUCCESSFUL; |
172 | } | 242 | } |
@@ -176,38 +246,20 @@ static struct pci_ops ar724x_pci_ops = { | |||
176 | .write = ar724x_pci_write, | 246 | .write = ar724x_pci_write, |
177 | }; | 247 | }; |
178 | 248 | ||
179 | static struct resource ar724x_io_resource = { | ||
180 | .name = "PCI IO space", | ||
181 | .start = 0, | ||
182 | .end = 0, | ||
183 | .flags = IORESOURCE_IO, | ||
184 | }; | ||
185 | |||
186 | static struct resource ar724x_mem_resource = { | ||
187 | .name = "PCI memory space", | ||
188 | .start = AR724X_PCI_MEM_BASE, | ||
189 | .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1, | ||
190 | .flags = IORESOURCE_MEM, | ||
191 | }; | ||
192 | |||
193 | static struct pci_controller ar724x_pci_controller = { | ||
194 | .pci_ops = &ar724x_pci_ops, | ||
195 | .io_resource = &ar724x_io_resource, | ||
196 | .mem_resource = &ar724x_mem_resource, | ||
197 | }; | ||
198 | |||
199 | static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | 249 | static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) |
200 | { | 250 | { |
251 | struct ar724x_pci_controller *apc; | ||
201 | void __iomem *base; | 252 | void __iomem *base; |
202 | u32 pending; | 253 | u32 pending; |
203 | 254 | ||
204 | base = ar724x_pci_ctrl_base; | 255 | apc = irq_get_handler_data(irq); |
256 | base = apc->ctrl_base; | ||
205 | 257 | ||
206 | pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & | 258 | pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & |
207 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); | 259 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); |
208 | 260 | ||
209 | if (pending & AR724X_PCI_INT_DEV0) | 261 | if (pending & AR724X_PCI_INT_DEV0) |
210 | generic_handle_irq(ATH79_PCI_IRQ(0)); | 262 | generic_handle_irq(apc->irq_base + 0); |
211 | 263 | ||
212 | else | 264 | else |
213 | spurious_interrupt(); | 265 | spurious_interrupt(); |
@@ -215,13 +267,17 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
215 | 267 | ||
216 | static void ar724x_pci_irq_unmask(struct irq_data *d) | 268 | static void ar724x_pci_irq_unmask(struct irq_data *d) |
217 | { | 269 | { |
270 | struct ar724x_pci_controller *apc; | ||
218 | void __iomem *base; | 271 | void __iomem *base; |
272 | int offset; | ||
219 | u32 t; | 273 | u32 t; |
220 | 274 | ||
221 | base = ar724x_pci_ctrl_base; | 275 | apc = irq_data_get_irq_chip_data(d); |
276 | base = apc->ctrl_base; | ||
277 | offset = apc->irq_base - d->irq; | ||
222 | 278 | ||
223 | switch (d->irq) { | 279 | switch (offset) { |
224 | case ATH79_PCI_IRQ(0): | 280 | case 0: |
225 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); | 281 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); |
226 | __raw_writel(t | AR724X_PCI_INT_DEV0, | 282 | __raw_writel(t | AR724X_PCI_INT_DEV0, |
227 | base + AR724X_PCI_REG_INT_MASK); | 283 | base + AR724X_PCI_REG_INT_MASK); |
@@ -232,13 +288,17 @@ static void ar724x_pci_irq_unmask(struct irq_data *d) | |||
232 | 288 | ||
233 | static void ar724x_pci_irq_mask(struct irq_data *d) | 289 | static void ar724x_pci_irq_mask(struct irq_data *d) |
234 | { | 290 | { |
291 | struct ar724x_pci_controller *apc; | ||
235 | void __iomem *base; | 292 | void __iomem *base; |
293 | int offset; | ||
236 | u32 t; | 294 | u32 t; |
237 | 295 | ||
238 | base = ar724x_pci_ctrl_base; | 296 | apc = irq_data_get_irq_chip_data(d); |
297 | base = apc->ctrl_base; | ||
298 | offset = apc->irq_base - d->irq; | ||
239 | 299 | ||
240 | switch (d->irq) { | 300 | switch (offset) { |
241 | case ATH79_PCI_IRQ(0): | 301 | case 0: |
242 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); | 302 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); |
243 | __raw_writel(t & ~AR724X_PCI_INT_DEV0, | 303 | __raw_writel(t & ~AR724X_PCI_INT_DEV0, |
244 | base + AR724X_PCI_REG_INT_MASK); | 304 | base + AR724X_PCI_REG_INT_MASK); |
@@ -262,53 +322,123 @@ static struct irq_chip ar724x_pci_irq_chip = { | |||
262 | .irq_mask_ack = ar724x_pci_irq_mask, | 322 | .irq_mask_ack = ar724x_pci_irq_mask, |
263 | }; | 323 | }; |
264 | 324 | ||
265 | static void __init ar724x_pci_irq_init(int irq) | 325 | static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc, |
326 | int id) | ||
266 | { | 327 | { |
267 | void __iomem *base; | 328 | void __iomem *base; |
268 | int i; | 329 | int i; |
269 | 330 | ||
270 | base = ar724x_pci_ctrl_base; | 331 | base = apc->ctrl_base; |
271 | 332 | ||
272 | __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); | 333 | __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); |
273 | __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); | 334 | __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); |
274 | 335 | ||
275 | BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); | 336 | apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT); |
276 | 337 | ||
277 | for (i = ATH79_PCI_IRQ_BASE; | 338 | for (i = apc->irq_base; |
278 | i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) | 339 | i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) { |
279 | irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, | 340 | irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, |
280 | handle_level_irq); | 341 | handle_level_irq); |
342 | irq_set_chip_data(i, apc); | ||
343 | } | ||
281 | 344 | ||
282 | irq_set_chained_handler(irq, ar724x_pci_irq_handler); | 345 | irq_set_handler_data(apc->irq, apc); |
346 | irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler); | ||
283 | } | 347 | } |
284 | 348 | ||
285 | int __init ar724x_pcibios_init(int irq) | 349 | static int ar724x_pci_probe(struct platform_device *pdev) |
286 | { | 350 | { |
287 | int ret; | 351 | struct ar724x_pci_controller *apc; |
352 | struct resource *res; | ||
353 | int id; | ||
288 | 354 | ||
289 | ret = -ENOMEM; | 355 | id = pdev->id; |
356 | if (id == -1) | ||
357 | id = 0; | ||
290 | 358 | ||
291 | ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, | 359 | apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller), |
292 | AR724X_PCI_CFG_SIZE); | 360 | GFP_KERNEL); |
293 | if (ar724x_pci_devcfg_base == NULL) | 361 | if (!apc) |
294 | goto err; | 362 | return -ENOMEM; |
295 | 363 | ||
296 | ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE, | 364 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); |
297 | AR724X_PCI_CTRL_SIZE); | 365 | if (!res) |
298 | if (ar724x_pci_ctrl_base == NULL) | 366 | return -EINVAL; |
299 | goto err_unmap_devcfg; | ||
300 | 367 | ||
301 | ar724x_pci_link_up = ar724x_pci_check_link(); | 368 | apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res); |
302 | if (!ar724x_pci_link_up) | 369 | if (apc->ctrl_base == NULL) |
303 | pr_warn("ar724x: PCIe link is down\n"); | 370 | return -EBUSY; |
304 | 371 | ||
305 | ar724x_pci_irq_init(irq); | 372 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); |
306 | register_pci_controller(&ar724x_pci_controller); | 373 | if (!res) |
374 | return -EINVAL; | ||
307 | 375 | ||
308 | return PCIBIOS_SUCCESSFUL; | 376 | apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res); |
377 | if (!apc->devcfg_base) | ||
378 | return -EBUSY; | ||
379 | |||
380 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base"); | ||
381 | if (!res) | ||
382 | return -EINVAL; | ||
309 | 383 | ||
310 | err_unmap_devcfg: | 384 | apc->crp_base = devm_request_and_ioremap(&pdev->dev, res); |
311 | iounmap(ar724x_pci_devcfg_base); | 385 | if (apc->crp_base == NULL) |
312 | err: | 386 | return -EBUSY; |
313 | return ret; | 387 | |
388 | apc->irq = platform_get_irq(pdev, 0); | ||
389 | if (apc->irq < 0) | ||
390 | return -EINVAL; | ||
391 | |||
392 | spin_lock_init(&apc->lock); | ||
393 | |||
394 | res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); | ||
395 | if (!res) | ||
396 | return -EINVAL; | ||
397 | |||
398 | apc->io_res.parent = res; | ||
399 | apc->io_res.name = "PCI IO space"; | ||
400 | apc->io_res.start = res->start; | ||
401 | apc->io_res.end = res->end; | ||
402 | apc->io_res.flags = IORESOURCE_IO; | ||
403 | |||
404 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base"); | ||
405 | if (!res) | ||
406 | return -EINVAL; | ||
407 | |||
408 | apc->mem_res.parent = res; | ||
409 | apc->mem_res.name = "PCI memory space"; | ||
410 | apc->mem_res.start = res->start; | ||
411 | apc->mem_res.end = res->end; | ||
412 | apc->mem_res.flags = IORESOURCE_MEM; | ||
413 | |||
414 | apc->pci_controller.pci_ops = &ar724x_pci_ops; | ||
415 | apc->pci_controller.io_resource = &apc->io_res; | ||
416 | apc->pci_controller.mem_resource = &apc->mem_res; | ||
417 | |||
418 | apc->link_up = ar724x_pci_check_link(apc); | ||
419 | if (!apc->link_up) | ||
420 | dev_warn(&pdev->dev, "PCIe link is down\n"); | ||
421 | |||
422 | ar724x_pci_irq_init(apc, id); | ||
423 | |||
424 | ar724x_pci_local_write(apc, PCI_COMMAND, 4, AR724X_PCI_CMD_INIT); | ||
425 | |||
426 | register_pci_controller(&apc->pci_controller); | ||
427 | |||
428 | return 0; | ||
314 | } | 429 | } |
430 | |||
431 | static struct platform_driver ar724x_pci_driver = { | ||
432 | .probe = ar724x_pci_probe, | ||
433 | .driver = { | ||
434 | .name = "ar724x-pci", | ||
435 | .owner = THIS_MODULE, | ||
436 | }, | ||
437 | }; | ||
438 | |||
439 | static int __init ar724x_pci_init(void) | ||
440 | { | ||
441 | return platform_driver_register(&ar724x_pci_driver); | ||
442 | } | ||
443 | |||
444 | postcore_initcall(ar724x_pci_init); | ||
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index 95681789b51e..f32664bbbe17 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c | |||
@@ -129,8 +129,16 @@ static int ltq_pci_startup(struct platform_device *pdev) | |||
129 | 129 | ||
130 | /* setup reset gpio used by pci */ | 130 | /* setup reset gpio used by pci */ |
131 | reset_gpio = of_get_named_gpio(node, "gpio-reset", 0); | 131 | reset_gpio = of_get_named_gpio(node, "gpio-reset", 0); |
132 | if (gpio_is_valid(reset_gpio)) | 132 | if (gpio_is_valid(reset_gpio)) { |
133 | devm_gpio_request(&pdev->dev, reset_gpio, "pci-reset"); | 133 | int ret = devm_gpio_request(&pdev->dev, |
134 | reset_gpio, "pci-reset"); | ||
135 | if (ret) { | ||
136 | dev_err(&pdev->dev, | ||
137 | "failed to request gpio %d\n", reset_gpio); | ||
138 | return ret; | ||
139 | } | ||
140 | gpio_direction_output(reset_gpio, 1); | ||
141 | } | ||
134 | 142 | ||
135 | /* enable auto-switching between PCI and EBU */ | 143 | /* enable auto-switching between PCI and EBU */ |
136 | ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); | 144 | ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); |
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c index ad55f2cfeec1..653d2db9e0c5 100644 --- a/arch/mips/pci/pci-xlp.c +++ b/arch/mips/pci/pci-xlp.c | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #include <asm/netlogic/interrupt.h> | 47 | #include <asm/netlogic/interrupt.h> |
48 | #include <asm/netlogic/haldefs.h> | 48 | #include <asm/netlogic/haldefs.h> |
49 | #include <asm/netlogic/common.h> | ||
49 | 50 | ||
50 | #include <asm/netlogic/xlp-hal/iomap.h> | 51 | #include <asm/netlogic/xlp-hal/iomap.h> |
51 | #include <asm/netlogic/xlp-hal/pic.h> | 52 | #include <asm/netlogic/xlp-hal/pic.h> |
@@ -64,8 +65,12 @@ static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn, | |||
64 | u32 data; | 65 | u32 data; |
65 | u32 *cfgaddr; | 66 | u32 *cfgaddr; |
66 | 67 | ||
68 | where &= ~3; | ||
69 | if (bus->number == 0 && PCI_SLOT(devfn) == 1 && where == 0x954) | ||
70 | return 0xffffffff; | ||
71 | |||
67 | cfgaddr = (u32 *)(pci_config_base + | 72 | cfgaddr = (u32 *)(pci_config_base + |
68 | pci_cfg_addr(bus->number, devfn, where & ~3)); | 73 | pci_cfg_addr(bus->number, devfn, where)); |
69 | data = *cfgaddr; | 74 | data = *cfgaddr; |
70 | return data; | 75 | return data; |
71 | } | 76 | } |
@@ -157,32 +162,38 @@ struct pci_controller nlm_pci_controller = { | |||
157 | .io_offset = 0x00000000UL, | 162 | .io_offset = 0x00000000UL, |
158 | }; | 163 | }; |
159 | 164 | ||
160 | static int get_irq_vector(const struct pci_dev *dev) | 165 | static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev) |
161 | { | 166 | { |
162 | /* | 167 | struct pci_bus *bus, *p; |
163 | * For XLP PCIe, there is an IRQ per Link, find out which | ||
164 | * link the device is on to assign interrupts | ||
165 | */ | ||
166 | if (dev->bus->self == NULL) | ||
167 | return 0; | ||
168 | 168 | ||
169 | switch (dev->bus->self->devfn) { | 169 | /* Find the bridge on bus 0 */ |
170 | case 0x8: | 170 | bus = dev->bus; |
171 | return PIC_PCIE_LINK_0_IRQ; | 171 | for (p = bus->parent; p && p->number != 0; p = p->parent) |
172 | case 0x9: | 172 | bus = p; |
173 | return PIC_PCIE_LINK_1_IRQ; | 173 | |
174 | case 0xa: | 174 | return p ? bus->self : NULL; |
175 | return PIC_PCIE_LINK_2_IRQ; | 175 | } |
176 | case 0xb: | 176 | |
177 | return PIC_PCIE_LINK_3_IRQ; | 177 | static inline int nlm_pci_link_to_irq(int link) |
178 | } | 178 | { |
179 | WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn); | 179 | return PIC_PCIE_LINK_0_IRQ + link; |
180 | return 0; | ||
181 | } | 180 | } |
182 | 181 | ||
183 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | 182 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
184 | { | 183 | { |
185 | return get_irq_vector(dev); | 184 | struct pci_dev *lnkdev; |
185 | int lnkslot, lnkfunc; | ||
186 | |||
187 | /* | ||
188 | * For XLP PCIe, there is an IRQ per Link, find out which | ||
189 | * link the device is on to assign interrupts | ||
190 | */ | ||
191 | lnkdev = xlp_get_pcie_link(dev); | ||
192 | if (lnkdev == NULL) | ||
193 | return 0; | ||
194 | lnkfunc = PCI_FUNC(lnkdev->devfn); | ||
195 | lnkslot = PCI_SLOT(lnkdev->devfn); | ||
196 | return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc)); | ||
186 | } | 197 | } |
187 | 198 | ||
188 | /* Do platform specific device initialization at pci_enable_device() time */ | 199 | /* Do platform specific device initialization at pci_enable_device() time */ |
@@ -191,42 +202,48 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
191 | return 0; | 202 | return 0; |
192 | } | 203 | } |
193 | 204 | ||
194 | static int xlp_enable_pci_bswap(void) | 205 | /* |
206 | * If big-endian, enable hardware byteswap on the PCIe bridges. | ||
207 | * This will make both the SoC and PCIe devices behave consistently with | ||
208 | * readl/writel. | ||
209 | */ | ||
210 | #ifdef __BIG_ENDIAN | ||
211 | static void xlp_config_pci_bswap(int node, int link) | ||
195 | { | 212 | { |
196 | uint64_t pciebase, sysbase; | 213 | uint64_t nbubase, lnkbase; |
197 | int node, i; | ||
198 | u32 reg; | 214 | u32 reg; |
199 | 215 | ||
200 | /* Chip-0 so node set to 0 */ | 216 | nbubase = nlm_get_bridge_regbase(node); |
201 | node = 0; | 217 | lnkbase = nlm_get_pcie_base(node, link); |
202 | sysbase = nlm_get_bridge_regbase(node); | 218 | |
203 | /* | 219 | /* |
204 | * Enable byte swap in hardware. Program each link's PCIe SWAP regions | 220 | * Enable byte swap in hardware. Program each link's PCIe SWAP regions |
205 | * from the link's address ranges. | 221 | * from the link's address ranges. |
206 | */ | 222 | */ |
207 | for (i = 0; i < 4; i++) { | 223 | reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link); |
208 | pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i)); | 224 | nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg); |
209 | if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff) | ||
210 | continue; | ||
211 | 225 | ||
212 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i); | 226 | reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link); |
213 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg); | 227 | nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff); |
214 | 228 | ||
215 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i); | 229 | reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link); |
216 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM, | 230 | nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg); |
217 | reg | 0xfff); | ||
218 | 231 | ||
219 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i); | 232 | reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link); |
220 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg); | 233 | nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff); |
221 | |||
222 | reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i); | ||
223 | nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff); | ||
224 | } | ||
225 | return 0; | ||
226 | } | 234 | } |
235 | #else | ||
236 | /* Swap configuration not needed in little-endian mode */ | ||
237 | static inline void xlp_config_pci_bswap(int node, int link) {} | ||
238 | #endif /* __BIG_ENDIAN */ | ||
227 | 239 | ||
228 | static int __init pcibios_init(void) | 240 | static int __init pcibios_init(void) |
229 | { | 241 | { |
242 | struct nlm_soc_info *nodep; | ||
243 | uint64_t pciebase; | ||
244 | int link, n; | ||
245 | u32 reg; | ||
246 | |||
230 | /* Firmware assigns PCI resources */ | 247 | /* Firmware assigns PCI resources */ |
231 | pci_set_flags(PCI_PROBE_ONLY); | 248 | pci_set_flags(PCI_PROBE_ONLY); |
232 | pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20); | 249 | pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20); |
@@ -235,7 +252,26 @@ static int __init pcibios_init(void) | |||
235 | ioport_resource.start = 0; | 252 | ioport_resource.start = 0; |
236 | ioport_resource.end = ~0; | 253 | ioport_resource.end = ~0; |
237 | 254 | ||
238 | xlp_enable_pci_bswap(); | 255 | for (n = 0; n < NLM_NR_NODES; n++) { |
256 | nodep = nlm_get_node(n); | ||
257 | if (!nodep->coremask) | ||
258 | continue; /* node does not exist */ | ||
259 | |||
260 | for (link = 0; link < 4; link++) { | ||
261 | pciebase = nlm_get_pcie_base(n, link); | ||
262 | if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff) | ||
263 | continue; | ||
264 | xlp_config_pci_bswap(n, link); | ||
265 | |||
266 | /* put in intpin and irq - u-boot does not */ | ||
267 | reg = nlm_read_pci_reg(pciebase, 0xf); | ||
268 | reg &= ~0x1fu; | ||
269 | reg |= (1 << 8) | nlm_pci_link_to_irq(link); | ||
270 | nlm_write_pci_reg(pciebase, 0xf, reg); | ||
271 | pr_info("XLP PCIe: Link %d-%d initialized.\n", n, link); | ||
272 | } | ||
273 | } | ||
274 | |||
239 | set_io_port_base(CKSEG1); | 275 | set_io_port_base(CKSEG1); |
240 | nlm_pci_controller.io_map_base = CKSEG1; | 276 | nlm_pci_controller.io_map_base = CKSEG1; |
241 | 277 | ||
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index e8a14a6514cf..0872f12f268d 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -175,9 +175,20 @@ static DEFINE_MUTEX(pci_scan_mutex); | |||
175 | 175 | ||
176 | void register_pci_controller(struct pci_controller *hose) | 176 | void register_pci_controller(struct pci_controller *hose) |
177 | { | 177 | { |
178 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) | 178 | struct resource *parent; |
179 | |||
180 | parent = hose->mem_resource->parent; | ||
181 | if (!parent) | ||
182 | parent = &iomem_resource; | ||
183 | |||
184 | if (request_resource(parent, hose->mem_resource) < 0) | ||
179 | goto out; | 185 | goto out; |
180 | if (request_resource(&ioport_resource, hose->io_resource) < 0) { | 186 | |
187 | parent = hose->io_resource->parent; | ||
188 | if (!parent) | ||
189 | parent = &ioport_resource; | ||
190 | |||
191 | if (request_resource(parent, hose->io_resource) < 0) { | ||
181 | release_resource(hose->mem_resource); | 192 | release_resource(hose->mem_resource); |
182 | goto out; | 193 | goto out; |
183 | } | 194 | } |
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig new file mode 100644 index 000000000000..a0b0197cab0a --- /dev/null +++ b/arch/mips/ralink/Kconfig | |||
@@ -0,0 +1,32 @@ | |||
1 | if RALINK | ||
2 | |||
3 | choice | ||
4 | prompt "Ralink SoC selection" | ||
5 | default SOC_RT305X | ||
6 | help | ||
7 | Select Ralink MIPS SoC type. | ||
8 | |||
9 | config SOC_RT305X | ||
10 | bool "RT305x" | ||
11 | select USB_ARCH_HAS_HCD | ||
12 | select USB_ARCH_HAS_OHCI | ||
13 | select USB_ARCH_HAS_EHCI | ||
14 | |||
15 | endchoice | ||
16 | |||
17 | choice | ||
18 | prompt "Devicetree selection" | ||
19 | default DTB_RT_NONE | ||
20 | help | ||
21 | Select the devicetree. | ||
22 | |||
23 | config DTB_RT_NONE | ||
24 | bool "None" | ||
25 | |||
26 | config DTB_RT305X_EVAL | ||
27 | bool "RT305x eval kit" | ||
28 | depends on SOC_RT305X | ||
29 | |||
30 | endchoice | ||
31 | |||
32 | endif | ||
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile new file mode 100644 index 000000000000..939757f0e71f --- /dev/null +++ b/arch/mips/ralink/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | # This program is free software; you can redistribute it and/or modify it | ||
2 | # under the terms of the GNU General Public License version 2 as published | ||
3 | # by the Free Software Foundation.# | ||
4 | # Makefile for the Ralink common stuff | ||
5 | # | ||
6 | # Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> | ||
7 | # Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
8 | |||
9 | obj-y := prom.o of.o reset.o clk.o irq.o | ||
10 | |||
11 | obj-$(CONFIG_SOC_RT305X) += rt305x.o | ||
12 | |||
13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
14 | |||
15 | obj-y += dts/ | ||
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform new file mode 100644 index 000000000000..6babd65765e6 --- /dev/null +++ b/arch/mips/ralink/Platform | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Ralink SoC common stuff | ||
3 | # | ||
4 | core-$(CONFIG_RALINK) += arch/mips/ralink/ | ||
5 | cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink | ||
6 | |||
7 | # | ||
8 | # Ralink RT305x | ||
9 | # | ||
10 | load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000 | ||
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c new file mode 100644 index 000000000000..8dfa22ff300b --- /dev/null +++ b/arch/mips/ralink/clk.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/clk.h> | ||
14 | |||
15 | #include <asm/time.h> | ||
16 | |||
17 | #include "common.h" | ||
18 | |||
19 | struct clk { | ||
20 | struct clk_lookup cl; | ||
21 | unsigned long rate; | ||
22 | }; | ||
23 | |||
24 | void ralink_clk_add(const char *dev, unsigned long rate) | ||
25 | { | ||
26 | struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
27 | |||
28 | if (!clk) | ||
29 | panic("failed to add clock\n"); | ||
30 | |||
31 | clk->cl.dev_id = dev; | ||
32 | clk->cl.clk = clk; | ||
33 | |||
34 | clk->rate = rate; | ||
35 | |||
36 | clkdev_add(&clk->cl); | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Linux clock API | ||
41 | */ | ||
42 | int clk_enable(struct clk *clk) | ||
43 | { | ||
44 | return 0; | ||
45 | } | ||
46 | EXPORT_SYMBOL_GPL(clk_enable); | ||
47 | |||
48 | void clk_disable(struct clk *clk) | ||
49 | { | ||
50 | } | ||
51 | EXPORT_SYMBOL_GPL(clk_disable); | ||
52 | |||
53 | unsigned long clk_get_rate(struct clk *clk) | ||
54 | { | ||
55 | return clk->rate; | ||
56 | } | ||
57 | EXPORT_SYMBOL_GPL(clk_get_rate); | ||
58 | |||
59 | void __init plat_time_init(void) | ||
60 | { | ||
61 | struct clk *clk; | ||
62 | |||
63 | ralink_of_remap(); | ||
64 | |||
65 | ralink_clk_init(); | ||
66 | clk = clk_get_sys("cpu", NULL); | ||
67 | if (IS_ERR(clk)) | ||
68 | panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); | ||
69 | pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); | ||
70 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
71 | clk_put(clk); | ||
72 | } | ||
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h new file mode 100644 index 000000000000..300990313e1b --- /dev/null +++ b/arch/mips/ralink/common.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _RALINK_COMMON_H__ | ||
10 | #define _RALINK_COMMON_H__ | ||
11 | |||
12 | #define RAMIPS_SYS_TYPE_LEN 32 | ||
13 | |||
14 | struct ralink_pinmux_grp { | ||
15 | const char *name; | ||
16 | u32 mask; | ||
17 | int gpio_first; | ||
18 | int gpio_last; | ||
19 | }; | ||
20 | |||
21 | struct ralink_pinmux { | ||
22 | struct ralink_pinmux_grp *mode; | ||
23 | struct ralink_pinmux_grp *uart; | ||
24 | int uart_shift; | ||
25 | void (*wdt_reset)(void); | ||
26 | }; | ||
27 | extern struct ralink_pinmux gpio_pinmux; | ||
28 | |||
29 | struct ralink_soc_info { | ||
30 | unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; | ||
31 | unsigned char *compatible; | ||
32 | }; | ||
33 | extern struct ralink_soc_info soc_info; | ||
34 | |||
35 | extern void ralink_of_remap(void); | ||
36 | |||
37 | extern void ralink_clk_init(void); | ||
38 | extern void ralink_clk_add(const char *dev, unsigned long rate); | ||
39 | |||
40 | extern void prom_soc_init(struct ralink_soc_info *soc_info); | ||
41 | |||
42 | __iomem void *plat_of_remap_node(const char *node); | ||
43 | |||
44 | #endif /* _RALINK_COMMON_H__ */ | ||
diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile new file mode 100644 index 000000000000..1a69fb300955 --- /dev/null +++ b/arch/mips/ralink/dts/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o | |||
diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/ralink/dts/rt3050.dtsi new file mode 100644 index 000000000000..069d0660e1dd --- /dev/null +++ b/arch/mips/ralink/dts/rt3050.dtsi | |||
@@ -0,0 +1,106 @@ | |||
1 | / { | ||
2 | #address-cells = <1>; | ||
3 | #size-cells = <1>; | ||
4 | compatible = "ralink,rt3050-soc", "ralink,rt3052-soc"; | ||
5 | |||
6 | cpus { | ||
7 | cpu@0 { | ||
8 | compatible = "mips,mips24KEc"; | ||
9 | }; | ||
10 | }; | ||
11 | |||
12 | chosen { | ||
13 | bootargs = "console=ttyS0,57600 init=/init"; | ||
14 | }; | ||
15 | |||
16 | cpuintc: cpuintc@0 { | ||
17 | #address-cells = <0>; | ||
18 | #interrupt-cells = <1>; | ||
19 | interrupt-controller; | ||
20 | compatible = "mti,cpu-interrupt-controller"; | ||
21 | }; | ||
22 | |||
23 | palmbus@10000000 { | ||
24 | compatible = "palmbus"; | ||
25 | reg = <0x10000000 0x200000>; | ||
26 | ranges = <0x0 0x10000000 0x1FFFFF>; | ||
27 | |||
28 | #address-cells = <1>; | ||
29 | #size-cells = <1>; | ||
30 | |||
31 | sysc@0 { | ||
32 | compatible = "ralink,rt3052-sysc", "ralink,rt3050-sysc"; | ||
33 | reg = <0x0 0x100>; | ||
34 | }; | ||
35 | |||
36 | timer@100 { | ||
37 | compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt"; | ||
38 | reg = <0x100 0x100>; | ||
39 | }; | ||
40 | |||
41 | intc: intc@200 { | ||
42 | compatible = "ralink,rt3052-intc", "ralink,rt2880-intc"; | ||
43 | reg = <0x200 0x100>; | ||
44 | |||
45 | interrupt-controller; | ||
46 | #interrupt-cells = <1>; | ||
47 | |||
48 | interrupt-parent = <&cpuintc>; | ||
49 | interrupts = <2>; | ||
50 | }; | ||
51 | |||
52 | memc@300 { | ||
53 | compatible = "ralink,rt3052-memc", "ralink,rt3050-memc"; | ||
54 | reg = <0x300 0x100>; | ||
55 | }; | ||
56 | |||
57 | gpio0: gpio@600 { | ||
58 | compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio"; | ||
59 | reg = <0x600 0x34>; | ||
60 | |||
61 | gpio-controller; | ||
62 | #gpio-cells = <2>; | ||
63 | |||
64 | ralink,ngpio = <24>; | ||
65 | ralink,regs = [ 00 04 08 0c | ||
66 | 20 24 28 2c | ||
67 | 30 34 ]; | ||
68 | }; | ||
69 | |||
70 | gpio1: gpio@638 { | ||
71 | compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio"; | ||
72 | reg = <0x638 0x24>; | ||
73 | |||
74 | gpio-controller; | ||
75 | #gpio-cells = <2>; | ||
76 | |||
77 | ralink,ngpio = <16>; | ||
78 | ralink,regs = [ 00 04 08 0c | ||
79 | 10 14 18 1c | ||
80 | 20 24 ]; | ||
81 | }; | ||
82 | |||
83 | gpio2: gpio@660 { | ||
84 | compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio"; | ||
85 | reg = <0x660 0x24>; | ||
86 | |||
87 | gpio-controller; | ||
88 | #gpio-cells = <2>; | ||
89 | |||
90 | ralink,ngpio = <12>; | ||
91 | ralink,regs = [ 00 04 08 0c | ||
92 | 10 14 18 1c | ||
93 | 20 24 ]; | ||
94 | }; | ||
95 | |||
96 | uartlite@c00 { | ||
97 | compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a"; | ||
98 | reg = <0xc00 0x100>; | ||
99 | |||
100 | interrupt-parent = <&intc>; | ||
101 | interrupts = <12>; | ||
102 | |||
103 | reg-shift = <2>; | ||
104 | }; | ||
105 | }; | ||
106 | }; | ||
diff --git a/arch/mips/ralink/dts/rt3052_eval.dts b/arch/mips/ralink/dts/rt3052_eval.dts new file mode 100644 index 000000000000..148a590bc419 --- /dev/null +++ b/arch/mips/ralink/dts/rt3052_eval.dts | |||
@@ -0,0 +1,52 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "rt3050.dtsi" | ||
4 | |||
5 | / { | ||
6 | #address-cells = <1>; | ||
7 | #size-cells = <1>; | ||
8 | compatible = "ralink,rt3052-eval-board", "ralink,rt3052-soc"; | ||
9 | model = "Ralink RT3052 evaluation board"; | ||
10 | |||
11 | memory@0 { | ||
12 | reg = <0x0 0x2000000>; | ||
13 | }; | ||
14 | |||
15 | palmbus@10000000 { | ||
16 | sysc@0 { | ||
17 | ralink,pinmmux = "uartlite", "spi"; | ||
18 | ralink,uartmux = "gpio"; | ||
19 | ralink,wdtmux = <0>; | ||
20 | }; | ||
21 | }; | ||
22 | |||
23 | cfi@1f000000 { | ||
24 | compatible = "cfi-flash"; | ||
25 | reg = <0x1f000000 0x800000>; | ||
26 | |||
27 | bank-width = <2>; | ||
28 | device-width = <2>; | ||
29 | #address-cells = <1>; | ||
30 | #size-cells = <1>; | ||
31 | |||
32 | partition@0 { | ||
33 | label = "uboot"; | ||
34 | reg = <0x0 0x30000>; | ||
35 | read-only; | ||
36 | }; | ||
37 | partition@30000 { | ||
38 | label = "uboot-env"; | ||
39 | reg = <0x30000 0x10000>; | ||
40 | read-only; | ||
41 | }; | ||
42 | partition@40000 { | ||
43 | label = "calibration"; | ||
44 | reg = <0x40000 0x10000>; | ||
45 | read-only; | ||
46 | }; | ||
47 | partition@50000 { | ||
48 | label = "linux"; | ||
49 | reg = <0x50000 0x7b0000>; | ||
50 | }; | ||
51 | }; | ||
52 | }; | ||
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c new file mode 100644 index 000000000000..c4ae47eb24ab --- /dev/null +++ b/arch/mips/ralink/early_printk.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/serial_reg.h> | ||
11 | |||
12 | #include <asm/addrspace.h> | ||
13 | |||
14 | #define EARLY_UART_BASE 0x10000c00 | ||
15 | |||
16 | #define UART_REG_RX 0x00 | ||
17 | #define UART_REG_TX 0x04 | ||
18 | #define UART_REG_IER 0x08 | ||
19 | #define UART_REG_IIR 0x0c | ||
20 | #define UART_REG_FCR 0x10 | ||
21 | #define UART_REG_LCR 0x14 | ||
22 | #define UART_REG_MCR 0x18 | ||
23 | #define UART_REG_LSR 0x1c | ||
24 | |||
25 | static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); | ||
26 | |||
27 | static inline void uart_w32(u32 val, unsigned reg) | ||
28 | { | ||
29 | __raw_writel(val, uart_membase + reg); | ||
30 | } | ||
31 | |||
32 | static inline u32 uart_r32(unsigned reg) | ||
33 | { | ||
34 | return __raw_readl(uart_membase + reg); | ||
35 | } | ||
36 | |||
37 | void prom_putchar(unsigned char ch) | ||
38 | { | ||
39 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) | ||
40 | ; | ||
41 | uart_w32(ch, UART_REG_TX); | ||
42 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) | ||
43 | ; | ||
44 | } | ||
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c new file mode 100644 index 000000000000..6d054c5ec9ab --- /dev/null +++ b/arch/mips/ralink/irq.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/io.h> | ||
11 | #include <linux/bitops.h> | ||
12 | #include <linux/of_platform.h> | ||
13 | #include <linux/of_address.h> | ||
14 | #include <linux/of_irq.h> | ||
15 | #include <linux/irqdomain.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | |||
18 | #include <asm/irq_cpu.h> | ||
19 | #include <asm/mipsregs.h> | ||
20 | |||
21 | #include "common.h" | ||
22 | |||
23 | /* INTC register offsets */ | ||
24 | #define INTC_REG_STATUS0 0x00 | ||
25 | #define INTC_REG_STATUS1 0x04 | ||
26 | #define INTC_REG_TYPE 0x20 | ||
27 | #define INTC_REG_RAW_STATUS 0x30 | ||
28 | #define INTC_REG_ENABLE 0x34 | ||
29 | #define INTC_REG_DISABLE 0x38 | ||
30 | |||
31 | #define INTC_INT_GLOBAL BIT(31) | ||
32 | |||
33 | #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) | ||
34 | #define RALINK_CPU_IRQ_FE (MIPS_CPU_IRQ_BASE + 5) | ||
35 | #define RALINK_CPU_IRQ_WIFI (MIPS_CPU_IRQ_BASE + 6) | ||
36 | #define RALINK_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7) | ||
37 | |||
38 | /* we have a cascade of 8 irqs */ | ||
39 | #define RALINK_INTC_IRQ_BASE 8 | ||
40 | |||
41 | /* we have 32 SoC irqs */ | ||
42 | #define RALINK_INTC_IRQ_COUNT 32 | ||
43 | |||
44 | #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) | ||
45 | |||
46 | static void __iomem *rt_intc_membase; | ||
47 | |||
48 | static inline void rt_intc_w32(u32 val, unsigned reg) | ||
49 | { | ||
50 | __raw_writel(val, rt_intc_membase + reg); | ||
51 | } | ||
52 | |||
53 | static inline u32 rt_intc_r32(unsigned reg) | ||
54 | { | ||
55 | return __raw_readl(rt_intc_membase + reg); | ||
56 | } | ||
57 | |||
58 | static void ralink_intc_irq_unmask(struct irq_data *d) | ||
59 | { | ||
60 | rt_intc_w32(BIT(d->hwirq), INTC_REG_ENABLE); | ||
61 | } | ||
62 | |||
63 | static void ralink_intc_irq_mask(struct irq_data *d) | ||
64 | { | ||
65 | rt_intc_w32(BIT(d->hwirq), INTC_REG_DISABLE); | ||
66 | } | ||
67 | |||
68 | static struct irq_chip ralink_intc_irq_chip = { | ||
69 | .name = "INTC", | ||
70 | .irq_unmask = ralink_intc_irq_unmask, | ||
71 | .irq_mask = ralink_intc_irq_mask, | ||
72 | .irq_mask_ack = ralink_intc_irq_mask, | ||
73 | }; | ||
74 | |||
75 | unsigned int __cpuinit get_c0_compare_int(void) | ||
76 | { | ||
77 | return CP0_LEGACY_COMPARE_IRQ; | ||
78 | } | ||
79 | |||
80 | static void ralink_intc_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
81 | { | ||
82 | u32 pending = rt_intc_r32(INTC_REG_STATUS0); | ||
83 | |||
84 | if (pending) { | ||
85 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
86 | generic_handle_irq(irq_find_mapping(domain, __ffs(pending))); | ||
87 | } else { | ||
88 | spurious_interrupt(); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | asmlinkage void plat_irq_dispatch(void) | ||
93 | { | ||
94 | unsigned long pending; | ||
95 | |||
96 | pending = read_c0_status() & read_c0_cause() & ST0_IM; | ||
97 | |||
98 | if (pending & STATUSF_IP7) | ||
99 | do_IRQ(RALINK_CPU_IRQ_COUNTER); | ||
100 | |||
101 | else if (pending & STATUSF_IP5) | ||
102 | do_IRQ(RALINK_CPU_IRQ_FE); | ||
103 | |||
104 | else if (pending & STATUSF_IP6) | ||
105 | do_IRQ(RALINK_CPU_IRQ_WIFI); | ||
106 | |||
107 | else if (pending & STATUSF_IP2) | ||
108 | do_IRQ(RALINK_CPU_IRQ_INTC); | ||
109 | |||
110 | else | ||
111 | spurious_interrupt(); | ||
112 | } | ||
113 | |||
114 | static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | ||
115 | { | ||
116 | irq_set_chip_and_handler(irq, &ralink_intc_irq_chip, handle_level_irq); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static const struct irq_domain_ops irq_domain_ops = { | ||
122 | .xlate = irq_domain_xlate_onecell, | ||
123 | .map = intc_map, | ||
124 | }; | ||
125 | |||
126 | static int __init intc_of_init(struct device_node *node, | ||
127 | struct device_node *parent) | ||
128 | { | ||
129 | struct resource res; | ||
130 | struct irq_domain *domain; | ||
131 | int irq; | ||
132 | |||
133 | irq = irq_of_parse_and_map(node, 0); | ||
134 | if (!irq) | ||
135 | panic("Failed to get INTC IRQ"); | ||
136 | |||
137 | if (of_address_to_resource(node, 0, &res)) | ||
138 | panic("Failed to get intc memory range"); | ||
139 | |||
140 | if (request_mem_region(res.start, resource_size(&res), | ||
141 | res.name) < 0) | ||
142 | pr_err("Failed to request intc memory"); | ||
143 | |||
144 | rt_intc_membase = ioremap_nocache(res.start, | ||
145 | resource_size(&res)); | ||
146 | if (!rt_intc_membase) | ||
147 | panic("Failed to remap intc memory"); | ||
148 | |||
149 | /* disable all interrupts */ | ||
150 | rt_intc_w32(~0, INTC_REG_DISABLE); | ||
151 | |||
152 | /* route all INTC interrupts to MIPS HW0 interrupt */ | ||
153 | rt_intc_w32(0, INTC_REG_TYPE); | ||
154 | |||
155 | domain = irq_domain_add_legacy(node, RALINK_INTC_IRQ_COUNT, | ||
156 | RALINK_INTC_IRQ_BASE, 0, &irq_domain_ops, NULL); | ||
157 | if (!domain) | ||
158 | panic("Failed to add irqdomain"); | ||
159 | |||
160 | rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE); | ||
161 | |||
162 | irq_set_chained_handler(irq, ralink_intc_irq_handler); | ||
163 | irq_set_handler_data(irq, domain); | ||
164 | |||
165 | cp0_perfcount_irq = irq_create_mapping(domain, 9); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static struct of_device_id __initdata of_irq_ids[] = { | ||
171 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, | ||
172 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, | ||
173 | {}, | ||
174 | }; | ||
175 | |||
176 | void __init arch_init_irq(void) | ||
177 | { | ||
178 | of_irq_init(of_irq_ids); | ||
179 | } | ||
180 | |||
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c new file mode 100644 index 000000000000..4165e70775be --- /dev/null +++ b/arch/mips/ralink/of.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> | ||
8 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
9 | */ | ||
10 | |||
11 | #include <linux/io.h> | ||
12 | #include <linux/clk.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/of_fdt.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/bootmem.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <linux/of_address.h> | ||
19 | |||
20 | #include <asm/reboot.h> | ||
21 | #include <asm/bootinfo.h> | ||
22 | #include <asm/addrspace.h> | ||
23 | |||
24 | #include "common.h" | ||
25 | |||
26 | __iomem void *rt_sysc_membase; | ||
27 | __iomem void *rt_memc_membase; | ||
28 | |||
29 | extern struct boot_param_header __dtb_start; | ||
30 | |||
31 | __iomem void *plat_of_remap_node(const char *node) | ||
32 | { | ||
33 | struct resource res; | ||
34 | struct device_node *np; | ||
35 | |||
36 | np = of_find_compatible_node(NULL, NULL, node); | ||
37 | if (!np) | ||
38 | panic("Failed to find %s node", node); | ||
39 | |||
40 | if (of_address_to_resource(np, 0, &res)) | ||
41 | panic("Failed to get resource for %s", node); | ||
42 | |||
43 | if ((request_mem_region(res.start, | ||
44 | resource_size(&res), | ||
45 | res.name) < 0)) | ||
46 | panic("Failed to request resources for %s", node); | ||
47 | |||
48 | return ioremap_nocache(res.start, resource_size(&res)); | ||
49 | } | ||
50 | |||
51 | void __init device_tree_init(void) | ||
52 | { | ||
53 | unsigned long base, size; | ||
54 | void *fdt_copy; | ||
55 | |||
56 | if (!initial_boot_params) | ||
57 | return; | ||
58 | |||
59 | base = virt_to_phys((void *)initial_boot_params); | ||
60 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
61 | |||
62 | /* Before we do anything, lets reserve the dt blob */ | ||
63 | reserve_bootmem(base, size, BOOTMEM_DEFAULT); | ||
64 | |||
65 | /* The strings in the flattened tree are referenced directly by the | ||
66 | * device tree, so copy the flattened device tree from init memory | ||
67 | * to regular memory. | ||
68 | */ | ||
69 | fdt_copy = alloc_bootmem(size); | ||
70 | memcpy(fdt_copy, initial_boot_params, size); | ||
71 | initial_boot_params = fdt_copy; | ||
72 | |||
73 | unflatten_device_tree(); | ||
74 | |||
75 | /* free the space reserved for the dt blob */ | ||
76 | free_bootmem(base, size); | ||
77 | } | ||
78 | |||
79 | void __init plat_mem_setup(void) | ||
80 | { | ||
81 | set_io_port_base(KSEG1); | ||
82 | |||
83 | /* | ||
84 | * Load the builtin devicetree. This causes the chosen node to be | ||
85 | * parsed resulting in our memory appearing | ||
86 | */ | ||
87 | __dt_setup_arch(&__dtb_start); | ||
88 | } | ||
89 | |||
90 | static int __init plat_of_setup(void) | ||
91 | { | ||
92 | static struct of_device_id of_ids[3]; | ||
93 | int len = sizeof(of_ids[0].compatible); | ||
94 | |||
95 | if (!of_have_populated_dt()) | ||
96 | panic("device tree not present"); | ||
97 | |||
98 | strncpy(of_ids[0].compatible, soc_info.compatible, len); | ||
99 | strncpy(of_ids[1].compatible, "palmbus", len); | ||
100 | |||
101 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) | ||
102 | panic("failed to populate DT\n"); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | arch_initcall(plat_of_setup); | ||
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c new file mode 100644 index 000000000000..9c64f029d047 --- /dev/null +++ b/arch/mips/ralink/prom.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2010 Joonas Lahtinen <joonas.lahtinen@gmail.com> | ||
8 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
9 | */ | ||
10 | |||
11 | #include <linux/string.h> | ||
12 | #include <linux/of_fdt.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | |||
15 | #include <asm/bootinfo.h> | ||
16 | #include <asm/addrspace.h> | ||
17 | |||
18 | #include "common.h" | ||
19 | |||
20 | struct ralink_soc_info soc_info; | ||
21 | |||
22 | const char *get_system_type(void) | ||
23 | { | ||
24 | return soc_info.sys_type; | ||
25 | } | ||
26 | |||
27 | static __init void prom_init_cmdline(int argc, char **argv) | ||
28 | { | ||
29 | int i; | ||
30 | |||
31 | pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n", | ||
32 | (unsigned int)fw_arg0, (unsigned int)fw_arg1, | ||
33 | (unsigned int)fw_arg2, (unsigned int)fw_arg3); | ||
34 | |||
35 | argc = fw_arg0; | ||
36 | argv = (char **) KSEG1ADDR(fw_arg1); | ||
37 | |||
38 | if (!argv) { | ||
39 | pr_debug("argv=%p is invalid, skipping\n", | ||
40 | argv); | ||
41 | return; | ||
42 | } | ||
43 | |||
44 | for (i = 0; i < argc; i++) { | ||
45 | char *p = (char *) KSEG1ADDR(argv[i]); | ||
46 | |||
47 | if (CPHYSADDR(p) && *p) { | ||
48 | pr_debug("argv[%d]: %s\n", i, p); | ||
49 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | ||
50 | strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
55 | void __init prom_init(void) | ||
56 | { | ||
57 | int argc; | ||
58 | char **argv; | ||
59 | |||
60 | prom_soc_init(&soc_info); | ||
61 | |||
62 | pr_info("SoC Type: %s\n", get_system_type()); | ||
63 | |||
64 | prom_init_cmdline(argc, argv); | ||
65 | } | ||
66 | |||
67 | void __init prom_free_prom_memory(void) | ||
68 | { | ||
69 | } | ||
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c new file mode 100644 index 000000000000..22120e512e7e --- /dev/null +++ b/arch/mips/ralink/reset.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
8 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
9 | */ | ||
10 | |||
11 | #include <linux/pm.h> | ||
12 | #include <linux/io.h> | ||
13 | |||
14 | #include <asm/reboot.h> | ||
15 | |||
16 | #include <asm/mach-ralink/ralink_regs.h> | ||
17 | |||
18 | /* Reset Control */ | ||
19 | #define SYSC_REG_RESET_CTRL 0x034 | ||
20 | #define RSTCTL_RESET_SYSTEM BIT(0) | ||
21 | |||
22 | static void ralink_restart(char *command) | ||
23 | { | ||
24 | local_irq_disable(); | ||
25 | rt_sysc_w32(RSTCTL_RESET_SYSTEM, SYSC_REG_RESET_CTRL); | ||
26 | unreachable(); | ||
27 | } | ||
28 | |||
29 | static void ralink_halt(void) | ||
30 | { | ||
31 | local_irq_disable(); | ||
32 | unreachable(); | ||
33 | } | ||
34 | |||
35 | static int __init mips_reboot_setup(void) | ||
36 | { | ||
37 | _machine_restart = ralink_restart; | ||
38 | _machine_halt = ralink_halt; | ||
39 | pm_power_off = ralink_halt; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | arch_initcall(mips_reboot_setup); | ||
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c new file mode 100644 index 000000000000..0a4bbdcf59d9 --- /dev/null +++ b/arch/mips/ralink/rt305x.c | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Parts of this file are based on Ralink's 2.6.21 BSP | ||
7 | * | ||
8 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
9 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
10 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | |||
17 | #include <asm/mipsregs.h> | ||
18 | #include <asm/mach-ralink/ralink_regs.h> | ||
19 | #include <asm/mach-ralink/rt305x.h> | ||
20 | |||
21 | #include "common.h" | ||
22 | |||
23 | enum rt305x_soc_type rt305x_soc; | ||
24 | |||
25 | struct ralink_pinmux_grp mode_mux[] = { | ||
26 | { | ||
27 | .name = "i2c", | ||
28 | .mask = RT305X_GPIO_MODE_I2C, | ||
29 | .gpio_first = RT305X_GPIO_I2C_SD, | ||
30 | .gpio_last = RT305X_GPIO_I2C_SCLK, | ||
31 | }, { | ||
32 | .name = "spi", | ||
33 | .mask = RT305X_GPIO_MODE_SPI, | ||
34 | .gpio_first = RT305X_GPIO_SPI_EN, | ||
35 | .gpio_last = RT305X_GPIO_SPI_CLK, | ||
36 | }, { | ||
37 | .name = "uartlite", | ||
38 | .mask = RT305X_GPIO_MODE_UART1, | ||
39 | .gpio_first = RT305X_GPIO_UART1_TXD, | ||
40 | .gpio_last = RT305X_GPIO_UART1_RXD, | ||
41 | }, { | ||
42 | .name = "jtag", | ||
43 | .mask = RT305X_GPIO_MODE_JTAG, | ||
44 | .gpio_first = RT305X_GPIO_JTAG_TDO, | ||
45 | .gpio_last = RT305X_GPIO_JTAG_TDI, | ||
46 | }, { | ||
47 | .name = "mdio", | ||
48 | .mask = RT305X_GPIO_MODE_MDIO, | ||
49 | .gpio_first = RT305X_GPIO_MDIO_MDC, | ||
50 | .gpio_last = RT305X_GPIO_MDIO_MDIO, | ||
51 | }, { | ||
52 | .name = "sdram", | ||
53 | .mask = RT305X_GPIO_MODE_SDRAM, | ||
54 | .gpio_first = RT305X_GPIO_SDRAM_MD16, | ||
55 | .gpio_last = RT305X_GPIO_SDRAM_MD31, | ||
56 | }, { | ||
57 | .name = "rgmii", | ||
58 | .mask = RT305X_GPIO_MODE_RGMII, | ||
59 | .gpio_first = RT305X_GPIO_GE0_TXD0, | ||
60 | .gpio_last = RT305X_GPIO_GE0_RXCLK, | ||
61 | }, {0} | ||
62 | }; | ||
63 | |||
64 | struct ralink_pinmux_grp uart_mux[] = { | ||
65 | { | ||
66 | .name = "uartf", | ||
67 | .mask = RT305X_GPIO_MODE_UARTF, | ||
68 | .gpio_first = RT305X_GPIO_7, | ||
69 | .gpio_last = RT305X_GPIO_14, | ||
70 | }, { | ||
71 | .name = "pcm uartf", | ||
72 | .mask = RT305X_GPIO_MODE_PCM_UARTF, | ||
73 | .gpio_first = RT305X_GPIO_7, | ||
74 | .gpio_last = RT305X_GPIO_14, | ||
75 | }, { | ||
76 | .name = "pcm i2s", | ||
77 | .mask = RT305X_GPIO_MODE_PCM_I2S, | ||
78 | .gpio_first = RT305X_GPIO_7, | ||
79 | .gpio_last = RT305X_GPIO_14, | ||
80 | }, { | ||
81 | .name = "i2s uartf", | ||
82 | .mask = RT305X_GPIO_MODE_I2S_UARTF, | ||
83 | .gpio_first = RT305X_GPIO_7, | ||
84 | .gpio_last = RT305X_GPIO_14, | ||
85 | }, { | ||
86 | .name = "pcm gpio", | ||
87 | .mask = RT305X_GPIO_MODE_PCM_GPIO, | ||
88 | .gpio_first = RT305X_GPIO_10, | ||
89 | .gpio_last = RT305X_GPIO_14, | ||
90 | }, { | ||
91 | .name = "gpio uartf", | ||
92 | .mask = RT305X_GPIO_MODE_GPIO_UARTF, | ||
93 | .gpio_first = RT305X_GPIO_7, | ||
94 | .gpio_last = RT305X_GPIO_14, | ||
95 | }, { | ||
96 | .name = "gpio i2s", | ||
97 | .mask = RT305X_GPIO_MODE_GPIO_I2S, | ||
98 | .gpio_first = RT305X_GPIO_7, | ||
99 | .gpio_last = RT305X_GPIO_14, | ||
100 | }, { | ||
101 | .name = "gpio", | ||
102 | .mask = RT305X_GPIO_MODE_GPIO, | ||
103 | }, {0} | ||
104 | }; | ||
105 | |||
106 | void rt305x_wdt_reset(void) | ||
107 | { | ||
108 | u32 t; | ||
109 | |||
110 | /* enable WDT reset output on pin SRAM_CS_N */ | ||
111 | t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); | ||
112 | t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT << | ||
113 | RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT; | ||
114 | rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); | ||
115 | } | ||
116 | |||
117 | struct ralink_pinmux gpio_pinmux = { | ||
118 | .mode = mode_mux, | ||
119 | .uart = uart_mux, | ||
120 | .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, | ||
121 | .wdt_reset = rt305x_wdt_reset, | ||
122 | }; | ||
123 | |||
124 | void __init ralink_clk_init(void) | ||
125 | { | ||
126 | unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate; | ||
127 | u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); | ||
128 | |||
129 | if (soc_is_rt305x() || soc_is_rt3350()) { | ||
130 | t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) & | ||
131 | RT305X_SYSCFG_CPUCLK_MASK; | ||
132 | switch (t) { | ||
133 | case RT305X_SYSCFG_CPUCLK_LOW: | ||
134 | cpu_rate = 320000000; | ||
135 | break; | ||
136 | case RT305X_SYSCFG_CPUCLK_HIGH: | ||
137 | cpu_rate = 384000000; | ||
138 | break; | ||
139 | } | ||
140 | sys_rate = uart_rate = wdt_rate = cpu_rate / 3; | ||
141 | } else if (soc_is_rt3352()) { | ||
142 | t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) & | ||
143 | RT3352_SYSCFG0_CPUCLK_MASK; | ||
144 | switch (t) { | ||
145 | case RT3352_SYSCFG0_CPUCLK_LOW: | ||
146 | cpu_rate = 384000000; | ||
147 | break; | ||
148 | case RT3352_SYSCFG0_CPUCLK_HIGH: | ||
149 | cpu_rate = 400000000; | ||
150 | break; | ||
151 | } | ||
152 | sys_rate = wdt_rate = cpu_rate / 3; | ||
153 | uart_rate = 40000000; | ||
154 | } else if (soc_is_rt5350()) { | ||
155 | t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) & | ||
156 | RT5350_SYSCFG0_CPUCLK_MASK; | ||
157 | switch (t) { | ||
158 | case RT5350_SYSCFG0_CPUCLK_360: | ||
159 | cpu_rate = 360000000; | ||
160 | sys_rate = cpu_rate / 3; | ||
161 | break; | ||
162 | case RT5350_SYSCFG0_CPUCLK_320: | ||
163 | cpu_rate = 320000000; | ||
164 | sys_rate = cpu_rate / 4; | ||
165 | break; | ||
166 | case RT5350_SYSCFG0_CPUCLK_300: | ||
167 | cpu_rate = 300000000; | ||
168 | sys_rate = cpu_rate / 3; | ||
169 | break; | ||
170 | default: | ||
171 | BUG(); | ||
172 | } | ||
173 | uart_rate = 40000000; | ||
174 | wdt_rate = sys_rate; | ||
175 | } else { | ||
176 | BUG(); | ||
177 | } | ||
178 | |||
179 | ralink_clk_add("cpu", cpu_rate); | ||
180 | ralink_clk_add("10000b00.spi", sys_rate); | ||
181 | ralink_clk_add("10000100.timer", wdt_rate); | ||
182 | ralink_clk_add("10000500.uart", uart_rate); | ||
183 | ralink_clk_add("10000c00.uartlite", uart_rate); | ||
184 | } | ||
185 | |||
186 | void __init ralink_of_remap(void) | ||
187 | { | ||
188 | rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc"); | ||
189 | rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc"); | ||
190 | |||
191 | if (!rt_sysc_membase || !rt_memc_membase) | ||
192 | panic("Failed to remap core resources"); | ||
193 | } | ||
194 | |||
195 | void prom_soc_init(struct ralink_soc_info *soc_info) | ||
196 | { | ||
197 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); | ||
198 | unsigned char *name; | ||
199 | u32 n0; | ||
200 | u32 n1; | ||
201 | u32 id; | ||
202 | |||
203 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); | ||
204 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); | ||
205 | |||
206 | if (n0 == RT3052_CHIP_NAME0 && n1 == RT3052_CHIP_NAME1) { | ||
207 | unsigned long icache_sets; | ||
208 | |||
209 | icache_sets = (read_c0_config1() >> 22) & 7; | ||
210 | if (icache_sets == 1) { | ||
211 | rt305x_soc = RT305X_SOC_RT3050; | ||
212 | name = "RT3050"; | ||
213 | soc_info->compatible = "ralink,rt3050-soc"; | ||
214 | } else { | ||
215 | rt305x_soc = RT305X_SOC_RT3052; | ||
216 | name = "RT3052"; | ||
217 | soc_info->compatible = "ralink,rt3052-soc"; | ||
218 | } | ||
219 | } else if (n0 == RT3350_CHIP_NAME0 && n1 == RT3350_CHIP_NAME1) { | ||
220 | rt305x_soc = RT305X_SOC_RT3350; | ||
221 | name = "RT3350"; | ||
222 | soc_info->compatible = "ralink,rt3350-soc"; | ||
223 | } else if (n0 == RT3352_CHIP_NAME0 && n1 == RT3352_CHIP_NAME1) { | ||
224 | rt305x_soc = RT305X_SOC_RT3352; | ||
225 | name = "RT3352"; | ||
226 | soc_info->compatible = "ralink,rt3352-soc"; | ||
227 | } else if (n0 == RT5350_CHIP_NAME0 && n1 == RT5350_CHIP_NAME1) { | ||
228 | rt305x_soc = RT305X_SOC_RT5350; | ||
229 | name = "RT5350"; | ||
230 | soc_info->compatible = "ralink,rt5350-soc"; | ||
231 | } else { | ||
232 | panic("rt305x: unknown SoC, n0:%08x n1:%08x\n", n0, n1); | ||
233 | } | ||
234 | |||
235 | id = __raw_readl(sysc + SYSC_REG_CHIP_ID); | ||
236 | |||
237 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, | ||
238 | "Ralink %s id:%u rev:%u", | ||
239 | name, | ||
240 | (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK, | ||
241 | (id & CHIP_ID_REV_MASK)); | ||
242 | } | ||
diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c index 984e561f0f7a..b952d5b1af86 100644 --- a/arch/mips/sgi-ip27/ip27-console.c +++ b/arch/mips/sgi-ip27/ip27-console.c | |||
@@ -31,7 +31,7 @@ static inline struct ioc3_uartregs *console_uart(void) | |||
31 | return &ioc3->sregs.uarta; | 31 | return &ioc3->sregs.uarta; |
32 | } | 32 | } |
33 | 33 | ||
34 | void __init prom_putchar(char c) | 34 | void prom_putchar(char c) |
35 | { | 35 | { |
36 | struct ioc3_uartregs *uart = console_uart(); | 36 | struct ioc3_uartregs *uart = console_uart(); |
37 | 37 | ||
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 560fe8991753..5524f2c7b05c 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -513,19 +513,19 @@ void __init txx9_sio_init(unsigned long baseaddr, int irq, | |||
513 | } | 513 | } |
514 | 514 | ||
515 | #ifdef CONFIG_EARLY_PRINTK | 515 | #ifdef CONFIG_EARLY_PRINTK |
516 | static void __init null_prom_putchar(char c) | 516 | static void null_prom_putchar(char c) |
517 | { | 517 | { |
518 | } | 518 | } |
519 | void (*txx9_prom_putchar)(char c) __initdata = null_prom_putchar; | 519 | void (*txx9_prom_putchar)(char c) = null_prom_putchar; |
520 | 520 | ||
521 | void __init prom_putchar(char c) | 521 | void prom_putchar(char c) |
522 | { | 522 | { |
523 | txx9_prom_putchar(c); | 523 | txx9_prom_putchar(c); |
524 | } | 524 | } |
525 | 525 | ||
526 | static void __iomem *early_txx9_sio_port; | 526 | static void __iomem *early_txx9_sio_port; |
527 | 527 | ||
528 | static void __init early_txx9_sio_putchar(char c) | 528 | static void early_txx9_sio_putchar(char c) |
529 | { | 529 | { |
530 | #define TXX9_SICISR 0x0c | 530 | #define TXX9_SICISR 0x0c |
531 | #define TXX9_SITFIFO 0x1c | 531 | #define TXX9_SITFIFO 0x1c |
diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h index c1be4397b1ed..a18abfc558eb 100644 --- a/arch/mn10300/include/asm/dma-mapping.h +++ b/arch/mn10300/include/asm/dma-mapping.h | |||
@@ -168,4 +168,19 @@ void dma_cache_sync(void *vaddr, size_t size, | |||
168 | mn10300_dcache_flush_inv(); | 168 | mn10300_dcache_flush_inv(); |
169 | } | 169 | } |
170 | 170 | ||
171 | /* Not supported for now */ | ||
172 | static inline int dma_mmap_coherent(struct device *dev, | ||
173 | struct vm_area_struct *vma, void *cpu_addr, | ||
174 | dma_addr_t dma_addr, size_t size) | ||
175 | { | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
180 | void *cpu_addr, dma_addr_t dma_addr, | ||
181 | size_t size) | ||
182 | { | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
171 | #endif | 186 | #endif |
diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h index 467bbd510eac..106b395688e1 100644 --- a/arch/parisc/include/asm/dma-mapping.h +++ b/arch/parisc/include/asm/dma-mapping.h | |||
@@ -238,4 +238,19 @@ void * sba_get_iommu(struct parisc_device *dev); | |||
238 | /* At the moment, we panic on error for IOMMU resource exaustion */ | 238 | /* At the moment, we panic on error for IOMMU resource exaustion */ |
239 | #define dma_mapping_error(dev, x) 0 | 239 | #define dma_mapping_error(dev, x) 0 |
240 | 240 | ||
241 | /* This API cannot be supported on PA-RISC */ | ||
242 | static inline int dma_mmap_coherent(struct device *dev, | ||
243 | struct vm_area_struct *vma, void *cpu_addr, | ||
244 | dma_addr_t dma_addr, size_t size) | ||
245 | { | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
250 | void *cpu_addr, dma_addr_t dma_addr, | ||
251 | size_t size) | ||
252 | { | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | |||
241 | #endif | 256 | #endif |
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 56585086413a..7443481a315c 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S | |||
@@ -115,11 +115,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
115 | sldi r29,r5,SID_SHIFT - VPN_SHIFT | 115 | sldi r29,r5,SID_SHIFT - VPN_SHIFT |
116 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) | 116 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) |
117 | or r29,r28,r29 | 117 | or r29,r28,r29 |
118 | 118 | /* | |
119 | /* Calculate hash value for primary slot and store it in r28 */ | 119 | * Calculate hash value for primary slot and store it in r28 |
120 | rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ | 120 | * r3 = va, r5 = vsid |
121 | rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */ | 121 | * r0 = (va >> 12) & ((1ul << (28 - 12)) -1) |
122 | xor r28,r5,r0 | 122 | */ |
123 | rldicl r0,r3,64-12,48 | ||
124 | xor r28,r5,r0 /* hash */ | ||
123 | b 4f | 125 | b 4f |
124 | 126 | ||
125 | 3: /* Calc vpn and put it in r29 */ | 127 | 3: /* Calc vpn and put it in r29 */ |
@@ -130,11 +132,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
130 | /* | 132 | /* |
131 | * calculate hash value for primary slot and | 133 | * calculate hash value for primary slot and |
132 | * store it in r28 for 1T segment | 134 | * store it in r28 for 1T segment |
135 | * r3 = va, r5 = vsid | ||
133 | */ | 136 | */ |
134 | rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ | 137 | sldi r28,r5,25 /* vsid << 25 */ |
135 | clrldi r5,r5,40 /* vsid & 0xffffff */ | 138 | /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */ |
136 | rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ | 139 | rldicl r0,r3,64-12,36 |
137 | xor r28,r28,r5 | 140 | xor r28,r28,r5 /* vsid ^ ( vsid << 25) */ |
138 | xor r28,r28,r0 /* hash */ | 141 | xor r28,r28,r0 /* hash */ |
139 | 142 | ||
140 | /* Convert linux PTE bits into HW equivalents */ | 143 | /* Convert linux PTE bits into HW equivalents */ |
@@ -407,11 +410,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
407 | */ | 410 | */ |
408 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) | 411 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) |
409 | or r29,r28,r29 | 412 | or r29,r28,r29 |
410 | 413 | /* | |
411 | /* Calculate hash value for primary slot and store it in r28 */ | 414 | * Calculate hash value for primary slot and store it in r28 |
412 | rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ | 415 | * r3 = va, r5 = vsid |
413 | rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */ | 416 | * r0 = (va >> 12) & ((1ul << (28 - 12)) -1) |
414 | xor r28,r5,r0 | 417 | */ |
418 | rldicl r0,r3,64-12,48 | ||
419 | xor r28,r5,r0 /* hash */ | ||
415 | b 4f | 420 | b 4f |
416 | 421 | ||
417 | 3: /* Calc vpn and put it in r29 */ | 422 | 3: /* Calc vpn and put it in r29 */ |
@@ -426,11 +431,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
426 | /* | 431 | /* |
427 | * Calculate hash value for primary slot and | 432 | * Calculate hash value for primary slot and |
428 | * store it in r28 for 1T segment | 433 | * store it in r28 for 1T segment |
434 | * r3 = va, r5 = vsid | ||
429 | */ | 435 | */ |
430 | rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ | 436 | sldi r28,r5,25 /* vsid << 25 */ |
431 | clrldi r5,r5,40 /* vsid & 0xffffff */ | 437 | /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */ |
432 | rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ | 438 | rldicl r0,r3,64-12,36 |
433 | xor r28,r28,r5 | 439 | xor r28,r28,r5 /* vsid ^ ( vsid << 25) */ |
434 | xor r28,r28,r0 /* hash */ | 440 | xor r28,r28,r0 /* hash */ |
435 | 441 | ||
436 | /* Convert linux PTE bits into HW equivalents */ | 442 | /* Convert linux PTE bits into HW equivalents */ |
@@ -752,25 +758,27 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
752 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) | 758 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) |
753 | or r29,r28,r29 | 759 | or r29,r28,r29 |
754 | 760 | ||
755 | /* Calculate hash value for primary slot and store it in r28 */ | 761 | /* Calculate hash value for primary slot and store it in r28 |
756 | rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ | 762 | * r3 = va, r5 = vsid |
757 | rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */ | 763 | * r0 = (va >> 16) & ((1ul << (28 - 16)) -1) |
758 | xor r28,r5,r0 | 764 | */ |
765 | rldicl r0,r3,64-16,52 | ||
766 | xor r28,r5,r0 /* hash */ | ||
759 | b 4f | 767 | b 4f |
760 | 768 | ||
761 | 3: /* Calc vpn and put it in r29 */ | 769 | 3: /* Calc vpn and put it in r29 */ |
762 | sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT | 770 | sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT |
763 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) | 771 | rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) |
764 | or r29,r28,r29 | 772 | or r29,r28,r29 |
765 | |||
766 | /* | 773 | /* |
767 | * calculate hash value for primary slot and | 774 | * calculate hash value for primary slot and |
768 | * store it in r28 for 1T segment | 775 | * store it in r28 for 1T segment |
776 | * r3 = va, r5 = vsid | ||
769 | */ | 777 | */ |
770 | rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ | 778 | sldi r28,r5,25 /* vsid << 25 */ |
771 | clrldi r5,r5,40 /* vsid & 0xffffff */ | 779 | /* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */ |
772 | rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */ | 780 | rldicl r0,r3,64-16,40 |
773 | xor r28,r28,r5 | 781 | xor r28,r28,r5 /* vsid ^ ( vsid << 25) */ |
774 | xor r28,r28,r0 /* hash */ | 782 | xor r28,r28,r0 /* hash */ |
775 | 783 | ||
776 | /* Convert linux PTE bits into HW equivalents */ | 784 | /* Convert linux PTE bits into HW equivalents */ |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 102ff7cb3e41..142c4ceff112 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -207,7 +207,7 @@ sysexit_from_sys_call: | |||
207 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) | 207 | testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) |
208 | jnz ia32_ret_from_sys_call | 208 | jnz ia32_ret_from_sys_call |
209 | TRACE_IRQS_ON | 209 | TRACE_IRQS_ON |
210 | sti | 210 | ENABLE_INTERRUPTS(CLBR_NONE) |
211 | movl %eax,%esi /* second arg, syscall return value */ | 211 | movl %eax,%esi /* second arg, syscall return value */ |
212 | cmpl $-MAX_ERRNO,%eax /* is it an error ? */ | 212 | cmpl $-MAX_ERRNO,%eax /* is it an error ? */ |
213 | jbe 1f | 213 | jbe 1f |
@@ -217,7 +217,7 @@ sysexit_from_sys_call: | |||
217 | call __audit_syscall_exit | 217 | call __audit_syscall_exit |
218 | movq RAX-ARGOFFSET(%rsp),%rax /* reload syscall return value */ | 218 | movq RAX-ARGOFFSET(%rsp),%rax /* reload syscall return value */ |
219 | movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi | 219 | movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi |
220 | cli | 220 | DISABLE_INTERRUPTS(CLBR_NONE) |
221 | TRACE_IRQS_OFF | 221 | TRACE_IRQS_OFF |
222 | testl %edi,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) | 222 | testl %edi,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) |
223 | jz \exit | 223 | jz \exit |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index fe9edec6698a..84c1309c4c0c 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -298,8 +298,7 @@ struct _cache_attr { | |||
298 | unsigned int); | 298 | unsigned int); |
299 | }; | 299 | }; |
300 | 300 | ||
301 | #ifdef CONFIG_AMD_NB | 301 | #if defined(CONFIG_AMD_NB) && defined(CONFIG_SYSFS) |
302 | |||
303 | /* | 302 | /* |
304 | * L3 cache descriptors | 303 | * L3 cache descriptors |
305 | */ | 304 | */ |
@@ -524,9 +523,9 @@ store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count, | |||
524 | static struct _cache_attr subcaches = | 523 | static struct _cache_attr subcaches = |
525 | __ATTR(subcaches, 0644, show_subcaches, store_subcaches); | 524 | __ATTR(subcaches, 0644, show_subcaches, store_subcaches); |
526 | 525 | ||
527 | #else /* CONFIG_AMD_NB */ | 526 | #else |
528 | #define amd_init_l3_cache(x, y) | 527 | #define amd_init_l3_cache(x, y) |
529 | #endif /* CONFIG_AMD_NB */ | 528 | #endif /* CONFIG_AMD_NB && CONFIG_SYSFS */ |
530 | 529 | ||
531 | static int | 530 | static int |
532 | __cpuinit cpuid4_cache_lookup_regs(int index, | 531 | __cpuinit cpuid4_cache_lookup_regs(int index, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 93b9e1181f83..4914e94ad6e8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -2019,7 +2019,10 @@ __init int intel_pmu_init(void) | |||
2019 | break; | 2019 | break; |
2020 | 2020 | ||
2021 | case 28: /* Atom */ | 2021 | case 28: /* Atom */ |
2022 | case 54: /* Cedariew */ | 2022 | case 38: /* Lincroft */ |
2023 | case 39: /* Penwell */ | ||
2024 | case 53: /* Cloverview */ | ||
2025 | case 54: /* Cedarview */ | ||
2023 | memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, | 2026 | memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, |
2024 | sizeof(hw_cache_event_ids)); | 2027 | sizeof(hw_cache_event_ids)); |
2025 | 2028 | ||
@@ -2084,6 +2087,7 @@ __init int intel_pmu_init(void) | |||
2084 | pr_cont("SandyBridge events, "); | 2087 | pr_cont("SandyBridge events, "); |
2085 | break; | 2088 | break; |
2086 | case 58: /* IvyBridge */ | 2089 | case 58: /* IvyBridge */ |
2090 | case 62: /* IvyBridge EP */ | ||
2087 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, | 2091 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, |
2088 | sizeof(hw_cache_event_ids)); | 2092 | sizeof(hw_cache_event_ids)); |
2089 | memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, | 2093 | memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, |
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index f2af39f5dc3d..4820c232a0b9 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -19,7 +19,7 @@ static const u64 p6_perfmon_event_map[] = | |||
19 | 19 | ||
20 | }; | 20 | }; |
21 | 21 | ||
22 | static __initconst u64 p6_hw_cache_event_ids | 22 | static u64 p6_hw_cache_event_ids |
23 | [PERF_COUNT_HW_CACHE_MAX] | 23 | [PERF_COUNT_HW_CACHE_MAX] |
24 | [PERF_COUNT_HW_CACHE_OP_MAX] | 24 | [PERF_COUNT_HW_CACHE_OP_MAX] |
25 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | 25 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = |
diff --git a/arch/x86/tools/insn_sanity.c b/arch/x86/tools/insn_sanity.c index cc2f8c131286..872eb60e7806 100644 --- a/arch/x86/tools/insn_sanity.c +++ b/arch/x86/tools/insn_sanity.c | |||
@@ -55,7 +55,7 @@ static FILE *input_file; /* Input file name */ | |||
55 | static void usage(const char *err) | 55 | static void usage(const char *err) |
56 | { | 56 | { |
57 | if (err) | 57 | if (err) |
58 | fprintf(stderr, "Error: %s\n\n", err); | 58 | fprintf(stderr, "%s: Error: %s\n\n", prog, err); |
59 | fprintf(stderr, "Usage: %s [-y|-n|-v] [-s seed[,no]] [-m max] [-i input]\n", prog); | 59 | fprintf(stderr, "Usage: %s [-y|-n|-v] [-s seed[,no]] [-m max] [-i input]\n", prog); |
60 | fprintf(stderr, "\t-y 64bit mode\n"); | 60 | fprintf(stderr, "\t-y 64bit mode\n"); |
61 | fprintf(stderr, "\t-n 32bit mode\n"); | 61 | fprintf(stderr, "\t-n 32bit mode\n"); |
@@ -269,7 +269,13 @@ int main(int argc, char **argv) | |||
269 | insns++; | 269 | insns++; |
270 | } | 270 | } |
271 | 271 | ||
272 | fprintf(stdout, "%s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n", (errors) ? "Failure" : "Success", insns, (input_file) ? "given" : "random", errors, seed); | 272 | fprintf(stdout, "%s: %s: decoded and checked %d %s instructions with %d errors (seed:0x%x)\n", |
273 | prog, | ||
274 | (errors) ? "Failure" : "Success", | ||
275 | insns, | ||
276 | (input_file) ? "given" : "random", | ||
277 | errors, | ||
278 | seed); | ||
273 | 279 | ||
274 | return errors ? 1 : 0; | 280 | return errors ? 1 : 0; |
275 | } | 281 | } |
diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 4acb5feba1fb..172a02a6ad14 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h | |||
@@ -170,4 +170,19 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
170 | consistent_sync(vaddr, size, direction); | 170 | consistent_sync(vaddr, size, direction); |
171 | } | 171 | } |
172 | 172 | ||
173 | /* Not supported for now */ | ||
174 | static inline int dma_mmap_coherent(struct device *dev, | ||
175 | struct vm_area_struct *vma, void *cpu_addr, | ||
176 | dma_addr_t dma_addr, size_t size) | ||
177 | { | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, | ||
182 | void *cpu_addr, dma_addr_t dma_addr, | ||
183 | size_t size) | ||
184 | { | ||
185 | return -EINVAL; | ||
186 | } | ||
187 | |||
173 | #endif /* _XTENSA_DMA_MAPPING_H */ | 188 | #endif /* _XTENSA_DMA_MAPPING_H */ |
diff --git a/block/genhd.c b/block/genhd.c index 9a289d7c84bb..3993ebf4135f 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -35,6 +35,8 @@ static DEFINE_IDR(ext_devt_idr); | |||
35 | 35 | ||
36 | static struct device_type disk_type; | 36 | static struct device_type disk_type; |
37 | 37 | ||
38 | static void disk_check_events(struct disk_events *ev, | ||
39 | unsigned int *clearing_ptr); | ||
38 | static void disk_alloc_events(struct gendisk *disk); | 40 | static void disk_alloc_events(struct gendisk *disk); |
39 | static void disk_add_events(struct gendisk *disk); | 41 | static void disk_add_events(struct gendisk *disk); |
40 | static void disk_del_events(struct gendisk *disk); | 42 | static void disk_del_events(struct gendisk *disk); |
@@ -1549,6 +1551,7 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask) | |||
1549 | const struct block_device_operations *bdops = disk->fops; | 1551 | const struct block_device_operations *bdops = disk->fops; |
1550 | struct disk_events *ev = disk->ev; | 1552 | struct disk_events *ev = disk->ev; |
1551 | unsigned int pending; | 1553 | unsigned int pending; |
1554 | unsigned int clearing = mask; | ||
1552 | 1555 | ||
1553 | if (!ev) { | 1556 | if (!ev) { |
1554 | /* for drivers still using the old ->media_changed method */ | 1557 | /* for drivers still using the old ->media_changed method */ |
@@ -1558,34 +1561,53 @@ unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask) | |||
1558 | return 0; | 1561 | return 0; |
1559 | } | 1562 | } |
1560 | 1563 | ||
1561 | /* tell the workfn about the events being cleared */ | 1564 | disk_block_events(disk); |
1565 | |||
1566 | /* | ||
1567 | * store the union of mask and ev->clearing on the stack so that the | ||
1568 | * race with disk_flush_events does not cause ambiguity (ev->clearing | ||
1569 | * can still be modified even if events are blocked). | ||
1570 | */ | ||
1562 | spin_lock_irq(&ev->lock); | 1571 | spin_lock_irq(&ev->lock); |
1563 | ev->clearing |= mask; | 1572 | clearing |= ev->clearing; |
1573 | ev->clearing = 0; | ||
1564 | spin_unlock_irq(&ev->lock); | 1574 | spin_unlock_irq(&ev->lock); |
1565 | 1575 | ||
1566 | /* uncondtionally schedule event check and wait for it to finish */ | 1576 | disk_check_events(ev, &clearing); |
1567 | disk_block_events(disk); | 1577 | /* |
1568 | queue_delayed_work(system_freezable_wq, &ev->dwork, 0); | 1578 | * if ev->clearing is not 0, the disk_flush_events got called in the |
1569 | flush_delayed_work(&ev->dwork); | 1579 | * middle of this function, so we want to run the workfn without delay. |
1570 | __disk_unblock_events(disk, false); | 1580 | */ |
1581 | __disk_unblock_events(disk, ev->clearing ? true : false); | ||
1571 | 1582 | ||
1572 | /* then, fetch and clear pending events */ | 1583 | /* then, fetch and clear pending events */ |
1573 | spin_lock_irq(&ev->lock); | 1584 | spin_lock_irq(&ev->lock); |
1574 | WARN_ON_ONCE(ev->clearing & mask); /* cleared by workfn */ | ||
1575 | pending = ev->pending & mask; | 1585 | pending = ev->pending & mask; |
1576 | ev->pending &= ~mask; | 1586 | ev->pending &= ~mask; |
1577 | spin_unlock_irq(&ev->lock); | 1587 | spin_unlock_irq(&ev->lock); |
1588 | WARN_ON_ONCE(clearing & mask); | ||
1578 | 1589 | ||
1579 | return pending; | 1590 | return pending; |
1580 | } | 1591 | } |
1581 | 1592 | ||
1593 | /* | ||
1594 | * Separate this part out so that a different pointer for clearing_ptr can be | ||
1595 | * passed in for disk_clear_events. | ||
1596 | */ | ||
1582 | static void disk_events_workfn(struct work_struct *work) | 1597 | static void disk_events_workfn(struct work_struct *work) |
1583 | { | 1598 | { |
1584 | struct delayed_work *dwork = to_delayed_work(work); | 1599 | struct delayed_work *dwork = to_delayed_work(work); |
1585 | struct disk_events *ev = container_of(dwork, struct disk_events, dwork); | 1600 | struct disk_events *ev = container_of(dwork, struct disk_events, dwork); |
1601 | |||
1602 | disk_check_events(ev, &ev->clearing); | ||
1603 | } | ||
1604 | |||
1605 | static void disk_check_events(struct disk_events *ev, | ||
1606 | unsigned int *clearing_ptr) | ||
1607 | { | ||
1586 | struct gendisk *disk = ev->disk; | 1608 | struct gendisk *disk = ev->disk; |
1587 | char *envp[ARRAY_SIZE(disk_uevents) + 1] = { }; | 1609 | char *envp[ARRAY_SIZE(disk_uevents) + 1] = { }; |
1588 | unsigned int clearing = ev->clearing; | 1610 | unsigned int clearing = *clearing_ptr; |
1589 | unsigned int events; | 1611 | unsigned int events; |
1590 | unsigned long intv; | 1612 | unsigned long intv; |
1591 | int nr_events = 0, i; | 1613 | int nr_events = 0, i; |
@@ -1598,7 +1620,7 @@ static void disk_events_workfn(struct work_struct *work) | |||
1598 | 1620 | ||
1599 | events &= ~ev->pending; | 1621 | events &= ~ev->pending; |
1600 | ev->pending |= events; | 1622 | ev->pending |= events; |
1601 | ev->clearing &= ~clearing; | 1623 | *clearing_ptr &= ~clearing; |
1602 | 1624 | ||
1603 | intv = disk_events_poll_jiffies(disk); | 1625 | intv = disk_events_poll_jiffies(disk); |
1604 | if (!ev->block && intv) | 1626 | if (!ev->block && intv) |
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index 6a0955e6d4fc..53ecac5a2161 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h | |||
@@ -636,82 +636,82 @@ struct rx_buf_desc { | |||
636 | #define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE | 636 | #define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE |
637 | #define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE | 637 | #define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE |
638 | 638 | ||
639 | typedef volatile u_int freg_t; | 639 | typedef volatile u_int ffreg_t; |
640 | typedef u_int rreg_t; | 640 | typedef u_int rreg_t; |
641 | 641 | ||
642 | typedef struct _ffredn_t { | 642 | typedef struct _ffredn_t { |
643 | freg_t idlehead_high; /* Idle cell header (high) */ | 643 | ffreg_t idlehead_high; /* Idle cell header (high) */ |
644 | freg_t idlehead_low; /* Idle cell header (low) */ | 644 | ffreg_t idlehead_low; /* Idle cell header (low) */ |
645 | freg_t maxrate; /* Maximum rate */ | 645 | ffreg_t maxrate; /* Maximum rate */ |
646 | freg_t stparms; /* Traffic Management Parameters */ | 646 | ffreg_t stparms; /* Traffic Management Parameters */ |
647 | freg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ | 647 | ffreg_t abrubr_abr; /* ABRUBR Priority Byte 1, TCR Byte 0 */ |
648 | freg_t rm_type; /* */ | 648 | ffreg_t rm_type; /* */ |
649 | u_int filler5[0x17 - 0x06]; | 649 | u_int filler5[0x17 - 0x06]; |
650 | freg_t cmd_reg; /* Command register */ | 650 | ffreg_t cmd_reg; /* Command register */ |
651 | u_int filler18[0x20 - 0x18]; | 651 | u_int filler18[0x20 - 0x18]; |
652 | freg_t cbr_base; /* CBR Pointer Base */ | 652 | ffreg_t cbr_base; /* CBR Pointer Base */ |
653 | freg_t vbr_base; /* VBR Pointer Base */ | 653 | ffreg_t vbr_base; /* VBR Pointer Base */ |
654 | freg_t abr_base; /* ABR Pointer Base */ | 654 | ffreg_t abr_base; /* ABR Pointer Base */ |
655 | freg_t ubr_base; /* UBR Pointer Base */ | 655 | ffreg_t ubr_base; /* UBR Pointer Base */ |
656 | u_int filler24; | 656 | u_int filler24; |
657 | freg_t vbrwq_base; /* VBR Wait Queue Base */ | 657 | ffreg_t vbrwq_base; /* VBR Wait Queue Base */ |
658 | freg_t abrwq_base; /* ABR Wait Queue Base */ | 658 | ffreg_t abrwq_base; /* ABR Wait Queue Base */ |
659 | freg_t ubrwq_base; /* UBR Wait Queue Base */ | 659 | ffreg_t ubrwq_base; /* UBR Wait Queue Base */ |
660 | freg_t vct_base; /* Main VC Table Base */ | 660 | ffreg_t vct_base; /* Main VC Table Base */ |
661 | freg_t vcte_base; /* Extended Main VC Table Base */ | 661 | ffreg_t vcte_base; /* Extended Main VC Table Base */ |
662 | u_int filler2a[0x2C - 0x2A]; | 662 | u_int filler2a[0x2C - 0x2A]; |
663 | freg_t cbr_tab_beg; /* CBR Table Begin */ | 663 | ffreg_t cbr_tab_beg; /* CBR Table Begin */ |
664 | freg_t cbr_tab_end; /* CBR Table End */ | 664 | ffreg_t cbr_tab_end; /* CBR Table End */ |
665 | freg_t cbr_pointer; /* CBR Pointer */ | 665 | ffreg_t cbr_pointer; /* CBR Pointer */ |
666 | u_int filler2f[0x30 - 0x2F]; | 666 | u_int filler2f[0x30 - 0x2F]; |
667 | freg_t prq_st_adr; /* Packet Ready Queue Start Address */ | 667 | ffreg_t prq_st_adr; /* Packet Ready Queue Start Address */ |
668 | freg_t prq_ed_adr; /* Packet Ready Queue End Address */ | 668 | ffreg_t prq_ed_adr; /* Packet Ready Queue End Address */ |
669 | freg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ | 669 | ffreg_t prq_rd_ptr; /* Packet Ready Queue read pointer */ |
670 | freg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ | 670 | ffreg_t prq_wr_ptr; /* Packet Ready Queue write pointer */ |
671 | freg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ | 671 | ffreg_t tcq_st_adr; /* Transmit Complete Queue Start Address*/ |
672 | freg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ | 672 | ffreg_t tcq_ed_adr; /* Transmit Complete Queue End Address */ |
673 | freg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ | 673 | ffreg_t tcq_rd_ptr; /* Transmit Complete Queue read pointer */ |
674 | freg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ | 674 | ffreg_t tcq_wr_ptr; /* Transmit Complete Queue write pointer*/ |
675 | u_int filler38[0x40 - 0x38]; | 675 | u_int filler38[0x40 - 0x38]; |
676 | freg_t queue_base; /* Base address for PRQ and TCQ */ | 676 | ffreg_t queue_base; /* Base address for PRQ and TCQ */ |
677 | freg_t desc_base; /* Base address of descriptor table */ | 677 | ffreg_t desc_base; /* Base address of descriptor table */ |
678 | u_int filler42[0x45 - 0x42]; | 678 | u_int filler42[0x45 - 0x42]; |
679 | freg_t mode_reg_0; /* Mode register 0 */ | 679 | ffreg_t mode_reg_0; /* Mode register 0 */ |
680 | freg_t mode_reg_1; /* Mode register 1 */ | 680 | ffreg_t mode_reg_1; /* Mode register 1 */ |
681 | freg_t intr_status_reg;/* Interrupt Status register */ | 681 | ffreg_t intr_status_reg;/* Interrupt Status register */ |
682 | freg_t mask_reg; /* Mask Register */ | 682 | ffreg_t mask_reg; /* Mask Register */ |
683 | freg_t cell_ctr_high1; /* Total cell transfer count (high) */ | 683 | ffreg_t cell_ctr_high1; /* Total cell transfer count (high) */ |
684 | freg_t cell_ctr_lo1; /* Total cell transfer count (low) */ | 684 | ffreg_t cell_ctr_lo1; /* Total cell transfer count (low) */ |
685 | freg_t state_reg; /* Status register */ | 685 | ffreg_t state_reg; /* Status register */ |
686 | u_int filler4c[0x58 - 0x4c]; | 686 | u_int filler4c[0x58 - 0x4c]; |
687 | freg_t curr_desc_num; /* Contains the current descriptor num */ | 687 | ffreg_t curr_desc_num; /* Contains the current descriptor num */ |
688 | freg_t next_desc; /* Next descriptor */ | 688 | ffreg_t next_desc; /* Next descriptor */ |
689 | freg_t next_vc; /* Next VC */ | 689 | ffreg_t next_vc; /* Next VC */ |
690 | u_int filler5b[0x5d - 0x5b]; | 690 | u_int filler5b[0x5d - 0x5b]; |
691 | freg_t present_slot_cnt;/* Present slot count */ | 691 | ffreg_t present_slot_cnt;/* Present slot count */ |
692 | u_int filler5e[0x6a - 0x5e]; | 692 | u_int filler5e[0x6a - 0x5e]; |
693 | freg_t new_desc_num; /* New descriptor number */ | 693 | ffreg_t new_desc_num; /* New descriptor number */ |
694 | freg_t new_vc; /* New VC */ | 694 | ffreg_t new_vc; /* New VC */ |
695 | freg_t sched_tbl_ptr; /* Schedule table pointer */ | 695 | ffreg_t sched_tbl_ptr; /* Schedule table pointer */ |
696 | freg_t vbrwq_wptr; /* VBR wait queue write pointer */ | 696 | ffreg_t vbrwq_wptr; /* VBR wait queue write pointer */ |
697 | freg_t vbrwq_rptr; /* VBR wait queue read pointer */ | 697 | ffreg_t vbrwq_rptr; /* VBR wait queue read pointer */ |
698 | freg_t abrwq_wptr; /* ABR wait queue write pointer */ | 698 | ffreg_t abrwq_wptr; /* ABR wait queue write pointer */ |
699 | freg_t abrwq_rptr; /* ABR wait queue read pointer */ | 699 | ffreg_t abrwq_rptr; /* ABR wait queue read pointer */ |
700 | freg_t ubrwq_wptr; /* UBR wait queue write pointer */ | 700 | ffreg_t ubrwq_wptr; /* UBR wait queue write pointer */ |
701 | freg_t ubrwq_rptr; /* UBR wait queue read pointer */ | 701 | ffreg_t ubrwq_rptr; /* UBR wait queue read pointer */ |
702 | freg_t cbr_vc; /* CBR VC */ | 702 | ffreg_t cbr_vc; /* CBR VC */ |
703 | freg_t vbr_sb_vc; /* VBR SB VC */ | 703 | ffreg_t vbr_sb_vc; /* VBR SB VC */ |
704 | freg_t abr_sb_vc; /* ABR SB VC */ | 704 | ffreg_t abr_sb_vc; /* ABR SB VC */ |
705 | freg_t ubr_sb_vc; /* UBR SB VC */ | 705 | ffreg_t ubr_sb_vc; /* UBR SB VC */ |
706 | freg_t vbr_next_link; /* VBR next link */ | 706 | ffreg_t vbr_next_link; /* VBR next link */ |
707 | freg_t abr_next_link; /* ABR next link */ | 707 | ffreg_t abr_next_link; /* ABR next link */ |
708 | freg_t ubr_next_link; /* UBR next link */ | 708 | ffreg_t ubr_next_link; /* UBR next link */ |
709 | u_int filler7a[0x7c-0x7a]; | 709 | u_int filler7a[0x7c-0x7a]; |
710 | freg_t out_rate_head; /* Out of rate head */ | 710 | ffreg_t out_rate_head; /* Out of rate head */ |
711 | u_int filler7d[0xca-0x7d]; /* pad out to full address space */ | 711 | u_int filler7d[0xca-0x7d]; /* pad out to full address space */ |
712 | freg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ | 712 | ffreg_t cell_ctr_high1_nc;/* Total cell transfer count (high) */ |
713 | freg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ | 713 | ffreg_t cell_ctr_lo1_nc;/* Total cell transfer count (low) */ |
714 | u_int fillercc[0x100-0xcc]; /* pad out to full address space */ | 714 | u_int fillercc[0x100-0xcc]; /* pad out to full address space */ |
715 | } ffredn_t; | 715 | } ffredn_t; |
716 | 716 | ||
717 | typedef struct _rfredn_t { | 717 | typedef struct _rfredn_t { |
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 19e3fbfd5757..cb0c45488572 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -94,11 +94,16 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); | |||
94 | #ifdef CONFIG_BCMA_DRIVER_GPIO | 94 | #ifdef CONFIG_BCMA_DRIVER_GPIO |
95 | /* driver_gpio.c */ | 95 | /* driver_gpio.c */ |
96 | int bcma_gpio_init(struct bcma_drv_cc *cc); | 96 | int bcma_gpio_init(struct bcma_drv_cc *cc); |
97 | int bcma_gpio_unregister(struct bcma_drv_cc *cc); | ||
97 | #else | 98 | #else |
98 | static inline int bcma_gpio_init(struct bcma_drv_cc *cc) | 99 | static inline int bcma_gpio_init(struct bcma_drv_cc *cc) |
99 | { | 100 | { |
100 | return -ENOTSUPP; | 101 | return -ENOTSUPP; |
101 | } | 102 | } |
103 | static inline int bcma_gpio_unregister(struct bcma_drv_cc *cc) | ||
104 | { | ||
105 | return 0; | ||
106 | } | ||
102 | #endif /* CONFIG_BCMA_DRIVER_GPIO */ | 107 | #endif /* CONFIG_BCMA_DRIVER_GPIO */ |
103 | 108 | ||
104 | #endif | 109 | #endif |
diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c index dbda91e4dff5..1f0b83e18f68 100644 --- a/drivers/bcma/driver_chipcommon_nflash.c +++ b/drivers/bcma/driver_chipcommon_nflash.c | |||
@@ -21,7 +21,7 @@ int bcma_nflash_init(struct bcma_drv_cc *cc) | |||
21 | struct bcma_bus *bus = cc->core->bus; | 21 | struct bcma_bus *bus = cc->core->bus; |
22 | 22 | ||
23 | if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && | 23 | if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && |
24 | cc->core->id.rev != 0x38) { | 24 | cc->core->id.rev != 38) { |
25 | bcma_err(bus, "NAND flash on unsupported board!\n"); | 25 | bcma_err(bus, "NAND flash on unsupported board!\n"); |
26 | return -ENOTSUPP; | 26 | return -ENOTSUPP; |
27 | } | 27 | } |
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 9a6f585da2d9..71f755c06fc6 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c | |||
@@ -96,3 +96,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
96 | 96 | ||
97 | return gpiochip_add(chip); | 97 | return gpiochip_add(chip); |
98 | } | 98 | } |
99 | |||
100 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) | ||
101 | { | ||
102 | return gpiochip_remove(&cc->gpio); | ||
103 | } | ||
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 4a92f647b58b..324f9debda88 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -268,6 +268,13 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
268 | void bcma_bus_unregister(struct bcma_bus *bus) | 268 | void bcma_bus_unregister(struct bcma_bus *bus) |
269 | { | 269 | { |
270 | struct bcma_device *cores[3]; | 270 | struct bcma_device *cores[3]; |
271 | int err; | ||
272 | |||
273 | err = bcma_gpio_unregister(&bus->drv_cc); | ||
274 | if (err == -EBUSY) | ||
275 | bcma_err(bus, "Some GPIOs are still in use.\n"); | ||
276 | else if (err) | ||
277 | bcma_err(bus, "Can not unregister GPIO driver: %i\n", err); | ||
271 | 278 | ||
272 | cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); | 279 | cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); |
273 | cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); | 280 | cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index f58a4a4b4dfb..2b8303ad63c9 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -168,7 +168,7 @@ static void wake_all_senders(struct drbd_tconn *tconn) { | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /* must hold resource->req_lock */ | 170 | /* must hold resource->req_lock */ |
171 | static void start_new_tl_epoch(struct drbd_tconn *tconn) | 171 | void start_new_tl_epoch(struct drbd_tconn *tconn) |
172 | { | 172 | { |
173 | /* no point closing an epoch, if it is empty, anyways. */ | 173 | /* no point closing an epoch, if it is empty, anyways. */ |
174 | if (tconn->current_tle_writes == 0) | 174 | if (tconn->current_tle_writes == 0) |
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 016de6b8bb57..c08d22964d06 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
@@ -267,6 +267,7 @@ struct bio_and_error { | |||
267 | int error; | 267 | int error; |
268 | }; | 268 | }; |
269 | 269 | ||
270 | extern void start_new_tl_epoch(struct drbd_tconn *tconn); | ||
270 | extern void drbd_req_destroy(struct kref *kref); | 271 | extern void drbd_req_destroy(struct kref *kref); |
271 | extern void _req_may_be_done(struct drbd_request *req, | 272 | extern void _req_may_be_done(struct drbd_request *req, |
272 | struct bio_and_error *m); | 273 | struct bio_and_error *m); |
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 53bf6182bac4..0fe220cfb9e9 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c | |||
@@ -931,6 +931,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, | |||
931 | enum drbd_state_rv rv = SS_SUCCESS; | 931 | enum drbd_state_rv rv = SS_SUCCESS; |
932 | enum sanitize_state_warnings ssw; | 932 | enum sanitize_state_warnings ssw; |
933 | struct after_state_chg_work *ascw; | 933 | struct after_state_chg_work *ascw; |
934 | bool did_remote, should_do_remote; | ||
934 | 935 | ||
935 | os = drbd_read_state(mdev); | 936 | os = drbd_read_state(mdev); |
936 | 937 | ||
@@ -981,11 +982,17 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, | |||
981 | (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) | 982 | (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) |
982 | atomic_inc(&mdev->local_cnt); | 983 | atomic_inc(&mdev->local_cnt); |
983 | 984 | ||
985 | did_remote = drbd_should_do_remote(mdev->state); | ||
984 | mdev->state.i = ns.i; | 986 | mdev->state.i = ns.i; |
987 | should_do_remote = drbd_should_do_remote(mdev->state); | ||
985 | mdev->tconn->susp = ns.susp; | 988 | mdev->tconn->susp = ns.susp; |
986 | mdev->tconn->susp_nod = ns.susp_nod; | 989 | mdev->tconn->susp_nod = ns.susp_nod; |
987 | mdev->tconn->susp_fen = ns.susp_fen; | 990 | mdev->tconn->susp_fen = ns.susp_fen; |
988 | 991 | ||
992 | /* put replicated vs not-replicated requests in seperate epochs */ | ||
993 | if (did_remote != should_do_remote) | ||
994 | start_new_tl_epoch(mdev->tconn); | ||
995 | |||
989 | if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING) | 996 | if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING) |
990 | drbd_print_uuids(mdev, "attached to UUIDs"); | 997 | drbd_print_uuids(mdev, "attached to UUIDs"); |
991 | 998 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 9694dd99bbbc..3fd100990453 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -626,12 +626,13 @@ static void mtip_timeout_function(unsigned long int data) | |||
626 | } | 626 | } |
627 | } | 627 | } |
628 | 628 | ||
629 | if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { | 629 | if (cmdto_cnt) { |
630 | print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); | 630 | print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); |
631 | 631 | if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { | |
632 | mtip_restart_port(port); | 632 | mtip_restart_port(port); |
633 | wake_up_interruptible(&port->svc_wait); | ||
634 | } | ||
633 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); | 635 | clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); |
634 | wake_up_interruptible(&port->svc_wait); | ||
635 | } | 636 | } |
636 | 637 | ||
637 | if (port->ic_pause_timer) { | 638 | if (port->ic_pause_timer) { |
@@ -3887,7 +3888,12 @@ static int mtip_block_remove(struct driver_data *dd) | |||
3887 | * Delete our gendisk structure. This also removes the device | 3888 | * Delete our gendisk structure. This also removes the device |
3888 | * from /dev | 3889 | * from /dev |
3889 | */ | 3890 | */ |
3890 | del_gendisk(dd->disk); | 3891 | if (dd->disk) { |
3892 | if (dd->disk->queue) | ||
3893 | del_gendisk(dd->disk); | ||
3894 | else | ||
3895 | put_disk(dd->disk); | ||
3896 | } | ||
3891 | 3897 | ||
3892 | spin_lock(&rssd_index_lock); | 3898 | spin_lock(&rssd_index_lock); |
3893 | ida_remove(&rssd_index_ida, dd->index); | 3899 | ida_remove(&rssd_index_ida, dd->index); |
@@ -3921,7 +3927,13 @@ static int mtip_block_shutdown(struct driver_data *dd) | |||
3921 | "Shutting down %s ...\n", dd->disk->disk_name); | 3927 | "Shutting down %s ...\n", dd->disk->disk_name); |
3922 | 3928 | ||
3923 | /* Delete our gendisk structure, and cleanup the blk queue. */ | 3929 | /* Delete our gendisk structure, and cleanup the blk queue. */ |
3924 | del_gendisk(dd->disk); | 3930 | if (dd->disk) { |
3931 | if (dd->disk->queue) | ||
3932 | del_gendisk(dd->disk); | ||
3933 | else | ||
3934 | put_disk(dd->disk); | ||
3935 | } | ||
3936 | |||
3925 | 3937 | ||
3926 | spin_lock(&rssd_index_lock); | 3938 | spin_lock(&rssd_index_lock); |
3927 | ida_remove(&rssd_index_ida, dd->index); | 3939 | ida_remove(&rssd_index_ida, dd->index); |
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 74374fb762aa..5ac841ff6cc7 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -161,10 +161,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, | |||
161 | static void make_response(struct xen_blkif *blkif, u64 id, | 161 | static void make_response(struct xen_blkif *blkif, u64 id, |
162 | unsigned short op, int st); | 162 | unsigned short op, int st); |
163 | 163 | ||
164 | #define foreach_grant(pos, rbtree, node) \ | 164 | #define foreach_grant_safe(pos, n, rbtree, node) \ |
165 | for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node); \ | 165 | for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \ |
166 | (n) = rb_next(&(pos)->node); \ | ||
166 | &(pos)->node != NULL; \ | 167 | &(pos)->node != NULL; \ |
167 | (pos) = container_of(rb_next(&(pos)->node), typeof(*(pos)), node)) | 168 | (pos) = container_of(n, typeof(*(pos)), node), \ |
169 | (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL) | ||
168 | 170 | ||
169 | 171 | ||
170 | static void add_persistent_gnt(struct rb_root *root, | 172 | static void add_persistent_gnt(struct rb_root *root, |
@@ -217,10 +219,11 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num) | |||
217 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 219 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
218 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 220 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
219 | struct persistent_gnt *persistent_gnt; | 221 | struct persistent_gnt *persistent_gnt; |
222 | struct rb_node *n; | ||
220 | int ret = 0; | 223 | int ret = 0; |
221 | int segs_to_unmap = 0; | 224 | int segs_to_unmap = 0; |
222 | 225 | ||
223 | foreach_grant(persistent_gnt, root, node) { | 226 | foreach_grant_safe(persistent_gnt, n, root, node) { |
224 | BUG_ON(persistent_gnt->handle == | 227 | BUG_ON(persistent_gnt->handle == |
225 | BLKBACK_INVALID_HANDLE); | 228 | BLKBACK_INVALID_HANDLE); |
226 | gnttab_set_unmap_op(&unmap[segs_to_unmap], | 229 | gnttab_set_unmap_op(&unmap[segs_to_unmap], |
@@ -230,9 +233,6 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num) | |||
230 | persistent_gnt->handle); | 233 | persistent_gnt->handle); |
231 | 234 | ||
232 | pages[segs_to_unmap] = persistent_gnt->page; | 235 | pages[segs_to_unmap] = persistent_gnt->page; |
233 | rb_erase(&persistent_gnt->node, root); | ||
234 | kfree(persistent_gnt); | ||
235 | num--; | ||
236 | 236 | ||
237 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || | 237 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || |
238 | !rb_next(&persistent_gnt->node)) { | 238 | !rb_next(&persistent_gnt->node)) { |
@@ -241,6 +241,10 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num) | |||
241 | BUG_ON(ret); | 241 | BUG_ON(ret); |
242 | segs_to_unmap = 0; | 242 | segs_to_unmap = 0; |
243 | } | 243 | } |
244 | |||
245 | rb_erase(&persistent_gnt->node, root); | ||
246 | kfree(persistent_gnt); | ||
247 | num--; | ||
244 | } | 248 | } |
245 | BUG_ON(num != 0); | 249 | BUG_ON(num != 0); |
246 | } | 250 | } |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 96e9b00db081..11043c18ac5a 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -792,6 +792,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) | |||
792 | { | 792 | { |
793 | struct llist_node *all_gnts; | 793 | struct llist_node *all_gnts; |
794 | struct grant *persistent_gnt; | 794 | struct grant *persistent_gnt; |
795 | struct llist_node *n; | ||
795 | 796 | ||
796 | /* Prevent new requests being issued until we fix things up. */ | 797 | /* Prevent new requests being issued until we fix things up. */ |
797 | spin_lock_irq(&info->io_lock); | 798 | spin_lock_irq(&info->io_lock); |
@@ -804,7 +805,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) | |||
804 | /* Remove all persistent grants */ | 805 | /* Remove all persistent grants */ |
805 | if (info->persistent_gnts_c) { | 806 | if (info->persistent_gnts_c) { |
806 | all_gnts = llist_del_all(&info->persistent_gnts); | 807 | all_gnts = llist_del_all(&info->persistent_gnts); |
807 | llist_for_each_entry(persistent_gnt, all_gnts, node) { | 808 | llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) { |
808 | gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); | 809 | gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); |
809 | __free_page(pfn_to_page(persistent_gnt->pfn)); | 810 | __free_page(pfn_to_page(persistent_gnt->pfn)); |
810 | kfree(persistent_gnt); | 811 | kfree(persistent_gnt); |
@@ -835,7 +836,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) | |||
835 | static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, | 836 | static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, |
836 | struct blkif_response *bret) | 837 | struct blkif_response *bret) |
837 | { | 838 | { |
838 | int i; | 839 | int i = 0; |
839 | struct bio_vec *bvec; | 840 | struct bio_vec *bvec; |
840 | struct req_iterator iter; | 841 | struct req_iterator iter; |
841 | unsigned long flags; | 842 | unsigned long flags; |
@@ -852,7 +853,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, | |||
852 | */ | 853 | */ |
853 | rq_for_each_segment(bvec, s->request, iter) { | 854 | rq_for_each_segment(bvec, s->request, iter) { |
854 | BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE); | 855 | BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE); |
855 | i = offset >> PAGE_SHIFT; | 856 | if (bvec->bv_offset < offset) |
857 | i++; | ||
856 | BUG_ON(i >= s->req.u.rw.nr_segments); | 858 | BUG_ON(i >= s->req.u.rw.nr_segments); |
857 | shared_data = kmap_atomic( | 859 | shared_data = kmap_atomic( |
858 | pfn_to_page(s->grants_used[i]->pfn)); | 860 | pfn_to_page(s->grants_used[i]->pfn)); |
@@ -861,7 +863,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, | |||
861 | bvec->bv_len); | 863 | bvec->bv_len); |
862 | bvec_kunmap_irq(bvec_data, &flags); | 864 | bvec_kunmap_irq(bvec_data, &flags); |
863 | kunmap_atomic(shared_data); | 865 | kunmap_atomic(shared_data); |
864 | offset += bvec->bv_len; | 866 | offset = bvec->bv_offset + bvec->bv_len; |
865 | } | 867 | } |
866 | } | 868 | } |
867 | /* Add the persistent grant into the list of free grants */ | 869 | /* Add the persistent grant into the list of free grants */ |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 684b0d53764f..ee4dbeafb377 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -2062,7 +2062,8 @@ static void virtcons_remove(struct virtio_device *vdev) | |||
2062 | /* Disable interrupts for vqs */ | 2062 | /* Disable interrupts for vqs */ |
2063 | vdev->config->reset(vdev); | 2063 | vdev->config->reset(vdev); |
2064 | /* Finish up work that's lined up */ | 2064 | /* Finish up work that's lined up */ |
2065 | cancel_work_sync(&portdev->control_work); | 2065 | if (use_multiport(portdev)) |
2066 | cancel_work_sync(&portdev->control_work); | ||
2066 | 2067 | ||
2067 | list_for_each_entry_safe(port, port2, &portdev->ports, list) | 2068 | list_for_each_entry_safe(port, port2, &portdev->ports, list) |
2068 | unplug_port(port); | 2069 | unplug_port(port); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4d0e60adbc6d..a2d478e8692a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1313,14 +1313,18 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
1313 | if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { | 1313 | if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { |
1314 | radeon_wait_for_vblank(rdev, i); | 1314 | radeon_wait_for_vblank(rdev, i); |
1315 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; | 1315 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
1316 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); | ||
1316 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 1317 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
1318 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
1317 | } | 1319 | } |
1318 | } else { | 1320 | } else { |
1319 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); | 1321 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
1320 | if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) { | 1322 | if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) { |
1321 | radeon_wait_for_vblank(rdev, i); | 1323 | radeon_wait_for_vblank(rdev, i); |
1322 | tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; | 1324 | tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; |
1325 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); | ||
1323 | WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); | 1326 | WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); |
1327 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
1324 | } | 1328 | } |
1325 | } | 1329 | } |
1326 | /* wait for the next frame */ | 1330 | /* wait for the next frame */ |
@@ -1345,6 +1349,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
1345 | blackout &= ~BLACKOUT_MODE_MASK; | 1349 | blackout &= ~BLACKOUT_MODE_MASK; |
1346 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1); | 1350 | WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1); |
1347 | } | 1351 | } |
1352 | /* wait for the MC to settle */ | ||
1353 | udelay(100); | ||
1348 | } | 1354 | } |
1349 | 1355 | ||
1350 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1356 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) |
@@ -1378,11 +1384,15 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
1378 | if (ASIC_IS_DCE6(rdev)) { | 1384 | if (ASIC_IS_DCE6(rdev)) { |
1379 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); | 1385 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); |
1380 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; | 1386 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
1387 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); | ||
1381 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 1388 | WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
1389 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
1382 | } else { | 1390 | } else { |
1383 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); | 1391 | tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); |
1384 | tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; | 1392 | tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; |
1393 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); | ||
1385 | WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); | 1394 | WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); |
1395 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
1386 | } | 1396 | } |
1387 | /* wait for the next frame */ | 1397 | /* wait for the next frame */ |
1388 | frame_count = radeon_get_vblank_counter(rdev, i); | 1398 | frame_count = radeon_get_vblank_counter(rdev, i); |
@@ -2036,9 +2046,20 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
2036 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); | 2046 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); |
2037 | WREG32(DMA_TILING_CONFIG, gb_addr_config); | 2047 | WREG32(DMA_TILING_CONFIG, gb_addr_config); |
2038 | 2048 | ||
2039 | tmp = gb_addr_config & NUM_PIPES_MASK; | 2049 | if ((rdev->config.evergreen.max_backends == 1) && |
2040 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, | 2050 | (rdev->flags & RADEON_IS_IGP)) { |
2041 | EVERGREEN_MAX_BACKENDS, disabled_rb_mask); | 2051 | if ((disabled_rb_mask & 3) == 1) { |
2052 | /* RB0 disabled, RB1 enabled */ | ||
2053 | tmp = 0x11111111; | ||
2054 | } else { | ||
2055 | /* RB1 disabled, RB0 enabled */ | ||
2056 | tmp = 0x00000000; | ||
2057 | } | ||
2058 | } else { | ||
2059 | tmp = gb_addr_config & NUM_PIPES_MASK; | ||
2060 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, | ||
2061 | EVERGREEN_MAX_BACKENDS, disabled_rb_mask); | ||
2062 | } | ||
2042 | WREG32(GB_BACKEND_MAP, tmp); | 2063 | WREG32(GB_BACKEND_MAP, tmp); |
2043 | 2064 | ||
2044 | WREG32(CGTS_SYS_TCC_DISABLE, 0); | 2065 | WREG32(CGTS_SYS_TCC_DISABLE, 0); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index bc2540b17c5e..becb03e8b32f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1462,12 +1462,15 @@ u32 r6xx_remap_render_backend(struct radeon_device *rdev, | |||
1462 | u32 disabled_rb_mask) | 1462 | u32 disabled_rb_mask) |
1463 | { | 1463 | { |
1464 | u32 rendering_pipe_num, rb_num_width, req_rb_num; | 1464 | u32 rendering_pipe_num, rb_num_width, req_rb_num; |
1465 | u32 pipe_rb_ratio, pipe_rb_remain; | 1465 | u32 pipe_rb_ratio, pipe_rb_remain, tmp; |
1466 | u32 data = 0, mask = 1 << (max_rb_num - 1); | 1466 | u32 data = 0, mask = 1 << (max_rb_num - 1); |
1467 | unsigned i, j; | 1467 | unsigned i, j; |
1468 | 1468 | ||
1469 | /* mask out the RBs that don't exist on that asic */ | 1469 | /* mask out the RBs that don't exist on that asic */ |
1470 | disabled_rb_mask |= (0xff << max_rb_num) & 0xff; | 1470 | tmp = disabled_rb_mask | ((0xff << max_rb_num) & 0xff); |
1471 | /* make sure at least one RB is available */ | ||
1472 | if ((tmp & 0xff) != 0xff) | ||
1473 | disabled_rb_mask = tmp; | ||
1471 | 1474 | ||
1472 | rendering_pipe_num = 1 << tiling_pipe_num; | 1475 | rendering_pipe_num = 1 << tiling_pipe_num; |
1473 | req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask); | 1476 | req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 9056fafb00ea..0b202c07fe50 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1445,7 +1445,7 @@ static struct radeon_asic cayman_asic = { | |||
1445 | .vm = { | 1445 | .vm = { |
1446 | .init = &cayman_vm_init, | 1446 | .init = &cayman_vm_init, |
1447 | .fini = &cayman_vm_fini, | 1447 | .fini = &cayman_vm_fini, |
1448 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 1448 | .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1449 | .set_page = &cayman_vm_set_page, | 1449 | .set_page = &cayman_vm_set_page, |
1450 | }, | 1450 | }, |
1451 | .ring = { | 1451 | .ring = { |
@@ -1572,7 +1572,7 @@ static struct radeon_asic trinity_asic = { | |||
1572 | .vm = { | 1572 | .vm = { |
1573 | .init = &cayman_vm_init, | 1573 | .init = &cayman_vm_init, |
1574 | .fini = &cayman_vm_fini, | 1574 | .fini = &cayman_vm_fini, |
1575 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 1575 | .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1576 | .set_page = &cayman_vm_set_page, | 1576 | .set_page = &cayman_vm_set_page, |
1577 | }, | 1577 | }, |
1578 | .ring = { | 1578 | .ring = { |
@@ -1699,7 +1699,7 @@ static struct radeon_asic si_asic = { | |||
1699 | .vm = { | 1699 | .vm = { |
1700 | .init = &si_vm_init, | 1700 | .init = &si_vm_init, |
1701 | .fini = &si_vm_fini, | 1701 | .fini = &si_vm_fini, |
1702 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 1702 | .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1703 | .set_page = &si_vm_set_page, | 1703 | .set_page = &si_vm_set_page, |
1704 | }, | 1704 | }, |
1705 | .ring = { | 1705 | .ring = { |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 33a56a09ff10..3e403bdda58f 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -2470,6 +2470,14 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2470 | 1), | 2470 | 1), |
2471 | ATOM_DEVICE_CRT1_SUPPORT); | 2471 | ATOM_DEVICE_CRT1_SUPPORT); |
2472 | } | 2472 | } |
2473 | /* RV100 board with external TDMS bit mis-set. | ||
2474 | * Actually uses internal TMDS, clear the bit. | ||
2475 | */ | ||
2476 | if (dev->pdev->device == 0x5159 && | ||
2477 | dev->pdev->subsystem_vendor == 0x1014 && | ||
2478 | dev->pdev->subsystem_device == 0x029A) { | ||
2479 | tmp &= ~(1 << 4); | ||
2480 | } | ||
2473 | if ((tmp >> 4) & 0x1) { | 2481 | if ((tmp >> 4) & 0x1) { |
2474 | devices |= ATOM_DEVICE_DFP2_SUPPORT; | 2482 | devices |= ATOM_DEVICE_DFP2_SUPPORT; |
2475 | radeon_add_legacy_encoder(dev, | 2483 | radeon_add_legacy_encoder(dev, |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index ff3def784619..05c96fa0b051 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1115,8 +1115,10 @@ radeon_user_framebuffer_create(struct drm_device *dev, | |||
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); | 1117 | radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); |
1118 | if (radeon_fb == NULL) | 1118 | if (radeon_fb == NULL) { |
1119 | drm_gem_object_unreference_unlocked(obj); | ||
1119 | return ERR_PTR(-ENOMEM); | 1120 | return ERR_PTR(-ENOMEM); |
1121 | } | ||
1120 | 1122 | ||
1121 | ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); | 1123 | ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); |
1122 | if (ret) { | 1124 | if (ret) { |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 2430d80b1871..cd72062d5a91 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -377,6 +377,9 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi | |||
377 | { | 377 | { |
378 | int r; | 378 | int r; |
379 | 379 | ||
380 | /* make sure we aren't trying to allocate more space than there is on the ring */ | ||
381 | if (ndw > (ring->ring_size / 4)) | ||
382 | return -ENOMEM; | ||
380 | /* Align requested size with padding so unlock_commit can | 383 | /* Align requested size with padding so unlock_commit can |
381 | * pad safely */ | 384 | * pad safely */ |
382 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; | 385 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman index 0f656b111c15..a072fa8c46b0 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/cayman +++ b/drivers/gpu/drm/radeon/reg_srcs/cayman | |||
@@ -1,5 +1,6 @@ | |||
1 | cayman 0x9400 | 1 | cayman 0x9400 |
2 | 0x0000802C GRBM_GFX_INDEX | 2 | 0x0000802C GRBM_GFX_INDEX |
3 | 0x00008040 WAIT_UNTIL | ||
3 | 0x000084FC CP_STRMOUT_CNTL | 4 | 0x000084FC CP_STRMOUT_CNTL |
4 | 0x000085F0 CP_COHER_CNTL | 5 | 0x000085F0 CP_COHER_CNTL |
5 | 0x000085F4 CP_COHER_SIZE | 6 | 0x000085F4 CP_COHER_SIZE |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 2bb6d0e84b3d..435ed3551364 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -336,6 +336,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
336 | WREG32(R600_CITF_CNTL, blackout); | 336 | WREG32(R600_CITF_CNTL, blackout); |
337 | } | 337 | } |
338 | } | 338 | } |
339 | /* wait for the MC to settle */ | ||
340 | udelay(100); | ||
339 | } | 341 | } |
340 | 342 | ||
341 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | 343 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 44420fca7dfa..8be35c809c7b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -429,7 +429,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
429 | struct ttm_bo_device *bdev = bo->bdev; | 429 | struct ttm_bo_device *bdev = bo->bdev; |
430 | struct ttm_bo_driver *driver = bdev->driver; | 430 | struct ttm_bo_driver *driver = bdev->driver; |
431 | 431 | ||
432 | fbo = kzalloc(sizeof(*fbo), GFP_KERNEL); | 432 | fbo = kmalloc(sizeof(*fbo), GFP_KERNEL); |
433 | if (!fbo) | 433 | if (!fbo) |
434 | return -ENOMEM; | 434 | return -ENOMEM; |
435 | 435 | ||
@@ -448,7 +448,12 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
448 | fbo->vm_node = NULL; | 448 | fbo->vm_node = NULL; |
449 | atomic_set(&fbo->cpu_writers, 0); | 449 | atomic_set(&fbo->cpu_writers, 0); |
450 | 450 | ||
451 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); | 451 | spin_lock(&bdev->fence_lock); |
452 | if (bo->sync_obj) | ||
453 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); | ||
454 | else | ||
455 | fbo->sync_obj = NULL; | ||
456 | spin_unlock(&bdev->fence_lock); | ||
452 | kref_init(&fbo->list_kref); | 457 | kref_init(&fbo->list_kref); |
453 | kref_init(&fbo->kref); | 458 | kref_init(&fbo->kref); |
454 | fbo->destroy = &ttm_transfered_destroy; | 459 | fbo->destroy = &ttm_transfered_destroy; |
@@ -661,13 +666,11 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, | |||
661 | */ | 666 | */ |
662 | 667 | ||
663 | set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); | 668 | set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); |
664 | |||
665 | /* ttm_buffer_object_transfer accesses bo->sync_obj */ | ||
666 | ret = ttm_buffer_object_transfer(bo, &ghost_obj); | ||
667 | spin_unlock(&bdev->fence_lock); | 669 | spin_unlock(&bdev->fence_lock); |
668 | if (tmp_obj) | 670 | if (tmp_obj) |
669 | driver->sync_obj_unref(&tmp_obj); | 671 | driver->sync_obj_unref(&tmp_obj); |
670 | 672 | ||
673 | ret = ttm_buffer_object_transfer(bo, &ghost_obj); | ||
671 | if (ret) | 674 | if (ret) |
672 | return ret; | 675 | return ret; |
673 | 676 | ||
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c index 4850d03870c2..35275099cafd 100644 --- a/drivers/infiniband/hw/qib/qib_qp.c +++ b/drivers/infiniband/hw/qib/qib_qp.c | |||
@@ -263,20 +263,15 @@ static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp) | |||
263 | struct qib_qp __rcu **qpp; | 263 | struct qib_qp __rcu **qpp; |
264 | 264 | ||
265 | qpp = &dev->qp_table[n]; | 265 | qpp = &dev->qp_table[n]; |
266 | q = rcu_dereference_protected(*qpp, | 266 | for (; (q = rcu_dereference_protected(*qpp, |
267 | lockdep_is_held(&dev->qpt_lock)); | 267 | lockdep_is_held(&dev->qpt_lock))) != NULL; |
268 | for (; q; qpp = &q->next) { | 268 | qpp = &q->next) |
269 | if (q == qp) { | 269 | if (q == qp) { |
270 | atomic_dec(&qp->refcount); | 270 | atomic_dec(&qp->refcount); |
271 | *qpp = qp->next; | 271 | *qpp = qp->next; |
272 | rcu_assign_pointer(qp->next, NULL); | 272 | rcu_assign_pointer(qp->next, NULL); |
273 | q = rcu_dereference_protected(*qpp, | ||
274 | lockdep_is_held(&dev->qpt_lock)); | ||
275 | break; | 273 | break; |
276 | } | 274 | } |
277 | q = rcu_dereference_protected(*qpp, | ||
278 | lockdep_is_held(&dev->qpt_lock)); | ||
279 | } | ||
280 | } | 275 | } |
281 | 276 | ||
282 | spin_unlock_irqrestore(&dev->qpt_lock, flags); | 277 | spin_unlock_irqrestore(&dev->qpt_lock, flags); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 03103d2bd641..67b0c1d23678 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -741,6 +741,9 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
741 | 741 | ||
742 | tx_req->mapping = addr; | 742 | tx_req->mapping = addr; |
743 | 743 | ||
744 | skb_orphan(skb); | ||
745 | skb_dst_drop(skb); | ||
746 | |||
744 | rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), | 747 | rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), |
745 | addr, skb->len); | 748 | addr, skb->len); |
746 | if (unlikely(rc)) { | 749 | if (unlikely(rc)) { |
@@ -752,9 +755,6 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
752 | dev->trans_start = jiffies; | 755 | dev->trans_start = jiffies; |
753 | ++tx->tx_head; | 756 | ++tx->tx_head; |
754 | 757 | ||
755 | skb_orphan(skb); | ||
756 | skb_dst_drop(skb); | ||
757 | |||
758 | if (++priv->tx_outstanding == ipoib_sendq_size) { | 758 | if (++priv->tx_outstanding == ipoib_sendq_size) { |
759 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", | 759 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", |
760 | tx->qp->qp_num); | 760 | tx->qp->qp_num); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index a1bca70e20aa..2cfa76f5d99e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -600,6 +600,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
600 | netif_stop_queue(dev); | 600 | netif_stop_queue(dev); |
601 | } | 601 | } |
602 | 602 | ||
603 | skb_orphan(skb); | ||
604 | skb_dst_drop(skb); | ||
605 | |||
603 | rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 606 | rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
604 | address->ah, qpn, tx_req, phead, hlen); | 607 | address->ah, qpn, tx_req, phead, hlen); |
605 | if (unlikely(rc)) { | 608 | if (unlikely(rc)) { |
@@ -615,9 +618,6 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
615 | 618 | ||
616 | address->last_send = priv->tx_head; | 619 | address->last_send = priv->tx_head; |
617 | ++priv->tx_head; | 620 | ++priv->tx_head; |
618 | |||
619 | skb_orphan(skb); | ||
620 | skb_dst_drop(skb); | ||
621 | } | 621 | } |
622 | 622 | ||
623 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) | 623 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) |
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c index e10e525f33e5..296941a9ae25 100644 --- a/drivers/media/radio/radio-keene.c +++ b/drivers/media/radio/radio-keene.c | |||
@@ -374,6 +374,7 @@ static int usb_keene_probe(struct usb_interface *intf, | |||
374 | radio->vdev.ioctl_ops = &usb_keene_ioctl_ops; | 374 | radio->vdev.ioctl_ops = &usb_keene_ioctl_ops; |
375 | radio->vdev.lock = &radio->lock; | 375 | radio->vdev.lock = &radio->lock; |
376 | radio->vdev.release = video_device_release_empty; | 376 | radio->vdev.release = video_device_release_empty; |
377 | radio->vdev.vfl_dir = VFL_DIR_TX; | ||
377 | 378 | ||
378 | radio->usbdev = interface_to_usbdev(intf); | 379 | radio->usbdev = interface_to_usbdev(intf); |
379 | radio->intf = intf; | 380 | radio->intf = intf; |
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index a082e400ed0f..1507c9d508d7 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c | |||
@@ -250,6 +250,7 @@ static struct video_device radio_si4713_vdev_template = { | |||
250 | .name = "radio-si4713", | 250 | .name = "radio-si4713", |
251 | .release = video_device_release, | 251 | .release = video_device_release, |
252 | .ioctl_ops = &radio_si4713_ioctl_ops, | 252 | .ioctl_ops = &radio_si4713_ioctl_ops, |
253 | .vfl_dir = VFL_DIR_TX, | ||
253 | }; | 254 | }; |
254 | 255 | ||
255 | /* Platform driver interface */ | 256 | /* Platform driver interface */ |
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index c48be195bbad..cabbe3adf435 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c | |||
@@ -1971,6 +1971,7 @@ static struct video_device wl1273_viddev_template = { | |||
1971 | .ioctl_ops = &wl1273_ioctl_ops, | 1971 | .ioctl_ops = &wl1273_ioctl_ops, |
1972 | .name = WL1273_FM_DRIVER_NAME, | 1972 | .name = WL1273_FM_DRIVER_NAME, |
1973 | .release = wl1273_vdev_release, | 1973 | .release = wl1273_vdev_release, |
1974 | .vfl_dir = VFL_DIR_TX, | ||
1974 | }; | 1975 | }; |
1975 | 1976 | ||
1976 | static int wl1273_fm_radio_remove(struct platform_device *pdev) | 1977 | static int wl1273_fm_radio_remove(struct platform_device *pdev) |
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c index 048de4536036..0a8ee8fab924 100644 --- a/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c | |||
@@ -518,6 +518,16 @@ static struct video_device fm_viddev_template = { | |||
518 | .ioctl_ops = &fm_drv_ioctl_ops, | 518 | .ioctl_ops = &fm_drv_ioctl_ops, |
519 | .name = FM_DRV_NAME, | 519 | .name = FM_DRV_NAME, |
520 | .release = video_device_release, | 520 | .release = video_device_release, |
521 | /* | ||
522 | * To ensure both the tuner and modulator ioctls are accessible we | ||
523 | * set the vfl_dir to M2M to indicate this. | ||
524 | * | ||
525 | * It is not really a mem2mem device of course, but it can both receive | ||
526 | * and transmit using the same radio device. It's the only radio driver | ||
527 | * that does this and it should really be split in two radio devices, | ||
528 | * but that would affect applications using this driver. | ||
529 | */ | ||
530 | .vfl_dir = VFL_DIR_M2M, | ||
521 | }; | 531 | }; |
522 | 532 | ||
523 | int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) | 533 | int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) |
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index e06d782489a6..6a1180502cc1 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/mtd/mtd.h> | 15 | #include <linux/mtd/mtd.h> |
16 | #include <linux/mtd/partitions.h> | 16 | #include <linux/mtd/partitions.h> |
17 | #include <asm/mach-bcm47xx/nvram.h> | 17 | #include <bcm47xx_nvram.h> |
18 | 18 | ||
19 | /* 10 parts were found on sflash on Netgear WNDR4500 */ | 19 | /* 10 parts were found on sflash on Netgear WNDR4500 */ |
20 | #define BCM47XXPART_MAX_PARTS 12 | 20 | #define BCM47XXPART_MAX_PARTS 12 |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 27f80cd8aef3..46dcb54c32ec 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -272,6 +272,7 @@ config MTD_DOCG3 | |||
272 | tristate "M-Systems Disk-On-Chip G3" | 272 | tristate "M-Systems Disk-On-Chip G3" |
273 | select BCH | 273 | select BCH |
274 | select BCH_CONST_PARAMS | 274 | select BCH_CONST_PARAMS |
275 | select BITREVERSE | ||
275 | ---help--- | 276 | ---help--- |
276 | This provides an MTD device driver for the M-Systems DiskOnChip | 277 | This provides an MTD device driver for the M-Systems DiskOnChip |
277 | G3 devices. | 278 | G3 devices. |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 67cc73c18ddd..7901d72c9242 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -170,7 +170,7 @@ static int of_flash_probe(struct platform_device *dev) | |||
170 | resource_size_t res_size; | 170 | resource_size_t res_size; |
171 | struct mtd_part_parser_data ppdata; | 171 | struct mtd_part_parser_data ppdata; |
172 | bool map_indirect; | 172 | bool map_indirect; |
173 | const char *mtd_name; | 173 | const char *mtd_name = NULL; |
174 | 174 | ||
175 | match = of_match_device(of_flash_match, &dev->dev); | 175 | match = of_match_device(of_flash_match, &dev->dev); |
176 | if (!match) | 176 | if (!match) |
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c index 86c9a79b89b3..595de4012e71 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include "bcm47xxnflash.h" | 17 | #include "bcm47xxnflash.h" |
18 | 18 | ||
19 | /* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has | 19 | /* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has |
20 | * shown 164 retries as maxiumum. */ | 20 | * shown ~1000 retries as maxiumum. */ |
21 | #define NFLASH_READY_RETRIES 1000 | 21 | #define NFLASH_READY_RETRIES 10000 |
22 | 22 | ||
23 | #define NFLASH_SECTOR_SIZE 512 | 23 | #define NFLASH_SECTOR_SIZE 512 |
24 | 24 | ||
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 3502606f6480..feae55c7b880 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -523,7 +523,7 @@ static struct nand_ecclayout hwecc4_2048 __initconst = { | |||
523 | static const struct of_device_id davinci_nand_of_match[] = { | 523 | static const struct of_device_id davinci_nand_of_match[] = { |
524 | {.compatible = "ti,davinci-nand", }, | 524 | {.compatible = "ti,davinci-nand", }, |
525 | {}, | 525 | {}, |
526 | } | 526 | }; |
527 | MODULE_DEVICE_TABLE(of, davinci_nand_of_match); | 527 | MODULE_DEVICE_TABLE(of, davinci_nand_of_match); |
528 | 528 | ||
529 | static struct davinci_nand_pdata | 529 | static struct davinci_nand_pdata |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 8323ac991ad1..3766682a0289 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2857,8 +2857,11 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
2857 | int i; | 2857 | int i; |
2858 | int val; | 2858 | int val; |
2859 | 2859 | ||
2860 | /* ONFI need to be probed in 8 bits mode */ | 2860 | /* ONFI need to be probed in 8 bits mode, and 16 bits should be selected with NAND_BUSWIDTH_AUTO */ |
2861 | WARN_ON(chip->options & NAND_BUSWIDTH_16); | 2861 | if (chip->options & NAND_BUSWIDTH_16) { |
2862 | pr_err("Trying ONFI probe in 16 bits mode, aborting !\n"); | ||
2863 | return 0; | ||
2864 | } | ||
2862 | /* Try ONFI for unknown chip or LP */ | 2865 | /* Try ONFI for unknown chip or LP */ |
2863 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); | 2866 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); |
2864 | if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || | 2867 | if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 1877ed7ca086..1c9e09fbdff8 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1053,6 +1053,7 @@ static ssize_t bonding_store_primary(struct device *d, | |||
1053 | pr_info("%s: Setting primary slave to None.\n", | 1053 | pr_info("%s: Setting primary slave to None.\n", |
1054 | bond->dev->name); | 1054 | bond->dev->name); |
1055 | bond->primary_slave = NULL; | 1055 | bond->primary_slave = NULL; |
1056 | memset(bond->params.primary, 0, sizeof(bond->params.primary)); | ||
1056 | bond_select_active_slave(bond); | 1057 | bond_select_active_slave(bond); |
1057 | goto out; | 1058 | goto out; |
1058 | } | 1059 | } |
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 58607f196c9e..2282b1ae9765 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -488,8 +488,12 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface, | |||
488 | 488 | ||
489 | priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), | 489 | priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), |
490 | IFX_WRITE_LOW_16BIT(mask)); | 490 | IFX_WRITE_LOW_16BIT(mask)); |
491 | |||
492 | /* According to C_CAN documentation, the reserved bit | ||
493 | * in IFx_MASK2 register is fixed 1 | ||
494 | */ | ||
491 | priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), | 495 | priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), |
492 | IFX_WRITE_HIGH_16BIT(mask)); | 496 | IFX_WRITE_HIGH_16BIT(mask) | BIT(13)); |
493 | 497 | ||
494 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), | 498 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), |
495 | IFX_WRITE_LOW_16BIT(id)); | 499 | IFX_WRITE_LOW_16BIT(id)); |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 219f6226fcb1..330b0908bf97 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
@@ -381,7 +381,7 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) | |||
381 | } | 381 | } |
382 | 382 | ||
383 | #ifdef CONFIG_BCM47XX | 383 | #ifdef CONFIG_BCM47XX |
384 | #include <asm/mach-bcm47xx/nvram.h> | 384 | #include <bcm47xx_nvram.h> |
385 | static void b44_wap54g10_workaround(struct b44 *bp) | 385 | static void b44_wap54g10_workaround(struct b44 *bp) |
386 | { | 386 | { |
387 | char buf[20]; | 387 | char buf[20]; |
@@ -393,7 +393,7 @@ static void b44_wap54g10_workaround(struct b44 *bp) | |||
393 | * see https://dev.openwrt.org/ticket/146 | 393 | * see https://dev.openwrt.org/ticket/146 |
394 | * check and reset bit "isolate" | 394 | * check and reset bit "isolate" |
395 | */ | 395 | */ |
396 | if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0) | 396 | if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) < 0) |
397 | return; | 397 | return; |
398 | if (simple_strtoul(buf, NULL, 0) == 2) { | 398 | if (simple_strtoul(buf, NULL, 0) == 2) { |
399 | err = __b44_readphy(bp, 0, MII_BMCR, &val); | 399 | err = __b44_readphy(bp, 0, MII_BMCR, &val); |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 4eba17b83ba8..f1b3df167ff2 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -36,13 +36,13 @@ | |||
36 | 36 | ||
37 | #define DRV_VER "4.4.161.0u" | 37 | #define DRV_VER "4.4.161.0u" |
38 | #define DRV_NAME "be2net" | 38 | #define DRV_NAME "be2net" |
39 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" | 39 | #define BE_NAME "Emulex BladeEngine2" |
40 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" | 40 | #define BE3_NAME "Emulex BladeEngine3" |
41 | #define OC_NAME "Emulex OneConnect 10Gbps NIC" | 41 | #define OC_NAME "Emulex OneConnect" |
42 | #define OC_NAME_BE OC_NAME "(be3)" | 42 | #define OC_NAME_BE OC_NAME "(be3)" |
43 | #define OC_NAME_LANCER OC_NAME "(Lancer)" | 43 | #define OC_NAME_LANCER OC_NAME "(Lancer)" |
44 | #define OC_NAME_SH OC_NAME "(Skyhawk)" | 44 | #define OC_NAME_SH OC_NAME "(Skyhawk)" |
45 | #define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver" | 45 | #define DRV_DESC "Emulex OneConnect 10Gbps NIC Driver" |
46 | 46 | ||
47 | #define BE_VENDOR_ID 0x19a2 | 47 | #define BE_VENDOR_ID 0x19a2 |
48 | #define EMULEX_VENDOR_ID 0x10df | 48 | #define EMULEX_VENDOR_ID 0x10df |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 5c995700e534..4d6f3c54427a 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -25,7 +25,7 @@ | |||
25 | MODULE_VERSION(DRV_VER); | 25 | MODULE_VERSION(DRV_VER); |
26 | MODULE_DEVICE_TABLE(pci, be_dev_ids); | 26 | MODULE_DEVICE_TABLE(pci, be_dev_ids); |
27 | MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); | 27 | MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); |
28 | MODULE_AUTHOR("ServerEngines Corporation"); | 28 | MODULE_AUTHOR("Emulex Corporation"); |
29 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
30 | 30 | ||
31 | static unsigned int num_vfs; | 31 | static unsigned int num_vfs; |
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 02a12b69555f..4dab6fc265a2 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h | |||
@@ -232,6 +232,7 @@ | |||
232 | #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ | 232 | #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ |
233 | #define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */ | 233 | #define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */ |
234 | #define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */ | 234 | #define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */ |
235 | #define E1000_CTRL_MEHE 0x00080000 /* Memory Error Handling Enable */ | ||
235 | #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ | 236 | #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ |
236 | #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ | 237 | #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ |
237 | #define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ | 238 | #define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ |
@@ -389,6 +390,12 @@ | |||
389 | 390 | ||
390 | #define E1000_PBS_16K E1000_PBA_16K | 391 | #define E1000_PBS_16K E1000_PBA_16K |
391 | 392 | ||
393 | /* Uncorrectable/correctable ECC Error counts and enable bits */ | ||
394 | #define E1000_PBECCSTS_CORR_ERR_CNT_MASK 0x000000FF | ||
395 | #define E1000_PBECCSTS_UNCORR_ERR_CNT_MASK 0x0000FF00 | ||
396 | #define E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT 8 | ||
397 | #define E1000_PBECCSTS_ECC_ENABLE 0x00010000 | ||
398 | |||
392 | #define IFS_MAX 80 | 399 | #define IFS_MAX 80 |
393 | #define IFS_MIN 40 | 400 | #define IFS_MIN 40 |
394 | #define IFS_RATIO 4 | 401 | #define IFS_RATIO 4 |
@@ -408,6 +415,7 @@ | |||
408 | #define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */ | 415 | #define E1000_ICR_RXSEQ 0x00000008 /* Rx sequence error */ |
409 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ | 416 | #define E1000_ICR_RXDMT0 0x00000010 /* Rx desc min. threshold (0) */ |
410 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ | 417 | #define E1000_ICR_RXT0 0x00000080 /* Rx timer intr (ring 0) */ |
418 | #define E1000_ICR_ECCER 0x00400000 /* Uncorrectable ECC Error */ | ||
411 | #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ | 419 | #define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ |
412 | #define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ | 420 | #define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ |
413 | #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ | 421 | #define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ |
@@ -443,6 +451,7 @@ | |||
443 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ | 451 | #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */ |
444 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ | 452 | #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ |
445 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ | 453 | #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* Rx timer intr */ |
454 | #define E1000_IMS_ECCER E1000_ICR_ECCER /* Uncorrectable ECC Error */ | ||
446 | #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ | 455 | #define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ |
447 | #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ | 456 | #define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ |
448 | #define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ | 457 | #define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ |
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 6782a2eea1bc..7e95f221d60b 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h | |||
@@ -309,6 +309,8 @@ struct e1000_adapter { | |||
309 | 309 | ||
310 | struct napi_struct napi; | 310 | struct napi_struct napi; |
311 | 311 | ||
312 | unsigned int uncorr_errors; /* uncorrectable ECC errors */ | ||
313 | unsigned int corr_errors; /* correctable ECC errors */ | ||
312 | unsigned int restart_queue; | 314 | unsigned int restart_queue; |
313 | u32 txd_cmd; | 315 | u32 txd_cmd; |
314 | 316 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index f95bc6ee1c22..fd4772a2691c 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c | |||
@@ -108,6 +108,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = { | |||
108 | E1000_STAT("dropped_smbus", stats.mgpdc), | 108 | E1000_STAT("dropped_smbus", stats.mgpdc), |
109 | E1000_STAT("rx_dma_failed", rx_dma_failed), | 109 | E1000_STAT("rx_dma_failed", rx_dma_failed), |
110 | E1000_STAT("tx_dma_failed", tx_dma_failed), | 110 | E1000_STAT("tx_dma_failed", tx_dma_failed), |
111 | E1000_STAT("uncorr_ecc_errors", uncorr_errors), | ||
112 | E1000_STAT("corr_ecc_errors", corr_errors), | ||
111 | }; | 113 | }; |
112 | 114 | ||
113 | #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) | 115 | #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) |
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index cf217777586c..b88676ff3d86 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h | |||
@@ -77,6 +77,7 @@ enum e1e_registers { | |||
77 | #define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ | 77 | #define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ |
78 | E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */ | 78 | E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */ |
79 | E1000_PBS = 0x01008, /* Packet Buffer Size */ | 79 | E1000_PBS = 0x01008, /* Packet Buffer Size */ |
80 | E1000_PBECCSTS = 0x0100C, /* Packet Buffer ECC Status - RW */ | ||
80 | E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */ | 81 | E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */ |
81 | E1000_EEWR = 0x0102C, /* EEPROM Write Register - RW */ | 82 | E1000_EEWR = 0x0102C, /* EEPROM Write Register - RW */ |
82 | E1000_FLOP = 0x0103C, /* FLASH Opcode Register */ | 83 | E1000_FLOP = 0x0103C, /* FLASH Opcode Register */ |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 976336547607..24d9f61956f0 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -3624,6 +3624,17 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) | |||
3624 | if (hw->mac.type == e1000_ich8lan) | 3624 | if (hw->mac.type == e1000_ich8lan) |
3625 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); | 3625 | reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS); |
3626 | ew32(RFCTL, reg); | 3626 | ew32(RFCTL, reg); |
3627 | |||
3628 | /* Enable ECC on Lynxpoint */ | ||
3629 | if (hw->mac.type == e1000_pch_lpt) { | ||
3630 | reg = er32(PBECCSTS); | ||
3631 | reg |= E1000_PBECCSTS_ECC_ENABLE; | ||
3632 | ew32(PBECCSTS, reg); | ||
3633 | |||
3634 | reg = er32(CTRL); | ||
3635 | reg |= E1000_CTRL_MEHE; | ||
3636 | ew32(CTRL, reg); | ||
3637 | } | ||
3627 | } | 3638 | } |
3628 | 3639 | ||
3629 | /** | 3640 | /** |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fbf75fdca994..643c883dd795 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -1678,6 +1678,23 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) | |||
1678 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 1678 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
1679 | } | 1679 | } |
1680 | 1680 | ||
1681 | /* Reset on uncorrectable ECC error */ | ||
1682 | if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) { | ||
1683 | u32 pbeccsts = er32(PBECCSTS); | ||
1684 | |||
1685 | adapter->corr_errors += | ||
1686 | pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; | ||
1687 | adapter->uncorr_errors += | ||
1688 | (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> | ||
1689 | E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; | ||
1690 | |||
1691 | /* Do the reset outside of interrupt context */ | ||
1692 | schedule_work(&adapter->reset_task); | ||
1693 | |||
1694 | /* return immediately since reset is imminent */ | ||
1695 | return IRQ_HANDLED; | ||
1696 | } | ||
1697 | |||
1681 | if (napi_schedule_prep(&adapter->napi)) { | 1698 | if (napi_schedule_prep(&adapter->napi)) { |
1682 | adapter->total_tx_bytes = 0; | 1699 | adapter->total_tx_bytes = 0; |
1683 | adapter->total_tx_packets = 0; | 1700 | adapter->total_tx_packets = 0; |
@@ -1741,6 +1758,23 @@ static irqreturn_t e1000_intr(int irq, void *data) | |||
1741 | mod_timer(&adapter->watchdog_timer, jiffies + 1); | 1758 | mod_timer(&adapter->watchdog_timer, jiffies + 1); |
1742 | } | 1759 | } |
1743 | 1760 | ||
1761 | /* Reset on uncorrectable ECC error */ | ||
1762 | if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) { | ||
1763 | u32 pbeccsts = er32(PBECCSTS); | ||
1764 | |||
1765 | adapter->corr_errors += | ||
1766 | pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; | ||
1767 | adapter->uncorr_errors += | ||
1768 | (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> | ||
1769 | E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; | ||
1770 | |||
1771 | /* Do the reset outside of interrupt context */ | ||
1772 | schedule_work(&adapter->reset_task); | ||
1773 | |||
1774 | /* return immediately since reset is imminent */ | ||
1775 | return IRQ_HANDLED; | ||
1776 | } | ||
1777 | |||
1744 | if (napi_schedule_prep(&adapter->napi)) { | 1778 | if (napi_schedule_prep(&adapter->napi)) { |
1745 | adapter->total_tx_bytes = 0; | 1779 | adapter->total_tx_bytes = 0; |
1746 | adapter->total_tx_packets = 0; | 1780 | adapter->total_tx_packets = 0; |
@@ -2104,6 +2138,8 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) | |||
2104 | if (adapter->msix_entries) { | 2138 | if (adapter->msix_entries) { |
2105 | ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); | 2139 | ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); |
2106 | ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); | 2140 | ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); |
2141 | } else if (hw->mac.type == e1000_pch_lpt) { | ||
2142 | ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); | ||
2107 | } else { | 2143 | } else { |
2108 | ew32(IMS, IMS_ENABLE_MASK); | 2144 | ew32(IMS, IMS_ENABLE_MASK); |
2109 | } | 2145 | } |
@@ -4251,6 +4287,16 @@ static void e1000e_update_stats(struct e1000_adapter *adapter) | |||
4251 | adapter->stats.mgptc += er32(MGTPTC); | 4287 | adapter->stats.mgptc += er32(MGTPTC); |
4252 | adapter->stats.mgprc += er32(MGTPRC); | 4288 | adapter->stats.mgprc += er32(MGTPRC); |
4253 | adapter->stats.mgpdc += er32(MGTPDC); | 4289 | adapter->stats.mgpdc += er32(MGTPDC); |
4290 | |||
4291 | /* Correctable ECC Errors */ | ||
4292 | if (hw->mac.type == e1000_pch_lpt) { | ||
4293 | u32 pbeccsts = er32(PBECCSTS); | ||
4294 | adapter->corr_errors += | ||
4295 | pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK; | ||
4296 | adapter->uncorr_errors += | ||
4297 | (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >> | ||
4298 | E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT; | ||
4299 | } | ||
4254 | } | 4300 | } |
4255 | 4301 | ||
4256 | /** | 4302 | /** |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index a6542d75374c..5163af314990 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -380,7 +380,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
380 | } | 380 | } |
381 | } | 381 | } |
382 | 382 | ||
383 | if ((dev_cap->flags & | 383 | if ((dev->caps.flags & |
384 | (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) && | 384 | (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) && |
385 | mlx4_is_master(dev)) | 385 | mlx4_is_master(dev)) |
386 | dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE; | 386 | dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE; |
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 7992b3e05d3d..78ace59efd29 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c | |||
@@ -1801,7 +1801,7 @@ static void rhine_tx(struct net_device *dev) | |||
1801 | rp->tx_skbuff[entry]->len, | 1801 | rp->tx_skbuff[entry]->len, |
1802 | PCI_DMA_TODEVICE); | 1802 | PCI_DMA_TODEVICE); |
1803 | } | 1803 | } |
1804 | dev_kfree_skb_irq(rp->tx_skbuff[entry]); | 1804 | dev_kfree_skb(rp->tx_skbuff[entry]); |
1805 | rp->tx_skbuff[entry] = NULL; | 1805 | rp->tx_skbuff[entry] = NULL; |
1806 | entry = (++rp->dirty_tx) % TX_RING_SIZE; | 1806 | entry = (++rp->dirty_tx) % TX_RING_SIZE; |
1807 | } | 1807 | } |
@@ -2010,11 +2010,7 @@ static void rhine_slow_event_task(struct work_struct *work) | |||
2010 | if (intr_status & IntrPCIErr) | 2010 | if (intr_status & IntrPCIErr) |
2011 | netif_warn(rp, hw, dev, "PCI error\n"); | 2011 | netif_warn(rp, hw, dev, "PCI error\n"); |
2012 | 2012 | ||
2013 | napi_disable(&rp->napi); | 2013 | iowrite16(RHINE_EVENT & 0xffff, rp->base + IntrEnable); |
2014 | rhine_irq_disable(rp); | ||
2015 | /* Slow and safe. Consider __napi_schedule as a replacement ? */ | ||
2016 | napi_enable(&rp->napi); | ||
2017 | napi_schedule(&rp->napi); | ||
2018 | 2014 | ||
2019 | out_unlock: | 2015 | out_unlock: |
2020 | mutex_unlock(&rp->task_lock); | 2016 | mutex_unlock(&rp->task_lock); |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index cc09b67c23bc..2917a86f4c43 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -298,11 +298,12 @@ static void tun_flow_cleanup(unsigned long data) | |||
298 | } | 298 | } |
299 | 299 | ||
300 | static void tun_flow_update(struct tun_struct *tun, u32 rxhash, | 300 | static void tun_flow_update(struct tun_struct *tun, u32 rxhash, |
301 | u16 queue_index) | 301 | struct tun_file *tfile) |
302 | { | 302 | { |
303 | struct hlist_head *head; | 303 | struct hlist_head *head; |
304 | struct tun_flow_entry *e; | 304 | struct tun_flow_entry *e; |
305 | unsigned long delay = tun->ageing_time; | 305 | unsigned long delay = tun->ageing_time; |
306 | u16 queue_index = tfile->queue_index; | ||
306 | 307 | ||
307 | if (!rxhash) | 308 | if (!rxhash) |
308 | return; | 309 | return; |
@@ -311,7 +312,9 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, | |||
311 | 312 | ||
312 | rcu_read_lock(); | 313 | rcu_read_lock(); |
313 | 314 | ||
314 | if (tun->numqueues == 1) | 315 | /* We may get a very small possibility of OOO during switching, not |
316 | * worth to optimize.*/ | ||
317 | if (tun->numqueues == 1 || tfile->detached) | ||
315 | goto unlock; | 318 | goto unlock; |
316 | 319 | ||
317 | e = tun_flow_find(head, rxhash); | 320 | e = tun_flow_find(head, rxhash); |
@@ -411,21 +414,21 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
411 | 414 | ||
412 | tun = rtnl_dereference(tfile->tun); | 415 | tun = rtnl_dereference(tfile->tun); |
413 | 416 | ||
414 | if (tun) { | 417 | if (tun && !tfile->detached) { |
415 | u16 index = tfile->queue_index; | 418 | u16 index = tfile->queue_index; |
416 | BUG_ON(index >= tun->numqueues); | 419 | BUG_ON(index >= tun->numqueues); |
417 | dev = tun->dev; | 420 | dev = tun->dev; |
418 | 421 | ||
419 | rcu_assign_pointer(tun->tfiles[index], | 422 | rcu_assign_pointer(tun->tfiles[index], |
420 | tun->tfiles[tun->numqueues - 1]); | 423 | tun->tfiles[tun->numqueues - 1]); |
421 | rcu_assign_pointer(tfile->tun, NULL); | ||
422 | ntfile = rtnl_dereference(tun->tfiles[index]); | 424 | ntfile = rtnl_dereference(tun->tfiles[index]); |
423 | ntfile->queue_index = index; | 425 | ntfile->queue_index = index; |
424 | 426 | ||
425 | --tun->numqueues; | 427 | --tun->numqueues; |
426 | if (clean) | 428 | if (clean) { |
429 | rcu_assign_pointer(tfile->tun, NULL); | ||
427 | sock_put(&tfile->sk); | 430 | sock_put(&tfile->sk); |
428 | else | 431 | } else |
429 | tun_disable_queue(tun, tfile); | 432 | tun_disable_queue(tun, tfile); |
430 | 433 | ||
431 | synchronize_net(); | 434 | synchronize_net(); |
@@ -439,10 +442,13 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
439 | } | 442 | } |
440 | 443 | ||
441 | if (clean) { | 444 | if (clean) { |
442 | if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && | 445 | if (tun && tun->numqueues == 0 && tun->numdisabled == 0) { |
443 | !(tun->flags & TUN_PERSIST)) | 446 | netif_carrier_off(tun->dev); |
444 | if (tun->dev->reg_state == NETREG_REGISTERED) | 447 | |
448 | if (!(tun->flags & TUN_PERSIST) && | ||
449 | tun->dev->reg_state == NETREG_REGISTERED) | ||
445 | unregister_netdevice(tun->dev); | 450 | unregister_netdevice(tun->dev); |
451 | } | ||
446 | 452 | ||
447 | BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, | 453 | BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, |
448 | &tfile->socket.flags)); | 454 | &tfile->socket.flags)); |
@@ -470,6 +476,10 @@ static void tun_detach_all(struct net_device *dev) | |||
470 | rcu_assign_pointer(tfile->tun, NULL); | 476 | rcu_assign_pointer(tfile->tun, NULL); |
471 | --tun->numqueues; | 477 | --tun->numqueues; |
472 | } | 478 | } |
479 | list_for_each_entry(tfile, &tun->disabled, next) { | ||
480 | wake_up_all(&tfile->wq.wait); | ||
481 | rcu_assign_pointer(tfile->tun, NULL); | ||
482 | } | ||
473 | BUG_ON(tun->numqueues != 0); | 483 | BUG_ON(tun->numqueues != 0); |
474 | 484 | ||
475 | synchronize_net(); | 485 | synchronize_net(); |
@@ -500,7 +510,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) | |||
500 | goto out; | 510 | goto out; |
501 | 511 | ||
502 | err = -EINVAL; | 512 | err = -EINVAL; |
503 | if (rtnl_dereference(tfile->tun)) | 513 | if (rtnl_dereference(tfile->tun) && !tfile->detached) |
504 | goto out; | 514 | goto out; |
505 | 515 | ||
506 | err = -EBUSY; | 516 | err = -EBUSY; |
@@ -1199,7 +1209,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1199 | tun->dev->stats.rx_packets++; | 1209 | tun->dev->stats.rx_packets++; |
1200 | tun->dev->stats.rx_bytes += len; | 1210 | tun->dev->stats.rx_bytes += len; |
1201 | 1211 | ||
1202 | tun_flow_update(tun, rxhash, tfile->queue_index); | 1212 | tun_flow_update(tun, rxhash, tfile); |
1203 | return total_len; | 1213 | return total_len; |
1204 | } | 1214 | } |
1205 | 1215 | ||
@@ -1658,10 +1668,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1658 | device_create_file(&tun->dev->dev, &dev_attr_owner) || | 1668 | device_create_file(&tun->dev->dev, &dev_attr_owner) || |
1659 | device_create_file(&tun->dev->dev, &dev_attr_group)) | 1669 | device_create_file(&tun->dev->dev, &dev_attr_group)) |
1660 | pr_err("Failed to create tun sysfs files\n"); | 1670 | pr_err("Failed to create tun sysfs files\n"); |
1661 | |||
1662 | netif_carrier_on(tun->dev); | ||
1663 | } | 1671 | } |
1664 | 1672 | ||
1673 | netif_carrier_on(tun->dev); | ||
1674 | |||
1665 | tun_debug(KERN_INFO, tun, "tun_set_iff\n"); | 1675 | tun_debug(KERN_INFO, tun, "tun_set_iff\n"); |
1666 | 1676 | ||
1667 | if (ifr->ifr_flags & IFF_NO_PI) | 1677 | if (ifr->ifr_flags & IFF_NO_PI) |
@@ -1813,7 +1823,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) | |||
1813 | ret = tun_attach(tun, file); | 1823 | ret = tun_attach(tun, file); |
1814 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { | 1824 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { |
1815 | tun = rtnl_dereference(tfile->tun); | 1825 | tun = rtnl_dereference(tfile->tun); |
1816 | if (!tun || !(tun->flags & TUN_TAP_MQ)) | 1826 | if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached) |
1817 | ret = -EINVAL; | 1827 | ret = -EINVAL; |
1818 | else | 1828 | else |
1819 | __tun_detach(tfile, false); | 1829 | __tun_detach(tfile, false); |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 9197b2c72ca3..00d3b2d37828 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -1215,6 +1215,9 @@ static const struct usb_device_id cdc_devs[] = { | |||
1215 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), | 1215 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), |
1216 | .driver_info = (unsigned long)&wwan_info, | 1216 | .driver_info = (unsigned long)&wwan_info, |
1217 | }, | 1217 | }, |
1218 | { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), | ||
1219 | .driver_info = (unsigned long)&wwan_info, | ||
1220 | }, | ||
1218 | 1221 | ||
1219 | /* Infineon(now Intel) HSPA Modem platform */ | 1222 | /* Infineon(now Intel) HSPA Modem platform */ |
1220 | { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, | 1223 | { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 575a5839ee34..c8e05e27f38c 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -351,6 +351,10 @@ static const struct usb_device_id products[] = { | |||
351 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), | 351 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), |
352 | .driver_info = (unsigned long)&qmi_wwan_info, | 352 | .driver_info = (unsigned long)&qmi_wwan_info, |
353 | }, | 353 | }, |
354 | { /* HUAWEI_INTERFACE_NDIS_CONTROL_QUALCOMM */ | ||
355 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69), | ||
356 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
357 | }, | ||
354 | 358 | ||
355 | /* 2. Combined interface devices matching on class+protocol */ | 359 | /* 2. Combined interface devices matching on class+protocol */ |
356 | { /* Huawei E367 and possibly others in "Windows mode" */ | 360 | { /* Huawei E367 and possibly others in "Windows mode" */ |
@@ -361,6 +365,14 @@ static const struct usb_device_id products[] = { | |||
361 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), | 365 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), |
362 | .driver_info = (unsigned long)&qmi_wwan_info, | 366 | .driver_info = (unsigned long)&qmi_wwan_info, |
363 | }, | 367 | }, |
368 | { /* HUAWEI_NDIS_SINGLE_INTERFACE_VDF */ | ||
369 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x37), | ||
370 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
371 | }, | ||
372 | { /* HUAWEI_INTERFACE_NDIS_HW_QUALCOMM */ | ||
373 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x67), | ||
374 | .driver_info = (unsigned long)&qmi_wwan_info, | ||
375 | }, | ||
364 | { /* Pantech UML290, P4200 and more */ | 376 | { /* Pantech UML290, P4200 and more */ |
365 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), | 377 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), |
366 | .driver_info = (unsigned long)&qmi_wwan_info, | 378 | .driver_info = (unsigned long)&qmi_wwan_info, |
@@ -461,6 +473,7 @@ static const struct usb_device_id products[] = { | |||
461 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 473 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
462 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 474 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
463 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 475 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
476 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | ||
464 | 477 | ||
465 | /* 4. Gobi 1000 devices */ | 478 | /* 4. Gobi 1000 devices */ |
466 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 479 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f34b2ebee815..5e33606c1366 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -380,6 +380,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
380 | unsigned long lockflags; | 380 | unsigned long lockflags; |
381 | size_t size = dev->rx_urb_size; | 381 | size_t size = dev->rx_urb_size; |
382 | 382 | ||
383 | /* prevent rx skb allocation when error ratio is high */ | ||
384 | if (test_bit(EVENT_RX_KILL, &dev->flags)) { | ||
385 | usb_free_urb(urb); | ||
386 | return -ENOLINK; | ||
387 | } | ||
388 | |||
383 | skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); | 389 | skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); |
384 | if (!skb) { | 390 | if (!skb) { |
385 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); | 391 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); |
@@ -539,6 +545,17 @@ block: | |||
539 | break; | 545 | break; |
540 | } | 546 | } |
541 | 547 | ||
548 | /* stop rx if packet error rate is high */ | ||
549 | if (++dev->pkt_cnt > 30) { | ||
550 | dev->pkt_cnt = 0; | ||
551 | dev->pkt_err = 0; | ||
552 | } else { | ||
553 | if (state == rx_cleanup) | ||
554 | dev->pkt_err++; | ||
555 | if (dev->pkt_err > 20) | ||
556 | set_bit(EVENT_RX_KILL, &dev->flags); | ||
557 | } | ||
558 | |||
542 | state = defer_bh(dev, skb, &dev->rxq, state); | 559 | state = defer_bh(dev, skb, &dev->rxq, state); |
543 | 560 | ||
544 | if (urb) { | 561 | if (urb) { |
@@ -791,6 +808,11 @@ int usbnet_open (struct net_device *net) | |||
791 | (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" : | 808 | (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" : |
792 | "simple"); | 809 | "simple"); |
793 | 810 | ||
811 | /* reset rx error state */ | ||
812 | dev->pkt_cnt = 0; | ||
813 | dev->pkt_err = 0; | ||
814 | clear_bit(EVENT_RX_KILL, &dev->flags); | ||
815 | |||
794 | // delay posting reads until we're fully open | 816 | // delay posting reads until we're fully open |
795 | tasklet_schedule (&dev->bh); | 817 | tasklet_schedule (&dev->bh); |
796 | if (info->manage_power) { | 818 | if (info->manage_power) { |
@@ -1103,13 +1125,11 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1103 | if (info->tx_fixup) { | 1125 | if (info->tx_fixup) { |
1104 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); | 1126 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); |
1105 | if (!skb) { | 1127 | if (!skb) { |
1106 | if (netif_msg_tx_err(dev)) { | 1128 | /* packet collected; minidriver waiting for more */ |
1107 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); | 1129 | if (info->flags & FLAG_MULTI_PACKET) |
1108 | goto drop; | ||
1109 | } else { | ||
1110 | /* cdc_ncm collected packet; waits for more */ | ||
1111 | goto not_drop; | 1130 | goto not_drop; |
1112 | } | 1131 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); |
1132 | goto drop; | ||
1113 | } | 1133 | } |
1114 | } | 1134 | } |
1115 | length = skb->len; | 1135 | length = skb->len; |
@@ -1254,6 +1274,9 @@ static void usbnet_bh (unsigned long param) | |||
1254 | } | 1274 | } |
1255 | } | 1275 | } |
1256 | 1276 | ||
1277 | /* restart RX again after disabling due to high error rate */ | ||
1278 | clear_bit(EVENT_RX_KILL, &dev->flags); | ||
1279 | |||
1257 | // waiting for all pending urbs to complete? | 1280 | // waiting for all pending urbs to complete? |
1258 | if (dev->wait) { | 1281 | if (dev->wait) { |
1259 | if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { | 1282 | if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index dc8913c6238c..12c6440d1649 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -154,8 +154,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue) | |||
154 | if (ret & 1) { /* Link is up. */ | 154 | if (ret & 1) { /* Link is up. */ |
155 | printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n", | 155 | printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n", |
156 | adapter->netdev->name, adapter->link_speed); | 156 | adapter->netdev->name, adapter->link_speed); |
157 | if (!netif_carrier_ok(adapter->netdev)) | 157 | netif_carrier_on(adapter->netdev); |
158 | netif_carrier_on(adapter->netdev); | ||
159 | 158 | ||
160 | if (affectTxQueue) { | 159 | if (affectTxQueue) { |
161 | for (i = 0; i < adapter->num_tx_queues; i++) | 160 | for (i = 0; i < adapter->num_tx_queues; i++) |
@@ -165,8 +164,7 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue) | |||
165 | } else { | 164 | } else { |
166 | printk(KERN_INFO "%s: NIC Link is Down\n", | 165 | printk(KERN_INFO "%s: NIC Link is Down\n", |
167 | adapter->netdev->name); | 166 | adapter->netdev->name); |
168 | if (netif_carrier_ok(adapter->netdev)) | 167 | netif_carrier_off(adapter->netdev); |
169 | netif_carrier_off(adapter->netdev); | ||
170 | 168 | ||
171 | if (affectTxQueue) { | 169 | if (affectTxQueue) { |
172 | for (i = 0; i < adapter->num_tx_queues; i++) | 170 | for (i = 0; i < adapter->num_tx_queues; i++) |
@@ -3061,6 +3059,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
3061 | netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); | 3059 | netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); |
3062 | netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); | 3060 | netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); |
3063 | 3061 | ||
3062 | netif_carrier_off(netdev); | ||
3064 | err = register_netdev(netdev); | 3063 | err = register_netdev(netdev); |
3065 | 3064 | ||
3066 | if (err) { | 3065 | if (err) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 0f71d1d4339d..e5fd20994bec 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "debug.h" | 36 | #include "debug.h" |
37 | 37 | ||
38 | #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ | 38 | #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ |
39 | #define BRCMS_FLUSH_TIMEOUT 500 /* msec */ | ||
39 | 40 | ||
40 | /* Flags we support */ | 41 | /* Flags we support */ |
41 | #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ | 42 | #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ |
@@ -708,16 +709,29 @@ static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw) | |||
708 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); | 709 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); |
709 | } | 710 | } |
710 | 711 | ||
712 | static bool brcms_tx_flush_completed(struct brcms_info *wl) | ||
713 | { | ||
714 | bool result; | ||
715 | |||
716 | spin_lock_bh(&wl->lock); | ||
717 | result = brcms_c_tx_flush_completed(wl->wlc); | ||
718 | spin_unlock_bh(&wl->lock); | ||
719 | return result; | ||
720 | } | ||
721 | |||
711 | static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) | 722 | static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) |
712 | { | 723 | { |
713 | struct brcms_info *wl = hw->priv; | 724 | struct brcms_info *wl = hw->priv; |
725 | int ret; | ||
714 | 726 | ||
715 | no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); | 727 | no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); |
716 | 728 | ||
717 | /* wait for packet queue and dma fifos to run empty */ | 729 | ret = wait_event_timeout(wl->tx_flush_wq, |
718 | spin_lock_bh(&wl->lock); | 730 | brcms_tx_flush_completed(wl), |
719 | brcms_c_wait_for_tx_completion(wl->wlc, drop); | 731 | msecs_to_jiffies(BRCMS_FLUSH_TIMEOUT)); |
720 | spin_unlock_bh(&wl->lock); | 732 | |
733 | brcms_dbg_mac80211(wl->wlc->hw->d11core, | ||
734 | "ret=%d\n", jiffies_to_msecs(ret)); | ||
721 | } | 735 | } |
722 | 736 | ||
723 | static const struct ieee80211_ops brcms_ops = { | 737 | static const struct ieee80211_ops brcms_ops = { |
@@ -772,6 +786,7 @@ void brcms_dpc(unsigned long data) | |||
772 | 786 | ||
773 | done: | 787 | done: |
774 | spin_unlock_bh(&wl->lock); | 788 | spin_unlock_bh(&wl->lock); |
789 | wake_up(&wl->tx_flush_wq); | ||
775 | } | 790 | } |
776 | 791 | ||
777 | /* | 792 | /* |
@@ -1020,6 +1035,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) | |||
1020 | 1035 | ||
1021 | atomic_set(&wl->callbacks, 0); | 1036 | atomic_set(&wl->callbacks, 0); |
1022 | 1037 | ||
1038 | init_waitqueue_head(&wl->tx_flush_wq); | ||
1039 | |||
1023 | /* setup the bottom half handler */ | 1040 | /* setup the bottom half handler */ |
1024 | tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); | 1041 | tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); |
1025 | 1042 | ||
@@ -1609,13 +1626,3 @@ bool brcms_rfkill_set_hw_state(struct brcms_info *wl) | |||
1609 | spin_lock_bh(&wl->lock); | 1626 | spin_lock_bh(&wl->lock); |
1610 | return blocked; | 1627 | return blocked; |
1611 | } | 1628 | } |
1612 | |||
1613 | /* | ||
1614 | * precondition: perimeter lock has been acquired | ||
1615 | */ | ||
1616 | void brcms_msleep(struct brcms_info *wl, uint ms) | ||
1617 | { | ||
1618 | spin_unlock_bh(&wl->lock); | ||
1619 | msleep(ms); | ||
1620 | spin_lock_bh(&wl->lock); | ||
1621 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 9358bd5ebd35..947ccacf43e6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h | |||
@@ -68,6 +68,8 @@ struct brcms_info { | |||
68 | spinlock_t lock; /* per-device perimeter lock */ | 68 | spinlock_t lock; /* per-device perimeter lock */ |
69 | spinlock_t isr_lock; /* per-device ISR synchronization lock */ | 69 | spinlock_t isr_lock; /* per-device ISR synchronization lock */ |
70 | 70 | ||
71 | /* tx flush */ | ||
72 | wait_queue_head_t tx_flush_wq; | ||
71 | 73 | ||
72 | /* timer related fields */ | 74 | /* timer related fields */ |
73 | atomic_t callbacks; /* # outstanding callback functions */ | 75 | atomic_t callbacks; /* # outstanding callback functions */ |
@@ -100,7 +102,6 @@ extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, | |||
100 | extern void brcms_free_timer(struct brcms_timer *timer); | 102 | extern void brcms_free_timer(struct brcms_timer *timer); |
101 | extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); | 103 | extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); |
102 | extern bool brcms_del_timer(struct brcms_timer *timer); | 104 | extern bool brcms_del_timer(struct brcms_timer *timer); |
103 | extern void brcms_msleep(struct brcms_info *wl, uint ms); | ||
104 | extern void brcms_dpc(unsigned long data); | 105 | extern void brcms_dpc(unsigned long data); |
105 | extern void brcms_timer(struct brcms_timer *t); | 106 | extern void brcms_timer(struct brcms_timer *t); |
106 | extern void brcms_fatal_error(struct brcms_info *wl); | 107 | extern void brcms_fatal_error(struct brcms_info *wl); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 17594de4199e..8b5839008af3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
1027 | static bool | 1027 | static bool |
1028 | brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | 1028 | brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) |
1029 | { | 1029 | { |
1030 | bool morepending = false; | ||
1031 | struct bcma_device *core; | 1030 | struct bcma_device *core; |
1032 | struct tx_status txstatus, *txs; | 1031 | struct tx_status txstatus, *txs; |
1033 | u32 s1, s2; | 1032 | u32 s1, s2; |
@@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1041 | txs = &txstatus; | 1040 | txs = &txstatus; |
1042 | core = wlc_hw->d11core; | 1041 | core = wlc_hw->d11core; |
1043 | *fatal = false; | 1042 | *fatal = false; |
1044 | s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); | ||
1045 | while (!(*fatal) | ||
1046 | && (s1 & TXS_V)) { | ||
1047 | /* !give others some time to run! */ | ||
1048 | if (n >= max_tx_num) { | ||
1049 | morepending = true; | ||
1050 | break; | ||
1051 | } | ||
1052 | 1043 | ||
1044 | while (n < max_tx_num) { | ||
1045 | s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); | ||
1053 | if (s1 == 0xffffffff) { | 1046 | if (s1 == 0xffffffff) { |
1054 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, | 1047 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
1055 | __func__); | 1048 | __func__); |
1056 | *fatal = true; | 1049 | *fatal = true; |
1057 | return false; | 1050 | return false; |
1058 | } | 1051 | } |
1059 | s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); | 1052 | /* only process when valid */ |
1053 | if (!(s1 & TXS_V)) | ||
1054 | break; | ||
1060 | 1055 | ||
1056 | s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); | ||
1061 | txs->status = s1 & TXS_STATUS_MASK; | 1057 | txs->status = s1 & TXS_STATUS_MASK; |
1062 | txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; | 1058 | txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; |
1063 | txs->sequence = s2 & TXS_SEQ_MASK; | 1059 | txs->sequence = s2 & TXS_SEQ_MASK; |
@@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1065 | txs->lasttxtime = 0; | 1061 | txs->lasttxtime = 0; |
1066 | 1062 | ||
1067 | *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); | 1063 | *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); |
1068 | 1064 | if (*fatal == true) | |
1069 | s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); | 1065 | return false; |
1070 | n++; | 1066 | n++; |
1071 | } | 1067 | } |
1072 | 1068 | ||
1073 | if (*fatal) | 1069 | return n >= max_tx_num; |
1074 | return false; | ||
1075 | |||
1076 | return morepending; | ||
1077 | } | 1070 | } |
1078 | 1071 | ||
1079 | static void brcms_c_tbtt(struct brcms_c_info *wlc) | 1072 | static void brcms_c_tbtt(struct brcms_c_info *wlc) |
@@ -7518,25 +7511,16 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) | |||
7518 | return wlc->band->bandunit; | 7511 | return wlc->band->bandunit; |
7519 | } | 7512 | } |
7520 | 7513 | ||
7521 | void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) | 7514 | bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc) |
7522 | { | 7515 | { |
7523 | int timeout = 20; | ||
7524 | int i; | 7516 | int i; |
7525 | 7517 | ||
7526 | /* Kick DMA to send any pending AMPDU */ | 7518 | /* Kick DMA to send any pending AMPDU */ |
7527 | for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) | 7519 | for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) |
7528 | if (wlc->hw->di[i]) | 7520 | if (wlc->hw->di[i]) |
7529 | dma_txflush(wlc->hw->di[i]); | 7521 | dma_kick_tx(wlc->hw->di[i]); |
7530 | |||
7531 | /* wait for queue and DMA fifos to run dry */ | ||
7532 | while (brcms_txpktpendtot(wlc) > 0) { | ||
7533 | brcms_msleep(wlc->wl, 1); | ||
7534 | |||
7535 | if (--timeout == 0) | ||
7536 | break; | ||
7537 | } | ||
7538 | 7522 | ||
7539 | WARN_ON_ONCE(timeout == 0); | 7523 | return !brcms_txpktpendtot(wlc); |
7540 | } | 7524 | } |
7541 | 7525 | ||
7542 | void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) | 7526 | void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 4fb2834f4e64..b0f14b7b8616 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h | |||
@@ -314,8 +314,6 @@ extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); | |||
314 | extern void brcms_c_scan_start(struct brcms_c_info *wlc); | 314 | extern void brcms_c_scan_start(struct brcms_c_info *wlc); |
315 | extern void brcms_c_scan_stop(struct brcms_c_info *wlc); | 315 | extern void brcms_c_scan_stop(struct brcms_c_info *wlc); |
316 | extern int brcms_c_get_curband(struct brcms_c_info *wlc); | 316 | extern int brcms_c_get_curband(struct brcms_c_info *wlc); |
317 | extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, | ||
318 | bool drop); | ||
319 | extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); | 317 | extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); |
320 | extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); | 318 | extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); |
321 | extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, | 319 | extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, |
@@ -332,5 +330,6 @@ extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); | |||
332 | extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); | 330 | extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); |
333 | extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); | 331 | extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); |
334 | extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); | 332 | extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); |
333 | extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); | ||
335 | 334 | ||
336 | #endif /* _BRCM_PUB_H_ */ | 335 | #endif /* _BRCM_PUB_H_ */ |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 31534f7c0548..279796419ea0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -1153,6 +1153,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1153 | next_reclaimed = ssn; | 1153 | next_reclaimed = ssn; |
1154 | } | 1154 | } |
1155 | 1155 | ||
1156 | if (tid != IWL_TID_NON_QOS) { | ||
1157 | priv->tid_data[sta_id][tid].next_reclaimed = | ||
1158 | next_reclaimed; | ||
1159 | IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n", | ||
1160 | next_reclaimed); | ||
1161 | } | ||
1162 | |||
1156 | iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); | 1163 | iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); |
1157 | 1164 | ||
1158 | iwlagn_check_ratid_empty(priv, sta_id, tid); | 1165 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
@@ -1203,28 +1210,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1203 | if (!is_agg) | 1210 | if (!is_agg) |
1204 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); | 1211 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); |
1205 | 1212 | ||
1206 | /* | ||
1207 | * W/A for FW bug - the seq_ctl isn't updated when the | ||
1208 | * queues are flushed. Fetch it from the packet itself | ||
1209 | */ | ||
1210 | if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) { | ||
1211 | next_reclaimed = le16_to_cpu(hdr->seq_ctrl); | ||
1212 | next_reclaimed = | ||
1213 | SEQ_TO_SN(next_reclaimed + 0x10); | ||
1214 | } | ||
1215 | |||
1216 | is_offchannel_skb = | 1213 | is_offchannel_skb = |
1217 | (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); | 1214 | (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); |
1218 | freed++; | 1215 | freed++; |
1219 | } | 1216 | } |
1220 | 1217 | ||
1221 | if (tid != IWL_TID_NON_QOS) { | ||
1222 | priv->tid_data[sta_id][tid].next_reclaimed = | ||
1223 | next_reclaimed; | ||
1224 | IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n", | ||
1225 | next_reclaimed); | ||
1226 | } | ||
1227 | |||
1228 | WARN_ON(!is_agg && freed != 1); | 1218 | WARN_ON(!is_agg && freed != 1); |
1229 | 1219 | ||
1230 | /* | 1220 | /* |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 9189a32b7844..973a9d90e9ea 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -1563,7 +1563,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1563 | dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", | 1563 | dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", |
1564 | scan_rsp->number_of_sets); | 1564 | scan_rsp->number_of_sets); |
1565 | ret = -1; | 1565 | ret = -1; |
1566 | goto done; | 1566 | goto check_next_scan; |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); | 1569 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); |
@@ -1634,7 +1634,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1634 | if (!beacon_size || beacon_size > bytes_left) { | 1634 | if (!beacon_size || beacon_size > bytes_left) { |
1635 | bss_info += bytes_left; | 1635 | bss_info += bytes_left; |
1636 | bytes_left = 0; | 1636 | bytes_left = 0; |
1637 | return -1; | 1637 | ret = -1; |
1638 | goto check_next_scan; | ||
1638 | } | 1639 | } |
1639 | 1640 | ||
1640 | /* Initialize the current working beacon pointer for this BSS | 1641 | /* Initialize the current working beacon pointer for this BSS |
@@ -1690,7 +1691,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1690 | dev_err(priv->adapter->dev, | 1691 | dev_err(priv->adapter->dev, |
1691 | "%s: bytes left < IE length\n", | 1692 | "%s: bytes left < IE length\n", |
1692 | __func__); | 1693 | __func__); |
1693 | goto done; | 1694 | goto check_next_scan; |
1694 | } | 1695 | } |
1695 | if (element_id == WLAN_EID_DS_PARAMS) { | 1696 | if (element_id == WLAN_EID_DS_PARAMS) { |
1696 | channel = *(current_ptr + sizeof(struct ieee_types_header)); | 1697 | channel = *(current_ptr + sizeof(struct ieee_types_header)); |
@@ -1753,6 +1754,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1753 | } | 1754 | } |
1754 | } | 1755 | } |
1755 | 1756 | ||
1757 | check_next_scan: | ||
1756 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 1758 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
1757 | if (list_empty(&adapter->scan_pending_q)) { | 1759 | if (list_empty(&adapter->scan_pending_q)) { |
1758 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 1760 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); |
@@ -1813,7 +1815,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1813 | } | 1815 | } |
1814 | } | 1816 | } |
1815 | 1817 | ||
1816 | done: | ||
1817 | return ret; | 1818 | return ret; |
1818 | } | 1819 | } |
1819 | 1820 | ||
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 4494d130b37c..0f8b05185eda 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -1004,7 +1004,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
1004 | is_tx ? "Tx" : "Rx"); | 1004 | is_tx ? "Tx" : "Rx"); |
1005 | 1005 | ||
1006 | if (is_tx) { | 1006 | if (is_tx) { |
1007 | rtl_lps_leave(hw); | 1007 | schedule_work(&rtlpriv-> |
1008 | works.lps_leave_work); | ||
1008 | ppsc->last_delaylps_stamp_jiffies = | 1009 | ppsc->last_delaylps_stamp_jiffies = |
1009 | jiffies; | 1010 | jiffies; |
1010 | } | 1011 | } |
@@ -1014,7 +1015,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
1014 | } | 1015 | } |
1015 | } else if (ETH_P_ARP == ether_type) { | 1016 | } else if (ETH_P_ARP == ether_type) { |
1016 | if (is_tx) { | 1017 | if (is_tx) { |
1017 | rtl_lps_leave(hw); | 1018 | schedule_work(&rtlpriv->works.lps_leave_work); |
1018 | ppsc->last_delaylps_stamp_jiffies = jiffies; | 1019 | ppsc->last_delaylps_stamp_jiffies = jiffies; |
1019 | } | 1020 | } |
1020 | 1021 | ||
@@ -1024,7 +1025,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
1024 | "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); | 1025 | "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); |
1025 | 1026 | ||
1026 | if (is_tx) { | 1027 | if (is_tx) { |
1027 | rtl_lps_leave(hw); | 1028 | schedule_work(&rtlpriv->works.lps_leave_work); |
1028 | ppsc->last_delaylps_stamp_jiffies = jiffies; | 1029 | ppsc->last_delaylps_stamp_jiffies = jiffies; |
1029 | } | 1030 | } |
1030 | 1031 | ||
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f2ecdeb3a90d..1535efda3d52 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
542 | WARN_ON(skb_queue_empty(&rx_queue)); | 542 | WARN_ON(skb_queue_empty(&rx_queue)); |
543 | while (!skb_queue_empty(&rx_queue)) { | 543 | while (!skb_queue_empty(&rx_queue)) { |
544 | _skb = skb_dequeue(&rx_queue); | 544 | _skb = skb_dequeue(&rx_queue); |
545 | _rtl_usb_rx_process_agg(hw, skb); | 545 | _rtl_usb_rx_process_agg(hw, _skb); |
546 | ieee80211_rx_irqsafe(hw, skb); | 546 | ieee80211_rx_irqsafe(hw, _skb); |
547 | } | 547 | } |
548 | } | 548 | } |
549 | 549 | ||
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 94b79c3338c4..9d7f1723dd8f 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
@@ -151,6 +151,9 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb); | |||
151 | /* Notify xenvif that ring now has space to send an skb to the frontend */ | 151 | /* Notify xenvif that ring now has space to send an skb to the frontend */ |
152 | void xenvif_notify_tx_completion(struct xenvif *vif); | 152 | void xenvif_notify_tx_completion(struct xenvif *vif); |
153 | 153 | ||
154 | /* Prevent the device from generating any further traffic. */ | ||
155 | void xenvif_carrier_off(struct xenvif *vif); | ||
156 | |||
154 | /* Returns number of ring slots required to send an skb to the frontend */ | 157 | /* Returns number of ring slots required to send an skb to the frontend */ |
155 | unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); | 158 | unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); |
156 | 159 | ||
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index b7d41f8c338a..b8c5193bd420 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -343,17 +343,22 @@ err: | |||
343 | return err; | 343 | return err; |
344 | } | 344 | } |
345 | 345 | ||
346 | void xenvif_disconnect(struct xenvif *vif) | 346 | void xenvif_carrier_off(struct xenvif *vif) |
347 | { | 347 | { |
348 | struct net_device *dev = vif->dev; | 348 | struct net_device *dev = vif->dev; |
349 | if (netif_carrier_ok(dev)) { | 349 | |
350 | rtnl_lock(); | 350 | rtnl_lock(); |
351 | netif_carrier_off(dev); /* discard queued packets */ | 351 | netif_carrier_off(dev); /* discard queued packets */ |
352 | if (netif_running(dev)) | 352 | if (netif_running(dev)) |
353 | xenvif_down(vif); | 353 | xenvif_down(vif); |
354 | rtnl_unlock(); | 354 | rtnl_unlock(); |
355 | xenvif_put(vif); | 355 | xenvif_put(vif); |
356 | } | 356 | } |
357 | |||
358 | void xenvif_disconnect(struct xenvif *vif) | ||
359 | { | ||
360 | if (netif_carrier_ok(vif->dev)) | ||
361 | xenvif_carrier_off(vif); | ||
357 | 362 | ||
358 | atomic_dec(&vif->refcnt); | 363 | atomic_dec(&vif->refcnt); |
359 | wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); | 364 | wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f2d6b78d901d..2b9520c46e97 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -147,7 +147,8 @@ void xen_netbk_remove_xenvif(struct xenvif *vif) | |||
147 | atomic_dec(&netbk->netfront_count); | 147 | atomic_dec(&netbk->netfront_count); |
148 | } | 148 | } |
149 | 149 | ||
150 | static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx); | 150 | static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, |
151 | u8 status); | ||
151 | static void make_tx_response(struct xenvif *vif, | 152 | static void make_tx_response(struct xenvif *vif, |
152 | struct xen_netif_tx_request *txp, | 153 | struct xen_netif_tx_request *txp, |
153 | s8 st); | 154 | s8 st); |
@@ -879,7 +880,7 @@ static void netbk_tx_err(struct xenvif *vif, | |||
879 | 880 | ||
880 | do { | 881 | do { |
881 | make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); | 882 | make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); |
882 | if (cons >= end) | 883 | if (cons == end) |
883 | break; | 884 | break; |
884 | txp = RING_GET_REQUEST(&vif->tx, cons++); | 885 | txp = RING_GET_REQUEST(&vif->tx, cons++); |
885 | } while (1); | 886 | } while (1); |
@@ -888,6 +889,13 @@ static void netbk_tx_err(struct xenvif *vif, | |||
888 | xenvif_put(vif); | 889 | xenvif_put(vif); |
889 | } | 890 | } |
890 | 891 | ||
892 | static void netbk_fatal_tx_err(struct xenvif *vif) | ||
893 | { | ||
894 | netdev_err(vif->dev, "fatal error; disabling device\n"); | ||
895 | xenvif_carrier_off(vif); | ||
896 | xenvif_put(vif); | ||
897 | } | ||
898 | |||
891 | static int netbk_count_requests(struct xenvif *vif, | 899 | static int netbk_count_requests(struct xenvif *vif, |
892 | struct xen_netif_tx_request *first, | 900 | struct xen_netif_tx_request *first, |
893 | struct xen_netif_tx_request *txp, | 901 | struct xen_netif_tx_request *txp, |
@@ -901,19 +909,22 @@ static int netbk_count_requests(struct xenvif *vif, | |||
901 | 909 | ||
902 | do { | 910 | do { |
903 | if (frags >= work_to_do) { | 911 | if (frags >= work_to_do) { |
904 | netdev_dbg(vif->dev, "Need more frags\n"); | 912 | netdev_err(vif->dev, "Need more frags\n"); |
913 | netbk_fatal_tx_err(vif); | ||
905 | return -frags; | 914 | return -frags; |
906 | } | 915 | } |
907 | 916 | ||
908 | if (unlikely(frags >= MAX_SKB_FRAGS)) { | 917 | if (unlikely(frags >= MAX_SKB_FRAGS)) { |
909 | netdev_dbg(vif->dev, "Too many frags\n"); | 918 | netdev_err(vif->dev, "Too many frags\n"); |
919 | netbk_fatal_tx_err(vif); | ||
910 | return -frags; | 920 | return -frags; |
911 | } | 921 | } |
912 | 922 | ||
913 | memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), | 923 | memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), |
914 | sizeof(*txp)); | 924 | sizeof(*txp)); |
915 | if (txp->size > first->size) { | 925 | if (txp->size > first->size) { |
916 | netdev_dbg(vif->dev, "Frags galore\n"); | 926 | netdev_err(vif->dev, "Frag is bigger than frame.\n"); |
927 | netbk_fatal_tx_err(vif); | ||
917 | return -frags; | 928 | return -frags; |
918 | } | 929 | } |
919 | 930 | ||
@@ -921,8 +932,9 @@ static int netbk_count_requests(struct xenvif *vif, | |||
921 | frags++; | 932 | frags++; |
922 | 933 | ||
923 | if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { | 934 | if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { |
924 | netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n", | 935 | netdev_err(vif->dev, "txp->offset: %x, size: %u\n", |
925 | txp->offset, txp->size); | 936 | txp->offset, txp->size); |
937 | netbk_fatal_tx_err(vif); | ||
926 | return -frags; | 938 | return -frags; |
927 | } | 939 | } |
928 | } while ((txp++)->flags & XEN_NETTXF_more_data); | 940 | } while ((txp++)->flags & XEN_NETTXF_more_data); |
@@ -966,7 +978,7 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, | |||
966 | pending_idx = netbk->pending_ring[index]; | 978 | pending_idx = netbk->pending_ring[index]; |
967 | page = xen_netbk_alloc_page(netbk, skb, pending_idx); | 979 | page = xen_netbk_alloc_page(netbk, skb, pending_idx); |
968 | if (!page) | 980 | if (!page) |
969 | return NULL; | 981 | goto err; |
970 | 982 | ||
971 | gop->source.u.ref = txp->gref; | 983 | gop->source.u.ref = txp->gref; |
972 | gop->source.domid = vif->domid; | 984 | gop->source.domid = vif->domid; |
@@ -988,6 +1000,17 @@ static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, | |||
988 | } | 1000 | } |
989 | 1001 | ||
990 | return gop; | 1002 | return gop; |
1003 | err: | ||
1004 | /* Unwind, freeing all pages and sending error responses. */ | ||
1005 | while (i-- > start) { | ||
1006 | xen_netbk_idx_release(netbk, frag_get_pending_idx(&frags[i]), | ||
1007 | XEN_NETIF_RSP_ERROR); | ||
1008 | } | ||
1009 | /* The head too, if necessary. */ | ||
1010 | if (start) | ||
1011 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); | ||
1012 | |||
1013 | return NULL; | ||
991 | } | 1014 | } |
992 | 1015 | ||
993 | static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, | 1016 | static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, |
@@ -996,30 +1019,20 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, | |||
996 | { | 1019 | { |
997 | struct gnttab_copy *gop = *gopp; | 1020 | struct gnttab_copy *gop = *gopp; |
998 | u16 pending_idx = *((u16 *)skb->data); | 1021 | u16 pending_idx = *((u16 *)skb->data); |
999 | struct pending_tx_info *pending_tx_info = netbk->pending_tx_info; | ||
1000 | struct xenvif *vif = pending_tx_info[pending_idx].vif; | ||
1001 | struct xen_netif_tx_request *txp; | ||
1002 | struct skb_shared_info *shinfo = skb_shinfo(skb); | 1022 | struct skb_shared_info *shinfo = skb_shinfo(skb); |
1003 | int nr_frags = shinfo->nr_frags; | 1023 | int nr_frags = shinfo->nr_frags; |
1004 | int i, err, start; | 1024 | int i, err, start; |
1005 | 1025 | ||
1006 | /* Check status of header. */ | 1026 | /* Check status of header. */ |
1007 | err = gop->status; | 1027 | err = gop->status; |
1008 | if (unlikely(err)) { | 1028 | if (unlikely(err)) |
1009 | pending_ring_idx_t index; | 1029 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); |
1010 | index = pending_index(netbk->pending_prod++); | ||
1011 | txp = &pending_tx_info[pending_idx].req; | ||
1012 | make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); | ||
1013 | netbk->pending_ring[index] = pending_idx; | ||
1014 | xenvif_put(vif); | ||
1015 | } | ||
1016 | 1030 | ||
1017 | /* Skip first skb fragment if it is on same page as header fragment. */ | 1031 | /* Skip first skb fragment if it is on same page as header fragment. */ |
1018 | start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx); | 1032 | start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx); |
1019 | 1033 | ||
1020 | for (i = start; i < nr_frags; i++) { | 1034 | for (i = start; i < nr_frags; i++) { |
1021 | int j, newerr; | 1035 | int j, newerr; |
1022 | pending_ring_idx_t index; | ||
1023 | 1036 | ||
1024 | pending_idx = frag_get_pending_idx(&shinfo->frags[i]); | 1037 | pending_idx = frag_get_pending_idx(&shinfo->frags[i]); |
1025 | 1038 | ||
@@ -1028,16 +1041,12 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, | |||
1028 | if (likely(!newerr)) { | 1041 | if (likely(!newerr)) { |
1029 | /* Had a previous error? Invalidate this fragment. */ | 1042 | /* Had a previous error? Invalidate this fragment. */ |
1030 | if (unlikely(err)) | 1043 | if (unlikely(err)) |
1031 | xen_netbk_idx_release(netbk, pending_idx); | 1044 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); |
1032 | continue; | 1045 | continue; |
1033 | } | 1046 | } |
1034 | 1047 | ||
1035 | /* Error on this fragment: respond to client with an error. */ | 1048 | /* Error on this fragment: respond to client with an error. */ |
1036 | txp = &netbk->pending_tx_info[pending_idx].req; | 1049 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); |
1037 | make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); | ||
1038 | index = pending_index(netbk->pending_prod++); | ||
1039 | netbk->pending_ring[index] = pending_idx; | ||
1040 | xenvif_put(vif); | ||
1041 | 1050 | ||
1042 | /* Not the first error? Preceding frags already invalidated. */ | 1051 | /* Not the first error? Preceding frags already invalidated. */ |
1043 | if (err) | 1052 | if (err) |
@@ -1045,10 +1054,10 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, | |||
1045 | 1054 | ||
1046 | /* First error: invalidate header and preceding fragments. */ | 1055 | /* First error: invalidate header and preceding fragments. */ |
1047 | pending_idx = *((u16 *)skb->data); | 1056 | pending_idx = *((u16 *)skb->data); |
1048 | xen_netbk_idx_release(netbk, pending_idx); | 1057 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); |
1049 | for (j = start; j < i; j++) { | 1058 | for (j = start; j < i; j++) { |
1050 | pending_idx = frag_get_pending_idx(&shinfo->frags[j]); | 1059 | pending_idx = frag_get_pending_idx(&shinfo->frags[j]); |
1051 | xen_netbk_idx_release(netbk, pending_idx); | 1060 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); |
1052 | } | 1061 | } |
1053 | 1062 | ||
1054 | /* Remember the error: invalidate all subsequent fragments. */ | 1063 | /* Remember the error: invalidate all subsequent fragments. */ |
@@ -1082,7 +1091,7 @@ static void xen_netbk_fill_frags(struct xen_netbk *netbk, struct sk_buff *skb) | |||
1082 | 1091 | ||
1083 | /* Take an extra reference to offset xen_netbk_idx_release */ | 1092 | /* Take an extra reference to offset xen_netbk_idx_release */ |
1084 | get_page(netbk->mmap_pages[pending_idx]); | 1093 | get_page(netbk->mmap_pages[pending_idx]); |
1085 | xen_netbk_idx_release(netbk, pending_idx); | 1094 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); |
1086 | } | 1095 | } |
1087 | } | 1096 | } |
1088 | 1097 | ||
@@ -1095,7 +1104,8 @@ static int xen_netbk_get_extras(struct xenvif *vif, | |||
1095 | 1104 | ||
1096 | do { | 1105 | do { |
1097 | if (unlikely(work_to_do-- <= 0)) { | 1106 | if (unlikely(work_to_do-- <= 0)) { |
1098 | netdev_dbg(vif->dev, "Missing extra info\n"); | 1107 | netdev_err(vif->dev, "Missing extra info\n"); |
1108 | netbk_fatal_tx_err(vif); | ||
1099 | return -EBADR; | 1109 | return -EBADR; |
1100 | } | 1110 | } |
1101 | 1111 | ||
@@ -1104,8 +1114,9 @@ static int xen_netbk_get_extras(struct xenvif *vif, | |||
1104 | if (unlikely(!extra.type || | 1114 | if (unlikely(!extra.type || |
1105 | extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { | 1115 | extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { |
1106 | vif->tx.req_cons = ++cons; | 1116 | vif->tx.req_cons = ++cons; |
1107 | netdev_dbg(vif->dev, | 1117 | netdev_err(vif->dev, |
1108 | "Invalid extra type: %d\n", extra.type); | 1118 | "Invalid extra type: %d\n", extra.type); |
1119 | netbk_fatal_tx_err(vif); | ||
1109 | return -EINVAL; | 1120 | return -EINVAL; |
1110 | } | 1121 | } |
1111 | 1122 | ||
@@ -1121,13 +1132,15 @@ static int netbk_set_skb_gso(struct xenvif *vif, | |||
1121 | struct xen_netif_extra_info *gso) | 1132 | struct xen_netif_extra_info *gso) |
1122 | { | 1133 | { |
1123 | if (!gso->u.gso.size) { | 1134 | if (!gso->u.gso.size) { |
1124 | netdev_dbg(vif->dev, "GSO size must not be zero.\n"); | 1135 | netdev_err(vif->dev, "GSO size must not be zero.\n"); |
1136 | netbk_fatal_tx_err(vif); | ||
1125 | return -EINVAL; | 1137 | return -EINVAL; |
1126 | } | 1138 | } |
1127 | 1139 | ||
1128 | /* Currently only TCPv4 S.O. is supported. */ | 1140 | /* Currently only TCPv4 S.O. is supported. */ |
1129 | if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { | 1141 | if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { |
1130 | netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); | 1142 | netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); |
1143 | netbk_fatal_tx_err(vif); | ||
1131 | return -EINVAL; | 1144 | return -EINVAL; |
1132 | } | 1145 | } |
1133 | 1146 | ||
@@ -1264,9 +1277,25 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) | |||
1264 | 1277 | ||
1265 | /* Get a netif from the list with work to do. */ | 1278 | /* Get a netif from the list with work to do. */ |
1266 | vif = poll_net_schedule_list(netbk); | 1279 | vif = poll_net_schedule_list(netbk); |
1280 | /* This can sometimes happen because the test of | ||
1281 | * list_empty(net_schedule_list) at the top of the | ||
1282 | * loop is unlocked. Just go back and have another | ||
1283 | * look. | ||
1284 | */ | ||
1267 | if (!vif) | 1285 | if (!vif) |
1268 | continue; | 1286 | continue; |
1269 | 1287 | ||
1288 | if (vif->tx.sring->req_prod - vif->tx.req_cons > | ||
1289 | XEN_NETIF_TX_RING_SIZE) { | ||
1290 | netdev_err(vif->dev, | ||
1291 | "Impossible number of requests. " | ||
1292 | "req_prod %d, req_cons %d, size %ld\n", | ||
1293 | vif->tx.sring->req_prod, vif->tx.req_cons, | ||
1294 | XEN_NETIF_TX_RING_SIZE); | ||
1295 | netbk_fatal_tx_err(vif); | ||
1296 | continue; | ||
1297 | } | ||
1298 | |||
1270 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); | 1299 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); |
1271 | if (!work_to_do) { | 1300 | if (!work_to_do) { |
1272 | xenvif_put(vif); | 1301 | xenvif_put(vif); |
@@ -1294,17 +1323,14 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) | |||
1294 | work_to_do = xen_netbk_get_extras(vif, extras, | 1323 | work_to_do = xen_netbk_get_extras(vif, extras, |
1295 | work_to_do); | 1324 | work_to_do); |
1296 | idx = vif->tx.req_cons; | 1325 | idx = vif->tx.req_cons; |
1297 | if (unlikely(work_to_do < 0)) { | 1326 | if (unlikely(work_to_do < 0)) |
1298 | netbk_tx_err(vif, &txreq, idx); | ||
1299 | continue; | 1327 | continue; |
1300 | } | ||
1301 | } | 1328 | } |
1302 | 1329 | ||
1303 | ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); | 1330 | ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); |
1304 | if (unlikely(ret < 0)) { | 1331 | if (unlikely(ret < 0)) |
1305 | netbk_tx_err(vif, &txreq, idx - ret); | ||
1306 | continue; | 1332 | continue; |
1307 | } | 1333 | |
1308 | idx += ret; | 1334 | idx += ret; |
1309 | 1335 | ||
1310 | if (unlikely(txreq.size < ETH_HLEN)) { | 1336 | if (unlikely(txreq.size < ETH_HLEN)) { |
@@ -1316,11 +1342,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) | |||
1316 | 1342 | ||
1317 | /* No crossing a page as the payload mustn't fragment. */ | 1343 | /* No crossing a page as the payload mustn't fragment. */ |
1318 | if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { | 1344 | if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { |
1319 | netdev_dbg(vif->dev, | 1345 | netdev_err(vif->dev, |
1320 | "txreq.offset: %x, size: %u, end: %lu\n", | 1346 | "txreq.offset: %x, size: %u, end: %lu\n", |
1321 | txreq.offset, txreq.size, | 1347 | txreq.offset, txreq.size, |
1322 | (txreq.offset&~PAGE_MASK) + txreq.size); | 1348 | (txreq.offset&~PAGE_MASK) + txreq.size); |
1323 | netbk_tx_err(vif, &txreq, idx); | 1349 | netbk_fatal_tx_err(vif); |
1324 | continue; | 1350 | continue; |
1325 | } | 1351 | } |
1326 | 1352 | ||
@@ -1348,8 +1374,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) | |||
1348 | gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; | 1374 | gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; |
1349 | 1375 | ||
1350 | if (netbk_set_skb_gso(vif, skb, gso)) { | 1376 | if (netbk_set_skb_gso(vif, skb, gso)) { |
1377 | /* Failure in netbk_set_skb_gso is fatal. */ | ||
1351 | kfree_skb(skb); | 1378 | kfree_skb(skb); |
1352 | netbk_tx_err(vif, &txreq, idx); | ||
1353 | continue; | 1379 | continue; |
1354 | } | 1380 | } |
1355 | } | 1381 | } |
@@ -1448,7 +1474,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk) | |||
1448 | txp->size -= data_len; | 1474 | txp->size -= data_len; |
1449 | } else { | 1475 | } else { |
1450 | /* Schedule a response immediately. */ | 1476 | /* Schedule a response immediately. */ |
1451 | xen_netbk_idx_release(netbk, pending_idx); | 1477 | xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_OKAY); |
1452 | } | 1478 | } |
1453 | 1479 | ||
1454 | if (txp->flags & XEN_NETTXF_csum_blank) | 1480 | if (txp->flags & XEN_NETTXF_csum_blank) |
@@ -1500,7 +1526,8 @@ static void xen_netbk_tx_action(struct xen_netbk *netbk) | |||
1500 | xen_netbk_tx_submit(netbk); | 1526 | xen_netbk_tx_submit(netbk); |
1501 | } | 1527 | } |
1502 | 1528 | ||
1503 | static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) | 1529 | static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx, |
1530 | u8 status) | ||
1504 | { | 1531 | { |
1505 | struct xenvif *vif; | 1532 | struct xenvif *vif; |
1506 | struct pending_tx_info *pending_tx_info; | 1533 | struct pending_tx_info *pending_tx_info; |
@@ -1514,7 +1541,7 @@ static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) | |||
1514 | 1541 | ||
1515 | vif = pending_tx_info->vif; | 1542 | vif = pending_tx_info->vif; |
1516 | 1543 | ||
1517 | make_tx_response(vif, &pending_tx_info->req, XEN_NETIF_RSP_OKAY); | 1544 | make_tx_response(vif, &pending_tx_info->req, status); |
1518 | 1545 | ||
1519 | index = pending_index(netbk->pending_prod++); | 1546 | index = pending_index(netbk->pending_prod++); |
1520 | netbk->pending_ring[index] = pending_idx; | 1547 | netbk->pending_ring[index] = pending_idx; |
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index efaecefe3f8c..a5f3c8ca480e 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -184,8 +184,8 @@ config PINCTRL_SAMSUNG | |||
184 | select PINMUX | 184 | select PINMUX |
185 | select PINCONF | 185 | select PINCONF |
186 | 186 | ||
187 | config PINCTRL_EXYNOS4 | 187 | config PINCTRL_EXYNOS |
188 | bool "Pinctrl driver data for Exynos4 SoC" | 188 | bool "Pinctrl driver data for Samsung EXYNOS SoCs" |
189 | depends on OF && GPIOLIB | 189 | depends on OF && GPIOLIB |
190 | select PINCTRL_SAMSUNG | 190 | select PINCTRL_SAMSUNG |
191 | 191 | ||
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index fc4606f27dc7..6e87e52eab5d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -36,7 +36,7 @@ obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o | |||
36 | obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o | 36 | obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o |
37 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o | 37 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o |
38 | obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o | 38 | obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o |
39 | obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o | 39 | obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o |
40 | obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o | 40 | obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o |
41 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o | 41 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o |
42 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o | 42 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 498b2ba905de..d02498b30c6e 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
@@ -1246,6 +1246,22 @@ static void __iomem *sirfsoc_rsc_of_iomap(void) | |||
1246 | return of_iomap(np, 0); | 1246 | return of_iomap(np, 0); |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc, | ||
1250 | const struct of_phandle_args *gpiospec, | ||
1251 | u32 *flags) | ||
1252 | { | ||
1253 | if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE) | ||
1254 | return -EINVAL; | ||
1255 | |||
1256 | if (gc != &sgpio_bank[gpiospec->args[0] / SIRFSOC_GPIO_BANK_SIZE].chip.gc) | ||
1257 | return -EINVAL; | ||
1258 | |||
1259 | if (flags) | ||
1260 | *flags = gpiospec->args[1]; | ||
1261 | |||
1262 | return gpiospec->args[0] % SIRFSOC_GPIO_BANK_SIZE; | ||
1263 | } | ||
1264 | |||
1249 | static int sirfsoc_pinmux_probe(struct platform_device *pdev) | 1265 | static int sirfsoc_pinmux_probe(struct platform_device *pdev) |
1250 | { | 1266 | { |
1251 | int ret; | 1267 | int ret; |
@@ -1736,6 +1752,8 @@ static int sirfsoc_gpio_probe(struct device_node *np) | |||
1736 | bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE; | 1752 | bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE; |
1737 | bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); | 1753 | bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL); |
1738 | bank->chip.gc.of_node = np; | 1754 | bank->chip.gc.of_node = np; |
1755 | bank->chip.gc.of_xlate = sirfsoc_gpio_of_xlate; | ||
1756 | bank->chip.gc.of_gpio_n_cells = 2; | ||
1739 | bank->chip.regs = regs; | 1757 | bank->chip.regs = regs; |
1740 | bank->id = i; | 1758 | bank->id = i; |
1741 | bank->is_marco = is_marco; | 1759 | bank->is_marco = is_marco; |
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index b85040caaea3..cca18a3c0294 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
@@ -379,9 +379,10 @@ static struct regulator_desc regulators[] = { | |||
379 | }; | 379 | }; |
380 | 380 | ||
381 | #ifdef CONFIG_OF | 381 | #ifdef CONFIG_OF |
382 | static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | 382 | static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, |
383 | struct max77686_platform_data *pdata) | 383 | struct max77686_platform_data *pdata) |
384 | { | 384 | { |
385 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
385 | struct device_node *pmic_np, *regulators_np; | 386 | struct device_node *pmic_np, *regulators_np; |
386 | struct max77686_regulator_data *rdata; | 387 | struct max77686_regulator_data *rdata; |
387 | struct of_regulator_match rmatch; | 388 | struct of_regulator_match rmatch; |
@@ -390,15 +391,15 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | |||
390 | pmic_np = iodev->dev->of_node; | 391 | pmic_np = iodev->dev->of_node; |
391 | regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators"); | 392 | regulators_np = of_find_node_by_name(pmic_np, "voltage-regulators"); |
392 | if (!regulators_np) { | 393 | if (!regulators_np) { |
393 | dev_err(iodev->dev, "could not find regulators sub-node\n"); | 394 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
394 | return -EINVAL; | 395 | return -EINVAL; |
395 | } | 396 | } |
396 | 397 | ||
397 | pdata->num_regulators = ARRAY_SIZE(regulators); | 398 | pdata->num_regulators = ARRAY_SIZE(regulators); |
398 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * | 399 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
399 | pdata->num_regulators, GFP_KERNEL); | 400 | pdata->num_regulators, GFP_KERNEL); |
400 | if (!rdata) { | 401 | if (!rdata) { |
401 | dev_err(iodev->dev, | 402 | dev_err(&pdev->dev, |
402 | "could not allocate memory for regulator data\n"); | 403 | "could not allocate memory for regulator data\n"); |
403 | return -ENOMEM; | 404 | return -ENOMEM; |
404 | } | 405 | } |
@@ -407,7 +408,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | |||
407 | rmatch.name = regulators[i].name; | 408 | rmatch.name = regulators[i].name; |
408 | rmatch.init_data = NULL; | 409 | rmatch.init_data = NULL; |
409 | rmatch.of_node = NULL; | 410 | rmatch.of_node = NULL; |
410 | of_regulator_match(iodev->dev, regulators_np, &rmatch, 1); | 411 | of_regulator_match(&pdev->dev, regulators_np, &rmatch, 1); |
411 | rdata[i].initdata = rmatch.init_data; | 412 | rdata[i].initdata = rmatch.init_data; |
412 | rdata[i].of_node = rmatch.of_node; | 413 | rdata[i].of_node = rmatch.of_node; |
413 | } | 414 | } |
@@ -417,7 +418,7 @@ static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | |||
417 | return 0; | 418 | return 0; |
418 | } | 419 | } |
419 | #else | 420 | #else |
420 | static int max77686_pmic_dt_parse_pdata(struct max77686_dev *iodev, | 421 | static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, |
421 | struct max77686_platform_data *pdata) | 422 | struct max77686_platform_data *pdata) |
422 | { | 423 | { |
423 | return 0; | 424 | return 0; |
@@ -440,7 +441,7 @@ static int max77686_pmic_probe(struct platform_device *pdev) | |||
440 | } | 441 | } |
441 | 442 | ||
442 | if (iodev->dev->of_node) { | 443 | if (iodev->dev->of_node) { |
443 | ret = max77686_pmic_dt_parse_pdata(iodev, pdata); | 444 | ret = max77686_pmic_dt_parse_pdata(pdev, pdata); |
444 | if (ret) | 445 | if (ret) |
445 | return ret; | 446 | return ret; |
446 | } | 447 | } |
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index d1a77512d83e..d40cf7fdb546 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c | |||
@@ -237,8 +237,7 @@ static int max8907_regulator_parse_dt(struct platform_device *pdev) | |||
237 | return -EINVAL; | 237 | return -EINVAL; |
238 | } | 238 | } |
239 | 239 | ||
240 | ret = of_regulator_match(pdev->dev.parent, regulators, | 240 | ret = of_regulator_match(&pdev->dev, regulators, max8907_matches, |
241 | max8907_matches, | ||
242 | ARRAY_SIZE(max8907_matches)); | 241 | ARRAY_SIZE(max8907_matches)); |
243 | if (ret < 0) { | 242 | if (ret < 0) { |
244 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | 243 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", |
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 02be7fcae32f..836908ce505e 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
@@ -934,7 +934,7 @@ static struct regulator_desc regulators[] = { | |||
934 | }; | 934 | }; |
935 | 935 | ||
936 | #ifdef CONFIG_OF | 936 | #ifdef CONFIG_OF |
937 | static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev, | 937 | static int max8997_pmic_dt_parse_dvs_gpio(struct platform_device *pdev, |
938 | struct max8997_platform_data *pdata, | 938 | struct max8997_platform_data *pdata, |
939 | struct device_node *pmic_np) | 939 | struct device_node *pmic_np) |
940 | { | 940 | { |
@@ -944,7 +944,7 @@ static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev, | |||
944 | gpio = of_get_named_gpio(pmic_np, | 944 | gpio = of_get_named_gpio(pmic_np, |
945 | "max8997,pmic-buck125-dvs-gpios", i); | 945 | "max8997,pmic-buck125-dvs-gpios", i); |
946 | if (!gpio_is_valid(gpio)) { | 946 | if (!gpio_is_valid(gpio)) { |
947 | dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio); | 947 | dev_err(&pdev->dev, "invalid gpio[%d]: %d\n", i, gpio); |
948 | return -EINVAL; | 948 | return -EINVAL; |
949 | } | 949 | } |
950 | pdata->buck125_gpios[i] = gpio; | 950 | pdata->buck125_gpios[i] = gpio; |
@@ -952,22 +952,23 @@ static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev, | |||
952 | return 0; | 952 | return 0; |
953 | } | 953 | } |
954 | 954 | ||
955 | static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | 955 | static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, |
956 | struct max8997_platform_data *pdata) | 956 | struct max8997_platform_data *pdata) |
957 | { | 957 | { |
958 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
958 | struct device_node *pmic_np, *regulators_np, *reg_np; | 959 | struct device_node *pmic_np, *regulators_np, *reg_np; |
959 | struct max8997_regulator_data *rdata; | 960 | struct max8997_regulator_data *rdata; |
960 | unsigned int i, dvs_voltage_nr = 1, ret; | 961 | unsigned int i, dvs_voltage_nr = 1, ret; |
961 | 962 | ||
962 | pmic_np = iodev->dev->of_node; | 963 | pmic_np = iodev->dev->of_node; |
963 | if (!pmic_np) { | 964 | if (!pmic_np) { |
964 | dev_err(iodev->dev, "could not find pmic sub-node\n"); | 965 | dev_err(&pdev->dev, "could not find pmic sub-node\n"); |
965 | return -ENODEV; | 966 | return -ENODEV; |
966 | } | 967 | } |
967 | 968 | ||
968 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | 969 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); |
969 | if (!regulators_np) { | 970 | if (!regulators_np) { |
970 | dev_err(iodev->dev, "could not find regulators sub-node\n"); | 971 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); |
971 | return -EINVAL; | 972 | return -EINVAL; |
972 | } | 973 | } |
973 | 974 | ||
@@ -976,11 +977,10 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | |||
976 | for_each_child_of_node(regulators_np, reg_np) | 977 | for_each_child_of_node(regulators_np, reg_np) |
977 | pdata->num_regulators++; | 978 | pdata->num_regulators++; |
978 | 979 | ||
979 | rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * | 980 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * |
980 | pdata->num_regulators, GFP_KERNEL); | 981 | pdata->num_regulators, GFP_KERNEL); |
981 | if (!rdata) { | 982 | if (!rdata) { |
982 | dev_err(iodev->dev, "could not allocate memory for " | 983 | dev_err(&pdev->dev, "could not allocate memory for regulator data\n"); |
983 | "regulator data\n"); | ||
984 | return -ENOMEM; | 984 | return -ENOMEM; |
985 | } | 985 | } |
986 | 986 | ||
@@ -991,14 +991,14 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | |||
991 | break; | 991 | break; |
992 | 992 | ||
993 | if (i == ARRAY_SIZE(regulators)) { | 993 | if (i == ARRAY_SIZE(regulators)) { |
994 | dev_warn(iodev->dev, "don't know how to configure " | 994 | dev_warn(&pdev->dev, "don't know how to configure regulator %s\n", |
995 | "regulator %s\n", reg_np->name); | 995 | reg_np->name); |
996 | continue; | 996 | continue; |
997 | } | 997 | } |
998 | 998 | ||
999 | rdata->id = i; | 999 | rdata->id = i; |
1000 | rdata->initdata = of_get_regulator_init_data( | 1000 | rdata->initdata = of_get_regulator_init_data(&pdev->dev, |
1001 | iodev->dev, reg_np); | 1001 | reg_np); |
1002 | rdata->reg_node = reg_np; | 1002 | rdata->reg_node = reg_np; |
1003 | rdata++; | 1003 | rdata++; |
1004 | } | 1004 | } |
@@ -1014,7 +1014,7 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | |||
1014 | 1014 | ||
1015 | if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || | 1015 | if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || |
1016 | pdata->buck5_gpiodvs) { | 1016 | pdata->buck5_gpiodvs) { |
1017 | ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); | 1017 | ret = max8997_pmic_dt_parse_dvs_gpio(pdev, pdata, pmic_np); |
1018 | if (ret) | 1018 | if (ret) |
1019 | return -EINVAL; | 1019 | return -EINVAL; |
1020 | 1020 | ||
@@ -1025,8 +1025,7 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | |||
1025 | } else { | 1025 | } else { |
1026 | if (pdata->buck125_default_idx >= 8) { | 1026 | if (pdata->buck125_default_idx >= 8) { |
1027 | pdata->buck125_default_idx = 0; | 1027 | pdata->buck125_default_idx = 0; |
1028 | dev_info(iodev->dev, "invalid value for " | 1028 | dev_info(&pdev->dev, "invalid value for default dvs index, using 0 instead\n"); |
1029 | "default dvs index, using 0 instead\n"); | ||
1030 | } | 1029 | } |
1031 | } | 1030 | } |
1032 | 1031 | ||
@@ -1040,28 +1039,28 @@ static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | |||
1040 | if (of_property_read_u32_array(pmic_np, | 1039 | if (of_property_read_u32_array(pmic_np, |
1041 | "max8997,pmic-buck1-dvs-voltage", | 1040 | "max8997,pmic-buck1-dvs-voltage", |
1042 | pdata->buck1_voltage, dvs_voltage_nr)) { | 1041 | pdata->buck1_voltage, dvs_voltage_nr)) { |
1043 | dev_err(iodev->dev, "buck1 voltages not specified\n"); | 1042 | dev_err(&pdev->dev, "buck1 voltages not specified\n"); |
1044 | return -EINVAL; | 1043 | return -EINVAL; |
1045 | } | 1044 | } |
1046 | 1045 | ||
1047 | if (of_property_read_u32_array(pmic_np, | 1046 | if (of_property_read_u32_array(pmic_np, |
1048 | "max8997,pmic-buck2-dvs-voltage", | 1047 | "max8997,pmic-buck2-dvs-voltage", |
1049 | pdata->buck2_voltage, dvs_voltage_nr)) { | 1048 | pdata->buck2_voltage, dvs_voltage_nr)) { |
1050 | dev_err(iodev->dev, "buck2 voltages not specified\n"); | 1049 | dev_err(&pdev->dev, "buck2 voltages not specified\n"); |
1051 | return -EINVAL; | 1050 | return -EINVAL; |
1052 | } | 1051 | } |
1053 | 1052 | ||
1054 | if (of_property_read_u32_array(pmic_np, | 1053 | if (of_property_read_u32_array(pmic_np, |
1055 | "max8997,pmic-buck5-dvs-voltage", | 1054 | "max8997,pmic-buck5-dvs-voltage", |
1056 | pdata->buck5_voltage, dvs_voltage_nr)) { | 1055 | pdata->buck5_voltage, dvs_voltage_nr)) { |
1057 | dev_err(iodev->dev, "buck5 voltages not specified\n"); | 1056 | dev_err(&pdev->dev, "buck5 voltages not specified\n"); |
1058 | return -EINVAL; | 1057 | return -EINVAL; |
1059 | } | 1058 | } |
1060 | 1059 | ||
1061 | return 0; | 1060 | return 0; |
1062 | } | 1061 | } |
1063 | #else | 1062 | #else |
1064 | static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev, | 1063 | static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, |
1065 | struct max8997_platform_data *pdata) | 1064 | struct max8997_platform_data *pdata) |
1066 | { | 1065 | { |
1067 | return 0; | 1066 | return 0; |
@@ -1085,7 +1084,7 @@ static int max8997_pmic_probe(struct platform_device *pdev) | |||
1085 | } | 1084 | } |
1086 | 1085 | ||
1087 | if (iodev->dev->of_node) { | 1086 | if (iodev->dev->of_node) { |
1088 | ret = max8997_pmic_dt_parse_pdata(iodev, pdata); | 1087 | ret = max8997_pmic_dt_parse_pdata(pdev, pdata); |
1089 | if (ret) | 1088 | if (ret) |
1090 | return ret; | 1089 | return ret; |
1091 | } | 1090 | } |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 1f0df4046b86..0a8dd1cbee6f 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -65,7 +65,7 @@ static const struct voltage_map_desc ldo9_voltage_map_desc = { | |||
65 | .min = 2800000, .step = 100000, .max = 3100000, | 65 | .min = 2800000, .step = 100000, .max = 3100000, |
66 | }; | 66 | }; |
67 | static const struct voltage_map_desc ldo10_voltage_map_desc = { | 67 | static const struct voltage_map_desc ldo10_voltage_map_desc = { |
68 | .min = 95000, .step = 50000, .max = 1300000, | 68 | .min = 950000, .step = 50000, .max = 1300000, |
69 | }; | 69 | }; |
70 | static const struct voltage_map_desc ldo1213_voltage_map_desc = { | 70 | static const struct voltage_map_desc ldo1213_voltage_map_desc = { |
71 | .min = 800000, .step = 100000, .max = 3300000, | 71 | .min = 800000, .step = 100000, .max = 3300000, |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 6f684916fd79..66ca769287ab 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -120,6 +120,12 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
120 | if (!dev || !node) | 120 | if (!dev || !node) |
121 | return -EINVAL; | 121 | return -EINVAL; |
122 | 122 | ||
123 | for (i = 0; i < num_matches; i++) { | ||
124 | struct of_regulator_match *match = &matches[i]; | ||
125 | match->init_data = NULL; | ||
126 | match->of_node = NULL; | ||
127 | } | ||
128 | |||
123 | for_each_child_of_node(node, child) { | 129 | for_each_child_of_node(node, child) { |
124 | name = of_get_property(child, | 130 | name = of_get_property(child, |
125 | "regulator-compatible", NULL); | 131 | "regulator-compatible", NULL); |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index bd062a2ffbe2..cd9ea2ea1826 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -174,9 +174,9 @@ static struct regulator_ops s2mps11_buck_ops = { | |||
174 | .min_uV = S2MPS11_BUCK_MIN2, \ | 174 | .min_uV = S2MPS11_BUCK_MIN2, \ |
175 | .uV_step = S2MPS11_BUCK_STEP2, \ | 175 | .uV_step = S2MPS11_BUCK_STEP2, \ |
176 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ | 176 | .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ |
177 | .vsel_reg = S2MPS11_REG_B9CTRL2, \ | 177 | .vsel_reg = S2MPS11_REG_B10CTRL2, \ |
178 | .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ | 178 | .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ |
179 | .enable_reg = S2MPS11_REG_B9CTRL1, \ | 179 | .enable_reg = S2MPS11_REG_B10CTRL1, \ |
180 | .enable_mask = S2MPS11_ENABLE_MASK \ | 180 | .enable_mask = S2MPS11_ENABLE_MASK \ |
181 | } | 181 | } |
182 | 182 | ||
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 73dce7664126..df395187c063 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -305,8 +305,8 @@ static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | |||
305 | if (!regs) | 305 | if (!regs) |
306 | return NULL; | 306 | return NULL; |
307 | 307 | ||
308 | count = of_regulator_match(pdev->dev.parent, regs, | 308 | count = of_regulator_match(&pdev->dev, regs, reg_matches, |
309 | reg_matches, TPS65217_NUM_REGULATOR); | 309 | TPS65217_NUM_REGULATOR); |
310 | of_node_put(regs); | 310 | of_node_put(regs); |
311 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) | 311 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) |
312 | return NULL; | 312 | return NULL; |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 59c3770fa77d..b0e4c0bc85c3 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -998,7 +998,7 @@ static struct tps65910_board *tps65910_parse_dt_reg_data( | |||
998 | return NULL; | 998 | return NULL; |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | ret = of_regulator_match(pdev->dev.parent, regulators, matches, count); | 1001 | ret = of_regulator_match(&pdev->dev, regulators, matches, count); |
1002 | if (ret < 0) { | 1002 | if (ret < 0) { |
1003 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", | 1003 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", |
1004 | ret); | 1004 | ret); |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index afb7cfa85ccc..c016ad81767a 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -506,6 +506,7 @@ isl1208_rtc_interrupt(int irq, void *data) | |||
506 | { | 506 | { |
507 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | 507 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
508 | struct i2c_client *client = data; | 508 | struct i2c_client *client = data; |
509 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
509 | int handled = 0, sr, err; | 510 | int handled = 0, sr, err; |
510 | 511 | ||
511 | /* | 512 | /* |
@@ -528,6 +529,8 @@ isl1208_rtc_interrupt(int irq, void *data) | |||
528 | if (sr & ISL1208_REG_SR_ALM) { | 529 | if (sr & ISL1208_REG_SR_ALM) { |
529 | dev_dbg(&client->dev, "alarm!\n"); | 530 | dev_dbg(&client->dev, "alarm!\n"); |
530 | 531 | ||
532 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); | ||
533 | |||
531 | /* Clear the alarm */ | 534 | /* Clear the alarm */ |
532 | sr &= ~ISL1208_REG_SR_ALM; | 535 | sr &= ~ISL1208_REG_SR_ALM; |
533 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); | 536 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 08378e3cc21c..10c1a3454e48 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define RTC_YMR 0x34 /* Year match register */ | 44 | #define RTC_YMR 0x34 /* Year match register */ |
45 | #define RTC_YLR 0x38 /* Year data load register */ | 45 | #define RTC_YLR 0x38 /* Year data load register */ |
46 | 46 | ||
47 | #define RTC_CR_EN (1 << 0) /* counter enable bit */ | ||
47 | #define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ | 48 | #define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ |
48 | 49 | ||
49 | #define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ | 50 | #define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ |
@@ -320,7 +321,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
320 | struct pl031_local *ldata; | 321 | struct pl031_local *ldata; |
321 | struct pl031_vendor_data *vendor = id->data; | 322 | struct pl031_vendor_data *vendor = id->data; |
322 | struct rtc_class_ops *ops = &vendor->ops; | 323 | struct rtc_class_ops *ops = &vendor->ops; |
323 | unsigned long time; | 324 | unsigned long time, data; |
324 | 325 | ||
325 | ret = amba_request_regions(adev, NULL); | 326 | ret = amba_request_regions(adev, NULL); |
326 | if (ret) | 327 | if (ret) |
@@ -345,10 +346,11 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) | |||
345 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); | 346 | dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); |
346 | dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); | 347 | dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); |
347 | 348 | ||
349 | data = readl(ldata->base + RTC_CR); | ||
348 | /* Enable the clockwatch on ST Variants */ | 350 | /* Enable the clockwatch on ST Variants */ |
349 | if (vendor->clockwatch) | 351 | if (vendor->clockwatch) |
350 | writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, | 352 | data |= RTC_CR_CWEN; |
351 | ldata->base + RTC_CR); | 353 | writel(data | RTC_CR_EN, ldata->base + RTC_CR); |
352 | 354 | ||
353 | /* | 355 | /* |
354 | * On ST PL031 variants, the RTC reset value does not provide correct | 356 | * On ST PL031 variants, the RTC reset value does not provide correct |
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 00c930f4b6f3..2730533e2d2d 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c | |||
@@ -137,7 +137,7 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | } | 138 | } |
139 | 139 | ||
140 | writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) | 140 | writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S) |
141 | | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) | 141 | | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) |
142 | | (bin2bcd(tm->tm_mday)) | 142 | | (bin2bcd(tm->tm_mday)) |
143 | | ((tm->tm_year >= 200) << DATE_CENTURY_S), | 143 | | ((tm->tm_year >= 200) << DATE_CENTURY_S), |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index a43415a7fbed..4c0f6d883dd3 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/export.h> | 15 | #include <linux/export.h> |
16 | #ifdef CONFIG_BCM47XX | 16 | #ifdef CONFIG_BCM47XX |
17 | #include <asm/mach-bcm47xx/nvram.h> | 17 | #include <bcm47xx_nvram.h> |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #include "ssb_private.h" | 20 | #include "ssb_private.h" |
@@ -322,7 +322,7 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) | |||
322 | if (bus->bustype == SSB_BUSTYPE_SSB) { | 322 | if (bus->bustype == SSB_BUSTYPE_SSB) { |
323 | #ifdef CONFIG_BCM47XX | 323 | #ifdef CONFIG_BCM47XX |
324 | char buf[20]; | 324 | char buf[20]; |
325 | if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0) | 325 | if (bcm47xx_nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0) |
326 | crystalfreq = simple_strtoul(buf, NULL, 0); | 326 | crystalfreq = simple_strtoul(buf, NULL, 0); |
327 | #endif | 327 | #endif |
328 | } | 328 | } |
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c index 97ac0a38e3d0..eb2753008ef0 100644 --- a/drivers/ssb/driver_gpio.c +++ b/drivers/ssb/driver_gpio.c | |||
@@ -174,3 +174,15 @@ int ssb_gpio_init(struct ssb_bus *bus) | |||
174 | 174 | ||
175 | return -1; | 175 | return -1; |
176 | } | 176 | } |
177 | |||
178 | int ssb_gpio_unregister(struct ssb_bus *bus) | ||
179 | { | ||
180 | if (ssb_chipco_available(&bus->chipco) || | ||
181 | ssb_extif_available(&bus->extif)) { | ||
182 | return gpiochip_remove(&bus->gpio); | ||
183 | } else { | ||
184 | SSB_WARN_ON(1); | ||
185 | } | ||
186 | |||
187 | return -1; | ||
188 | } | ||
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 772ad9b5c304..24dc331b4701 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -443,6 +443,15 @@ static void ssb_devices_unregister(struct ssb_bus *bus) | |||
443 | 443 | ||
444 | void ssb_bus_unregister(struct ssb_bus *bus) | 444 | void ssb_bus_unregister(struct ssb_bus *bus) |
445 | { | 445 | { |
446 | int err; | ||
447 | |||
448 | err = ssb_gpio_unregister(bus); | ||
449 | if (err == -EBUSY) | ||
450 | ssb_dprintk(KERN_ERR PFX "Some GPIOs are still in use.\n"); | ||
451 | else if (err) | ||
452 | ssb_dprintk(KERN_ERR PFX | ||
453 | "Can not unregister GPIO driver: %i\n", err); | ||
454 | |||
446 | ssb_buses_lock(); | 455 | ssb_buses_lock(); |
447 | ssb_devices_unregister(bus); | 456 | ssb_devices_unregister(bus); |
448 | list_del(&bus->list); | 457 | list_del(&bus->list); |
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 6c10b66c796c..da38305a2d22 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h | |||
@@ -252,11 +252,16 @@ static inline void ssb_extif_init(struct ssb_extif *extif) | |||
252 | 252 | ||
253 | #ifdef CONFIG_SSB_DRIVER_GPIO | 253 | #ifdef CONFIG_SSB_DRIVER_GPIO |
254 | extern int ssb_gpio_init(struct ssb_bus *bus); | 254 | extern int ssb_gpio_init(struct ssb_bus *bus); |
255 | extern int ssb_gpio_unregister(struct ssb_bus *bus); | ||
255 | #else /* CONFIG_SSB_DRIVER_GPIO */ | 256 | #else /* CONFIG_SSB_DRIVER_GPIO */ |
256 | static inline int ssb_gpio_init(struct ssb_bus *bus) | 257 | static inline int ssb_gpio_init(struct ssb_bus *bus) |
257 | { | 258 | { |
258 | return -ENOTSUPP; | 259 | return -ENOTSUPP; |
259 | } | 260 | } |
261 | static inline int ssb_gpio_unregister(struct ssb_bus *bus) | ||
262 | { | ||
263 | return 0; | ||
264 | } | ||
260 | #endif /* CONFIG_SSB_DRIVER_GPIO */ | 265 | #endif /* CONFIG_SSB_DRIVER_GPIO */ |
261 | 266 | ||
262 | #endif /* LINUX_SSB_PRIVATE_H_ */ | 267 | #endif /* LINUX_SSB_PRIVATE_H_ */ |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index e2695101bb99..f2aa7543d20a 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -941,6 +941,8 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) | |||
941 | 941 | ||
942 | int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | 942 | int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) |
943 | { | 943 | { |
944 | int block_size = dev->dev_attrib.block_size; | ||
945 | |||
944 | if (dev->export_count) { | 946 | if (dev->export_count) { |
945 | pr_err("dev[%p]: Unable to change SE Device" | 947 | pr_err("dev[%p]: Unable to change SE Device" |
946 | " fabric_max_sectors while export_count is %d\n", | 948 | " fabric_max_sectors while export_count is %d\n", |
@@ -978,8 +980,12 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | |||
978 | /* | 980 | /* |
979 | * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() | 981 | * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() |
980 | */ | 982 | */ |
983 | if (!block_size) { | ||
984 | block_size = 512; | ||
985 | pr_warn("Defaulting to 512 for zero block_size\n"); | ||
986 | } | ||
981 | fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, | 987 | fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, |
982 | dev->dev_attrib.block_size); | 988 | block_size); |
983 | 989 | ||
984 | dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; | 990 | dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; |
985 | pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", | 991 | pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", |
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 810263dfa4a1..c57bbbc7a7d1 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
@@ -754,6 +754,11 @@ static int target_fabric_port_link( | |||
754 | return -EFAULT; | 754 | return -EFAULT; |
755 | } | 755 | } |
756 | 756 | ||
757 | if (!(dev->dev_flags & DF_CONFIGURED)) { | ||
758 | pr_err("se_device not configured yet, cannot port link\n"); | ||
759 | return -ENODEV; | ||
760 | } | ||
761 | |||
757 | tpg_ci = &lun_ci->ci_parent->ci_group->cg_item; | 762 | tpg_ci = &lun_ci->ci_parent->ci_group->cg_item; |
758 | se_tpg = container_of(to_config_group(tpg_ci), | 763 | se_tpg = container_of(to_config_group(tpg_ci), |
759 | struct se_portal_group, tpg_group); | 764 | struct se_portal_group, tpg_group); |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 26a6d183ccb1..a664c664a31a 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -58,11 +58,10 @@ sbc_emulate_readcapacity(struct se_cmd *cmd) | |||
58 | buf[7] = dev->dev_attrib.block_size & 0xff; | 58 | buf[7] = dev->dev_attrib.block_size & 0xff; |
59 | 59 | ||
60 | rbuf = transport_kmap_data_sg(cmd); | 60 | rbuf = transport_kmap_data_sg(cmd); |
61 | if (!rbuf) | 61 | if (rbuf) { |
62 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 62 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
63 | 63 | transport_kunmap_data_sg(cmd); | |
64 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 64 | } |
65 | transport_kunmap_data_sg(cmd); | ||
66 | 65 | ||
67 | target_complete_cmd(cmd, GOOD); | 66 | target_complete_cmd(cmd, GOOD); |
68 | return 0; | 67 | return 0; |
@@ -97,11 +96,10 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd) | |||
97 | buf[14] = 0x80; | 96 | buf[14] = 0x80; |
98 | 97 | ||
99 | rbuf = transport_kmap_data_sg(cmd); | 98 | rbuf = transport_kmap_data_sg(cmd); |
100 | if (!rbuf) | 99 | if (rbuf) { |
101 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 100 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
102 | 101 | transport_kunmap_data_sg(cmd); | |
103 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 102 | } |
104 | transport_kunmap_data_sg(cmd); | ||
105 | 103 | ||
106 | target_complete_cmd(cmd, GOOD); | 104 | target_complete_cmd(cmd, GOOD); |
107 | return 0; | 105 | return 0; |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 84f9e96e8ace..2d88f087d961 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -641,11 +641,10 @@ spc_emulate_inquiry(struct se_cmd *cmd) | |||
641 | 641 | ||
642 | out: | 642 | out: |
643 | rbuf = transport_kmap_data_sg(cmd); | 643 | rbuf = transport_kmap_data_sg(cmd); |
644 | if (!rbuf) | 644 | if (rbuf) { |
645 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 645 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
646 | 646 | transport_kunmap_data_sg(cmd); | |
647 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 647 | } |
648 | transport_kunmap_data_sg(cmd); | ||
649 | 648 | ||
650 | if (!ret) | 649 | if (!ret) |
651 | target_complete_cmd(cmd, GOOD); | 650 | target_complete_cmd(cmd, GOOD); |
@@ -851,7 +850,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) | |||
851 | { | 850 | { |
852 | struct se_device *dev = cmd->se_dev; | 851 | struct se_device *dev = cmd->se_dev; |
853 | char *cdb = cmd->t_task_cdb; | 852 | char *cdb = cmd->t_task_cdb; |
854 | unsigned char *buf, *map_buf; | 853 | unsigned char buf[SE_MODE_PAGE_BUF], *rbuf; |
855 | int type = dev->transport->get_device_type(dev); | 854 | int type = dev->transport->get_device_type(dev); |
856 | int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); | 855 | int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); |
857 | bool dbd = !!(cdb[1] & 0x08); | 856 | bool dbd = !!(cdb[1] & 0x08); |
@@ -863,26 +862,8 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) | |||
863 | int ret; | 862 | int ret; |
864 | int i; | 863 | int i; |
865 | 864 | ||
866 | map_buf = transport_kmap_data_sg(cmd); | 865 | memset(buf, 0, SE_MODE_PAGE_BUF); |
867 | if (!map_buf) | 866 | |
868 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
869 | /* | ||
870 | * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we | ||
871 | * know we actually allocated a full page. Otherwise, if the | ||
872 | * data buffer is too small, allocate a temporary buffer so we | ||
873 | * don't have to worry about overruns in all our INQUIRY | ||
874 | * emulation handling. | ||
875 | */ | ||
876 | if (cmd->data_length < SE_MODE_PAGE_BUF && | ||
877 | (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { | ||
878 | buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL); | ||
879 | if (!buf) { | ||
880 | transport_kunmap_data_sg(cmd); | ||
881 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
882 | } | ||
883 | } else { | ||
884 | buf = map_buf; | ||
885 | } | ||
886 | /* | 867 | /* |
887 | * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for | 868 | * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for |
888 | * MODE_SENSE_10 and byte 2 for MODE_SENSE (6). | 869 | * MODE_SENSE_10 and byte 2 for MODE_SENSE (6). |
@@ -934,8 +915,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) | |||
934 | if (page == 0x3f) { | 915 | if (page == 0x3f) { |
935 | if (subpage != 0x00 && subpage != 0xff) { | 916 | if (subpage != 0x00 && subpage != 0xff) { |
936 | pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage); | 917 | pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage); |
937 | kfree(buf); | ||
938 | transport_kunmap_data_sg(cmd); | ||
939 | return TCM_INVALID_CDB_FIELD; | 918 | return TCM_INVALID_CDB_FIELD; |
940 | } | 919 | } |
941 | 920 | ||
@@ -972,7 +951,6 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) | |||
972 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", | 951 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", |
973 | page, subpage); | 952 | page, subpage); |
974 | 953 | ||
975 | transport_kunmap_data_sg(cmd); | ||
976 | return TCM_UNKNOWN_MODE_PAGE; | 954 | return TCM_UNKNOWN_MODE_PAGE; |
977 | 955 | ||
978 | set_length: | 956 | set_length: |
@@ -981,12 +959,12 @@ set_length: | |||
981 | else | 959 | else |
982 | buf[0] = length - 1; | 960 | buf[0] = length - 1; |
983 | 961 | ||
984 | if (buf != map_buf) { | 962 | rbuf = transport_kmap_data_sg(cmd); |
985 | memcpy(map_buf, buf, cmd->data_length); | 963 | if (rbuf) { |
986 | kfree(buf); | 964 | memcpy(rbuf, buf, min_t(u32, SE_MODE_PAGE_BUF, cmd->data_length)); |
965 | transport_kunmap_data_sg(cmd); | ||
987 | } | 966 | } |
988 | 967 | ||
989 | transport_kunmap_data_sg(cmd); | ||
990 | target_complete_cmd(cmd, GOOD); | 968 | target_complete_cmd(cmd, GOOD); |
991 | return 0; | 969 | return 0; |
992 | } | 970 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 4225d5e72131..8e64adf8e4d5 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <asm/unaligned.h> | 39 | #include <asm/unaligned.h> |
40 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
42 | #include <linux/pm_runtime.h> | ||
42 | 43 | ||
43 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
44 | #include <linux/usb/hcd.h> | 45 | #include <linux/usb/hcd.h> |
@@ -1025,6 +1026,49 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
1025 | return retval; | 1026 | return retval; |
1026 | } | 1027 | } |
1027 | 1028 | ||
1029 | /* | ||
1030 | * usb_hcd_start_port_resume - a root-hub port is sending a resume signal | ||
1031 | * @bus: the bus which the root hub belongs to | ||
1032 | * @portnum: the port which is being resumed | ||
1033 | * | ||
1034 | * HCDs should call this function when they know that a resume signal is | ||
1035 | * being sent to a root-hub port. The root hub will be prevented from | ||
1036 | * going into autosuspend until usb_hcd_end_port_resume() is called. | ||
1037 | * | ||
1038 | * The bus's private lock must be held by the caller. | ||
1039 | */ | ||
1040 | void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum) | ||
1041 | { | ||
1042 | unsigned bit = 1 << portnum; | ||
1043 | |||
1044 | if (!(bus->resuming_ports & bit)) { | ||
1045 | bus->resuming_ports |= bit; | ||
1046 | pm_runtime_get_noresume(&bus->root_hub->dev); | ||
1047 | } | ||
1048 | } | ||
1049 | EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume); | ||
1050 | |||
1051 | /* | ||
1052 | * usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal | ||
1053 | * @bus: the bus which the root hub belongs to | ||
1054 | * @portnum: the port which is being resumed | ||
1055 | * | ||
1056 | * HCDs should call this function when they know that a resume signal has | ||
1057 | * stopped being sent to a root-hub port. The root hub will be allowed to | ||
1058 | * autosuspend again. | ||
1059 | * | ||
1060 | * The bus's private lock must be held by the caller. | ||
1061 | */ | ||
1062 | void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum) | ||
1063 | { | ||
1064 | unsigned bit = 1 << portnum; | ||
1065 | |||
1066 | if (bus->resuming_ports & bit) { | ||
1067 | bus->resuming_ports &= ~bit; | ||
1068 | pm_runtime_put_noidle(&bus->root_hub->dev); | ||
1069 | } | ||
1070 | } | ||
1071 | EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume); | ||
1028 | 1072 | ||
1029 | /*-------------------------------------------------------------------------*/ | 1073 | /*-------------------------------------------------------------------------*/ |
1030 | 1074 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 957ed2c41482..cbf7168e3ce7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev) | |||
2838 | EXPORT_SYMBOL_GPL(usb_enable_ltm); | 2838 | EXPORT_SYMBOL_GPL(usb_enable_ltm); |
2839 | 2839 | ||
2840 | #ifdef CONFIG_USB_SUSPEND | 2840 | #ifdef CONFIG_USB_SUSPEND |
2841 | /* | ||
2842 | * usb_disable_function_remotewakeup - disable usb3.0 | ||
2843 | * device's function remote wakeup | ||
2844 | * @udev: target device | ||
2845 | * | ||
2846 | * Assume there's only one function on the USB 3.0 | ||
2847 | * device and disable remote wake for the first | ||
2848 | * interface. FIXME if the interface association | ||
2849 | * descriptor shows there's more than one function. | ||
2850 | */ | ||
2851 | static int usb_disable_function_remotewakeup(struct usb_device *udev) | ||
2852 | { | ||
2853 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
2854 | USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, | ||
2855 | USB_INTRF_FUNC_SUSPEND, 0, NULL, 0, | ||
2856 | USB_CTRL_SET_TIMEOUT); | ||
2857 | } | ||
2841 | 2858 | ||
2842 | /* | 2859 | /* |
2843 | * usb_port_suspend - suspend a usb device's upstream port | 2860 | * usb_port_suspend - suspend a usb device's upstream port |
@@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2955 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", | 2972 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", |
2956 | port1, status); | 2973 | port1, status); |
2957 | /* paranoia: "should not happen" */ | 2974 | /* paranoia: "should not happen" */ |
2958 | if (udev->do_remote_wakeup) | 2975 | if (udev->do_remote_wakeup) { |
2959 | (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 2976 | if (!hub_is_superspeed(hub->hdev)) { |
2960 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, | 2977 | (void) usb_control_msg(udev, |
2961 | USB_DEVICE_REMOTE_WAKEUP, 0, | 2978 | usb_sndctrlpipe(udev, 0), |
2962 | NULL, 0, | 2979 | USB_REQ_CLEAR_FEATURE, |
2963 | USB_CTRL_SET_TIMEOUT); | 2980 | USB_RECIP_DEVICE, |
2981 | USB_DEVICE_REMOTE_WAKEUP, 0, | ||
2982 | NULL, 0, | ||
2983 | USB_CTRL_SET_TIMEOUT); | ||
2984 | } else | ||
2985 | (void) usb_disable_function_remotewakeup(udev); | ||
2986 | |||
2987 | } | ||
2964 | 2988 | ||
2965 | /* Try to enable USB2 hardware LPM again */ | 2989 | /* Try to enable USB2 hardware LPM again */ |
2966 | if (udev->usb2_hw_lpm_capable == 1) | 2990 | if (udev->usb2_hw_lpm_capable == 1) |
@@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev) | |||
3052 | * udev->reset_resume | 3076 | * udev->reset_resume |
3053 | */ | 3077 | */ |
3054 | } else if (udev->actconfig && !udev->reset_resume) { | 3078 | } else if (udev->actconfig && !udev->reset_resume) { |
3055 | le16_to_cpus(&devstatus); | 3079 | if (!hub_is_superspeed(udev->parent)) { |
3056 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { | 3080 | le16_to_cpus(&devstatus); |
3057 | status = usb_control_msg(udev, | 3081 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
3058 | usb_sndctrlpipe(udev, 0), | 3082 | status = usb_control_msg(udev, |
3059 | USB_REQ_CLEAR_FEATURE, | 3083 | usb_sndctrlpipe(udev, 0), |
3084 | USB_REQ_CLEAR_FEATURE, | ||
3060 | USB_RECIP_DEVICE, | 3085 | USB_RECIP_DEVICE, |
3061 | USB_DEVICE_REMOTE_WAKEUP, 0, | 3086 | USB_DEVICE_REMOTE_WAKEUP, 0, |
3062 | NULL, 0, | 3087 | NULL, 0, |
3063 | USB_CTRL_SET_TIMEOUT); | 3088 | USB_CTRL_SET_TIMEOUT); |
3064 | if (status) | 3089 | } else { |
3065 | dev_dbg(&udev->dev, | 3090 | status = usb_get_status(udev, USB_RECIP_INTERFACE, 0, |
3066 | "disable remote wakeup, status %d\n", | 3091 | &devstatus); |
3067 | status); | 3092 | le16_to_cpus(&devstatus); |
3093 | if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP | ||
3094 | | USB_INTRF_STAT_FUNC_RW)) | ||
3095 | status = | ||
3096 | usb_disable_function_remotewakeup(udev); | ||
3068 | } | 3097 | } |
3098 | |||
3099 | if (status) | ||
3100 | dev_dbg(&udev->dev, | ||
3101 | "disable remote wakeup, status %d\n", | ||
3102 | status); | ||
3069 | status = 0; | 3103 | status = 0; |
3070 | } | 3104 | } |
3071 | return status; | 3105 | return status; |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 09537b2f1002..b416a3fc9959 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
797 | ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); | 797 | ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); |
798 | set_bit(i, &ehci->resuming_ports); | 798 | set_bit(i, &ehci->resuming_ports); |
799 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); | 799 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); |
800 | usb_hcd_start_port_resume(&hcd->self, i); | ||
800 | mod_timer(&hcd->rh_timer, ehci->reset_done[i]); | 801 | mod_timer(&hcd->rh_timer, ehci->reset_done[i]); |
801 | } | 802 | } |
802 | } | 803 | } |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4ccb97c0678f..4d3b294f203e 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
649 | status = STS_PCD; | 649 | status = STS_PCD; |
650 | } | 650 | } |
651 | } | 651 | } |
652 | /* FIXME autosuspend idle root hubs */ | 652 | |
653 | /* If a resume is in progress, make sure it can finish */ | ||
654 | if (ehci->resuming_ports) | ||
655 | mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25)); | ||
656 | |||
653 | spin_unlock_irqrestore (&ehci->lock, flags); | 657 | spin_unlock_irqrestore (&ehci->lock, flags); |
654 | return status ? retval : 0; | 658 | return status ? retval : 0; |
655 | } | 659 | } |
@@ -851,6 +855,7 @@ static int ehci_hub_control ( | |||
851 | /* resume signaling for 20 msec */ | 855 | /* resume signaling for 20 msec */ |
852 | ehci->reset_done[wIndex] = jiffies | 856 | ehci->reset_done[wIndex] = jiffies |
853 | + msecs_to_jiffies(20); | 857 | + msecs_to_jiffies(20); |
858 | usb_hcd_start_port_resume(&hcd->self, wIndex); | ||
854 | /* check the port again */ | 859 | /* check the port again */ |
855 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, | 860 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, |
856 | ehci->reset_done[wIndex]); | 861 | ehci->reset_done[wIndex]); |
@@ -862,6 +867,7 @@ static int ehci_hub_control ( | |||
862 | clear_bit(wIndex, &ehci->suspended_ports); | 867 | clear_bit(wIndex, &ehci->suspended_ports); |
863 | set_bit(wIndex, &ehci->port_c_suspend); | 868 | set_bit(wIndex, &ehci->port_c_suspend); |
864 | ehci->reset_done[wIndex] = 0; | 869 | ehci->reset_done[wIndex] = 0; |
870 | usb_hcd_end_port_resume(&hcd->self, wIndex); | ||
865 | 871 | ||
866 | /* stop resume signaling */ | 872 | /* stop resume signaling */ |
867 | temp = ehci_readl(ehci, status_reg); | 873 | temp = ehci_readl(ehci, status_reg); |
@@ -950,6 +956,7 @@ static int ehci_hub_control ( | |||
950 | ehci->reset_done[wIndex] = 0; | 956 | ehci->reset_done[wIndex] = 0; |
951 | if (temp & PORT_PE) | 957 | if (temp & PORT_PE) |
952 | set_bit(wIndex, &ehci->port_c_suspend); | 958 | set_bit(wIndex, &ehci->port_c_suspend); |
959 | usb_hcd_end_port_resume(&hcd->self, wIndex); | ||
953 | } | 960 | } |
954 | 961 | ||
955 | if (temp & PORT_OC) | 962 | if (temp & PORT_OC) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3d989028c836..fd252f0cfb3a 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested) | |||
1197 | if (ehci->async_iaa || ehci->async_unlinking) | 1197 | if (ehci->async_iaa || ehci->async_unlinking) |
1198 | return; | 1198 | return; |
1199 | 1199 | ||
1200 | /* Do all the waiting QHs at once */ | ||
1201 | ehci->async_iaa = ehci->async_unlink; | ||
1202 | ehci->async_unlink = NULL; | ||
1203 | |||
1204 | /* If the controller isn't running, we don't have to wait for it */ | 1200 | /* If the controller isn't running, we don't have to wait for it */ |
1205 | if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { | 1201 | if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { |
1202 | |||
1203 | /* Do all the waiting QHs */ | ||
1204 | ehci->async_iaa = ehci->async_unlink; | ||
1205 | ehci->async_unlink = NULL; | ||
1206 | |||
1206 | if (!nested) /* Avoid recursion */ | 1207 | if (!nested) /* Avoid recursion */ |
1207 | end_unlink_async(ehci); | 1208 | end_unlink_async(ehci); |
1208 | 1209 | ||
1209 | /* Otherwise start a new IAA cycle */ | 1210 | /* Otherwise start a new IAA cycle */ |
1210 | } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { | 1211 | } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { |
1212 | struct ehci_qh *qh; | ||
1213 | |||
1214 | /* Do only the first waiting QH (nVidia bug?) */ | ||
1215 | qh = ehci->async_unlink; | ||
1216 | ehci->async_iaa = qh; | ||
1217 | ehci->async_unlink = qh->unlink_next; | ||
1218 | qh->unlink_next = NULL; | ||
1219 | |||
1211 | /* Make sure the unlinks are all visible to the hardware */ | 1220 | /* Make sure the unlinks are all visible to the hardware */ |
1212 | wmb(); | 1221 | wmb(); |
1213 | 1222 | ||
@@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci) | |||
1255 | } | 1264 | } |
1256 | } | 1265 | } |
1257 | 1266 | ||
1267 | static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh); | ||
1268 | |||
1258 | static void unlink_empty_async(struct ehci_hcd *ehci) | 1269 | static void unlink_empty_async(struct ehci_hcd *ehci) |
1259 | { | 1270 | { |
1260 | struct ehci_qh *qh, *next; | 1271 | struct ehci_qh *qh; |
1261 | bool stopped = (ehci->rh_state < EHCI_RH_RUNNING); | 1272 | struct ehci_qh *qh_to_unlink = NULL; |
1262 | bool check_unlinks_later = false; | 1273 | bool check_unlinks_later = false; |
1274 | int count = 0; | ||
1263 | 1275 | ||
1264 | /* Unlink all the async QHs that have been empty for a timer cycle */ | 1276 | /* Find the last async QH which has been empty for a timer cycle */ |
1265 | next = ehci->async->qh_next.qh; | 1277 | for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) { |
1266 | while (next) { | ||
1267 | qh = next; | ||
1268 | next = qh->qh_next.qh; | ||
1269 | |||
1270 | if (list_empty(&qh->qtd_list) && | 1278 | if (list_empty(&qh->qtd_list) && |
1271 | qh->qh_state == QH_STATE_LINKED) { | 1279 | qh->qh_state == QH_STATE_LINKED) { |
1272 | if (!stopped && qh->unlink_cycle == | 1280 | ++count; |
1273 | ehci->async_unlink_cycle) | 1281 | if (qh->unlink_cycle == ehci->async_unlink_cycle) |
1274 | check_unlinks_later = true; | 1282 | check_unlinks_later = true; |
1275 | else | 1283 | else |
1276 | single_unlink_async(ehci, qh); | 1284 | qh_to_unlink = qh; |
1277 | } | 1285 | } |
1278 | } | 1286 | } |
1279 | 1287 | ||
1280 | /* Start a new IAA cycle if any QHs are waiting for it */ | 1288 | /* If nothing else is being unlinked, unlink the last empty QH */ |
1281 | if (ehci->async_unlink) | 1289 | if (!ehci->async_iaa && !ehci->async_unlink && qh_to_unlink) { |
1282 | start_iaa_cycle(ehci, false); | 1290 | start_unlink_async(ehci, qh_to_unlink); |
1291 | --count; | ||
1292 | } | ||
1283 | 1293 | ||
1284 | /* QHs that haven't been empty for long enough will be handled later */ | 1294 | /* Other QHs will be handled later */ |
1285 | if (check_unlinks_later) { | 1295 | if (count > 0) { |
1286 | ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true); | 1296 | ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true); |
1287 | ++ehci->async_unlink_cycle; | 1297 | ++ehci->async_unlink_cycle; |
1288 | } | 1298 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 69ebee73c0c1..b476daf49f6f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) | |||
213 | } | 213 | } |
214 | 214 | ||
215 | static const unsigned char | 215 | static const unsigned char |
216 | max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; | 216 | max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 }; |
217 | 217 | ||
218 | /* carryover low/fullspeed bandwidth that crosses uframe boundries */ | 218 | /* carryover low/fullspeed bandwidth that crosses uframe boundries */ |
219 | static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) | 219 | static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) |
@@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci) | |||
2212 | } | 2212 | } |
2213 | ehci->now_frame = now_frame; | 2213 | ehci->now_frame = now_frame; |
2214 | 2214 | ||
2215 | frame = ehci->last_iso_frame; | ||
2215 | for (;;) { | 2216 | for (;;) { |
2216 | union ehci_shadow q, *q_p; | 2217 | union ehci_shadow q, *q_p; |
2217 | __hc32 type, *hw_p; | 2218 | __hc32 type, *hw_p; |
2218 | 2219 | ||
2219 | frame = ehci->last_iso_frame; | ||
2220 | restart: | 2220 | restart: |
2221 | /* scan each element in frame's queue for completions */ | 2221 | /* scan each element in frame's queue for completions */ |
2222 | q_p = &ehci->pshadow [frame]; | 2222 | q_p = &ehci->pshadow [frame]; |
@@ -2321,6 +2321,9 @@ restart: | |||
2321 | /* Stop when we have reached the current frame */ | 2321 | /* Stop when we have reached the current frame */ |
2322 | if (frame == now_frame) | 2322 | if (frame == now_frame) |
2323 | break; | 2323 | break; |
2324 | ehci->last_iso_frame = (frame + 1) & fmask; | 2324 | |
2325 | /* The last frame may still have active siTDs */ | ||
2326 | ehci->last_iso_frame = frame; | ||
2327 | frame = (frame + 1) & fmask; | ||
2325 | } | 2328 | } |
2326 | } | 2329 | } |
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 20dbdcbe9b0f..f904071d70df 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c | |||
@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci) | |||
113 | 113 | ||
114 | if (want != actual) { | 114 | if (want != actual) { |
115 | 115 | ||
116 | /* Poll again later, but give up after about 20 ms */ | 116 | /* Poll again later */ |
117 | if (ehci->ASS_poll_count++ < 20) { | 117 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); |
118 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); | 118 | ++ehci->ASS_poll_count; |
119 | return; | 119 | return; |
120 | } | ||
121 | ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n", | ||
122 | want, actual); | ||
123 | } | 120 | } |
121 | |||
122 | if (ehci->ASS_poll_count > 20) | ||
123 | ehci_dbg(ehci, "ASS poll count reached %d\n", | ||
124 | ehci->ASS_poll_count); | ||
124 | ehci->ASS_poll_count = 0; | 125 | ehci->ASS_poll_count = 0; |
125 | 126 | ||
126 | /* The status is up-to-date; restart or stop the schedule as needed */ | 127 | /* The status is up-to-date; restart or stop the schedule as needed */ |
@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci) | |||
159 | 160 | ||
160 | if (want != actual) { | 161 | if (want != actual) { |
161 | 162 | ||
162 | /* Poll again later, but give up after about 20 ms */ | 163 | /* Poll again later */ |
163 | if (ehci->PSS_poll_count++ < 20) { | 164 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); |
164 | ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); | 165 | return; |
165 | return; | ||
166 | } | ||
167 | ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n", | ||
168 | want, actual); | ||
169 | } | 166 | } |
167 | |||
168 | if (ehci->PSS_poll_count > 20) | ||
169 | ehci_dbg(ehci, "PSS poll count reached %d\n", | ||
170 | ehci->PSS_poll_count); | ||
170 | ehci->PSS_poll_count = 0; | 171 | ehci->PSS_poll_count = 0; |
171 | 172 | ||
172 | /* The status is up-to-date; restart or stop the schedule as needed */ | 173 | /* The status is up-to-date; restart or stop the schedule as needed */ |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index a3b6d7104ae2..4c338ec03a07 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
780 | "defaulting to EHCI.\n"); | 780 | "defaulting to EHCI.\n"); |
781 | dev_warn(&xhci_pdev->dev, | 781 | dev_warn(&xhci_pdev->dev, |
782 | "USB 3.0 devices will work at USB 2.0 speeds.\n"); | 782 | "USB 3.0 devices will work at USB 2.0 speeds.\n"); |
783 | usb_disable_xhci_ports(xhci_pdev); | ||
783 | return; | 784 | return; |
784 | } | 785 | } |
785 | 786 | ||
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 768d54295a20..15d13229ddbb 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | clear_bit(port, &uhci->resuming_ports); | 118 | clear_bit(port, &uhci->resuming_ports); |
119 | usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port); | ||
119 | } | 120 | } |
120 | 121 | ||
121 | /* Wait for the UHCI controller in HP's iLO2 server management chip. | 122 | /* Wait for the UHCI controller in HP's iLO2 server management chip. |
@@ -167,6 +168,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci) | |||
167 | set_bit(port, &uhci->resuming_ports); | 168 | set_bit(port, &uhci->resuming_ports); |
168 | uhci->ports_timeout = jiffies + | 169 | uhci->ports_timeout = jiffies + |
169 | msecs_to_jiffies(25); | 170 | msecs_to_jiffies(25); |
171 | usb_hcd_start_port_resume( | ||
172 | &uhci_to_hcd(uhci)->self, port); | ||
170 | 173 | ||
171 | /* Make sure we see the port again | 174 | /* Make sure we see the port again |
172 | * after the resuming period is over. */ | 175 | * after the resuming period is over. */ |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 59fb5c677dbe..7f76a49e90d3 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1698 | faked_port_index + 1); | 1698 | faked_port_index + 1); |
1699 | if (slot_id && xhci->devs[slot_id]) | 1699 | if (slot_id && xhci->devs[slot_id]) |
1700 | xhci_ring_device(xhci, slot_id); | 1700 | xhci_ring_device(xhci, slot_id); |
1701 | if (bus_state->port_remote_wakeup && (1 << faked_port_index)) { | 1701 | if (bus_state->port_remote_wakeup & (1 << faked_port_index)) { |
1702 | bus_state->port_remote_wakeup &= | 1702 | bus_state->port_remote_wakeup &= |
1703 | ~(1 << faked_port_index); | 1703 | ~(1 << faked_port_index); |
1704 | xhci_test_and_clear_bit(xhci, port_array, | 1704 | xhci_test_and_clear_bit(xhci, port_array, |
@@ -2589,6 +2589,8 @@ cleanup: | |||
2589 | (trb_comp_code != COMP_STALL && | 2589 | (trb_comp_code != COMP_STALL && |
2590 | trb_comp_code != COMP_BABBLE)) | 2590 | trb_comp_code != COMP_BABBLE)) |
2591 | xhci_urb_free_priv(xhci, urb_priv); | 2591 | xhci_urb_free_priv(xhci, urb_priv); |
2592 | else | ||
2593 | kfree(urb_priv); | ||
2592 | 2594 | ||
2593 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); | 2595 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
2594 | if ((urb->actual_length != urb->transfer_buffer_length && | 2596 | if ((urb->actual_length != urb->transfer_buffer_length && |
@@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, | |||
3108 | * running_total. | 3110 | * running_total. |
3109 | */ | 3111 | */ |
3110 | packets_transferred = (running_total + trb_buff_len) / | 3112 | packets_transferred = (running_total + trb_buff_len) / |
3111 | usb_endpoint_maxp(&urb->ep->desc); | 3113 | GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); |
3112 | 3114 | ||
3113 | if ((total_packet_count - packets_transferred) > 31) | 3115 | if ((total_packet_count - packets_transferred) > 31) |
3114 | return 31 << 17; | 3116 | return 31 << 17; |
@@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3642 | td_len = urb->iso_frame_desc[i].length; | 3644 | td_len = urb->iso_frame_desc[i].length; |
3643 | td_remain_len = td_len; | 3645 | td_remain_len = td_len; |
3644 | total_packet_count = DIV_ROUND_UP(td_len, | 3646 | total_packet_count = DIV_ROUND_UP(td_len, |
3645 | usb_endpoint_maxp(&urb->ep->desc)); | 3647 | GET_MAX_PACKET( |
3648 | usb_endpoint_maxp(&urb->ep->desc))); | ||
3646 | /* A zero-length transfer still involves at least one packet. */ | 3649 | /* A zero-length transfer still involves at least one packet. */ |
3647 | if (total_packet_count == 0) | 3650 | if (total_packet_count == 0) |
3648 | total_packet_count++; | 3651 | total_packet_count++; |
@@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3664 | td = urb_priv->td[i]; | 3667 | td = urb_priv->td[i]; |
3665 | for (j = 0; j < trbs_per_td; j++) { | 3668 | for (j = 0; j < trbs_per_td; j++) { |
3666 | u32 remainder = 0; | 3669 | u32 remainder = 0; |
3667 | field = TRB_TBC(burst_count) | TRB_TLBPC(residue); | 3670 | field = 0; |
3668 | 3671 | ||
3669 | if (first_trb) { | 3672 | if (first_trb) { |
3673 | field = TRB_TBC(burst_count) | | ||
3674 | TRB_TLBPC(residue); | ||
3670 | /* Queue the isoc TRB */ | 3675 | /* Queue the isoc TRB */ |
3671 | field |= TRB_TYPE(TRB_ISOC); | 3676 | field |= TRB_TYPE(TRB_ISOC); |
3672 | /* Assume URB_ISO_ASAP is set */ | 3677 | /* Assume URB_ISO_ASAP is set */ |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f14736f647ff..edc0f0dcad83 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { | |||
60 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 60 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
61 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ | 61 | { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ |
62 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ | 62 | { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ |
63 | { USB_DEVICE(0x0FDE, 0xCA05) }, /* OWL Wireless Electricity Monitor CM-160 */ | ||
63 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 64 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
64 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 65 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
65 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 66 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ba68835d06a6..90ceef1776c3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = { | |||
584 | /* | 584 | /* |
585 | * ELV devices: | 585 | * ELV devices: |
586 | */ | 586 | */ |
587 | { USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) }, | ||
587 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, | 588 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, |
588 | { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, | 589 | { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, |
589 | { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, | 590 | { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, |
@@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = { | |||
670 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, | 671 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, |
671 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, | 672 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, |
672 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, | 673 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, |
674 | { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, | ||
673 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 675 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
674 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 676 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
675 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, | 677 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index fa5d56038276..9d359e189a64 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -147,6 +147,11 @@ | |||
147 | #define XSENS_CONVERTER_6_PID 0xD38E | 147 | #define XSENS_CONVERTER_6_PID 0xD38E |
148 | #define XSENS_CONVERTER_7_PID 0xD38F | 148 | #define XSENS_CONVERTER_7_PID 0xD38F |
149 | 149 | ||
150 | /** | ||
151 | * Zolix (www.zolix.com.cb) product ids | ||
152 | */ | ||
153 | #define FTDI_OMNI1509 0xD491 /* Omni1509 embedded USB-serial */ | ||
154 | |||
150 | /* | 155 | /* |
151 | * NDI (www.ndigital.com) product ids | 156 | * NDI (www.ndigital.com) product ids |
152 | */ | 157 | */ |
@@ -204,7 +209,7 @@ | |||
204 | 209 | ||
205 | /* | 210 | /* |
206 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). | 211 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). |
207 | * All of these devices use FTDI's vendor ID (0x0403). | 212 | * Almost all of these devices use FTDI's vendor ID (0x0403). |
208 | * Further IDs taken from ELV Windows .inf file. | 213 | * Further IDs taken from ELV Windows .inf file. |
209 | * | 214 | * |
210 | * The previously included PID for the UO 100 module was incorrect. | 215 | * The previously included PID for the UO 100 module was incorrect. |
@@ -212,6 +217,8 @@ | |||
212 | * | 217 | * |
213 | * Armin Laeuger originally sent the PID for the UM 100 module. | 218 | * Armin Laeuger originally sent the PID for the UM 100 module. |
214 | */ | 219 | */ |
220 | #define FTDI_ELV_VID 0x1B1F /* ELV AG */ | ||
221 | #define FTDI_ELV_WS300_PID 0xC006 /* eQ3 WS 300 PC II */ | ||
215 | #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ | 222 | #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ |
216 | #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ | 223 | #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ |
217 | #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ | 224 | #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0d9dac9e7f93..567bc77d6397 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb); | |||
242 | #define TELIT_PRODUCT_CC864_DUAL 0x1005 | 242 | #define TELIT_PRODUCT_CC864_DUAL 0x1005 |
243 | #define TELIT_PRODUCT_CC864_SINGLE 0x1006 | 243 | #define TELIT_PRODUCT_CC864_SINGLE 0x1006 |
244 | #define TELIT_PRODUCT_DE910_DUAL 0x1010 | 244 | #define TELIT_PRODUCT_DE910_DUAL 0x1010 |
245 | #define TELIT_PRODUCT_LE920 0x1200 | ||
245 | 246 | ||
246 | /* ZTE PRODUCTS */ | 247 | /* ZTE PRODUCTS */ |
247 | #define ZTE_VENDOR_ID 0x19d2 | 248 | #define ZTE_VENDOR_ID 0x19d2 |
@@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb); | |||
453 | #define TPLINK_VENDOR_ID 0x2357 | 454 | #define TPLINK_VENDOR_ID 0x2357 |
454 | #define TPLINK_PRODUCT_MA180 0x0201 | 455 | #define TPLINK_PRODUCT_MA180 0x0201 |
455 | 456 | ||
457 | /* Changhong products */ | ||
458 | #define CHANGHONG_VENDOR_ID 0x2077 | ||
459 | #define CHANGHONG_PRODUCT_CH690 0x7001 | ||
460 | |||
456 | /* some devices interfaces need special handling due to a number of reasons */ | 461 | /* some devices interfaces need special handling due to a number of reasons */ |
457 | enum option_blacklist_reason { | 462 | enum option_blacklist_reason { |
458 | OPTION_BLACKLIST_NONE = 0, | 463 | OPTION_BLACKLIST_NONE = 0, |
@@ -534,6 +539,11 @@ static const struct option_blacklist_info zte_1255_blacklist = { | |||
534 | .reserved = BIT(3) | BIT(4), | 539 | .reserved = BIT(3) | BIT(4), |
535 | }; | 540 | }; |
536 | 541 | ||
542 | static const struct option_blacklist_info telit_le920_blacklist = { | ||
543 | .sendsetup = BIT(0), | ||
544 | .reserved = BIT(1) | BIT(5), | ||
545 | }; | ||
546 | |||
537 | static const struct usb_device_id option_ids[] = { | 547 | static const struct usb_device_id option_ids[] = { |
538 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 548 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
539 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 549 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -784,6 +794,8 @@ static const struct usb_device_id option_ids[] = { | |||
784 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, | 794 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, |
785 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, | 795 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, |
786 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, | 796 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, |
797 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), | ||
798 | .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, | ||
787 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 799 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
788 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), | 800 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), |
789 | .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, | 801 | .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, |
@@ -1318,6 +1330,7 @@ static const struct usb_device_id option_ids[] = { | |||
1318 | { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, | 1330 | { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, |
1319 | { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), | 1331 | { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), |
1320 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1332 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
1333 | { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, | ||
1321 | { } /* Terminating entry */ | 1334 | { } /* Terminating entry */ |
1322 | }; | 1335 | }; |
1323 | MODULE_DEVICE_TABLE(usb, option_ids); | 1336 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index aa148c21ea40..24662547dc5b 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = { | |||
53 | {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ | 53 | {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ |
54 | {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ | 54 | {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ |
55 | {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ | 55 | {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ |
56 | {DEVICE_G1K(0x1bc7, 0x900e)}, /* Telit Gobi QDL device */ | ||
56 | 57 | ||
57 | /* Gobi 2000 devices */ | 58 | /* Gobi 2000 devices */ |
58 | {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ | 59 | {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ |
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 105d900150c1..16b0bf055eeb 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | /* This places the HUAWEI E220 devices in multi-port mode */ | 95 | /* This places the HUAWEI usb dongles in multi-port mode */ |
96 | int usb_stor_huawei_e220_init(struct us_data *us) | 96 | static int usb_stor_huawei_feature_init(struct us_data *us) |
97 | { | 97 | { |
98 | int result; | 98 | int result; |
99 | 99 | ||
@@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us) | |||
104 | US_DEBUGP("Huawei mode set result is %d\n", result); | 104 | US_DEBUGP("Huawei mode set result is %d\n", result); |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | |||
108 | /* | ||
109 | * It will send a scsi switch command called rewind' to huawei dongle. | ||
110 | * When the dongle receives this command at the first time, | ||
111 | * it will reboot immediately. After rebooted, it will ignore this command. | ||
112 | * So it is unnecessary to read its response. | ||
113 | */ | ||
114 | static int usb_stor_huawei_scsi_init(struct us_data *us) | ||
115 | { | ||
116 | int result = 0; | ||
117 | int act_len = 0; | ||
118 | struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; | ||
119 | char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, | ||
120 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
121 | |||
122 | bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); | ||
123 | bcbw->Tag = 0; | ||
124 | bcbw->DataTransferLength = 0; | ||
125 | bcbw->Flags = bcbw->Lun = 0; | ||
126 | bcbw->Length = sizeof(rewind_cmd); | ||
127 | memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); | ||
128 | memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); | ||
129 | |||
130 | result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, | ||
131 | US_BULK_CB_WRAP_LEN, &act_len); | ||
132 | US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); | ||
133 | return result; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * It tries to find the supported Huawei USB dongles. | ||
138 | * In Huawei, they assign the following product IDs | ||
139 | * for all of their mobile broadband dongles, | ||
140 | * including the new dongles in the future. | ||
141 | * So if the product ID is not included in this list, | ||
142 | * it means it is not Huawei's mobile broadband dongles. | ||
143 | */ | ||
144 | static int usb_stor_huawei_dongles_pid(struct us_data *us) | ||
145 | { | ||
146 | struct usb_interface_descriptor *idesc; | ||
147 | int idProduct; | ||
148 | |||
149 | idesc = &us->pusb_intf->cur_altsetting->desc; | ||
150 | idProduct = us->pusb_dev->descriptor.idProduct; | ||
151 | /* The first port is CDROM, | ||
152 | * means the dongle in the single port mode, | ||
153 | * and a switch command is required to be sent. */ | ||
154 | if (idesc && idesc->bInterfaceNumber == 0) { | ||
155 | if ((idProduct == 0x1001) | ||
156 | || (idProduct == 0x1003) | ||
157 | || (idProduct == 0x1004) | ||
158 | || (idProduct >= 0x1401 && idProduct <= 0x1500) | ||
159 | || (idProduct >= 0x1505 && idProduct <= 0x1600) | ||
160 | || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { | ||
161 | return 1; | ||
162 | } | ||
163 | } | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | int usb_stor_huawei_init(struct us_data *us) | ||
168 | { | ||
169 | int result = 0; | ||
170 | |||
171 | if (usb_stor_huawei_dongles_pid(us)) { | ||
172 | if (us->pusb_dev->descriptor.idProduct >= 0x1446) | ||
173 | result = usb_stor_huawei_scsi_init(us); | ||
174 | else | ||
175 | result = usb_stor_huawei_feature_init(us); | ||
176 | } | ||
177 | return result; | ||
178 | } | ||
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 529327fbb06b..5376d4fc76f0 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); | |||
46 | * flash reader */ | 46 | * flash reader */ |
47 | int usb_stor_ucr61s2b_init(struct us_data *us); | 47 | int usb_stor_ucr61s2b_init(struct us_data *us); |
48 | 48 | ||
49 | /* This places the HUAWEI E220 devices in multi-port mode */ | 49 | /* This places the HUAWEI usb dongles in multi-port mode */ |
50 | int usb_stor_huawei_e220_init(struct us_data *us); | 50 | int usb_stor_huawei_init(struct us_data *us); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d305a5aa3a5d..72923b56bbf6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1527,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, | |||
1527 | /* Reported by fangxiaozhi <huananhu@huawei.com> | 1527 | /* Reported by fangxiaozhi <huananhu@huawei.com> |
1528 | * This brings the HUAWEI data card devices into multi-port mode | 1528 | * This brings the HUAWEI data card devices into multi-port mode |
1529 | */ | 1529 | */ |
1530 | UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, | 1530 | UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, |
1531 | "HUAWEI MOBILE", | 1531 | "HUAWEI MOBILE", |
1532 | "Mass Storage", | 1532 | "Mass Storage", |
1533 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | 1533 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, |
1534 | 0), | ||
1535 | UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, | ||
1536 | "HUAWEI MOBILE", | ||
1537 | "Mass Storage", | ||
1538 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1539 | 0), | ||
1540 | UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, | ||
1541 | "HUAWEI MOBILE", | ||
1542 | "Mass Storage", | ||
1543 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1544 | 0), | ||
1545 | UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, | ||
1546 | "HUAWEI MOBILE", | ||
1547 | "Mass Storage", | ||
1548 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1549 | 0), | ||
1550 | UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, | ||
1551 | "HUAWEI MOBILE", | ||
1552 | "Mass Storage", | ||
1553 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1554 | 0), | ||
1555 | UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, | ||
1556 | "HUAWEI MOBILE", | ||
1557 | "Mass Storage", | ||
1558 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1559 | 0), | ||
1560 | UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, | ||
1561 | "HUAWEI MOBILE", | ||
1562 | "Mass Storage", | ||
1563 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1564 | 0), | ||
1565 | UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, | ||
1566 | "HUAWEI MOBILE", | ||
1567 | "Mass Storage", | ||
1568 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1569 | 0), | ||
1570 | UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, | ||
1571 | "HUAWEI MOBILE", | ||
1572 | "Mass Storage", | ||
1573 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1574 | 0), | ||
1575 | UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, | ||
1576 | "HUAWEI MOBILE", | ||
1577 | "Mass Storage", | ||
1578 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1579 | 0), | ||
1580 | UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, | ||
1581 | "HUAWEI MOBILE", | ||
1582 | "Mass Storage", | ||
1583 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1584 | 0), | ||
1585 | UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, | ||
1586 | "HUAWEI MOBILE", | ||
1587 | "Mass Storage", | ||
1588 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1589 | 0), | ||
1590 | UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, | ||
1591 | "HUAWEI MOBILE", | ||
1592 | "Mass Storage", | ||
1593 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1594 | 0), | ||
1595 | UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, | ||
1596 | "HUAWEI MOBILE", | ||
1597 | "Mass Storage", | ||
1598 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1599 | 0), | ||
1600 | UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, | ||
1601 | "HUAWEI MOBILE", | ||
1602 | "Mass Storage", | ||
1603 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1604 | 0), | ||
1605 | UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, | ||
1606 | "HUAWEI MOBILE", | ||
1607 | "Mass Storage", | ||
1608 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1609 | 0), | ||
1610 | UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, | ||
1611 | "HUAWEI MOBILE", | ||
1612 | "Mass Storage", | ||
1613 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1614 | 0), | ||
1615 | UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, | ||
1616 | "HUAWEI MOBILE", | ||
1617 | "Mass Storage", | ||
1618 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1619 | 0), | ||
1620 | UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, | ||
1621 | "HUAWEI MOBILE", | ||
1622 | "Mass Storage", | ||
1623 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1624 | 0), | ||
1625 | UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, | ||
1626 | "HUAWEI MOBILE", | ||
1627 | "Mass Storage", | ||
1628 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1629 | 0), | ||
1630 | UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, | ||
1631 | "HUAWEI MOBILE", | ||
1632 | "Mass Storage", | ||
1633 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1634 | 0), | ||
1635 | UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, | ||
1636 | "HUAWEI MOBILE", | ||
1637 | "Mass Storage", | ||
1638 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1639 | 0), | ||
1640 | UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, | ||
1641 | "HUAWEI MOBILE", | ||
1642 | "Mass Storage", | ||
1643 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1644 | 0), | ||
1645 | UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, | ||
1646 | "HUAWEI MOBILE", | ||
1647 | "Mass Storage", | ||
1648 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1649 | 0), | ||
1650 | UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, | ||
1651 | "HUAWEI MOBILE", | ||
1652 | "Mass Storage", | ||
1653 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1654 | 0), | ||
1655 | UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, | ||
1656 | "HUAWEI MOBILE", | ||
1657 | "Mass Storage", | ||
1658 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1659 | 0), | ||
1660 | UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, | ||
1661 | "HUAWEI MOBILE", | ||
1662 | "Mass Storage", | ||
1663 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1664 | 0), | ||
1665 | UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, | ||
1666 | "HUAWEI MOBILE", | ||
1667 | "Mass Storage", | ||
1668 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1669 | 0), | ||
1670 | UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, | ||
1671 | "HUAWEI MOBILE", | ||
1672 | "Mass Storage", | ||
1673 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1674 | 0), | ||
1675 | UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, | ||
1676 | "HUAWEI MOBILE", | ||
1677 | "Mass Storage", | ||
1678 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1679 | 0), | ||
1680 | UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, | ||
1681 | "HUAWEI MOBILE", | ||
1682 | "Mass Storage", | ||
1683 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1684 | 0), | ||
1685 | UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, | ||
1686 | "HUAWEI MOBILE", | ||
1687 | "Mass Storage", | ||
1688 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1689 | 0), | ||
1690 | UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, | ||
1691 | "HUAWEI MOBILE", | ||
1692 | "Mass Storage", | ||
1693 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1694 | 0), | ||
1695 | UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, | ||
1696 | "HUAWEI MOBILE", | ||
1697 | "Mass Storage", | ||
1698 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1699 | 0), | ||
1700 | UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, | ||
1701 | "HUAWEI MOBILE", | ||
1702 | "Mass Storage", | ||
1703 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1704 | 0), | ||
1705 | UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, | ||
1706 | "HUAWEI MOBILE", | ||
1707 | "Mass Storage", | ||
1708 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1709 | 0), | ||
1710 | UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, | ||
1711 | "HUAWEI MOBILE", | ||
1712 | "Mass Storage", | ||
1713 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1714 | 0), | ||
1715 | UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, | ||
1716 | "HUAWEI MOBILE", | ||
1717 | "Mass Storage", | ||
1718 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1719 | 0), | ||
1720 | UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, | ||
1721 | "HUAWEI MOBILE", | ||
1722 | "Mass Storage", | ||
1723 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1724 | 0), | ||
1725 | UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, | ||
1726 | "HUAWEI MOBILE", | ||
1727 | "Mass Storage", | ||
1728 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1729 | 0), | ||
1730 | UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, | ||
1731 | "HUAWEI MOBILE", | ||
1732 | "Mass Storage", | ||
1733 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1734 | 0), | ||
1735 | UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, | ||
1736 | "HUAWEI MOBILE", | ||
1737 | "Mass Storage", | ||
1738 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1739 | 0), | ||
1740 | UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, | ||
1741 | "HUAWEI MOBILE", | ||
1742 | "Mass Storage", | ||
1743 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1744 | 0), | ||
1745 | UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, | ||
1746 | "HUAWEI MOBILE", | ||
1747 | "Mass Storage", | ||
1748 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1749 | 0), | ||
1750 | UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, | ||
1751 | "HUAWEI MOBILE", | ||
1752 | "Mass Storage", | ||
1753 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1754 | 0), | ||
1755 | UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, | ||
1756 | "HUAWEI MOBILE", | ||
1757 | "Mass Storage", | ||
1758 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1759 | 0), | ||
1760 | UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, | ||
1761 | "HUAWEI MOBILE", | ||
1762 | "Mass Storage", | ||
1763 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1764 | 0), | ||
1765 | UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, | ||
1766 | "HUAWEI MOBILE", | ||
1767 | "Mass Storage", | ||
1768 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1769 | 0), | ||
1770 | UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, | ||
1771 | "HUAWEI MOBILE", | ||
1772 | "Mass Storage", | ||
1773 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1774 | 0), | ||
1775 | UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, | ||
1776 | "HUAWEI MOBILE", | ||
1777 | "Mass Storage", | ||
1778 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1779 | 0), | ||
1780 | UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, | ||
1781 | "HUAWEI MOBILE", | ||
1782 | "Mass Storage", | ||
1783 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1784 | 0), | ||
1785 | UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, | ||
1786 | "HUAWEI MOBILE", | ||
1787 | "Mass Storage", | ||
1788 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1789 | 0), | ||
1790 | UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, | ||
1791 | "HUAWEI MOBILE", | ||
1792 | "Mass Storage", | ||
1793 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1794 | 0), | ||
1795 | UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, | ||
1796 | "HUAWEI MOBILE", | ||
1797 | "Mass Storage", | ||
1798 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1799 | 0), | ||
1800 | UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, | ||
1801 | "HUAWEI MOBILE", | ||
1802 | "Mass Storage", | ||
1803 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1804 | 0), | ||
1805 | UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, | ||
1806 | "HUAWEI MOBILE", | ||
1807 | "Mass Storage", | ||
1808 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1809 | 0), | ||
1810 | UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, | ||
1811 | "HUAWEI MOBILE", | ||
1812 | "Mass Storage", | ||
1813 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1814 | 0), | ||
1815 | UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, | ||
1816 | "HUAWEI MOBILE", | ||
1817 | "Mass Storage", | ||
1818 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1819 | 0), | ||
1820 | UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, | ||
1821 | "HUAWEI MOBILE", | ||
1822 | "Mass Storage", | ||
1823 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1824 | 0), | ||
1825 | UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, | ||
1826 | "HUAWEI MOBILE", | ||
1827 | "Mass Storage", | ||
1828 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1829 | 0), | ||
1830 | UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, | ||
1831 | "HUAWEI MOBILE", | ||
1832 | "Mass Storage", | ||
1833 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1834 | 0), | ||
1835 | UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, | ||
1836 | "HUAWEI MOBILE", | ||
1837 | "Mass Storage", | ||
1838 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1839 | 0), | ||
1840 | UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, | ||
1841 | "HUAWEI MOBILE", | ||
1842 | "Mass Storage", | ||
1843 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1844 | 0), | ||
1845 | UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, | ||
1846 | "HUAWEI MOBILE", | ||
1847 | "Mass Storage", | ||
1848 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1849 | 0), | ||
1850 | UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, | ||
1851 | "HUAWEI MOBILE", | ||
1852 | "Mass Storage", | ||
1853 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1854 | 0), | ||
1855 | UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, | ||
1856 | "HUAWEI MOBILE", | ||
1857 | "Mass Storage", | ||
1858 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1859 | 0), | 1534 | 0), |
1860 | 1535 | ||
1861 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1536 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 31b3e1a61bbd..cf09b6ba71ff 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
120 | .useTransport = use_transport, \ | 120 | .useTransport = use_transport, \ |
121 | } | 121 | } |
122 | 122 | ||
123 | #define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \ | ||
124 | vendor_name, product_name, use_protocol, use_transport, \ | ||
125 | init_function, Flags) \ | ||
126 | { \ | ||
127 | .vendorName = vendor_name, \ | ||
128 | .productName = product_name, \ | ||
129 | .useProtocol = use_protocol, \ | ||
130 | .useTransport = use_transport, \ | ||
131 | .initFunction = init_function, \ | ||
132 | } | ||
133 | |||
123 | static struct us_unusual_dev us_unusual_dev_list[] = { | 134 | static struct us_unusual_dev us_unusual_dev_list[] = { |
124 | # include "unusual_devs.h" | 135 | # include "unusual_devs.h" |
125 | { } /* Terminating entry */ | 136 | { } /* Terminating entry */ |
@@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids = | |||
131 | #undef UNUSUAL_DEV | 142 | #undef UNUSUAL_DEV |
132 | #undef COMPLIANT_DEV | 143 | #undef COMPLIANT_DEV |
133 | #undef USUAL_DEV | 144 | #undef USUAL_DEV |
145 | #undef UNUSUAL_VENDOR_INTF | ||
134 | 146 | ||
135 | #ifdef CONFIG_LOCKDEP | 147 | #ifdef CONFIG_LOCKDEP |
136 | 148 | ||
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index b78a526910fb..5ef8ce74aae4 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c | |||
@@ -41,6 +41,20 @@ | |||
41 | #define USUAL_DEV(useProto, useTrans) \ | 41 | #define USUAL_DEV(useProto, useTrans) \ |
42 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } | 42 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } |
43 | 43 | ||
44 | /* Define the device is matched with Vendor ID and interface descriptors */ | ||
45 | #define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \ | ||
46 | vendorName, productName, useProtocol, useTransport, \ | ||
47 | initFunction, flags) \ | ||
48 | { \ | ||
49 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ | ||
50 | | USB_DEVICE_ID_MATCH_VENDOR, \ | ||
51 | .idVendor = (id_vendor), \ | ||
52 | .bInterfaceClass = (cl), \ | ||
53 | .bInterfaceSubClass = (sc), \ | ||
54 | .bInterfaceProtocol = (pr), \ | ||
55 | .driver_info = (flags) \ | ||
56 | } | ||
57 | |||
44 | struct usb_device_id usb_storage_usb_ids[] = { | 58 | struct usb_device_id usb_storage_usb_ids[] = { |
45 | # include "unusual_devs.h" | 59 | # include "unusual_devs.h" |
46 | { } /* Terminating entry */ | 60 | { } /* Terminating entry */ |
@@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); | |||
50 | #undef UNUSUAL_DEV | 64 | #undef UNUSUAL_DEV |
51 | #undef COMPLIANT_DEV | 65 | #undef COMPLIANT_DEV |
52 | #undef USUAL_DEV | 66 | #undef USUAL_DEV |
67 | #undef UNUSUAL_VENDOR_INTF | ||
53 | 68 | ||
54 | /* | 69 | /* |
55 | * The table of devices to ignore | 70 | * The table of devices to ignore |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index ebd08b21b234..959b1cd89e6a 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -165,12 +165,16 @@ static void tx_poll_stop(struct vhost_net *net) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* Caller must have TX VQ lock */ | 167 | /* Caller must have TX VQ lock */ |
168 | static void tx_poll_start(struct vhost_net *net, struct socket *sock) | 168 | static int tx_poll_start(struct vhost_net *net, struct socket *sock) |
169 | { | 169 | { |
170 | int ret; | ||
171 | |||
170 | if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED)) | 172 | if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED)) |
171 | return; | 173 | return 0; |
172 | vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file); | 174 | ret = vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file); |
173 | net->tx_poll_state = VHOST_NET_POLL_STARTED; | 175 | if (!ret) |
176 | net->tx_poll_state = VHOST_NET_POLL_STARTED; | ||
177 | return ret; | ||
174 | } | 178 | } |
175 | 179 | ||
176 | /* In case of DMA done not in order in lower device driver for some reason. | 180 | /* In case of DMA done not in order in lower device driver for some reason. |
@@ -642,20 +646,23 @@ static void vhost_net_disable_vq(struct vhost_net *n, | |||
642 | vhost_poll_stop(n->poll + VHOST_NET_VQ_RX); | 646 | vhost_poll_stop(n->poll + VHOST_NET_VQ_RX); |
643 | } | 647 | } |
644 | 648 | ||
645 | static void vhost_net_enable_vq(struct vhost_net *n, | 649 | static int vhost_net_enable_vq(struct vhost_net *n, |
646 | struct vhost_virtqueue *vq) | 650 | struct vhost_virtqueue *vq) |
647 | { | 651 | { |
648 | struct socket *sock; | 652 | struct socket *sock; |
653 | int ret; | ||
649 | 654 | ||
650 | sock = rcu_dereference_protected(vq->private_data, | 655 | sock = rcu_dereference_protected(vq->private_data, |
651 | lockdep_is_held(&vq->mutex)); | 656 | lockdep_is_held(&vq->mutex)); |
652 | if (!sock) | 657 | if (!sock) |
653 | return; | 658 | return 0; |
654 | if (vq == n->vqs + VHOST_NET_VQ_TX) { | 659 | if (vq == n->vqs + VHOST_NET_VQ_TX) { |
655 | n->tx_poll_state = VHOST_NET_POLL_STOPPED; | 660 | n->tx_poll_state = VHOST_NET_POLL_STOPPED; |
656 | tx_poll_start(n, sock); | 661 | ret = tx_poll_start(n, sock); |
657 | } else | 662 | } else |
658 | vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file); | 663 | ret = vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file); |
664 | |||
665 | return ret; | ||
659 | } | 666 | } |
660 | 667 | ||
661 | static struct socket *vhost_net_stop_vq(struct vhost_net *n, | 668 | static struct socket *vhost_net_stop_vq(struct vhost_net *n, |
@@ -827,15 +834,18 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
827 | r = PTR_ERR(ubufs); | 834 | r = PTR_ERR(ubufs); |
828 | goto err_ubufs; | 835 | goto err_ubufs; |
829 | } | 836 | } |
830 | oldubufs = vq->ubufs; | 837 | |
831 | vq->ubufs = ubufs; | ||
832 | vhost_net_disable_vq(n, vq); | 838 | vhost_net_disable_vq(n, vq); |
833 | rcu_assign_pointer(vq->private_data, sock); | 839 | rcu_assign_pointer(vq->private_data, sock); |
834 | vhost_net_enable_vq(n, vq); | ||
835 | |||
836 | r = vhost_init_used(vq); | 840 | r = vhost_init_used(vq); |
837 | if (r) | 841 | if (r) |
838 | goto err_vq; | 842 | goto err_used; |
843 | r = vhost_net_enable_vq(n, vq); | ||
844 | if (r) | ||
845 | goto err_used; | ||
846 | |||
847 | oldubufs = vq->ubufs; | ||
848 | vq->ubufs = ubufs; | ||
839 | 849 | ||
840 | n->tx_packets = 0; | 850 | n->tx_packets = 0; |
841 | n->tx_zcopy_err = 0; | 851 | n->tx_zcopy_err = 0; |
@@ -859,6 +869,11 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
859 | mutex_unlock(&n->dev.mutex); | 869 | mutex_unlock(&n->dev.mutex); |
860 | return 0; | 870 | return 0; |
861 | 871 | ||
872 | err_used: | ||
873 | rcu_assign_pointer(vq->private_data, oldsock); | ||
874 | vhost_net_enable_vq(n, vq); | ||
875 | if (ubufs) | ||
876 | vhost_ubuf_put_and_wait(ubufs); | ||
862 | err_ubufs: | 877 | err_ubufs: |
863 | fput(sock->file); | 878 | fput(sock->file); |
864 | err_vq: | 879 | err_vq: |
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index b20df5c829f5..22321cf84fbe 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c | |||
@@ -575,10 +575,8 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs) | |||
575 | 575 | ||
576 | /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ | 576 | /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ |
577 | tv_tpg = vs->vs_tpg; | 577 | tv_tpg = vs->vs_tpg; |
578 | if (unlikely(!tv_tpg)) { | 578 | if (unlikely(!tv_tpg)) |
579 | pr_err("%s endpoint not set\n", __func__); | ||
580 | return; | 579 | return; |
581 | } | ||
582 | 580 | ||
583 | mutex_lock(&vq->mutex); | 581 | mutex_lock(&vq->mutex); |
584 | vhost_disable_notify(&vs->dev, vq); | 582 | vhost_disable_notify(&vs->dev, vq); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 34389f75fe65..9759249e6d90 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -77,26 +77,38 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | |||
77 | init_poll_funcptr(&poll->table, vhost_poll_func); | 77 | init_poll_funcptr(&poll->table, vhost_poll_func); |
78 | poll->mask = mask; | 78 | poll->mask = mask; |
79 | poll->dev = dev; | 79 | poll->dev = dev; |
80 | poll->wqh = NULL; | ||
80 | 81 | ||
81 | vhost_work_init(&poll->work, fn); | 82 | vhost_work_init(&poll->work, fn); |
82 | } | 83 | } |
83 | 84 | ||
84 | /* Start polling a file. We add ourselves to file's wait queue. The caller must | 85 | /* Start polling a file. We add ourselves to file's wait queue. The caller must |
85 | * keep a reference to a file until after vhost_poll_stop is called. */ | 86 | * keep a reference to a file until after vhost_poll_stop is called. */ |
86 | void vhost_poll_start(struct vhost_poll *poll, struct file *file) | 87 | int vhost_poll_start(struct vhost_poll *poll, struct file *file) |
87 | { | 88 | { |
88 | unsigned long mask; | 89 | unsigned long mask; |
90 | int ret = 0; | ||
89 | 91 | ||
90 | mask = file->f_op->poll(file, &poll->table); | 92 | mask = file->f_op->poll(file, &poll->table); |
91 | if (mask) | 93 | if (mask) |
92 | vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); | 94 | vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); |
95 | if (mask & POLLERR) { | ||
96 | if (poll->wqh) | ||
97 | remove_wait_queue(poll->wqh, &poll->wait); | ||
98 | ret = -EINVAL; | ||
99 | } | ||
100 | |||
101 | return ret; | ||
93 | } | 102 | } |
94 | 103 | ||
95 | /* Stop polling a file. After this function returns, it becomes safe to drop the | 104 | /* Stop polling a file. After this function returns, it becomes safe to drop the |
96 | * file reference. You must also flush afterwards. */ | 105 | * file reference. You must also flush afterwards. */ |
97 | void vhost_poll_stop(struct vhost_poll *poll) | 106 | void vhost_poll_stop(struct vhost_poll *poll) |
98 | { | 107 | { |
99 | remove_wait_queue(poll->wqh, &poll->wait); | 108 | if (poll->wqh) { |
109 | remove_wait_queue(poll->wqh, &poll->wait); | ||
110 | poll->wqh = NULL; | ||
111 | } | ||
100 | } | 112 | } |
101 | 113 | ||
102 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, | 114 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, |
@@ -792,7 +804,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) | |||
792 | fput(filep); | 804 | fput(filep); |
793 | 805 | ||
794 | if (pollstart && vq->handle_kick) | 806 | if (pollstart && vq->handle_kick) |
795 | vhost_poll_start(&vq->poll, vq->kick); | 807 | r = vhost_poll_start(&vq->poll, vq->kick); |
796 | 808 | ||
797 | mutex_unlock(&vq->mutex); | 809 | mutex_unlock(&vq->mutex); |
798 | 810 | ||
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 2639c58b23ab..17261e277c02 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -42,7 +42,7 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work); | |||
42 | 42 | ||
43 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | 43 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, |
44 | unsigned long mask, struct vhost_dev *dev); | 44 | unsigned long mask, struct vhost_dev *dev); |
45 | void vhost_poll_start(struct vhost_poll *poll, struct file *file); | 45 | int vhost_poll_start(struct vhost_poll *poll, struct file *file); |
46 | void vhost_poll_stop(struct vhost_poll *poll); | 46 | void vhost_poll_stop(struct vhost_poll *poll); |
47 | void vhost_poll_flush(struct vhost_poll *poll); | 47 | void vhost_poll_flush(struct vhost_poll *poll); |
48 | void vhost_poll_queue(struct vhost_poll *poll); | 48 | void vhost_poll_queue(struct vhost_poll *poll); |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 0be4df39e953..74d77dfa5f63 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -840,7 +840,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
840 | 840 | ||
841 | if (irq == -1) { | 841 | if (irq == -1) { |
842 | irq = xen_allocate_irq_dynamic(); | 842 | irq = xen_allocate_irq_dynamic(); |
843 | if (irq == -1) | 843 | if (irq < 0) |
844 | goto out; | 844 | goto out; |
845 | 845 | ||
846 | irq_set_chip_and_handler_name(irq, &xen_dynamic_chip, | 846 | irq_set_chip_and_handler_name(irq, &xen_dynamic_chip, |
@@ -944,7 +944,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
944 | 944 | ||
945 | if (irq == -1) { | 945 | if (irq == -1) { |
946 | irq = xen_allocate_irq_dynamic(); | 946 | irq = xen_allocate_irq_dynamic(); |
947 | if (irq == -1) | 947 | if (irq < 0) |
948 | goto out; | 948 | goto out; |
949 | 949 | ||
950 | irq_set_chip_and_handler_name(irq, &xen_percpu_chip, | 950 | irq_set_chip_and_handler_name(irq, &xen_percpu_chip, |
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index 97f5d264c31e..37c1f825f513 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c | |||
@@ -135,7 +135,6 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, | |||
135 | struct pci_dev *dev, struct xen_pci_op *op) | 135 | struct pci_dev *dev, struct xen_pci_op *op) |
136 | { | 136 | { |
137 | struct xen_pcibk_dev_data *dev_data; | 137 | struct xen_pcibk_dev_data *dev_data; |
138 | int otherend = pdev->xdev->otherend_id; | ||
139 | int status; | 138 | int status; |
140 | 139 | ||
141 | if (unlikely(verbose_request)) | 140 | if (unlikely(verbose_request)) |
@@ -144,8 +143,9 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, | |||
144 | status = pci_enable_msi(dev); | 143 | status = pci_enable_msi(dev); |
145 | 144 | ||
146 | if (status) { | 145 | if (status) { |
147 | printk(KERN_ERR "error enable msi for guest %x status %x\n", | 146 | pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI for guest %u: err %d\n", |
148 | otherend, status); | 147 | pci_name(dev), pdev->xdev->otherend_id, |
148 | status); | ||
149 | op->value = 0; | 149 | op->value = 0; |
150 | return XEN_PCI_ERR_op_failed; | 150 | return XEN_PCI_ERR_op_failed; |
151 | } | 151 | } |
@@ -223,10 +223,10 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, | |||
223 | pci_name(dev), i, | 223 | pci_name(dev), i, |
224 | op->msix_entries[i].vector); | 224 | op->msix_entries[i].vector); |
225 | } | 225 | } |
226 | } else { | 226 | } else |
227 | printk(KERN_WARNING DRV_NAME ": %s: failed to enable MSI-X: err %d!\n", | 227 | pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI-X for guest %u: err %d!\n", |
228 | pci_name(dev), result); | 228 | pci_name(dev), pdev->xdev->otherend_id, |
229 | } | 229 | result); |
230 | kfree(entries); | 230 | kfree(entries); |
231 | 231 | ||
232 | op->value = result; | 232 | op->value = result; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a8b8adc05070..5a3327b8f90d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4534,7 +4534,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4534 | unsigned nr_extents = 0; | 4534 | unsigned nr_extents = 0; |
4535 | int extra_reserve = 0; | 4535 | int extra_reserve = 0; |
4536 | enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL; | 4536 | enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL; |
4537 | int ret; | 4537 | int ret = 0; |
4538 | bool delalloc_lock = true; | 4538 | bool delalloc_lock = true; |
4539 | 4539 | ||
4540 | /* If we are a free space inode we need to not flush since we will be in | 4540 | /* If we are a free space inode we need to not flush since we will be in |
@@ -4579,20 +4579,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4579 | csum_bytes = BTRFS_I(inode)->csum_bytes; | 4579 | csum_bytes = BTRFS_I(inode)->csum_bytes; |
4580 | spin_unlock(&BTRFS_I(inode)->lock); | 4580 | spin_unlock(&BTRFS_I(inode)->lock); |
4581 | 4581 | ||
4582 | if (root->fs_info->quota_enabled) { | 4582 | if (root->fs_info->quota_enabled) |
4583 | ret = btrfs_qgroup_reserve(root, num_bytes + | 4583 | ret = btrfs_qgroup_reserve(root, num_bytes + |
4584 | nr_extents * root->leafsize); | 4584 | nr_extents * root->leafsize); |
4585 | if (ret) { | ||
4586 | spin_lock(&BTRFS_I(inode)->lock); | ||
4587 | calc_csum_metadata_size(inode, num_bytes, 0); | ||
4588 | spin_unlock(&BTRFS_I(inode)->lock); | ||
4589 | if (delalloc_lock) | ||
4590 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
4591 | return ret; | ||
4592 | } | ||
4593 | } | ||
4594 | 4585 | ||
4595 | ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); | 4586 | /* |
4587 | * ret != 0 here means the qgroup reservation failed, we go straight to | ||
4588 | * the shared error handling then. | ||
4589 | */ | ||
4590 | if (ret == 0) | ||
4591 | ret = reserve_metadata_bytes(root, block_rsv, | ||
4592 | to_reserve, flush); | ||
4593 | |||
4596 | if (ret) { | 4594 | if (ret) { |
4597 | u64 to_free = 0; | 4595 | u64 to_free = 0; |
4598 | unsigned dropped; | 4596 | unsigned dropped; |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 2e8cae63d247..fdb7a8db3b57 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -288,7 +288,8 @@ out: | |||
288 | void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) | 288 | void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em) |
289 | { | 289 | { |
290 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); | 290 | clear_bit(EXTENT_FLAG_LOGGING, &em->flags); |
291 | try_merge_map(tree, em); | 291 | if (em->in_tree) |
292 | try_merge_map(tree, em); | ||
292 | } | 293 | } |
293 | 294 | ||
294 | /** | 295 | /** |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f76b1fd160d4..aeb84469d2c4 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -293,15 +293,24 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, | |||
293 | struct btrfs_key key; | 293 | struct btrfs_key key; |
294 | struct btrfs_ioctl_defrag_range_args range; | 294 | struct btrfs_ioctl_defrag_range_args range; |
295 | int num_defrag; | 295 | int num_defrag; |
296 | int index; | ||
297 | int ret; | ||
296 | 298 | ||
297 | /* get the inode */ | 299 | /* get the inode */ |
298 | key.objectid = defrag->root; | 300 | key.objectid = defrag->root; |
299 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 301 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
300 | key.offset = (u64)-1; | 302 | key.offset = (u64)-1; |
303 | |||
304 | index = srcu_read_lock(&fs_info->subvol_srcu); | ||
305 | |||
301 | inode_root = btrfs_read_fs_root_no_name(fs_info, &key); | 306 | inode_root = btrfs_read_fs_root_no_name(fs_info, &key); |
302 | if (IS_ERR(inode_root)) { | 307 | if (IS_ERR(inode_root)) { |
303 | kmem_cache_free(btrfs_inode_defrag_cachep, defrag); | 308 | ret = PTR_ERR(inode_root); |
304 | return PTR_ERR(inode_root); | 309 | goto cleanup; |
310 | } | ||
311 | if (btrfs_root_refs(&inode_root->root_item) == 0) { | ||
312 | ret = -ENOENT; | ||
313 | goto cleanup; | ||
305 | } | 314 | } |
306 | 315 | ||
307 | key.objectid = defrag->ino; | 316 | key.objectid = defrag->ino; |
@@ -309,9 +318,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, | |||
309 | key.offset = 0; | 318 | key.offset = 0; |
310 | inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL); | 319 | inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL); |
311 | if (IS_ERR(inode)) { | 320 | if (IS_ERR(inode)) { |
312 | kmem_cache_free(btrfs_inode_defrag_cachep, defrag); | 321 | ret = PTR_ERR(inode); |
313 | return PTR_ERR(inode); | 322 | goto cleanup; |
314 | } | 323 | } |
324 | srcu_read_unlock(&fs_info->subvol_srcu, index); | ||
315 | 325 | ||
316 | /* do a chunk of defrag */ | 326 | /* do a chunk of defrag */ |
317 | clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags); | 327 | clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags); |
@@ -346,6 +356,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info, | |||
346 | 356 | ||
347 | iput(inode); | 357 | iput(inode); |
348 | return 0; | 358 | return 0; |
359 | cleanup: | ||
360 | srcu_read_unlock(&fs_info->subvol_srcu, index); | ||
361 | kmem_cache_free(btrfs_inode_defrag_cachep, defrag); | ||
362 | return ret; | ||
349 | } | 363 | } |
350 | 364 | ||
351 | /* | 365 | /* |
@@ -1594,9 +1608,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1594 | if (err < 0 && num_written > 0) | 1608 | if (err < 0 && num_written > 0) |
1595 | num_written = err; | 1609 | num_written = err; |
1596 | } | 1610 | } |
1597 | out: | 1611 | |
1598 | if (sync) | 1612 | if (sync) |
1599 | atomic_dec(&BTRFS_I(inode)->sync_writers); | 1613 | atomic_dec(&BTRFS_I(inode)->sync_writers); |
1614 | out: | ||
1600 | sb_end_write(inode->i_sb); | 1615 | sb_end_write(inode->i_sb); |
1601 | current->backing_dev_info = NULL; | 1616 | current->backing_dev_info = NULL; |
1602 | return num_written ? num_written : err; | 1617 | return num_written ? num_written : err; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 5b22d45d3c6a..338f2597bf7f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -515,7 +515,6 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
515 | 515 | ||
516 | BUG_ON(ret); | 516 | BUG_ON(ret); |
517 | 517 | ||
518 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | ||
519 | fail: | 518 | fail: |
520 | if (async_transid) { | 519 | if (async_transid) { |
521 | *async_transid = trans->transid; | 520 | *async_transid = trans->transid; |
@@ -525,6 +524,10 @@ fail: | |||
525 | } | 524 | } |
526 | if (err && !ret) | 525 | if (err && !ret) |
527 | ret = err; | 526 | ret = err; |
527 | |||
528 | if (!ret) | ||
529 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | ||
530 | |||
528 | return ret; | 531 | return ret; |
529 | } | 532 | } |
530 | 533 | ||
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index f10731297040..e5ed56729607 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -836,9 +836,16 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
836 | * if the disk i_size is already at the inode->i_size, or | 836 | * if the disk i_size is already at the inode->i_size, or |
837 | * this ordered extent is inside the disk i_size, we're done | 837 | * this ordered extent is inside the disk i_size, we're done |
838 | */ | 838 | */ |
839 | if (disk_i_size == i_size || offset <= disk_i_size) { | 839 | if (disk_i_size == i_size) |
840 | goto out; | ||
841 | |||
842 | /* | ||
843 | * We still need to update disk_i_size if outstanding_isize is greater | ||
844 | * than disk_i_size. | ||
845 | */ | ||
846 | if (offset <= disk_i_size && | ||
847 | (!ordered || ordered->outstanding_isize <= disk_i_size)) | ||
840 | goto out; | 848 | goto out; |
841 | } | ||
842 | 849 | ||
843 | /* | 850 | /* |
844 | * walk backward from this ordered extent to disk_i_size. | 851 | * walk backward from this ordered extent to disk_i_size. |
@@ -870,7 +877,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, | |||
870 | break; | 877 | break; |
871 | if (test->file_offset >= i_size) | 878 | if (test->file_offset >= i_size) |
872 | break; | 879 | break; |
873 | if (test->file_offset >= disk_i_size) { | 880 | if (entry_end(test) > disk_i_size) { |
874 | /* | 881 | /* |
875 | * we don't update disk_i_size now, so record this | 882 | * we don't update disk_i_size now, so record this |
876 | * undealt i_size. Or we will not know the real | 883 | * undealt i_size. Or we will not know the real |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index bdbb94f245c9..67783e03d121 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -580,20 +580,29 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx) | |||
580 | int corrected = 0; | 580 | int corrected = 0; |
581 | struct btrfs_key key; | 581 | struct btrfs_key key; |
582 | struct inode *inode = NULL; | 582 | struct inode *inode = NULL; |
583 | struct btrfs_fs_info *fs_info; | ||
583 | u64 end = offset + PAGE_SIZE - 1; | 584 | u64 end = offset + PAGE_SIZE - 1; |
584 | struct btrfs_root *local_root; | 585 | struct btrfs_root *local_root; |
586 | int srcu_index; | ||
585 | 587 | ||
586 | key.objectid = root; | 588 | key.objectid = root; |
587 | key.type = BTRFS_ROOT_ITEM_KEY; | 589 | key.type = BTRFS_ROOT_ITEM_KEY; |
588 | key.offset = (u64)-1; | 590 | key.offset = (u64)-1; |
589 | local_root = btrfs_read_fs_root_no_name(fixup->root->fs_info, &key); | 591 | |
590 | if (IS_ERR(local_root)) | 592 | fs_info = fixup->root->fs_info; |
593 | srcu_index = srcu_read_lock(&fs_info->subvol_srcu); | ||
594 | |||
595 | local_root = btrfs_read_fs_root_no_name(fs_info, &key); | ||
596 | if (IS_ERR(local_root)) { | ||
597 | srcu_read_unlock(&fs_info->subvol_srcu, srcu_index); | ||
591 | return PTR_ERR(local_root); | 598 | return PTR_ERR(local_root); |
599 | } | ||
592 | 600 | ||
593 | key.type = BTRFS_INODE_ITEM_KEY; | 601 | key.type = BTRFS_INODE_ITEM_KEY; |
594 | key.objectid = inum; | 602 | key.objectid = inum; |
595 | key.offset = 0; | 603 | key.offset = 0; |
596 | inode = btrfs_iget(fixup->root->fs_info->sb, &key, local_root, NULL); | 604 | inode = btrfs_iget(fs_info->sb, &key, local_root, NULL); |
605 | srcu_read_unlock(&fs_info->subvol_srcu, srcu_index); | ||
597 | if (IS_ERR(inode)) | 606 | if (IS_ERR(inode)) |
598 | return PTR_ERR(inode); | 607 | return PTR_ERR(inode); |
599 | 608 | ||
@@ -606,7 +615,6 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx) | |||
606 | } | 615 | } |
607 | 616 | ||
608 | if (PageUptodate(page)) { | 617 | if (PageUptodate(page)) { |
609 | struct btrfs_fs_info *fs_info; | ||
610 | if (PageDirty(page)) { | 618 | if (PageDirty(page)) { |
611 | /* | 619 | /* |
612 | * we need to write the data to the defect sector. the | 620 | * we need to write the data to the defect sector. the |
@@ -3180,18 +3188,25 @@ static int copy_nocow_pages_for_inode(u64 inum, u64 offset, u64 root, void *ctx) | |||
3180 | u64 physical_for_dev_replace; | 3188 | u64 physical_for_dev_replace; |
3181 | u64 len; | 3189 | u64 len; |
3182 | struct btrfs_fs_info *fs_info = nocow_ctx->sctx->dev_root->fs_info; | 3190 | struct btrfs_fs_info *fs_info = nocow_ctx->sctx->dev_root->fs_info; |
3191 | int srcu_index; | ||
3183 | 3192 | ||
3184 | key.objectid = root; | 3193 | key.objectid = root; |
3185 | key.type = BTRFS_ROOT_ITEM_KEY; | 3194 | key.type = BTRFS_ROOT_ITEM_KEY; |
3186 | key.offset = (u64)-1; | 3195 | key.offset = (u64)-1; |
3196 | |||
3197 | srcu_index = srcu_read_lock(&fs_info->subvol_srcu); | ||
3198 | |||
3187 | local_root = btrfs_read_fs_root_no_name(fs_info, &key); | 3199 | local_root = btrfs_read_fs_root_no_name(fs_info, &key); |
3188 | if (IS_ERR(local_root)) | 3200 | if (IS_ERR(local_root)) { |
3201 | srcu_read_unlock(&fs_info->subvol_srcu, srcu_index); | ||
3189 | return PTR_ERR(local_root); | 3202 | return PTR_ERR(local_root); |
3203 | } | ||
3190 | 3204 | ||
3191 | key.type = BTRFS_INODE_ITEM_KEY; | 3205 | key.type = BTRFS_INODE_ITEM_KEY; |
3192 | key.objectid = inum; | 3206 | key.objectid = inum; |
3193 | key.offset = 0; | 3207 | key.offset = 0; |
3194 | inode = btrfs_iget(fs_info->sb, &key, local_root, NULL); | 3208 | inode = btrfs_iget(fs_info->sb, &key, local_root, NULL); |
3209 | srcu_read_unlock(&fs_info->subvol_srcu, srcu_index); | ||
3195 | if (IS_ERR(inode)) | 3210 | if (IS_ERR(inode)) |
3196 | return PTR_ERR(inode); | 3211 | return PTR_ERR(inode); |
3197 | 3212 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f15494699f3b..fc03aa60b684 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -333,12 +333,14 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type, | |||
333 | &root->fs_info->trans_block_rsv, | 333 | &root->fs_info->trans_block_rsv, |
334 | num_bytes, flush); | 334 | num_bytes, flush); |
335 | if (ret) | 335 | if (ret) |
336 | return ERR_PTR(ret); | 336 | goto reserve_fail; |
337 | } | 337 | } |
338 | again: | 338 | again: |
339 | h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); | 339 | h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); |
340 | if (!h) | 340 | if (!h) { |
341 | return ERR_PTR(-ENOMEM); | 341 | ret = -ENOMEM; |
342 | goto alloc_fail; | ||
343 | } | ||
342 | 344 | ||
343 | /* | 345 | /* |
344 | * If we are JOIN_NOLOCK we're already committing a transaction and | 346 | * If we are JOIN_NOLOCK we're already committing a transaction and |
@@ -365,11 +367,7 @@ again: | |||
365 | if (ret < 0) { | 367 | if (ret < 0) { |
366 | /* We must get the transaction if we are JOIN_NOLOCK. */ | 368 | /* We must get the transaction if we are JOIN_NOLOCK. */ |
367 | BUG_ON(type == TRANS_JOIN_NOLOCK); | 369 | BUG_ON(type == TRANS_JOIN_NOLOCK); |
368 | 370 | goto join_fail; | |
369 | if (type < TRANS_JOIN_NOLOCK) | ||
370 | sb_end_intwrite(root->fs_info->sb); | ||
371 | kmem_cache_free(btrfs_trans_handle_cachep, h); | ||
372 | return ERR_PTR(ret); | ||
373 | } | 371 | } |
374 | 372 | ||
375 | cur_trans = root->fs_info->running_transaction; | 373 | cur_trans = root->fs_info->running_transaction; |
@@ -410,6 +408,19 @@ got_it: | |||
410 | if (!current->journal_info && type != TRANS_USERSPACE) | 408 | if (!current->journal_info && type != TRANS_USERSPACE) |
411 | current->journal_info = h; | 409 | current->journal_info = h; |
412 | return h; | 410 | return h; |
411 | |||
412 | join_fail: | ||
413 | if (type < TRANS_JOIN_NOLOCK) | ||
414 | sb_end_intwrite(root->fs_info->sb); | ||
415 | kmem_cache_free(btrfs_trans_handle_cachep, h); | ||
416 | alloc_fail: | ||
417 | if (num_bytes) | ||
418 | btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv, | ||
419 | num_bytes); | ||
420 | reserve_fail: | ||
421 | if (qgroup_reserved) | ||
422 | btrfs_qgroup_free(root, qgroup_reserved); | ||
423 | return ERR_PTR(ret); | ||
413 | } | 424 | } |
414 | 425 | ||
415 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | 426 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 15f6efdf6463..5cbb7f4b1672 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1556,7 +1556,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1556 | ret = 0; | 1556 | ret = 0; |
1557 | 1557 | ||
1558 | /* Notify udev that device has changed */ | 1558 | /* Notify udev that device has changed */ |
1559 | btrfs_kobject_uevent(bdev, KOBJ_CHANGE); | 1559 | if (bdev) |
1560 | btrfs_kobject_uevent(bdev, KOBJ_CHANGE); | ||
1560 | 1561 | ||
1561 | error_brelse: | 1562 | error_brelse: |
1562 | brelse(bh); | 1563 | brelse(bh); |
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 7ff49852b0cb..911649a47dd5 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -503,11 +503,11 @@ static ssize_t device_write(struct file *file, const char __user *buf, | |||
503 | #endif | 503 | #endif |
504 | return -EINVAL; | 504 | return -EINVAL; |
505 | 505 | ||
506 | #ifdef CONFIG_COMPAT | 506 | /* |
507 | if (count > sizeof(struct dlm_write_request32) + DLM_RESNAME_MAXLEN) | 507 | * can't compare against COMPAT/dlm_write_request32 because |
508 | #else | 508 | * we don't yet know if is64bit is zero |
509 | */ | ||
509 | if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN) | 510 | if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN) |
510 | #endif | ||
511 | return -EINVAL; | 511 | return -EINVAL; |
512 | 512 | ||
513 | kbuf = kzalloc(count + 1, GFP_NOFS); | 513 | kbuf = kzalloc(count + 1, GFP_NOFS); |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index fdb180769485..f3859354e41a 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -664,8 +664,11 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, | |||
664 | if (ret < 0) | 664 | if (ret < 0) |
665 | printk(KERN_ERR "NILFS: GC failed during preparation: " | 665 | printk(KERN_ERR "NILFS: GC failed during preparation: " |
666 | "cannot read source blocks: err=%d\n", ret); | 666 | "cannot read source blocks: err=%d\n", ret); |
667 | else | 667 | else { |
668 | if (nilfs_sb_need_update(nilfs)) | ||
669 | set_nilfs_discontinued(nilfs); | ||
668 | ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); | 670 | ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); |
671 | } | ||
669 | 672 | ||
670 | nilfs_remove_all_gcinodes(nilfs); | 673 | nilfs_remove_all_gcinodes(nilfs); |
671 | clear_nilfs_gc_running(nilfs); | 674 | clear_nilfs_gc_running(nilfs); |
diff --git a/include/linux/llist.h b/include/linux/llist.h index a5199f6d0e82..d0ab98f73d38 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h | |||
@@ -125,6 +125,31 @@ static inline void init_llist_head(struct llist_head *list) | |||
125 | (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) | 125 | (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) |
126 | 126 | ||
127 | /** | 127 | /** |
128 | * llist_for_each_entry_safe - iterate safely against remove over some entries | ||
129 | * of lock-less list of given type. | ||
130 | * @pos: the type * to use as a loop cursor. | ||
131 | * @n: another type * to use as a temporary storage. | ||
132 | * @node: the fist entry of deleted list entries. | ||
133 | * @member: the name of the llist_node with the struct. | ||
134 | * | ||
135 | * In general, some entries of the lock-less list can be traversed | ||
136 | * safely only after being removed from list, so start with an entry | ||
137 | * instead of list head. This variant allows removal of entries | ||
138 | * as we iterate. | ||
139 | * | ||
140 | * If being used on entries deleted from lock-less list directly, the | ||
141 | * traverse order is from the newest to the oldest added entry. If | ||
142 | * you want to traverse from the oldest to the newest, you must | ||
143 | * reverse the order by yourself before traversing. | ||
144 | */ | ||
145 | #define llist_for_each_entry_safe(pos, n, node, member) \ | ||
146 | for ((pos) = llist_entry((node), typeof(*(pos)), member), \ | ||
147 | (n) = (pos)->member.next; \ | ||
148 | &(pos)->member != NULL; \ | ||
149 | (pos) = llist_entry(n, typeof(*(pos)), member), \ | ||
150 | (n) = (&(pos)->member != NULL) ? (pos)->member.next : NULL) | ||
151 | |||
152 | /** | ||
128 | * llist_empty - tests whether a lock-less list is empty | 153 | * llist_empty - tests whether a lock-less list is empty |
129 | * @head: the list to test | 154 | * @head: the list to test |
130 | * | 155 | * |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 0108a56f814e..28bd5fa2ff2e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -429,7 +429,7 @@ extern int memcg_limited_groups_array_size; | |||
429 | * the slab_mutex must be held when looping through those caches | 429 | * the slab_mutex must be held when looping through those caches |
430 | */ | 430 | */ |
431 | #define for_each_memcg_cache_index(_idx) \ | 431 | #define for_each_memcg_cache_index(_idx) \ |
432 | for ((_idx) = 0; i < memcg_limited_groups_array_size; (_idx)++) | 432 | for ((_idx) = 0; (_idx) < memcg_limited_groups_array_size; (_idx)++) |
433 | 433 | ||
434 | static inline bool memcg_kmem_enabled(void) | 434 | static inline bool memcg_kmem_enabled(void) |
435 | { | 435 | { |
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index bc823c4c028b..deca87452528 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h | |||
@@ -151,7 +151,7 @@ struct mmu_notifier_ops { | |||
151 | * Therefore notifier chains can only be traversed when either | 151 | * Therefore notifier chains can only be traversed when either |
152 | * | 152 | * |
153 | * 1. mmap_sem is held. | 153 | * 1. mmap_sem is held. |
154 | * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->mutex). | 154 | * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->rwsem). |
155 | * 3. No other concurrent thread can access the list (release) | 155 | * 3. No other concurrent thread can access the list (release) |
156 | */ | 156 | */ |
157 | struct mmu_notifier { | 157 | struct mmu_notifier { |
diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h index 6b05dcd927ff..6d92a92573df 100644 --- a/include/linux/ssb/ssb_driver_gige.h +++ b/include/linux/ssb/ssb_driver_gige.h | |||
@@ -98,14 +98,14 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev) | |||
98 | } | 98 | } |
99 | 99 | ||
100 | #ifdef CONFIG_BCM47XX | 100 | #ifdef CONFIG_BCM47XX |
101 | #include <asm/mach-bcm47xx/nvram.h> | 101 | #include <bcm47xx_nvram.h> |
102 | /* Get the device MAC address */ | 102 | /* Get the device MAC address */ |
103 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | 103 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) |
104 | { | 104 | { |
105 | char buf[20]; | 105 | char buf[20]; |
106 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0) | 106 | if (bcm47xx_nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0) |
107 | return; | 107 | return; |
108 | nvram_parse_macaddr(buf, macaddr); | 108 | bcm47xx_nvram_parse_macaddr(buf, macaddr); |
109 | } | 109 | } |
110 | #else | 110 | #else |
111 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | 111 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 689b14b26c8d..4d22d0f6167a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -357,6 +357,8 @@ struct usb_bus { | |||
357 | int bandwidth_int_reqs; /* number of Interrupt requests */ | 357 | int bandwidth_int_reqs; /* number of Interrupt requests */ |
358 | int bandwidth_isoc_reqs; /* number of Isoc. requests */ | 358 | int bandwidth_isoc_reqs; /* number of Isoc. requests */ |
359 | 359 | ||
360 | unsigned resuming_ports; /* bit array: resuming root-hub ports */ | ||
361 | |||
360 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) | 362 | #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) |
361 | struct mon_bus *mon_bus; /* non-null when associated */ | 363 | struct mon_bus *mon_bus; /* non-null when associated */ |
362 | int monitored; /* non-zero when monitored */ | 364 | int monitored; /* non-zero when monitored */ |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 608050b2545f..0a78df5f6cfd 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -430,6 +430,9 @@ extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); | |||
430 | extern void usb_wakeup_notification(struct usb_device *hdev, | 430 | extern void usb_wakeup_notification(struct usb_device *hdev, |
431 | unsigned int portnum); | 431 | unsigned int portnum); |
432 | 432 | ||
433 | extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum); | ||
434 | extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum); | ||
435 | |||
433 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ | 436 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ |
434 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) | 437 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) |
435 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) | 438 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) |
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 5de7a220e986..0e5ac93bab10 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h | |||
@@ -33,6 +33,7 @@ struct usbnet { | |||
33 | wait_queue_head_t *wait; | 33 | wait_queue_head_t *wait; |
34 | struct mutex phy_mutex; | 34 | struct mutex phy_mutex; |
35 | unsigned char suspend_count; | 35 | unsigned char suspend_count; |
36 | unsigned char pkt_cnt, pkt_err; | ||
36 | 37 | ||
37 | /* i/o info: pipes etc */ | 38 | /* i/o info: pipes etc */ |
38 | unsigned in, out; | 39 | unsigned in, out; |
@@ -70,6 +71,7 @@ struct usbnet { | |||
70 | # define EVENT_DEV_OPEN 7 | 71 | # define EVENT_DEV_OPEN 7 |
71 | # define EVENT_DEVICE_REPORT_IDLE 8 | 72 | # define EVENT_DEVICE_REPORT_IDLE 8 |
72 | # define EVENT_NO_RUNTIME_PM 9 | 73 | # define EVENT_NO_RUNTIME_PM 9 |
74 | # define EVENT_RX_KILL 10 | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | static inline struct usb_driver *driver_of(struct usb_interface *intf) | 77 | static inline struct usb_driver *driver_of(struct usb_interface *intf) |
@@ -100,7 +102,6 @@ struct driver_info { | |||
100 | #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ | 102 | #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ |
101 | 103 | ||
102 | #define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ | 104 | #define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ |
103 | #define FLAG_NOARP 0x2000 /* device can't do ARP */ | ||
104 | 105 | ||
105 | /* | 106 | /* |
106 | * Indicates to usbnet, that USB driver accumulates multiple IP packets. | 107 | * Indicates to usbnet, that USB driver accumulates multiple IP packets. |
@@ -108,6 +109,7 @@ struct driver_info { | |||
108 | */ | 109 | */ |
109 | #define FLAG_MULTI_PACKET 0x2000 | 110 | #define FLAG_MULTI_PACKET 0x2000 |
110 | #define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */ | 111 | #define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */ |
112 | #define FLAG_NOARP 0x8000 /* device can't do ARP */ | ||
111 | 113 | ||
112 | /* init device ... can sleep, or cause probe() failure */ | 114 | /* init device ... can sleep, or cause probe() failure */ |
113 | int (*bind)(struct usbnet *, struct usb_interface *); | 115 | int (*bind)(struct usbnet *, struct usb_interface *); |
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index 498433dd067d..938b7fd11204 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h | |||
@@ -34,17 +34,17 @@ extern int udpv6_connect(struct sock *sk, | |||
34 | struct sockaddr *uaddr, | 34 | struct sockaddr *uaddr, |
35 | int addr_len); | 35 | int addr_len); |
36 | 36 | ||
37 | extern int datagram_recv_ctl(struct sock *sk, | 37 | extern int ip6_datagram_recv_ctl(struct sock *sk, |
38 | struct msghdr *msg, | 38 | struct msghdr *msg, |
39 | struct sk_buff *skb); | 39 | struct sk_buff *skb); |
40 | 40 | ||
41 | extern int datagram_send_ctl(struct net *net, | 41 | extern int ip6_datagram_send_ctl(struct net *net, |
42 | struct sock *sk, | 42 | struct sock *sk, |
43 | struct msghdr *msg, | 43 | struct msghdr *msg, |
44 | struct flowi6 *fl6, | 44 | struct flowi6 *fl6, |
45 | struct ipv6_txoptions *opt, | 45 | struct ipv6_txoptions *opt, |
46 | int *hlimit, int *tclass, | 46 | int *hlimit, int *tclass, |
47 | int *dontfrag); | 47 | int *dontfrag); |
48 | 48 | ||
49 | #define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006) | 49 | #define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006) |
50 | 50 | ||
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index 50598472dc41..f738e25377ff 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h | |||
@@ -152,6 +152,12 @@ | |||
152 | #define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0)) | 152 | #define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0)) |
153 | #define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1)) | 153 | #define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1)) |
154 | 154 | ||
155 | /* | ||
156 | * Interface status, Figure 9-5 USB 3.0 spec | ||
157 | */ | ||
158 | #define USB_INTRF_STAT_FUNC_RW_CAP 1 | ||
159 | #define USB_INTRF_STAT_FUNC_RW 2 | ||
160 | |||
155 | #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ | 161 | #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ |
156 | 162 | ||
157 | /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ | 163 | /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 301079d06f24..7b6646a8c067 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -908,6 +908,15 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) | |||
908 | } | 908 | } |
909 | 909 | ||
910 | /* | 910 | /* |
911 | * Initialize event state based on the perf_event_attr::disabled. | ||
912 | */ | ||
913 | static inline void perf_event__state_init(struct perf_event *event) | ||
914 | { | ||
915 | event->state = event->attr.disabled ? PERF_EVENT_STATE_OFF : | ||
916 | PERF_EVENT_STATE_INACTIVE; | ||
917 | } | ||
918 | |||
919 | /* | ||
911 | * Called at perf_event creation and when events are attached/detached from a | 920 | * Called at perf_event creation and when events are attached/detached from a |
912 | * group. | 921 | * group. |
913 | */ | 922 | */ |
@@ -6179,8 +6188,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
6179 | event->overflow_handler = overflow_handler; | 6188 | event->overflow_handler = overflow_handler; |
6180 | event->overflow_handler_context = context; | 6189 | event->overflow_handler_context = context; |
6181 | 6190 | ||
6182 | if (attr->disabled) | 6191 | perf_event__state_init(event); |
6183 | event->state = PERF_EVENT_STATE_OFF; | ||
6184 | 6192 | ||
6185 | pmu = NULL; | 6193 | pmu = NULL; |
6186 | 6194 | ||
@@ -6609,9 +6617,17 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6609 | 6617 | ||
6610 | mutex_lock(&gctx->mutex); | 6618 | mutex_lock(&gctx->mutex); |
6611 | perf_remove_from_context(group_leader); | 6619 | perf_remove_from_context(group_leader); |
6620 | |||
6621 | /* | ||
6622 | * Removing from the context ends up with disabled | ||
6623 | * event. What we want here is event in the initial | ||
6624 | * startup state, ready to be add into new context. | ||
6625 | */ | ||
6626 | perf_event__state_init(group_leader); | ||
6612 | list_for_each_entry(sibling, &group_leader->sibling_list, | 6627 | list_for_each_entry(sibling, &group_leader->sibling_list, |
6613 | group_entry) { | 6628 | group_entry) { |
6614 | perf_remove_from_context(sibling); | 6629 | perf_remove_from_context(sibling); |
6630 | perf_event__state_init(sibling); | ||
6615 | put_ctx(gctx); | 6631 | put_ctx(gctx); |
6616 | } | 6632 | } |
6617 | mutex_unlock(&gctx->mutex); | 6633 | mutex_unlock(&gctx->mutex); |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index f6e5ec2932b4..c1cc7e17ff9d 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -40,8 +40,7 @@ | |||
40 | #ifdef CONFIG_RCU_NOCB_CPU | 40 | #ifdef CONFIG_RCU_NOCB_CPU |
41 | static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ | 41 | static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ |
42 | static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ | 42 | static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ |
43 | static bool rcu_nocb_poll; /* Offload kthread are to poll. */ | 43 | static bool __read_mostly rcu_nocb_poll; /* Offload kthread are to poll. */ |
44 | module_param(rcu_nocb_poll, bool, 0444); | ||
45 | static char __initdata nocb_buf[NR_CPUS * 5]; | 44 | static char __initdata nocb_buf[NR_CPUS * 5]; |
46 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ | 45 | #endif /* #ifdef CONFIG_RCU_NOCB_CPU */ |
47 | 46 | ||
@@ -2159,6 +2158,13 @@ static int __init rcu_nocb_setup(char *str) | |||
2159 | } | 2158 | } |
2160 | __setup("rcu_nocbs=", rcu_nocb_setup); | 2159 | __setup("rcu_nocbs=", rcu_nocb_setup); |
2161 | 2160 | ||
2161 | static int __init parse_rcu_nocb_poll(char *arg) | ||
2162 | { | ||
2163 | rcu_nocb_poll = 1; | ||
2164 | return 0; | ||
2165 | } | ||
2166 | early_param("rcu_nocb_poll", parse_rcu_nocb_poll); | ||
2167 | |||
2162 | /* Is the specified CPU a no-CPUs CPU? */ | 2168 | /* Is the specified CPU a no-CPUs CPU? */ |
2163 | static bool is_nocb_cpu(int cpu) | 2169 | static bool is_nocb_cpu(int cpu) |
2164 | { | 2170 | { |
@@ -2366,10 +2372,11 @@ static int rcu_nocb_kthread(void *arg) | |||
2366 | for (;;) { | 2372 | for (;;) { |
2367 | /* If not polling, wait for next batch of callbacks. */ | 2373 | /* If not polling, wait for next batch of callbacks. */ |
2368 | if (!rcu_nocb_poll) | 2374 | if (!rcu_nocb_poll) |
2369 | wait_event(rdp->nocb_wq, rdp->nocb_head); | 2375 | wait_event_interruptible(rdp->nocb_wq, rdp->nocb_head); |
2370 | list = ACCESS_ONCE(rdp->nocb_head); | 2376 | list = ACCESS_ONCE(rdp->nocb_head); |
2371 | if (!list) { | 2377 | if (!list) { |
2372 | schedule_timeout_interruptible(1); | 2378 | schedule_timeout_interruptible(1); |
2379 | flush_signals(current); | ||
2373 | continue; | 2380 | continue; |
2374 | } | 2381 | } |
2375 | 2382 | ||
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 2cd3c1b4e582..7ae4c4c5420e 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c | |||
@@ -222,8 +222,8 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) | |||
222 | cfs_rq->runnable_load_avg); | 222 | cfs_rq->runnable_load_avg); |
223 | SEQ_printf(m, " .%-30s: %lld\n", "blocked_load_avg", | 223 | SEQ_printf(m, " .%-30s: %lld\n", "blocked_load_avg", |
224 | cfs_rq->blocked_load_avg); | 224 | cfs_rq->blocked_load_avg); |
225 | SEQ_printf(m, " .%-30s: %ld\n", "tg_load_avg", | 225 | SEQ_printf(m, " .%-30s: %lld\n", "tg_load_avg", |
226 | atomic64_read(&cfs_rq->tg->load_avg)); | 226 | (unsigned long long)atomic64_read(&cfs_rq->tg->load_avg)); |
227 | SEQ_printf(m, " .%-30s: %lld\n", "tg_load_contrib", | 227 | SEQ_printf(m, " .%-30s: %lld\n", "tg_load_contrib", |
228 | cfs_rq->tg_load_contrib); | 228 | cfs_rq->tg_load_contrib); |
229 | SEQ_printf(m, " .%-30s: %d\n", "tg_runnable_contrib", | 229 | SEQ_printf(m, " .%-30s: %d\n", "tg_runnable_contrib", |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5eea8707234a..81fa53643409 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -2663,7 +2663,7 @@ static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) | |||
2663 | hrtimer_cancel(&cfs_b->slack_timer); | 2663 | hrtimer_cancel(&cfs_b->slack_timer); |
2664 | } | 2664 | } |
2665 | 2665 | ||
2666 | static void unthrottle_offline_cfs_rqs(struct rq *rq) | 2666 | static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq) |
2667 | { | 2667 | { |
2668 | struct cfs_rq *cfs_rq; | 2668 | struct cfs_rq *cfs_rq; |
2669 | 2669 | ||
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 418feb01344e..4f02b2847357 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
@@ -566,7 +566,7 @@ static inline struct rt_bandwidth *sched_rt_bandwidth(struct rt_rq *rt_rq) | |||
566 | static int do_balance_runtime(struct rt_rq *rt_rq) | 566 | static int do_balance_runtime(struct rt_rq *rt_rq) |
567 | { | 567 | { |
568 | struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq); | 568 | struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq); |
569 | struct root_domain *rd = cpu_rq(smp_processor_id())->rd; | 569 | struct root_domain *rd = rq_of_rt_rq(rt_rq)->rd; |
570 | int i, weight, more = 0; | 570 | int i, weight, more = 0; |
571 | u64 rt_period; | 571 | u64 rt_period; |
572 | 572 | ||
diff --git a/lib/digsig.c b/lib/digsig.c index 8c0e62975c88..dc2be7ed1765 100644 --- a/lib/digsig.c +++ b/lib/digsig.c | |||
@@ -162,6 +162,8 @@ static int digsig_verify_rsa(struct key *key, | |||
162 | memset(out1, 0, head); | 162 | memset(out1, 0, head); |
163 | memcpy(out1 + head, p, l); | 163 | memcpy(out1 + head, p, l); |
164 | 164 | ||
165 | kfree(p); | ||
166 | |||
165 | err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); | 167 | err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); |
166 | if (err) | 168 | if (err) |
167 | goto err; | 169 | goto err; |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 6001ee6347a9..b5783d81eda9 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1257,6 +1257,10 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, | |||
1257 | if (flags & FOLL_WRITE && !pmd_write(*pmd)) | 1257 | if (flags & FOLL_WRITE && !pmd_write(*pmd)) |
1258 | goto out; | 1258 | goto out; |
1259 | 1259 | ||
1260 | /* Avoid dumping huge zero page */ | ||
1261 | if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd)) | ||
1262 | return ERR_PTR(-EFAULT); | ||
1263 | |||
1260 | page = pmd_page(*pmd); | 1264 | page = pmd_page(*pmd); |
1261 | VM_BUG_ON(!PageHead(page)); | 1265 | VM_BUG_ON(!PageHead(page)); |
1262 | if (flags & FOLL_TOUCH) { | 1266 | if (flags & FOLL_TOUCH) { |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 4f3ea0b1e57c..546db81820e4 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -3033,6 +3033,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, | |||
3033 | if (!huge_pte_none(huge_ptep_get(ptep))) { | 3033 | if (!huge_pte_none(huge_ptep_get(ptep))) { |
3034 | pte = huge_ptep_get_and_clear(mm, address, ptep); | 3034 | pte = huge_ptep_get_and_clear(mm, address, ptep); |
3035 | pte = pte_mkhuge(pte_modify(pte, newprot)); | 3035 | pte = pte_mkhuge(pte_modify(pte, newprot)); |
3036 | pte = arch_make_huge_pte(pte, vma, NULL, 0); | ||
3036 | set_huge_pte_at(mm, address, ptep, pte); | 3037 | set_huge_pte_at(mm, address, ptep, pte); |
3037 | pages++; | 3038 | pages++; |
3038 | } | 3039 | } |
diff --git a/mm/migrate.c b/mm/migrate.c index c38778610aa8..2fd8b4af4744 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -160,8 +160,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma, | |||
160 | if (is_write_migration_entry(entry)) | 160 | if (is_write_migration_entry(entry)) |
161 | pte = pte_mkwrite(pte); | 161 | pte = pte_mkwrite(pte); |
162 | #ifdef CONFIG_HUGETLB_PAGE | 162 | #ifdef CONFIG_HUGETLB_PAGE |
163 | if (PageHuge(new)) | 163 | if (PageHuge(new)) { |
164 | pte = pte_mkhuge(pte); | 164 | pte = pte_mkhuge(pte); |
165 | pte = arch_make_huge_pte(pte, vma, new, 0); | ||
166 | } | ||
165 | #endif | 167 | #endif |
166 | flush_cache_page(vma, addr, pte_pfn(pte)); | 168 | flush_cache_page(vma, addr, pte_pfn(pte)); |
167 | set_pte_at(mm, addr, ptep, pte); | 169 | set_pte_at(mm, addr, ptep, pte); |
@@ -2943,7 +2943,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping) | |||
2943 | * vma in this mm is backed by the same anon_vma or address_space. | 2943 | * vma in this mm is backed by the same anon_vma or address_space. |
2944 | * | 2944 | * |
2945 | * We can take all the locks in random order because the VM code | 2945 | * We can take all the locks in random order because the VM code |
2946 | * taking i_mmap_mutex or anon_vma->mutex outside the mmap_sem never | 2946 | * taking i_mmap_mutex or anon_vma->rwsem outside the mmap_sem never |
2947 | * takes more than one of them in a row. Secondly we're protected | 2947 | * takes more than one of them in a row. Secondly we're protected |
2948 | * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. | 2948 | * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. |
2949 | * | 2949 | * |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 25bfce0666eb..4925a02ae7e4 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -249,12 +249,12 @@ static void hci_conn_disconnect(struct hci_conn *conn) | |||
249 | __u8 reason = hci_proto_disconn_ind(conn); | 249 | __u8 reason = hci_proto_disconn_ind(conn); |
250 | 250 | ||
251 | switch (conn->type) { | 251 | switch (conn->type) { |
252 | case ACL_LINK: | ||
253 | hci_acl_disconn(conn, reason); | ||
254 | break; | ||
255 | case AMP_LINK: | 252 | case AMP_LINK: |
256 | hci_amp_disconn(conn, reason); | 253 | hci_amp_disconn(conn, reason); |
257 | break; | 254 | break; |
255 | default: | ||
256 | hci_acl_disconn(conn, reason); | ||
257 | break; | ||
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 68a9587c9694..5abefb12891d 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -859,6 +859,19 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
859 | 859 | ||
860 | skb_pull(skb, sizeof(code)); | 860 | skb_pull(skb, sizeof(code)); |
861 | 861 | ||
862 | /* | ||
863 | * The SMP context must be initialized for all other PDUs except | ||
864 | * pairing and security requests. If we get any other PDU when | ||
865 | * not initialized simply disconnect (done if this function | ||
866 | * returns an error). | ||
867 | */ | ||
868 | if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && | ||
869 | !conn->smp_chan) { | ||
870 | BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); | ||
871 | kfree_skb(skb); | ||
872 | return -ENOTSUPP; | ||
873 | } | ||
874 | |||
862 | switch (code) { | 875 | switch (code) { |
863 | case SMP_CMD_PAIRING_REQ: | 876 | case SMP_CMD_PAIRING_REQ: |
864 | reason = smp_cmd_pairing_req(conn, skb); | 877 | reason = smp_cmd_pairing_req(conn, skb); |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b29dacf900f9..e6e1cbe863f5 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -1781,10 +1781,13 @@ static ssize_t pktgen_thread_write(struct file *file, | |||
1781 | return -EFAULT; | 1781 | return -EFAULT; |
1782 | i += len; | 1782 | i += len; |
1783 | mutex_lock(&pktgen_thread_lock); | 1783 | mutex_lock(&pktgen_thread_lock); |
1784 | pktgen_add_device(t, f); | 1784 | ret = pktgen_add_device(t, f); |
1785 | mutex_unlock(&pktgen_thread_lock); | 1785 | mutex_unlock(&pktgen_thread_lock); |
1786 | ret = count; | 1786 | if (!ret) { |
1787 | sprintf(pg_result, "OK: add_device=%s", f); | 1787 | ret = count; |
1788 | sprintf(pg_result, "OK: add_device=%s", f); | ||
1789 | } else | ||
1790 | sprintf(pg_result, "ERROR: can not add device %s", f); | ||
1788 | goto out; | 1791 | goto out; |
1789 | } | 1792 | } |
1790 | 1793 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index a9a2ae3e2213..32443ebc3e89 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -683,7 +683,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
683 | new->network_header = old->network_header; | 683 | new->network_header = old->network_header; |
684 | new->mac_header = old->mac_header; | 684 | new->mac_header = old->mac_header; |
685 | new->inner_transport_header = old->inner_transport_header; | 685 | new->inner_transport_header = old->inner_transport_header; |
686 | new->inner_network_header = old->inner_transport_header; | 686 | new->inner_network_header = old->inner_network_header; |
687 | skb_dst_copy(new, old); | 687 | skb_dst_copy(new, old); |
688 | new->rxhash = old->rxhash; | 688 | new->rxhash = old->rxhash; |
689 | new->ooo_okay = old->ooo_okay; | 689 | new->ooo_okay = old->ooo_okay; |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 291f2ed7cc31..cdf2e707bb10 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -310,6 +310,12 @@ void tcp_slow_start(struct tcp_sock *tp) | |||
310 | { | 310 | { |
311 | int cnt; /* increase in packets */ | 311 | int cnt; /* increase in packets */ |
312 | unsigned int delta = 0; | 312 | unsigned int delta = 0; |
313 | u32 snd_cwnd = tp->snd_cwnd; | ||
314 | |||
315 | if (unlikely(!snd_cwnd)) { | ||
316 | pr_err_once("snd_cwnd is nul, please report this bug.\n"); | ||
317 | snd_cwnd = 1U; | ||
318 | } | ||
313 | 319 | ||
314 | /* RFC3465: ABC Slow start | 320 | /* RFC3465: ABC Slow start |
315 | * Increase only after a full MSS of bytes is acked | 321 | * Increase only after a full MSS of bytes is acked |
@@ -324,7 +330,7 @@ void tcp_slow_start(struct tcp_sock *tp) | |||
324 | if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh) | 330 | if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh) |
325 | cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */ | 331 | cnt = sysctl_tcp_max_ssthresh >> 1; /* limited slow start */ |
326 | else | 332 | else |
327 | cnt = tp->snd_cwnd; /* exponential increase */ | 333 | cnt = snd_cwnd; /* exponential increase */ |
328 | 334 | ||
329 | /* RFC3465: ABC | 335 | /* RFC3465: ABC |
330 | * We MAY increase by 2 if discovered delayed ack | 336 | * We MAY increase by 2 if discovered delayed ack |
@@ -334,11 +340,11 @@ void tcp_slow_start(struct tcp_sock *tp) | |||
334 | tp->bytes_acked = 0; | 340 | tp->bytes_acked = 0; |
335 | 341 | ||
336 | tp->snd_cwnd_cnt += cnt; | 342 | tp->snd_cwnd_cnt += cnt; |
337 | while (tp->snd_cwnd_cnt >= tp->snd_cwnd) { | 343 | while (tp->snd_cwnd_cnt >= snd_cwnd) { |
338 | tp->snd_cwnd_cnt -= tp->snd_cwnd; | 344 | tp->snd_cwnd_cnt -= snd_cwnd; |
339 | delta++; | 345 | delta++; |
340 | } | 346 | } |
341 | tp->snd_cwnd = min(tp->snd_cwnd + delta, tp->snd_cwnd_clamp); | 347 | tp->snd_cwnd = min(snd_cwnd + delta, tp->snd_cwnd_clamp); |
342 | } | 348 | } |
343 | EXPORT_SYMBOL_GPL(tcp_slow_start); | 349 | EXPORT_SYMBOL_GPL(tcp_slow_start); |
344 | 350 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 18f97ca76b00..ad70a962c20e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3504,6 +3504,11 @@ static bool tcp_process_frto(struct sock *sk, int flag) | |||
3504 | } | 3504 | } |
3505 | } else { | 3505 | } else { |
3506 | if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) { | 3506 | if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) { |
3507 | if (!tcp_packets_in_flight(tp)) { | ||
3508 | tcp_enter_frto_loss(sk, 2, flag); | ||
3509 | return true; | ||
3510 | } | ||
3511 | |||
3507 | /* Prevent sending of new data. */ | 3512 | /* Prevent sending of new data. */ |
3508 | tp->snd_cwnd = min(tp->snd_cwnd, | 3513 | tp->snd_cwnd = min(tp->snd_cwnd, |
3509 | tcp_packets_in_flight(tp)); | 3514 | tcp_packets_in_flight(tp)); |
@@ -5649,8 +5654,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5649 | * the remote receives only the retransmitted (regular) SYNs: either | 5654 | * the remote receives only the retransmitted (regular) SYNs: either |
5650 | * the original SYN-data or the corresponding SYN-ACK is lost. | 5655 | * the original SYN-data or the corresponding SYN-ACK is lost. |
5651 | */ | 5656 | */ |
5652 | syn_drop = (cookie->len <= 0 && data && | 5657 | syn_drop = (cookie->len <= 0 && data && tp->total_retrans); |
5653 | inet_csk(sk)->icsk_retransmits); | ||
5654 | 5658 | ||
5655 | tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); | 5659 | tcp_fastopen_cache_set(sk, mss, cookie, syn_drop); |
5656 | 5660 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 70b09ef2463b..eadb693eef55 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -496,6 +496,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
496 | * errors returned from accept(). | 496 | * errors returned from accept(). |
497 | */ | 497 | */ |
498 | inet_csk_reqsk_queue_drop(sk, req, prev); | 498 | inet_csk_reqsk_queue_drop(sk, req, prev); |
499 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
499 | goto out; | 500 | goto out; |
500 | 501 | ||
501 | case TCP_SYN_SENT: | 502 | case TCP_SYN_SENT: |
@@ -1500,8 +1501,10 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1500 | * clogging syn queue with openreqs with exponentially increasing | 1501 | * clogging syn queue with openreqs with exponentially increasing |
1501 | * timeout. | 1502 | * timeout. |
1502 | */ | 1503 | */ |
1503 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 1504 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) { |
1505 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); | ||
1504 | goto drop; | 1506 | goto drop; |
1507 | } | ||
1505 | 1508 | ||
1506 | req = inet_reqsk_alloc(&tcp_request_sock_ops); | 1509 | req = inet_reqsk_alloc(&tcp_request_sock_ops); |
1507 | if (!req) | 1510 | if (!req) |
@@ -1666,6 +1669,7 @@ drop_and_release: | |||
1666 | drop_and_free: | 1669 | drop_and_free: |
1667 | reqsk_free(req); | 1670 | reqsk_free(req); |
1668 | drop: | 1671 | drop: |
1672 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
1669 | return 0; | 1673 | return 0; |
1670 | } | 1674 | } |
1671 | EXPORT_SYMBOL(tcp_v4_conn_request); | 1675 | EXPORT_SYMBOL(tcp_v4_conn_request); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 420e56326384..1b5d8cb9b123 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1660,6 +1660,7 @@ static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev) | |||
1660 | if (dev->addr_len != IEEE802154_ADDR_LEN) | 1660 | if (dev->addr_len != IEEE802154_ADDR_LEN) |
1661 | return -1; | 1661 | return -1; |
1662 | memcpy(eui, dev->dev_addr, 8); | 1662 | memcpy(eui, dev->dev_addr, 8); |
1663 | eui[0] ^= 2; | ||
1663 | return 0; | 1664 | return 0; |
1664 | } | 1665 | } |
1665 | 1666 | ||
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 8edf2601065a..7a778b9a7b85 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -380,7 +380,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
380 | if (skb->protocol == htons(ETH_P_IPV6)) { | 380 | if (skb->protocol == htons(ETH_P_IPV6)) { |
381 | sin->sin6_addr = ipv6_hdr(skb)->saddr; | 381 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
382 | if (np->rxopt.all) | 382 | if (np->rxopt.all) |
383 | datagram_recv_ctl(sk, msg, skb); | 383 | ip6_datagram_recv_ctl(sk, msg, skb); |
384 | if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 384 | if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
385 | sin->sin6_scope_id = IP6CB(skb)->iif; | 385 | sin->sin6_scope_id = IP6CB(skb)->iif; |
386 | } else { | 386 | } else { |
@@ -468,7 +468,8 @@ out: | |||
468 | } | 468 | } |
469 | 469 | ||
470 | 470 | ||
471 | int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | 471 | int ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg, |
472 | struct sk_buff *skb) | ||
472 | { | 473 | { |
473 | struct ipv6_pinfo *np = inet6_sk(sk); | 474 | struct ipv6_pinfo *np = inet6_sk(sk); |
474 | struct inet6_skb_parm *opt = IP6CB(skb); | 475 | struct inet6_skb_parm *opt = IP6CB(skb); |
@@ -597,11 +598,12 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | |||
597 | } | 598 | } |
598 | return 0; | 599 | return 0; |
599 | } | 600 | } |
601 | EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl); | ||
600 | 602 | ||
601 | int datagram_send_ctl(struct net *net, struct sock *sk, | 603 | int ip6_datagram_send_ctl(struct net *net, struct sock *sk, |
602 | struct msghdr *msg, struct flowi6 *fl6, | 604 | struct msghdr *msg, struct flowi6 *fl6, |
603 | struct ipv6_txoptions *opt, | 605 | struct ipv6_txoptions *opt, |
604 | int *hlimit, int *tclass, int *dontfrag) | 606 | int *hlimit, int *tclass, int *dontfrag) |
605 | { | 607 | { |
606 | struct in6_pktinfo *src_info; | 608 | struct in6_pktinfo *src_info; |
607 | struct cmsghdr *cmsg; | 609 | struct cmsghdr *cmsg; |
@@ -871,4 +873,4 @@ int datagram_send_ctl(struct net *net, struct sock *sk, | |||
871 | exit_f: | 873 | exit_f: |
872 | return err; | 874 | return err; |
873 | } | 875 | } |
874 | EXPORT_SYMBOL_GPL(datagram_send_ctl); | 876 | EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl); |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 29124b7a04c8..d6de4b447250 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -365,8 +365,8 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, | |||
365 | msg.msg_control = (void*)(fl->opt+1); | 365 | msg.msg_control = (void*)(fl->opt+1); |
366 | memset(&flowi6, 0, sizeof(flowi6)); | 366 | memset(&flowi6, 0, sizeof(flowi6)); |
367 | 367 | ||
368 | err = datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, &junk, | 368 | err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt, |
369 | &junk, &junk); | 369 | &junk, &junk, &junk); |
370 | if (err) | 370 | if (err) |
371 | goto done; | 371 | goto done; |
372 | err = -EINVAL; | 372 | err = -EINVAL; |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index c727e4712751..131dd097736d 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -960,7 +960,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb, | |||
960 | int ret; | 960 | int ret; |
961 | 961 | ||
962 | if (!ip6_tnl_xmit_ctl(t)) | 962 | if (!ip6_tnl_xmit_ctl(t)) |
963 | return -1; | 963 | goto tx_err; |
964 | 964 | ||
965 | switch (skb->protocol) { | 965 | switch (skb->protocol) { |
966 | case htons(ETH_P_IP): | 966 | case htons(ETH_P_IP): |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ee94d31c9d4d..d1e2e8ef29c5 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -476,8 +476,8 @@ sticky_done: | |||
476 | msg.msg_controllen = optlen; | 476 | msg.msg_controllen = optlen; |
477 | msg.msg_control = (void*)(opt+1); | 477 | msg.msg_control = (void*)(opt+1); |
478 | 478 | ||
479 | retv = datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, &junk, | 479 | retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk, |
480 | &junk); | 480 | &junk, &junk); |
481 | if (retv) | 481 | if (retv) |
482 | goto done; | 482 | goto done; |
483 | update: | 483 | update: |
@@ -1002,7 +1002,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1002 | release_sock(sk); | 1002 | release_sock(sk); |
1003 | 1003 | ||
1004 | if (skb) { | 1004 | if (skb) { |
1005 | int err = datagram_recv_ctl(sk, &msg, skb); | 1005 | int err = ip6_datagram_recv_ctl(sk, &msg, skb); |
1006 | kfree_skb(skb); | 1006 | kfree_skb(skb); |
1007 | if (err) | 1007 | if (err) |
1008 | return err; | 1008 | return err; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 6cd29b1e8b92..70fa81449997 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -507,7 +507,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
507 | sock_recv_ts_and_drops(msg, sk, skb); | 507 | sock_recv_ts_and_drops(msg, sk, skb); |
508 | 508 | ||
509 | if (np->rxopt.all) | 509 | if (np->rxopt.all) |
510 | datagram_recv_ctl(sk, msg, skb); | 510 | ip6_datagram_recv_ctl(sk, msg, skb); |
511 | 511 | ||
512 | err = copied; | 512 | err = copied; |
513 | if (flags & MSG_TRUNC) | 513 | if (flags & MSG_TRUNC) |
@@ -822,8 +822,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
822 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 822 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
823 | opt->tot_len = sizeof(struct ipv6_txoptions); | 823 | opt->tot_len = sizeof(struct ipv6_txoptions); |
824 | 824 | ||
825 | err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, | 825 | err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, |
826 | &hlimit, &tclass, &dontfrag); | 826 | &hlimit, &tclass, &dontfrag); |
827 | if (err < 0) { | 827 | if (err < 0) { |
828 | fl6_sock_release(flowlabel); | 828 | fl6_sock_release(flowlabel); |
829 | return err; | 829 | return err; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e229a3bc345d..363d8b7772e8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -928,7 +928,7 @@ restart: | |||
928 | dst_hold(&rt->dst); | 928 | dst_hold(&rt->dst); |
929 | read_unlock_bh(&table->tb6_lock); | 929 | read_unlock_bh(&table->tb6_lock); |
930 | 930 | ||
931 | if (!rt->n && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 931 | if (!rt->n && !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL))) |
932 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); | 932 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); |
933 | else if (!(rt->dst.flags & DST_HOST)) | 933 | else if (!(rt->dst.flags & DST_HOST)) |
934 | nrt = rt6_alloc_clone(rt, &fl6->daddr); | 934 | nrt = rt6_alloc_clone(rt, &fl6->daddr); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 93825dd3a7c0..4f43537197ef 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -423,6 +423,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
423 | } | 423 | } |
424 | 424 | ||
425 | inet_csk_reqsk_queue_drop(sk, req, prev); | 425 | inet_csk_reqsk_queue_drop(sk, req, prev); |
426 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
426 | goto out; | 427 | goto out; |
427 | 428 | ||
428 | case TCP_SYN_SENT: | 429 | case TCP_SYN_SENT: |
@@ -958,8 +959,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
958 | goto drop; | 959 | goto drop; |
959 | } | 960 | } |
960 | 961 | ||
961 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 962 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) { |
963 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); | ||
962 | goto drop; | 964 | goto drop; |
965 | } | ||
963 | 966 | ||
964 | req = inet6_reqsk_alloc(&tcp6_request_sock_ops); | 967 | req = inet6_reqsk_alloc(&tcp6_request_sock_ops); |
965 | if (req == NULL) | 968 | if (req == NULL) |
@@ -1108,6 +1111,7 @@ drop_and_release: | |||
1108 | drop_and_free: | 1111 | drop_and_free: |
1109 | reqsk_free(req); | 1112 | reqsk_free(req); |
1110 | drop: | 1113 | drop: |
1114 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | ||
1111 | return 0; /* don't send reset */ | 1115 | return 0; /* don't send reset */ |
1112 | } | 1116 | } |
1113 | 1117 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index dfaa29b8b293..fb083295ff0b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -443,7 +443,7 @@ try_again: | |||
443 | ip_cmsg_recv(msg, skb); | 443 | ip_cmsg_recv(msg, skb); |
444 | } else { | 444 | } else { |
445 | if (np->rxopt.all) | 445 | if (np->rxopt.all) |
446 | datagram_recv_ctl(sk, msg, skb); | 446 | ip6_datagram_recv_ctl(sk, msg, skb); |
447 | } | 447 | } |
448 | 448 | ||
449 | err = copied; | 449 | err = copied; |
@@ -1153,8 +1153,8 @@ do_udp_sendmsg: | |||
1153 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 1153 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
1154 | opt->tot_len = sizeof(*opt); | 1154 | opt->tot_len = sizeof(*opt); |
1155 | 1155 | ||
1156 | err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, | 1156 | err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, |
1157 | &hlimit, &tclass, &dontfrag); | 1157 | &hlimit, &tclass, &dontfrag); |
1158 | if (err < 0) { | 1158 | if (err < 0) { |
1159 | fl6_sock_release(flowlabel); | 1159 | fl6_sock_release(flowlabel); |
1160 | return err; | 1160 | return err; |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 1a9f3723c13c..2ac884d0e89b 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -168,6 +168,51 @@ l2tp_session_id_hash_2(struct l2tp_net *pn, u32 session_id) | |||
168 | 168 | ||
169 | } | 169 | } |
170 | 170 | ||
171 | /* Lookup the tunnel socket, possibly involving the fs code if the socket is | ||
172 | * owned by userspace. A struct sock returned from this function must be | ||
173 | * released using l2tp_tunnel_sock_put once you're done with it. | ||
174 | */ | ||
175 | struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel) | ||
176 | { | ||
177 | int err = 0; | ||
178 | struct socket *sock = NULL; | ||
179 | struct sock *sk = NULL; | ||
180 | |||
181 | if (!tunnel) | ||
182 | goto out; | ||
183 | |||
184 | if (tunnel->fd >= 0) { | ||
185 | /* Socket is owned by userspace, who might be in the process | ||
186 | * of closing it. Look the socket up using the fd to ensure | ||
187 | * consistency. | ||
188 | */ | ||
189 | sock = sockfd_lookup(tunnel->fd, &err); | ||
190 | if (sock) | ||
191 | sk = sock->sk; | ||
192 | } else { | ||
193 | /* Socket is owned by kernelspace */ | ||
194 | sk = tunnel->sock; | ||
195 | } | ||
196 | |||
197 | out: | ||
198 | return sk; | ||
199 | } | ||
200 | EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_lookup); | ||
201 | |||
202 | /* Drop a reference to a tunnel socket obtained via. l2tp_tunnel_sock_put */ | ||
203 | void l2tp_tunnel_sock_put(struct sock *sk) | ||
204 | { | ||
205 | struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk); | ||
206 | if (tunnel) { | ||
207 | if (tunnel->fd >= 0) { | ||
208 | /* Socket is owned by userspace */ | ||
209 | sockfd_put(sk->sk_socket); | ||
210 | } | ||
211 | sock_put(sk); | ||
212 | } | ||
213 | } | ||
214 | EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_put); | ||
215 | |||
171 | /* Lookup a session by id in the global session list | 216 | /* Lookup a session by id in the global session list |
172 | */ | 217 | */ |
173 | static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id) | 218 | static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id) |
@@ -1123,8 +1168,6 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
1123 | struct udphdr *uh; | 1168 | struct udphdr *uh; |
1124 | struct inet_sock *inet; | 1169 | struct inet_sock *inet; |
1125 | __wsum csum; | 1170 | __wsum csum; |
1126 | int old_headroom; | ||
1127 | int new_headroom; | ||
1128 | int headroom; | 1171 | int headroom; |
1129 | int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; | 1172 | int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; |
1130 | int udp_len; | 1173 | int udp_len; |
@@ -1136,16 +1179,12 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
1136 | */ | 1179 | */ |
1137 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + | 1180 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + |
1138 | uhlen + hdr_len; | 1181 | uhlen + hdr_len; |
1139 | old_headroom = skb_headroom(skb); | ||
1140 | if (skb_cow_head(skb, headroom)) { | 1182 | if (skb_cow_head(skb, headroom)) { |
1141 | kfree_skb(skb); | 1183 | kfree_skb(skb); |
1142 | return NET_XMIT_DROP; | 1184 | return NET_XMIT_DROP; |
1143 | } | 1185 | } |
1144 | 1186 | ||
1145 | new_headroom = skb_headroom(skb); | ||
1146 | skb_orphan(skb); | 1187 | skb_orphan(skb); |
1147 | skb->truesize += new_headroom - old_headroom; | ||
1148 | |||
1149 | /* Setup L2TP header */ | 1188 | /* Setup L2TP header */ |
1150 | session->build_header(session, __skb_push(skb, hdr_len)); | 1189 | session->build_header(session, __skb_push(skb, hdr_len)); |
1151 | 1190 | ||
@@ -1607,6 +1646,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 | |||
1607 | tunnel->old_sk_destruct = sk->sk_destruct; | 1646 | tunnel->old_sk_destruct = sk->sk_destruct; |
1608 | sk->sk_destruct = &l2tp_tunnel_destruct; | 1647 | sk->sk_destruct = &l2tp_tunnel_destruct; |
1609 | tunnel->sock = sk; | 1648 | tunnel->sock = sk; |
1649 | tunnel->fd = fd; | ||
1610 | lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock"); | 1650 | lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock"); |
1611 | 1651 | ||
1612 | sk->sk_allocation = GFP_ATOMIC; | 1652 | sk->sk_allocation = GFP_ATOMIC; |
@@ -1642,24 +1682,32 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create); | |||
1642 | */ | 1682 | */ |
1643 | int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) | 1683 | int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) |
1644 | { | 1684 | { |
1645 | int err = 0; | 1685 | int err = -EBADF; |
1646 | struct socket *sock = tunnel->sock ? tunnel->sock->sk_socket : NULL; | 1686 | struct socket *sock = NULL; |
1687 | struct sock *sk = NULL; | ||
1688 | |||
1689 | sk = l2tp_tunnel_sock_lookup(tunnel); | ||
1690 | if (!sk) | ||
1691 | goto out; | ||
1692 | |||
1693 | sock = sk->sk_socket; | ||
1694 | BUG_ON(!sock); | ||
1647 | 1695 | ||
1648 | /* Force the tunnel socket to close. This will eventually | 1696 | /* Force the tunnel socket to close. This will eventually |
1649 | * cause the tunnel to be deleted via the normal socket close | 1697 | * cause the tunnel to be deleted via the normal socket close |
1650 | * mechanisms when userspace closes the tunnel socket. | 1698 | * mechanisms when userspace closes the tunnel socket. |
1651 | */ | 1699 | */ |
1652 | if (sock != NULL) { | 1700 | err = inet_shutdown(sock, 2); |
1653 | err = inet_shutdown(sock, 2); | ||
1654 | 1701 | ||
1655 | /* If the tunnel's socket was created by the kernel, | 1702 | /* If the tunnel's socket was created by the kernel, |
1656 | * close the socket here since the socket was not | 1703 | * close the socket here since the socket was not |
1657 | * created by userspace. | 1704 | * created by userspace. |
1658 | */ | 1705 | */ |
1659 | if (sock->file == NULL) | 1706 | if (sock->file == NULL) |
1660 | err = inet_release(sock); | 1707 | err = inet_release(sock); |
1661 | } | ||
1662 | 1708 | ||
1709 | l2tp_tunnel_sock_put(sk); | ||
1710 | out: | ||
1663 | return err; | 1711 | return err; |
1664 | } | 1712 | } |
1665 | EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); | 1713 | EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); |
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 56d583e083a7..e62204cad4fe 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h | |||
@@ -188,7 +188,8 @@ struct l2tp_tunnel { | |||
188 | int (*recv_payload_hook)(struct sk_buff *skb); | 188 | int (*recv_payload_hook)(struct sk_buff *skb); |
189 | void (*old_sk_destruct)(struct sock *); | 189 | void (*old_sk_destruct)(struct sock *); |
190 | struct sock *sock; /* Parent socket */ | 190 | struct sock *sock; /* Parent socket */ |
191 | int fd; | 191 | int fd; /* Parent fd, if tunnel socket |
192 | * was created by userspace */ | ||
192 | 193 | ||
193 | uint8_t priv[0]; /* private data */ | 194 | uint8_t priv[0]; /* private data */ |
194 | }; | 195 | }; |
@@ -228,6 +229,8 @@ out: | |||
228 | return tunnel; | 229 | return tunnel; |
229 | } | 230 | } |
230 | 231 | ||
232 | extern struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel); | ||
233 | extern void l2tp_tunnel_sock_put(struct sock *sk); | ||
231 | extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); | 234 | extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); |
232 | extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth); | 235 | extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth); |
233 | extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname); | 236 | extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname); |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 927547171bc7..8ee4a86ae996 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -554,8 +554,8 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
554 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 554 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
555 | opt->tot_len = sizeof(struct ipv6_txoptions); | 555 | opt->tot_len = sizeof(struct ipv6_txoptions); |
556 | 556 | ||
557 | err = datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, | 557 | err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, |
558 | &hlimit, &tclass, &dontfrag); | 558 | &hlimit, &tclass, &dontfrag); |
559 | if (err < 0) { | 559 | if (err < 0) { |
560 | fl6_sock_release(flowlabel); | 560 | fl6_sock_release(flowlabel); |
561 | return err; | 561 | return err; |
@@ -646,7 +646,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
646 | struct msghdr *msg, size_t len, int noblock, | 646 | struct msghdr *msg, size_t len, int noblock, |
647 | int flags, int *addr_len) | 647 | int flags, int *addr_len) |
648 | { | 648 | { |
649 | struct inet_sock *inet = inet_sk(sk); | 649 | struct ipv6_pinfo *np = inet6_sk(sk); |
650 | struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name; | 650 | struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name; |
651 | size_t copied = 0; | 651 | size_t copied = 0; |
652 | int err = -EOPNOTSUPP; | 652 | int err = -EOPNOTSUPP; |
@@ -688,8 +688,8 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
688 | lsa->l2tp_scope_id = IP6CB(skb)->iif; | 688 | lsa->l2tp_scope_id = IP6CB(skb)->iif; |
689 | } | 689 | } |
690 | 690 | ||
691 | if (inet->cmsg_flags) | 691 | if (np->rxopt.all) |
692 | ip_cmsg_recv(msg, skb); | 692 | ip6_datagram_recv_ctl(sk, msg, skb); |
693 | 693 | ||
694 | if (flags & MSG_TRUNC) | 694 | if (flags & MSG_TRUNC) |
695 | copied = skb->len; | 695 | copied = skb->len; |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 286366ef8930..716605c241f4 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -388,8 +388,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
388 | struct l2tp_session *session; | 388 | struct l2tp_session *session; |
389 | struct l2tp_tunnel *tunnel; | 389 | struct l2tp_tunnel *tunnel; |
390 | struct pppol2tp_session *ps; | 390 | struct pppol2tp_session *ps; |
391 | int old_headroom; | ||
392 | int new_headroom; | ||
393 | int uhlen, headroom; | 391 | int uhlen, headroom; |
394 | 392 | ||
395 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 393 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
@@ -408,7 +406,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
408 | if (tunnel == NULL) | 406 | if (tunnel == NULL) |
409 | goto abort_put_sess; | 407 | goto abort_put_sess; |
410 | 408 | ||
411 | old_headroom = skb_headroom(skb); | ||
412 | uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; | 409 | uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; |
413 | headroom = NET_SKB_PAD + | 410 | headroom = NET_SKB_PAD + |
414 | sizeof(struct iphdr) + /* IP header */ | 411 | sizeof(struct iphdr) + /* IP header */ |
@@ -418,9 +415,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
418 | if (skb_cow_head(skb, headroom)) | 415 | if (skb_cow_head(skb, headroom)) |
419 | goto abort_put_sess_tun; | 416 | goto abort_put_sess_tun; |
420 | 417 | ||
421 | new_headroom = skb_headroom(skb); | ||
422 | skb->truesize += new_headroom - old_headroom; | ||
423 | |||
424 | /* Setup PPP header */ | 418 | /* Setup PPP header */ |
425 | __skb_push(skb, sizeof(ppph)); | 419 | __skb_push(skb, sizeof(ppph)); |
426 | skb->data[0] = ppph[0]; | 420 | skb->data[0] = ppph[0]; |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index a9327e2e48ce..670cbc3518de 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
@@ -35,10 +35,11 @@ | |||
35 | /* Must be called with rcu_read_lock. */ | 35 | /* Must be called with rcu_read_lock. */ |
36 | static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) | 36 | static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) |
37 | { | 37 | { |
38 | if (unlikely(!vport)) { | 38 | if (unlikely(!vport)) |
39 | kfree_skb(skb); | 39 | goto error; |
40 | return; | 40 | |
41 | } | 41 | if (unlikely(skb_warn_if_lro(skb))) |
42 | goto error; | ||
42 | 43 | ||
43 | /* Make our own copy of the packet. Otherwise we will mangle the | 44 | /* Make our own copy of the packet. Otherwise we will mangle the |
44 | * packet for anyone who came before us (e.g. tcpdump via AF_PACKET). | 45 | * packet for anyone who came before us (e.g. tcpdump via AF_PACKET). |
@@ -50,6 +51,10 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) | |||
50 | 51 | ||
51 | skb_push(skb, ETH_HLEN); | 52 | skb_push(skb, ETH_HLEN); |
52 | ovs_vport_receive(vport, skb); | 53 | ovs_vport_receive(vport, skb); |
54 | return; | ||
55 | |||
56 | error: | ||
57 | kfree_skb(skb); | ||
53 | } | 58 | } |
54 | 59 | ||
55 | /* Called with rcu_read_lock and bottom-halves disabled. */ | 60 | /* Called with rcu_read_lock and bottom-halves disabled. */ |
@@ -169,9 +174,6 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) | |||
169 | goto error; | 174 | goto error; |
170 | } | 175 | } |
171 | 176 | ||
172 | if (unlikely(skb_warn_if_lro(skb))) | ||
173 | goto error; | ||
174 | |||
175 | skb->dev = netdev_vport->dev; | 177 | skb->dev = netdev_vport->dev; |
176 | len = skb->len; | 178 | len = skb->len; |
177 | dev_queue_xmit(skb); | 179 | dev_queue_xmit(skb); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e639645e8fec..c111bd0e083a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2361,13 +2361,15 @@ static int packet_release(struct socket *sock) | |||
2361 | 2361 | ||
2362 | packet_flush_mclist(sk); | 2362 | packet_flush_mclist(sk); |
2363 | 2363 | ||
2364 | memset(&req_u, 0, sizeof(req_u)); | 2364 | if (po->rx_ring.pg_vec) { |
2365 | 2365 | memset(&req_u, 0, sizeof(req_u)); | |
2366 | if (po->rx_ring.pg_vec) | ||
2367 | packet_set_ring(sk, &req_u, 1, 0); | 2366 | packet_set_ring(sk, &req_u, 1, 0); |
2367 | } | ||
2368 | 2368 | ||
2369 | if (po->tx_ring.pg_vec) | 2369 | if (po->tx_ring.pg_vec) { |
2370 | memset(&req_u, 0, sizeof(req_u)); | ||
2370 | packet_set_ring(sk, &req_u, 1, 1); | 2371 | packet_set_ring(sk, &req_u, 1, 1); |
2372 | } | ||
2371 | 2373 | ||
2372 | fanout_release(sk); | 2374 | fanout_release(sk); |
2373 | 2375 | ||
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 298c0ddfb57e..3d2acc7a9c80 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -438,18 +438,18 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
438 | if (q->rate) { | 438 | if (q->rate) { |
439 | struct sk_buff_head *list = &sch->q; | 439 | struct sk_buff_head *list = &sch->q; |
440 | 440 | ||
441 | delay += packet_len_2_sched_time(skb->len, q); | ||
442 | |||
443 | if (!skb_queue_empty(list)) { | 441 | if (!skb_queue_empty(list)) { |
444 | /* | 442 | /* |
445 | * Last packet in queue is reference point (now). | 443 | * Last packet in queue is reference point (now), |
446 | * First packet in queue is already in flight, | 444 | * calculate this time bonus and subtract |
447 | * calculate this time bonus and substract | ||
448 | * from delay. | 445 | * from delay. |
449 | */ | 446 | */ |
450 | delay -= now - netem_skb_cb(skb_peek(list))->time_to_send; | 447 | delay -= netem_skb_cb(skb_peek_tail(list))->time_to_send - now; |
448 | delay = max_t(psched_tdiff_t, 0, delay); | ||
451 | now = netem_skb_cb(skb_peek_tail(list))->time_to_send; | 449 | now = netem_skb_cb(skb_peek_tail(list))->time_to_send; |
452 | } | 450 | } |
451 | |||
452 | delay += packet_len_2_sched_time(skb->len, q); | ||
453 | } | 453 | } |
454 | 454 | ||
455 | cb->time_to_send = now + delay; | 455 | cb->time_to_send = now + delay; |
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 159b9bc5d633..d8420ae614dc 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -71,7 +71,7 @@ void sctp_auth_key_put(struct sctp_auth_bytes *key) | |||
71 | return; | 71 | return; |
72 | 72 | ||
73 | if (atomic_dec_and_test(&key->refcnt)) { | 73 | if (atomic_dec_and_test(&key->refcnt)) { |
74 | kfree(key); | 74 | kzfree(key); |
75 | SCTP_DBG_OBJCNT_DEC(keys); | 75 | SCTP_DBG_OBJCNT_DEC(keys); |
76 | } | 76 | } |
77 | } | 77 | } |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 17a001bac2cc..1a9c5fb77310 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -249,6 +249,8 @@ void sctp_endpoint_free(struct sctp_endpoint *ep) | |||
249 | /* Final destructor for endpoint. */ | 249 | /* Final destructor for endpoint. */ |
250 | static void sctp_endpoint_destroy(struct sctp_endpoint *ep) | 250 | static void sctp_endpoint_destroy(struct sctp_endpoint *ep) |
251 | { | 251 | { |
252 | int i; | ||
253 | |||
252 | SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); | 254 | SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); |
253 | 255 | ||
254 | /* Free up the HMAC transform. */ | 256 | /* Free up the HMAC transform. */ |
@@ -271,6 +273,9 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) | |||
271 | sctp_inq_free(&ep->base.inqueue); | 273 | sctp_inq_free(&ep->base.inqueue); |
272 | sctp_bind_addr_free(&ep->base.bind_addr); | 274 | sctp_bind_addr_free(&ep->base.bind_addr); |
273 | 275 | ||
276 | for (i = 0; i < SCTP_HOW_MANY_SECRETS; ++i) | ||
277 | memset(&ep->secret_key[i], 0, SCTP_SECRET_SIZE); | ||
278 | |||
274 | /* Remove and free the port */ | 279 | /* Remove and free the port */ |
275 | if (sctp_sk(ep->base.sk)->bind_hash) | 280 | if (sctp_sk(ep->base.sk)->bind_hash) |
276 | sctp_put_port(ep->base.sk); | 281 | sctp_put_port(ep->base.sk); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9e65758cb038..cedd9bf67b8c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3390,7 +3390,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3390 | 3390 | ||
3391 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); | 3391 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); |
3392 | out: | 3392 | out: |
3393 | kfree(authkey); | 3393 | kzfree(authkey); |
3394 | return ret; | 3394 | return ret; |
3395 | } | 3395 | } |
3396 | 3396 | ||
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 0a148c9d2a5c..0f679df7d072 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -465,7 +465,7 @@ static int svc_udp_get_dest_address4(struct svc_rqst *rqstp, | |||
465 | } | 465 | } |
466 | 466 | ||
467 | /* | 467 | /* |
468 | * See net/ipv6/datagram.c : datagram_recv_ctl | 468 | * See net/ipv6/datagram.c : ip6_datagram_recv_ctl |
469 | */ | 469 | */ |
470 | static int svc_udp_get_dest_address6(struct svc_rqst *rqstp, | 470 | static int svc_udp_get_dest_address6(struct svc_rqst *rqstp, |
471 | struct cmsghdr *cmh) | 471 | struct cmsghdr *cmh) |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 01592d7d4789..45f1618c8e23 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -1358,7 +1358,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1358 | &iwe, IW_EV_UINT_LEN); | 1358 | &iwe, IW_EV_UINT_LEN); |
1359 | } | 1359 | } |
1360 | 1360 | ||
1361 | buf = kmalloc(30, GFP_ATOMIC); | 1361 | buf = kmalloc(31, GFP_ATOMIC); |
1362 | if (buf) { | 1362 | if (buf) { |
1363 | memset(&iwe, 0, sizeof(iwe)); | 1363 | memset(&iwe, 0, sizeof(iwe)); |
1364 | iwe.cmd = IWEVCUSTOM; | 1364 | iwe.cmd = IWEVCUSTOM; |
diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile index bbbd276659ba..7203e66dcd6f 100644 --- a/samples/seccomp/Makefile +++ b/samples/seccomp/Makefile | |||
@@ -19,6 +19,7 @@ bpf-direct-objs := bpf-direct.o | |||
19 | 19 | ||
20 | # Try to match the kernel target. | 20 | # Try to match the kernel target. |
21 | ifndef CONFIG_64BIT | 21 | ifndef CONFIG_64BIT |
22 | ifndef CROSS_COMPILE | ||
22 | 23 | ||
23 | # s390 has -m31 flag to build 31 bit binaries | 24 | # s390 has -m31 flag to build 31 bit binaries |
24 | ifndef CONFIG_S390 | 25 | ifndef CONFIG_S390 |
@@ -35,6 +36,7 @@ HOSTLOADLIBES_bpf-direct += $(MFLAG) | |||
35 | HOSTLOADLIBES_bpf-fancy += $(MFLAG) | 36 | HOSTLOADLIBES_bpf-fancy += $(MFLAG) |
36 | HOSTLOADLIBES_dropper += $(MFLAG) | 37 | HOSTLOADLIBES_dropper += $(MFLAG) |
37 | endif | 38 | endif |
39 | endif | ||
38 | 40 | ||
39 | # Tell kbuild to always build the programs | 41 | # Tell kbuild to always build the programs |
40 | always := $(hostprogs-y) | 42 | always := $(hostprogs-y) |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4d2c7dfdaabd..2bb08a962ce3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -230,12 +230,12 @@ our $Inline = qr{inline|__always_inline|noinline}; | |||
230 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; | 230 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; |
231 | our $Lval = qr{$Ident(?:$Member)*}; | 231 | our $Lval = qr{$Ident(?:$Member)*}; |
232 | 232 | ||
233 | our $Float_hex = qr{(?i:0x[0-9a-f]+p-?[0-9]+[fl]?)}; | 233 | our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; |
234 | our $Float_dec = qr{(?i:((?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?))}; | 234 | our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; |
235 | our $Float_int = qr{(?i:[0-9]+e-?[0-9]+[fl]?)}; | 235 | our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; |
236 | our $Float = qr{$Float_hex|$Float_dec|$Float_int}; | 236 | our $Float = qr{$Float_hex|$Float_dec|$Float_int}; |
237 | our $Constant = qr{(?:$Float|(?i:(?:0x[0-9a-f]+|[0-9]+)[ul]*))}; | 237 | our $Constant = qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*}; |
238 | our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; | 238 | our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; |
239 | our $Compare = qr{<=|>=|==|!=|<|>}; | 239 | our $Compare = qr{<=|>=|==|!=|<|>}; |
240 | our $Operators = qr{ | 240 | our $Operators = qr{ |
241 | <=|>=|==|!=| | 241 | <=|>=|==|!=| |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index a210c8d7b4bc..3b98159d9645 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -108,13 +108,18 @@ if SND_IMX_SOC | |||
108 | config SND_SOC_IMX_SSI | 108 | config SND_SOC_IMX_SSI |
109 | tristate | 109 | tristate |
110 | 110 | ||
111 | config SND_SOC_IMX_PCM_FIQ | 111 | config SND_SOC_IMX_PCM |
112 | tristate | 112 | tristate |
113 | |||
114 | config SND_SOC_IMX_PCM_FIQ | ||
115 | bool | ||
113 | select FIQ | 116 | select FIQ |
117 | select SND_SOC_IMX_PCM | ||
114 | 118 | ||
115 | config SND_SOC_IMX_PCM_DMA | 119 | config SND_SOC_IMX_PCM_DMA |
116 | tristate | 120 | bool |
117 | select SND_SOC_DMAENGINE_PCM | 121 | select SND_SOC_DMAENGINE_PCM |
122 | select SND_SOC_IMX_PCM | ||
118 | 123 | ||
119 | config SND_SOC_IMX_AUDMUX | 124 | config SND_SOC_IMX_AUDMUX |
120 | tristate | 125 | tristate |
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index ec1457915d7c..afd34794db53 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -41,10 +41,7 @@ endif | |||
41 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o | 41 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o |
42 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o | 42 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o |
43 | 43 | ||
44 | obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += snd-soc-imx-pcm-fiq.o | 44 | obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o |
45 | snd-soc-imx-pcm-fiq-y := imx-pcm-fiq.o imx-pcm.o | ||
46 | obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += snd-soc-imx-pcm-dma.o | ||
47 | snd-soc-imx-pcm-dma-y := imx-pcm-dma.o imx-pcm.o | ||
48 | 45 | ||
49 | # i.MX Machine Support | 46 | # i.MX Machine Support |
50 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o | 47 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o |
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index bf363d8d044a..500f8ce55d78 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c | |||
@@ -154,26 +154,7 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = { | |||
154 | .pcm_free = imx_pcm_free, | 154 | .pcm_free = imx_pcm_free, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static int imx_soc_platform_probe(struct platform_device *pdev) | 157 | int imx_pcm_dma_init(struct platform_device *pdev) |
158 | { | 158 | { |
159 | return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); | 159 | return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); |
160 | } | 160 | } |
161 | |||
162 | static int imx_soc_platform_remove(struct platform_device *pdev) | ||
163 | { | ||
164 | snd_soc_unregister_platform(&pdev->dev); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static struct platform_driver imx_pcm_driver = { | ||
169 | .driver = { | ||
170 | .name = "imx-pcm-audio", | ||
171 | .owner = THIS_MODULE, | ||
172 | }, | ||
173 | .probe = imx_soc_platform_probe, | ||
174 | .remove = imx_soc_platform_remove, | ||
175 | }; | ||
176 | |||
177 | module_platform_driver(imx_pcm_driver); | ||
178 | MODULE_LICENSE("GPL"); | ||
179 | MODULE_ALIAS("platform:imx-pcm-audio"); | ||
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 5ec362ae4d01..920f945cb2f4 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c | |||
@@ -281,7 +281,7 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = { | |||
281 | .pcm_free = imx_pcm_fiq_free, | 281 | .pcm_free = imx_pcm_fiq_free, |
282 | }; | 282 | }; |
283 | 283 | ||
284 | static int imx_soc_platform_probe(struct platform_device *pdev) | 284 | int imx_pcm_fiq_init(struct platform_device *pdev) |
285 | { | 285 | { |
286 | struct imx_ssi *ssi = platform_get_drvdata(pdev); | 286 | struct imx_ssi *ssi = platform_get_drvdata(pdev); |
287 | int ret; | 287 | int ret; |
@@ -314,23 +314,3 @@ failed_register: | |||
314 | 314 | ||
315 | return ret; | 315 | return ret; |
316 | } | 316 | } |
317 | |||
318 | static int imx_soc_platform_remove(struct platform_device *pdev) | ||
319 | { | ||
320 | snd_soc_unregister_platform(&pdev->dev); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static struct platform_driver imx_pcm_driver = { | ||
325 | .driver = { | ||
326 | .name = "imx-fiq-pcm-audio", | ||
327 | .owner = THIS_MODULE, | ||
328 | }, | ||
329 | |||
330 | .probe = imx_soc_platform_probe, | ||
331 | .remove = imx_soc_platform_remove, | ||
332 | }; | ||
333 | |||
334 | module_platform_driver(imx_pcm_driver); | ||
335 | |||
336 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c index 0c9f188ddc68..0d0625bfcb65 100644 --- a/sound/soc/fsl/imx-pcm.c +++ b/sound/soc/fsl/imx-pcm.c | |||
@@ -31,6 +31,7 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | |||
31 | runtime->dma_bytes); | 31 | runtime->dma_bytes); |
32 | return ret; | 32 | return ret; |
33 | } | 33 | } |
34 | EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); | ||
34 | 35 | ||
35 | static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | 36 | static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) |
36 | { | 37 | { |
@@ -79,6 +80,7 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
79 | out: | 80 | out: |
80 | return ret; | 81 | return ret; |
81 | } | 82 | } |
83 | EXPORT_SYMBOL_GPL(imx_pcm_new); | ||
82 | 84 | ||
83 | void imx_pcm_free(struct snd_pcm *pcm) | 85 | void imx_pcm_free(struct snd_pcm *pcm) |
84 | { | 86 | { |
@@ -100,6 +102,39 @@ void imx_pcm_free(struct snd_pcm *pcm) | |||
100 | buf->area = NULL; | 102 | buf->area = NULL; |
101 | } | 103 | } |
102 | } | 104 | } |
105 | EXPORT_SYMBOL_GPL(imx_pcm_free); | ||
106 | |||
107 | static int imx_pcm_probe(struct platform_device *pdev) | ||
108 | { | ||
109 | if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0) | ||
110 | return imx_pcm_fiq_init(pdev); | ||
111 | |||
112 | return imx_pcm_dma_init(pdev); | ||
113 | } | ||
114 | |||
115 | static int imx_pcm_remove(struct platform_device *pdev) | ||
116 | { | ||
117 | snd_soc_unregister_platform(&pdev->dev); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static struct platform_device_id imx_pcm_devtype[] = { | ||
122 | { .name = "imx-pcm-audio", }, | ||
123 | { .name = "imx-fiq-pcm-audio", }, | ||
124 | { /* sentinel */ } | ||
125 | }; | ||
126 | MODULE_DEVICE_TABLE(platform, imx_pcm_devtype); | ||
127 | |||
128 | static struct platform_driver imx_pcm_driver = { | ||
129 | .driver = { | ||
130 | .name = "imx-pcm", | ||
131 | .owner = THIS_MODULE, | ||
132 | }, | ||
133 | .id_table = imx_pcm_devtype, | ||
134 | .probe = imx_pcm_probe, | ||
135 | .remove = imx_pcm_remove, | ||
136 | }; | ||
137 | module_platform_driver(imx_pcm_driver); | ||
103 | 138 | ||
104 | MODULE_DESCRIPTION("Freescale i.MX PCM driver"); | 139 | MODULE_DESCRIPTION("Freescale i.MX PCM driver"); |
105 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | 140 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); |
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h index 83c0ed7d55c9..5ae13a13a353 100644 --- a/sound/soc/fsl/imx-pcm.h +++ b/sound/soc/fsl/imx-pcm.h | |||
@@ -30,4 +30,22 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | |||
30 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); | 30 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); |
31 | void imx_pcm_free(struct snd_pcm *pcm); | 31 | void imx_pcm_free(struct snd_pcm *pcm); |
32 | 32 | ||
33 | #ifdef CONFIG_SND_SOC_IMX_PCM_DMA | ||
34 | int imx_pcm_dma_init(struct platform_device *pdev); | ||
35 | #else | ||
36 | static inline int imx_pcm_dma_init(struct platform_device *pdev) | ||
37 | { | ||
38 | return -ENODEV; | ||
39 | } | ||
40 | #endif | ||
41 | |||
42 | #ifdef CONFIG_SND_SOC_IMX_PCM_FIQ | ||
43 | int imx_pcm_fiq_init(struct platform_device *pdev); | ||
44 | #else | ||
45 | static inline int imx_pcm_fiq_init(struct platform_device *pdev) | ||
46 | { | ||
47 | return -ENODEV; | ||
48 | } | ||
49 | #endif | ||
50 | |||
33 | #endif /* _IMX_PCM_H */ | 51 | #endif /* _IMX_PCM_H */ |
diff --git a/tools/vm/.gitignore b/tools/vm/.gitignore new file mode 100644 index 000000000000..44f095fa2604 --- /dev/null +++ b/tools/vm/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | slabinfo | ||
2 | page-types | ||