diff options
274 files changed, 6768 insertions, 1191 deletions
diff --git a/Documentation/DocBook/media/v4l/dev-codec.xml b/Documentation/DocBook/media/v4l/dev-codec.xml index dca0ecd54dc6..ff44c16fc080 100644 --- a/Documentation/DocBook/media/v4l/dev-codec.xml +++ b/Documentation/DocBook/media/v4l/dev-codec.xml | |||
| @@ -1,18 +1,27 @@ | |||
| 1 | <title>Codec Interface</title> | 1 | <title>Codec Interface</title> |
| 2 | 2 | ||
| 3 | <note> | 3 | <para>A V4L2 codec can compress, decompress, transform, or otherwise |
| 4 | <title>Suspended</title> | 4 | convert video data from one format into another format, in memory. Typically |
| 5 | such devices are memory-to-memory devices (i.e. devices with the | ||
| 6 | <constant>V4L2_CAP_VIDEO_M2M</constant> or <constant>V4L2_CAP_VIDEO_M2M_MPLANE</constant> | ||
| 7 | capability set). | ||
| 8 | </para> | ||
| 5 | 9 | ||
| 6 | <para>This interface has been be suspended from the V4L2 API | 10 | <para>A memory-to-memory video node acts just like a normal video node, but it |
| 7 | implemented in Linux 2.6 until we have more experience with codec | 11 | supports both output (sending frames from memory to the codec hardware) and |
| 8 | device interfaces.</para> | 12 | capture (receiving the processed frames from the codec hardware into memory) |
| 9 | </note> | 13 | stream I/O. An application will have to setup the stream |
| 14 | I/O for both sides and finally call &VIDIOC-STREAMON; for both capture and output | ||
| 15 | to start the codec.</para> | ||
| 10 | 16 | ||
| 11 | <para>A V4L2 codec can compress, decompress, transform, or otherwise | 17 | <para>Video compression codecs use the MPEG controls to setup their codec parameters |
| 12 | convert video data from one format into another format, in memory. | 18 | (note that the MPEG controls actually support many more codecs than just MPEG). |
| 13 | Applications send data to be converted to the driver through a | 19 | See <xref linkend="mpeg-controls"></xref>.</para> |
| 14 | &func-write; call, and receive the converted data through a | ||
| 15 | &func-read; call. For efficiency a driver may also support streaming | ||
| 16 | I/O.</para> | ||
| 17 | 20 | ||
| 18 | <para>[to do]</para> | 21 | <para>Memory-to-memory devices can often be used as a shared resource: you can |
| 22 | open the video node multiple times, each application setting up their own codec properties | ||
| 23 | that are local to the file handle, and each can use it independently from the others. | ||
| 24 | The driver will arbitrate access to the codec and reprogram it whenever another file | ||
| 25 | handler gets access. This is different from the usual video node behavior where the video properties | ||
| 26 | are global to the device (i.e. changing something through one file handle is visible | ||
| 27 | through another file handle).</para> | ||
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index bfc93cdcf696..bfe823dd0f31 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml | |||
| @@ -493,7 +493,7 @@ and discussions on the V4L mailing list.</revremark> | |||
| 493 | </partinfo> | 493 | </partinfo> |
| 494 | 494 | ||
| 495 | <title>Video for Linux Two API Specification</title> | 495 | <title>Video for Linux Two API Specification</title> |
| 496 | <subtitle>Revision 3.9</subtitle> | 496 | <subtitle>Revision 3.10</subtitle> |
| 497 | 497 | ||
| 498 | <chapter id="common"> | 498 | <chapter id="common"> |
| 499 | &sub-common; | 499 | &sub-common; |
diff --git a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt index 3f62adfb3e0b..de9f6b78ee51 100644 --- a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt +++ b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt | |||
| @@ -2,7 +2,7 @@ Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE) | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | 4 | ||
| 5 | - compatible : should be "samsung,exynos4212-fimc" for Exynos4212 and | 5 | - compatible : should be "samsung,exynos4212-fimc-lite" for Exynos4212 and |
| 6 | Exynos4412 SoCs; | 6 | Exynos4412 SoCs; |
| 7 | - reg : physical base address and size of the device memory mapped | 7 | - reg : physical base address and size of the device memory mapped |
| 8 | registers; | 8 | registers; |
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index f98ca633b528..3458d6343e01 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
| @@ -420,10 +420,10 @@ tcp_synack_retries - INTEGER | |||
| 420 | for a passive TCP connection will happen after 63seconds. | 420 | for a passive TCP connection will happen after 63seconds. |
| 421 | 421 | ||
| 422 | tcp_syncookies - BOOLEAN | 422 | tcp_syncookies - BOOLEAN |
| 423 | Only valid when the kernel was compiled with CONFIG_SYNCOOKIES | 423 | Only valid when the kernel was compiled with CONFIG_SYN_COOKIES |
| 424 | Send out syncookies when the syn backlog queue of a socket | 424 | Send out syncookies when the syn backlog queue of a socket |
| 425 | overflows. This is to prevent against the common 'SYN flood attack' | 425 | overflows. This is to prevent against the common 'SYN flood attack' |
| 426 | Default: FALSE | 426 | Default: 1 |
| 427 | 427 | ||
| 428 | Note, that syncookies is fallback facility. | 428 | Note, that syncookies is fallback facility. |
| 429 | It MUST NOT be used to help highly loaded servers to stand | 429 | It MUST NOT be used to help highly loaded servers to stand |
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index bb8b0dc532b8..77d68e23b247 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
| @@ -29,6 +29,8 @@ ALC269/270/275/276/280/282 | |||
| 29 | alc271-dmic Enable ALC271X digital mic workaround | 29 | alc271-dmic Enable ALC271X digital mic workaround |
| 30 | inv-dmic Inverted internal mic workaround | 30 | inv-dmic Inverted internal mic workaround |
| 31 | lenovo-dock Enables docking station I/O for some Lenovos | 31 | lenovo-dock Enables docking station I/O for some Lenovos |
| 32 | dell-headset-multi Headset jack, which can also be used as mic-in | ||
| 33 | dell-headset-dock Headset jack (without mic-in), and also dock I/O | ||
| 32 | 34 | ||
| 33 | ALC662/663/272 | 35 | ALC662/663/272 |
| 34 | ============== | 36 | ============== |
| @@ -42,6 +44,7 @@ ALC662/663/272 | |||
| 42 | asus-mode7 ASUS | 44 | asus-mode7 ASUS |
| 43 | asus-mode8 ASUS | 45 | asus-mode8 ASUS |
| 44 | inv-dmic Inverted internal mic workaround | 46 | inv-dmic Inverted internal mic workaround |
| 47 | dell-headset-multi Headset jack, which can also be used as mic-in | ||
| 45 | 48 | ||
| 46 | ALC680 | 49 | ALC680 |
| 47 | ====== | 50 | ====== |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 3 | 1 | VERSION = 3 |
| 2 | PATCHLEVEL = 10 | 2 | PATCHLEVEL = 10 |
| 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/Kconfig b/arch/arm/Kconfig index 49d993cee512..136f263ed47b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -1087,6 +1087,20 @@ if !MMU | |||
| 1087 | source "arch/arm/Kconfig-nommu" | 1087 | source "arch/arm/Kconfig-nommu" |
| 1088 | endif | 1088 | endif |
| 1089 | 1089 | ||
| 1090 | config PJ4B_ERRATA_4742 | ||
| 1091 | bool "PJ4B Errata 4742: IDLE Wake Up Commands can Cause the CPU Core to Cease Operation" | ||
| 1092 | depends on CPU_PJ4B && MACH_ARMADA_370 | ||
| 1093 | default y | ||
| 1094 | help | ||
| 1095 | When coming out of either a Wait for Interrupt (WFI) or a Wait for | ||
| 1096 | Event (WFE) IDLE states, a specific timing sensitivity exists between | ||
| 1097 | the retiring WFI/WFE instructions and the newly issued subsequent | ||
| 1098 | instructions. This sensitivity can result in a CPU hang scenario. | ||
| 1099 | Workaround: | ||
| 1100 | The software must insert either a Data Synchronization Barrier (DSB) | ||
| 1101 | or Data Memory Barrier (DMB) command immediately after the WFI/WFE | ||
| 1102 | instruction | ||
| 1103 | |||
| 1090 | config ARM_ERRATA_326103 | 1104 | config ARM_ERRATA_326103 |
| 1091 | bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" | 1105 | bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" |
| 1092 | depends on CPU_V6 | 1106 | depends on CPU_V6 |
| @@ -1189,6 +1203,16 @@ config PL310_ERRATA_588369 | |||
| 1189 | is not correctly implemented in PL310 as clean lines are not | 1203 | is not correctly implemented in PL310 as clean lines are not |
| 1190 | invalidated as a result of these operations. | 1204 | invalidated as a result of these operations. |
| 1191 | 1205 | ||
| 1206 | config ARM_ERRATA_643719 | ||
| 1207 | bool "ARM errata: LoUIS bit field in CLIDR register is incorrect" | ||
| 1208 | depends on CPU_V7 && SMP | ||
| 1209 | help | ||
| 1210 | This option enables the workaround for the 643719 Cortex-A9 (prior to | ||
| 1211 | r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR | ||
| 1212 | register returns zero when it should return one. The workaround | ||
| 1213 | corrects this value, ensuring cache maintenance operations which use | ||
| 1214 | it behave as intended and avoiding data corruption. | ||
| 1215 | |||
| 1192 | config ARM_ERRATA_720789 | 1216 | config ARM_ERRATA_720789 |
| 1193 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" | 1217 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" |
| 1194 | depends on CPU_V7 | 1218 | depends on CPU_V7 |
| @@ -2006,7 +2030,7 @@ config XIP_PHYS_ADDR | |||
| 2006 | 2030 | ||
| 2007 | config KEXEC | 2031 | config KEXEC |
| 2008 | bool "Kexec system call (EXPERIMENTAL)" | 2032 | bool "Kexec system call (EXPERIMENTAL)" |
| 2009 | depends on (!SMP || HOTPLUG_CPU) | 2033 | depends on (!SMP || PM_SLEEP_SMP) |
| 2010 | help | 2034 | help |
| 2011 | kexec is a system call that implements the ability to shutdown your | 2035 | kexec is a system call that implements the ability to shutdown your |
| 2012 | current kernel, and to start another kernel. It is like a reboot | 2036 | current kernel, and to start another kernel. It is like a reboot |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 79e9bdbfc491..120b83bfde20 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
| @@ -116,7 +116,8 @@ targets := vmlinux vmlinux.lds \ | |||
| 116 | 116 | ||
| 117 | # Make sure files are removed during clean | 117 | # Make sure files are removed during clean |
| 118 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ | 118 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ |
| 119 | lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) | 119 | lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \ |
| 120 | hyp-stub.S | ||
| 120 | 121 | ||
| 121 | ifeq ($(CONFIG_FUNCTION_TRACER),y) | 122 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
| 122 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 123 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi index d1650fb34c0a..ded558bb0f3b 100644 --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi | |||
| @@ -763,7 +763,7 @@ | |||
| 763 | }; | 763 | }; |
| 764 | }; | 764 | }; |
| 765 | 765 | ||
| 766 | pinctrl@03680000 { | 766 | pinctrl@03860000 { |
| 767 | gpz: gpz { | 767 | gpz: gpz { |
| 768 | gpio-controller; | 768 | gpio-controller; |
| 769 | #gpio-cells = <2>; | 769 | #gpio-cells = <2>; |
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 0673524238a6..fc9fb3d526e2 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi | |||
| @@ -161,9 +161,9 @@ | |||
| 161 | interrupts = <0 50 0>; | 161 | interrupts = <0 50 0>; |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
| 164 | pinctrl_3: pinctrl@03680000 { | 164 | pinctrl_3: pinctrl@03860000 { |
| 165 | compatible = "samsung,exynos5250-pinctrl"; | 165 | compatible = "samsung,exynos5250-pinctrl"; |
| 166 | reg = <0x0368000 0x1000>; | 166 | reg = <0x03860000 0x1000>; |
| 167 | interrupts = <0 47 0>; | 167 | interrupts = <0 47 0>; |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index bff71388e72a..17d0ae8672fa 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
| @@ -320,9 +320,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE | 322 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE |
| 323 | static inline void flush_kernel_dcache_page(struct page *page) | 323 | extern void flush_kernel_dcache_page(struct page *); |
| 324 | { | ||
| 325 | } | ||
| 326 | 324 | ||
| 327 | #define flush_dcache_mmap_lock(mapping) \ | 325 | #define flush_dcache_mmap_lock(mapping) \ |
| 328 | spin_lock_irq(&(mapping)->tree_lock) | 326 | spin_lock_irq(&(mapping)->tree_lock) |
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 7652712d1d14..dba62cb1ad08 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | 32 | ||
| 33 | #define MPIDR_HWID_BITMASK 0xFFFFFF | 33 | #define MPIDR_HWID_BITMASK 0xFFFFFF |
| 34 | 34 | ||
| 35 | #define MPIDR_INVALID (~MPIDR_HWID_BITMASK) | ||
| 36 | |||
| 35 | #define MPIDR_LEVEL_BITS 8 | 37 | #define MPIDR_LEVEL_BITS 8 |
| 36 | #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) | 38 | #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) |
| 37 | 39 | ||
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h index ac1dd54724b6..8017e94acc5e 100644 --- a/arch/arm/include/asm/glue-proc.h +++ b/arch/arm/include/asm/glue-proc.h | |||
| @@ -230,6 +230,15 @@ | |||
| 230 | # endif | 230 | # endif |
| 231 | #endif | 231 | #endif |
| 232 | 232 | ||
| 233 | #ifdef CONFIG_CPU_PJ4B | ||
| 234 | # ifdef CPU_NAME | ||
| 235 | # undef MULTI_CPU | ||
| 236 | # define MULTI_CPU | ||
| 237 | # else | ||
| 238 | # define CPU_NAME cpu_pj4b | ||
| 239 | # endif | ||
| 240 | #endif | ||
| 241 | |||
| 233 | #ifndef MULTI_CPU | 242 | #ifndef MULTI_CPU |
| 234 | #define cpu_proc_init __glue(CPU_NAME,_proc_init) | 243 | #define cpu_proc_init __glue(CPU_NAME,_proc_init) |
| 235 | #define cpu_proc_fin __glue(CPU_NAME,_proc_fin) | 244 | #define cpu_proc_fin __glue(CPU_NAME,_proc_fin) |
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index aaa61b6f50ff..e78983202737 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h | |||
| @@ -49,7 +49,7 @@ static inline int cache_ops_need_broadcast(void) | |||
| 49 | /* | 49 | /* |
| 50 | * Logical CPU mapping. | 50 | * Logical CPU mapping. |
| 51 | */ | 51 | */ |
| 52 | extern int __cpu_logical_map[]; | 52 | extern u32 __cpu_logical_map[]; |
| 53 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] | 53 | #define cpu_logical_map(cpu) __cpu_logical_map[cpu] |
| 54 | /* | 54 | /* |
| 55 | * Retrieve logical cpu index corresponding to a given MPIDR[23:0] | 55 | * Retrieve logical cpu index corresponding to a given MPIDR[23:0] |
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 5af04f6daa33..0905502bee15 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c | |||
| @@ -82,7 +82,7 @@ void __init arm_dt_init_cpu_maps(void) | |||
| 82 | u32 i, j, cpuidx = 1; | 82 | u32 i, j, cpuidx = 1; |
| 83 | u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; | 83 | u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; |
| 84 | 84 | ||
| 85 | u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = UINT_MAX }; | 85 | u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID }; |
| 86 | bool bootcpu_valid = false; | 86 | bool bootcpu_valid = false; |
| 87 | cpus = of_find_node_by_path("/cpus"); | 87 | cpus = of_find_node_by_path("/cpus"); |
| 88 | 88 | ||
| @@ -92,6 +92,9 @@ void __init arm_dt_init_cpu_maps(void) | |||
| 92 | for_each_child_of_node(cpus, cpu) { | 92 | for_each_child_of_node(cpus, cpu) { |
| 93 | u32 hwid; | 93 | u32 hwid; |
| 94 | 94 | ||
| 95 | if (of_node_cmp(cpu->type, "cpu")) | ||
| 96 | continue; | ||
| 97 | |||
| 95 | pr_debug(" * %s...\n", cpu->full_name); | 98 | pr_debug(" * %s...\n", cpu->full_name); |
| 96 | /* | 99 | /* |
| 97 | * A device tree containing CPU nodes with missing "reg" | 100 | * A device tree containing CPU nodes with missing "reg" |
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8ef8c9337809..4fb074c446bf 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
| @@ -134,6 +134,10 @@ void machine_kexec(struct kimage *image) | |||
| 134 | unsigned long reboot_code_buffer_phys; | 134 | unsigned long reboot_code_buffer_phys; |
| 135 | void *reboot_code_buffer; | 135 | void *reboot_code_buffer; |
| 136 | 136 | ||
| 137 | if (num_online_cpus() > 1) { | ||
| 138 | pr_err("kexec: error: multiple CPUs still online\n"); | ||
| 139 | return; | ||
| 140 | } | ||
| 137 | 141 | ||
| 138 | page_list = image->head & PAGE_MASK; | 142 | page_list = image->head & PAGE_MASK; |
| 139 | 143 | ||
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 282de4826abb..6e8931ccf13e 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
| @@ -184,30 +184,61 @@ int __init reboot_setup(char *str) | |||
| 184 | 184 | ||
| 185 | __setup("reboot=", reboot_setup); | 185 | __setup("reboot=", reboot_setup); |
| 186 | 186 | ||
| 187 | /* | ||
| 188 | * Called by kexec, immediately prior to machine_kexec(). | ||
| 189 | * | ||
| 190 | * This must completely disable all secondary CPUs; simply causing those CPUs | ||
| 191 | * to execute e.g. a RAM-based pin loop is not sufficient. This allows the | ||
| 192 | * kexec'd kernel to use any and all RAM as it sees fit, without having to | ||
| 193 | * avoid any code or data used by any SW CPU pin loop. The CPU hotplug | ||
| 194 | * functionality embodied in disable_nonboot_cpus() to achieve this. | ||
| 195 | */ | ||
| 187 | void machine_shutdown(void) | 196 | void machine_shutdown(void) |
| 188 | { | 197 | { |
| 189 | #ifdef CONFIG_SMP | 198 | disable_nonboot_cpus(); |
| 190 | smp_send_stop(); | ||
| 191 | #endif | ||
| 192 | } | 199 | } |
| 193 | 200 | ||
| 201 | /* | ||
| 202 | * Halting simply requires that the secondary CPUs stop performing any | ||
| 203 | * activity (executing tasks, handling interrupts). smp_send_stop() | ||
| 204 | * achieves this. | ||
| 205 | */ | ||
| 194 | void machine_halt(void) | 206 | void machine_halt(void) |
| 195 | { | 207 | { |
| 196 | machine_shutdown(); | 208 | smp_send_stop(); |
| 209 | |||
| 197 | local_irq_disable(); | 210 | local_irq_disable(); |
| 198 | while (1); | 211 | while (1); |
| 199 | } | 212 | } |
| 200 | 213 | ||
| 214 | /* | ||
| 215 | * Power-off simply requires that the secondary CPUs stop performing any | ||
| 216 | * activity (executing tasks, handling interrupts). smp_send_stop() | ||
| 217 | * achieves this. When the system power is turned off, it will take all CPUs | ||
| 218 | * with it. | ||
| 219 | */ | ||
| 201 | void machine_power_off(void) | 220 | void machine_power_off(void) |
| 202 | { | 221 | { |
| 203 | machine_shutdown(); | 222 | smp_send_stop(); |
| 223 | |||
| 204 | if (pm_power_off) | 224 | if (pm_power_off) |
| 205 | pm_power_off(); | 225 | pm_power_off(); |
| 206 | } | 226 | } |
| 207 | 227 | ||
| 228 | /* | ||
| 229 | * Restart requires that the secondary CPUs stop performing any activity | ||
| 230 | * while the primary CPU resets the system. Systems with a single CPU can | ||
| 231 | * use soft_restart() as their machine descriptor's .restart hook, since that | ||
| 232 | * will cause the only available CPU to reset. Systems with multiple CPUs must | ||
| 233 | * provide a HW restart implementation, to ensure that all CPUs reset at once. | ||
| 234 | * This is required so that any code running after reset on the primary CPU | ||
| 235 | * doesn't have to co-ordinate with other CPUs to ensure they aren't still | ||
| 236 | * executing pre-reset code, and using RAM that the primary CPU's code wishes | ||
| 237 | * to use. Implementing such co-ordination would be essentially impossible. | ||
| 238 | */ | ||
| 208 | void machine_restart(char *cmd) | 239 | void machine_restart(char *cmd) |
| 209 | { | 240 | { |
| 210 | machine_shutdown(); | 241 | smp_send_stop(); |
| 211 | 242 | ||
| 212 | arm_pm_restart(reboot_mode, cmd); | 243 | arm_pm_restart(reboot_mode, cmd); |
| 213 | 244 | ||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 1522c7ae31b0..b4b1d397592b 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
| @@ -444,7 +444,7 @@ void notrace cpu_init(void) | |||
| 444 | : "r14"); | 444 | : "r14"); |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | int __cpu_logical_map[NR_CPUS]; | 447 | u32 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID }; |
| 448 | 448 | ||
| 449 | void __init smp_setup_processor_id(void) | 449 | void __init smp_setup_processor_id(void) |
| 450 | { | 450 | { |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 550d63cef68e..5919eb451bb9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
| @@ -651,17 +651,6 @@ void smp_send_reschedule(int cpu) | |||
| 651 | smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); | 651 | smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); |
| 652 | } | 652 | } |
| 653 | 653 | ||
| 654 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 655 | static void smp_kill_cpus(cpumask_t *mask) | ||
| 656 | { | ||
| 657 | unsigned int cpu; | ||
| 658 | for_each_cpu(cpu, mask) | ||
| 659 | platform_cpu_kill(cpu); | ||
| 660 | } | ||
| 661 | #else | ||
| 662 | static void smp_kill_cpus(cpumask_t *mask) { } | ||
| 663 | #endif | ||
| 664 | |||
| 665 | void smp_send_stop(void) | 654 | void smp_send_stop(void) |
| 666 | { | 655 | { |
| 667 | unsigned long timeout; | 656 | unsigned long timeout; |
| @@ -679,8 +668,6 @@ void smp_send_stop(void) | |||
| 679 | 668 | ||
| 680 | if (num_online_cpus() > 1) | 669 | if (num_online_cpus() > 1) |
| 681 | pr_warning("SMP: failed to stop secondary CPUs\n"); | 670 | pr_warning("SMP: failed to stop secondary CPUs\n"); |
| 682 | |||
| 683 | smp_kill_cpus(&mask); | ||
| 684 | } | 671 | } |
| 685 | 672 | ||
| 686 | /* | 673 | /* |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 15451ee4acc8..515b00064da8 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
| @@ -92,6 +92,14 @@ ENTRY(v7_flush_dcache_louis) | |||
| 92 | mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr | 92 | mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr |
| 93 | ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr | 93 | ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr |
| 94 | ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr | 94 | ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr |
| 95 | #ifdef CONFIG_ARM_ERRATA_643719 | ||
| 96 | ALT_SMP(mrceq p15, 0, r2, c0, c0, 0) @ read main ID register | ||
| 97 | ALT_UP(moveq pc, lr) @ LoUU is zero, so nothing to do | ||
| 98 | ldreq r1, =0x410fc090 @ ID of ARM Cortex A9 r0p? | ||
| 99 | biceq r2, r2, #0x0000000f @ clear minor revision number | ||
| 100 | teqeq r2, r1 @ test for errata affected core and if so... | ||
| 101 | orreqs r3, #(1 << 21) @ fix LoUIS value (and set flags state to 'ne') | ||
| 102 | #endif | ||
| 95 | ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 | 103 | ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 |
| 96 | ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 | 104 | ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 |
| 97 | moveq pc, lr @ return if level == 0 | 105 | moveq pc, lr @ return if level == 0 |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 0d473cce501c..32aa5861119f 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
| @@ -301,6 +301,39 @@ void flush_dcache_page(struct page *page) | |||
| 301 | EXPORT_SYMBOL(flush_dcache_page); | 301 | EXPORT_SYMBOL(flush_dcache_page); |
| 302 | 302 | ||
| 303 | /* | 303 | /* |
| 304 | * Ensure cache coherency for the kernel mapping of this page. We can | ||
| 305 | * assume that the page is pinned via kmap. | ||
| 306 | * | ||
| 307 | * If the page only exists in the page cache and there are no user | ||
| 308 | * space mappings, this is a no-op since the page was already marked | ||
| 309 | * dirty at creation. Otherwise, we need to flush the dirty kernel | ||
| 310 | * cache lines directly. | ||
| 311 | */ | ||
| 312 | void flush_kernel_dcache_page(struct page *page) | ||
| 313 | { | ||
| 314 | if (cache_is_vivt() || cache_is_vipt_aliasing()) { | ||
| 315 | struct address_space *mapping; | ||
| 316 | |||
| 317 | mapping = page_mapping(page); | ||
| 318 | |||
| 319 | if (!mapping || mapping_mapped(mapping)) { | ||
| 320 | void *addr; | ||
| 321 | |||
| 322 | addr = page_address(page); | ||
| 323 | /* | ||
| 324 | * kmap_atomic() doesn't set the page virtual | ||
| 325 | * address for highmem pages, and | ||
| 326 | * kunmap_atomic() takes care of cache | ||
| 327 | * flushing already. | ||
| 328 | */ | ||
| 329 | if (!IS_ENABLED(CONFIG_HIGHMEM) || addr) | ||
| 330 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); | ||
| 331 | } | ||
| 332 | } | ||
| 333 | } | ||
| 334 | EXPORT_SYMBOL(flush_kernel_dcache_page); | ||
| 335 | |||
| 336 | /* | ||
| 304 | * Flush an anonymous page so that users of get_user_pages() | 337 | * Flush an anonymous page so that users of get_user_pages() |
| 305 | * can safely access the data. The expected sequence is: | 338 | * can safely access the data. The expected sequence is: |
| 306 | * | 339 | * |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e0d8565671a6..4d409e6a552d 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
| @@ -616,10 +616,12 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, | |||
| 616 | } while (pte++, addr += PAGE_SIZE, addr != end); | 616 | } while (pte++, addr += PAGE_SIZE, addr != end); |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | static void __init map_init_section(pmd_t *pmd, unsigned long addr, | 619 | static void __init __map_init_section(pmd_t *pmd, unsigned long addr, |
| 620 | unsigned long end, phys_addr_t phys, | 620 | unsigned long end, phys_addr_t phys, |
| 621 | const struct mem_type *type) | 621 | const struct mem_type *type) |
| 622 | { | 622 | { |
| 623 | pmd_t *p = pmd; | ||
| 624 | |||
| 623 | #ifndef CONFIG_ARM_LPAE | 625 | #ifndef CONFIG_ARM_LPAE |
| 624 | /* | 626 | /* |
| 625 | * In classic MMU format, puds and pmds are folded in to | 627 | * In classic MMU format, puds and pmds are folded in to |
| @@ -638,7 +640,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr, | |||
| 638 | phys += SECTION_SIZE; | 640 | phys += SECTION_SIZE; |
| 639 | } while (pmd++, addr += SECTION_SIZE, addr != end); | 641 | } while (pmd++, addr += SECTION_SIZE, addr != end); |
| 640 | 642 | ||
| 641 | flush_pmd_entry(pmd); | 643 | flush_pmd_entry(p); |
| 642 | } | 644 | } |
| 643 | 645 | ||
| 644 | static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, | 646 | static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, |
| @@ -661,7 +663,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, | |||
| 661 | */ | 663 | */ |
| 662 | if (type->prot_sect && | 664 | if (type->prot_sect && |
| 663 | ((addr | next | phys) & ~SECTION_MASK) == 0) { | 665 | ((addr | next | phys) & ~SECTION_MASK) == 0) { |
| 664 | map_init_section(pmd, addr, next, phys, type); | 666 | __map_init_section(pmd, addr, next, phys, type); |
| 665 | } else { | 667 | } else { |
| 666 | alloc_init_pte(pmd, addr, next, | 668 | alloc_init_pte(pmd, addr, next, |
| 667 | __phys_to_pfn(phys), type); | 669 | __phys_to_pfn(phys), type); |
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index d51225f90ae2..eb5293a69a84 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c | |||
| @@ -57,6 +57,12 @@ void flush_dcache_page(struct page *page) | |||
| 57 | } | 57 | } |
| 58 | EXPORT_SYMBOL(flush_dcache_page); | 58 | EXPORT_SYMBOL(flush_dcache_page); |
| 59 | 59 | ||
| 60 | void flush_kernel_dcache_page(struct page *page) | ||
| 61 | { | ||
| 62 | __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); | ||
| 63 | } | ||
| 64 | EXPORT_SYMBOL(flush_kernel_dcache_page); | ||
| 65 | |||
| 60 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | 66 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
| 61 | unsigned long uaddr, void *dst, const void *src, | 67 | unsigned long uaddr, void *dst, const void *src, |
| 62 | unsigned long len) | 68 | unsigned long len) |
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S index d217e9795d74..aaeb6c127c7a 100644 --- a/arch/arm/mm/proc-fa526.S +++ b/arch/arm/mm/proc-fa526.S | |||
| @@ -81,7 +81,6 @@ ENDPROC(cpu_fa526_reset) | |||
| 81 | */ | 81 | */ |
| 82 | .align 4 | 82 | .align 4 |
| 83 | ENTRY(cpu_fa526_do_idle) | 83 | ENTRY(cpu_fa526_do_idle) |
| 84 | mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt | ||
| 85 | mov pc, lr | 84 | mov pc, lr |
| 86 | 85 | ||
| 87 | 86 | ||
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index f9a0aa725ea9..e3c48a3fe063 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
| @@ -333,3 +333,8 @@ ENTRY(\name\()_tlb_fns) | |||
| 333 | .endif | 333 | .endif |
| 334 | .size \name\()_tlb_fns, . - \name\()_tlb_fns | 334 | .size \name\()_tlb_fns, . - \name\()_tlb_fns |
| 335 | .endm | 335 | .endm |
| 336 | |||
| 337 | .macro globl_equ x, y | ||
| 338 | .globl \x | ||
| 339 | .equ \x, \y | ||
| 340 | .endm | ||
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 2c73a7301ff7..e35fec34453e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
| @@ -140,6 +140,29 @@ ENTRY(cpu_v7_do_resume) | |||
| 140 | ENDPROC(cpu_v7_do_resume) | 140 | ENDPROC(cpu_v7_do_resume) |
| 141 | #endif | 141 | #endif |
| 142 | 142 | ||
| 143 | #ifdef CONFIG_CPU_PJ4B | ||
| 144 | globl_equ cpu_pj4b_switch_mm, cpu_v7_switch_mm | ||
| 145 | globl_equ cpu_pj4b_set_pte_ext, cpu_v7_set_pte_ext | ||
| 146 | globl_equ cpu_pj4b_proc_init, cpu_v7_proc_init | ||
| 147 | globl_equ cpu_pj4b_proc_fin, cpu_v7_proc_fin | ||
| 148 | globl_equ cpu_pj4b_reset, cpu_v7_reset | ||
| 149 | #ifdef CONFIG_PJ4B_ERRATA_4742 | ||
| 150 | ENTRY(cpu_pj4b_do_idle) | ||
| 151 | dsb @ WFI may enter a low-power mode | ||
| 152 | wfi | ||
| 153 | dsb @barrier | ||
| 154 | mov pc, lr | ||
| 155 | ENDPROC(cpu_pj4b_do_idle) | ||
| 156 | #else | ||
| 157 | globl_equ cpu_pj4b_do_idle, cpu_v7_do_idle | ||
| 158 | #endif | ||
| 159 | globl_equ cpu_pj4b_dcache_clean_area, cpu_v7_dcache_clean_area | ||
| 160 | globl_equ cpu_pj4b_do_suspend, cpu_v7_do_suspend | ||
| 161 | globl_equ cpu_pj4b_do_resume, cpu_v7_do_resume | ||
| 162 | globl_equ cpu_pj4b_suspend_size, cpu_v7_suspend_size | ||
| 163 | |||
| 164 | #endif | ||
| 165 | |||
| 143 | __CPUINIT | 166 | __CPUINIT |
| 144 | 167 | ||
| 145 | /* | 168 | /* |
| @@ -350,6 +373,9 @@ __v7_setup_stack: | |||
| 350 | 373 | ||
| 351 | @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) | 374 | @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) |
| 352 | define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 | 375 | define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 |
| 376 | #ifdef CONFIG_CPU_PJ4B | ||
| 377 | define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 | ||
| 378 | #endif | ||
| 353 | 379 | ||
| 354 | .section ".rodata" | 380 | .section ".rodata" |
| 355 | 381 | ||
| @@ -362,7 +388,7 @@ __v7_setup_stack: | |||
| 362 | /* | 388 | /* |
| 363 | * Standard v7 proc info content | 389 | * Standard v7 proc info content |
| 364 | */ | 390 | */ |
| 365 | .macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0 | 391 | .macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions |
| 366 | ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ | 392 | ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ |
| 367 | PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags) | 393 | PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags) |
| 368 | ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ | 394 | ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ |
| @@ -375,7 +401,7 @@ __v7_setup_stack: | |||
| 375 | .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \ | 401 | .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \ |
| 376 | HWCAP_EDSP | HWCAP_TLS | \hwcaps | 402 | HWCAP_EDSP | HWCAP_TLS | \hwcaps |
| 377 | .long cpu_v7_name | 403 | .long cpu_v7_name |
| 378 | .long v7_processor_functions | 404 | .long \proc_fns |
| 379 | .long v7wbi_tlb_fns | 405 | .long v7wbi_tlb_fns |
| 380 | .long v6_user_fns | 406 | .long v6_user_fns |
| 381 | .long v7_cache_fns | 407 | .long v7_cache_fns |
| @@ -407,12 +433,14 @@ __v7_ca9mp_proc_info: | |||
| 407 | /* | 433 | /* |
| 408 | * Marvell PJ4B processor. | 434 | * Marvell PJ4B processor. |
| 409 | */ | 435 | */ |
| 436 | #ifdef CONFIG_CPU_PJ4B | ||
| 410 | .type __v7_pj4b_proc_info, #object | 437 | .type __v7_pj4b_proc_info, #object |
| 411 | __v7_pj4b_proc_info: | 438 | __v7_pj4b_proc_info: |
| 412 | .long 0x562f5840 | 439 | .long 0x560f5800 |
| 413 | .long 0xfffffff0 | 440 | .long 0xff0fff00 |
| 414 | __v7_proc __v7_pj4b_setup | 441 | __v7_proc __v7_pj4b_setup, proc_fns = pj4b_processor_functions |
| 415 | .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info | 442 | .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info |
| 443 | #endif | ||
| 416 | 444 | ||
| 417 | /* | 445 | /* |
| 418 | * ARM Ltd. Cortex A7 processor. | 446 | * ARM Ltd. Cortex A7 processor. |
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 1e49e5eb81e9..9ba33c40cdf8 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c | |||
| @@ -1336,6 +1336,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry, | |||
| 1336 | return; | 1336 | return; |
| 1337 | } | 1337 | } |
| 1338 | 1338 | ||
| 1339 | perf_callchain_store(entry, regs->pc); | ||
| 1339 | tail = (struct frame_tail __user *)regs->regs[29]; | 1340 | tail = (struct frame_tail __user *)regs->regs[29]; |
| 1340 | 1341 | ||
| 1341 | while (entry->nr < PERF_MAX_STACK_DEPTH && | 1342 | while (entry->nr < PERF_MAX_STACK_DEPTH && |
diff --git a/arch/ia64/include/asm/irqflags.h b/arch/ia64/include/asm/irqflags.h index 1bf2cf2f4ab4..cec6c06b52c0 100644 --- a/arch/ia64/include/asm/irqflags.h +++ b/arch/ia64/include/asm/irqflags.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #define _ASM_IA64_IRQFLAGS_H | 11 | #define _ASM_IA64_IRQFLAGS_H |
| 12 | 12 | ||
| 13 | #include <asm/pal.h> | 13 | #include <asm/pal.h> |
| 14 | #include <asm/kregs.h> | ||
| 14 | 15 | ||
| 15 | #ifdef CONFIG_IA64_DEBUG_IRQ | 16 | #ifdef CONFIG_IA64_DEBUG_IRQ |
| 16 | extern unsigned long last_cli_ip; | 17 | extern unsigned long last_cli_ip; |
diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h index f545477e61f3..471f481e67f3 100644 --- a/arch/metag/include/asm/hugetlb.h +++ b/arch/metag/include/asm/hugetlb.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define _ASM_METAG_HUGETLB_H | 2 | #define _ASM_METAG_HUGETLB_H |
| 3 | 3 | ||
| 4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
| 5 | #include <asm-generic/hugetlb.h> | ||
| 5 | 6 | ||
| 6 | 7 | ||
| 7 | static inline int is_hugepage_only_range(struct mm_struct *mm, | 8 | static inline int is_hugepage_only_range(struct mm_struct *mm, |
diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h index 678f68d5f37b..8730c0a3c37d 100644 --- a/arch/mn10300/include/asm/irqflags.h +++ b/arch/mn10300/include/asm/irqflags.h | |||
| @@ -13,9 +13,8 @@ | |||
| 13 | #define _ASM_IRQFLAGS_H | 13 | #define _ASM_IRQFLAGS_H |
| 14 | 14 | ||
| 15 | #include <asm/cpu-regs.h> | 15 | #include <asm/cpu-regs.h> |
| 16 | #ifndef __ASSEMBLY__ | 16 | /* linux/smp.h <- linux/irqflags.h needs asm/smp.h first */ |
| 17 | #include <linux/smp.h> | 17 | #include <asm/smp.h> |
| 18 | #endif | ||
| 19 | 18 | ||
| 20 | /* | 19 | /* |
| 21 | * interrupt control | 20 | * interrupt control |
diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h index 6745dbe64944..56c42417d428 100644 --- a/arch/mn10300/include/asm/smp.h +++ b/arch/mn10300/include/asm/smp.h | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #ifndef __ASSEMBLY__ | 24 | #ifndef __ASSEMBLY__ |
| 25 | #include <linux/threads.h> | 25 | #include <linux/threads.h> |
| 26 | #include <linux/cpumask.h> | 26 | #include <linux/cpumask.h> |
| 27 | #include <linux/thread_info.h> | ||
| 27 | #endif | 28 | #endif |
| 28 | 29 | ||
| 29 | #ifdef CONFIG_SMP | 30 | #ifdef CONFIG_SMP |
| @@ -85,7 +86,7 @@ extern cpumask_t cpu_boot_map; | |||
| 85 | extern void smp_init_cpus(void); | 86 | extern void smp_init_cpus(void); |
| 86 | extern void smp_cache_interrupt(void); | 87 | extern void smp_cache_interrupt(void); |
| 87 | extern void send_IPI_allbutself(int irq); | 88 | extern void send_IPI_allbutself(int irq); |
| 88 | extern int smp_nmi_call_function(smp_call_func_t func, void *info, int wait); | 89 | extern int smp_nmi_call_function(void (*func)(void *), void *info, int wait); |
| 89 | 90 | ||
| 90 | extern void arch_send_call_function_single_ipi(int cpu); | 91 | extern void arch_send_call_function_single_ipi(int cpu); |
| 91 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); | 92 | extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); |
| @@ -100,6 +101,7 @@ extern void __cpu_die(unsigned int cpu); | |||
| 100 | #ifndef __ASSEMBLY__ | 101 | #ifndef __ASSEMBLY__ |
| 101 | 102 | ||
| 102 | static inline void smp_init_cpus(void) {} | 103 | static inline void smp_init_cpus(void) {} |
| 104 | #define raw_smp_processor_id() 0 | ||
| 103 | 105 | ||
| 104 | #endif /* __ASSEMBLY__ */ | 106 | #endif /* __ASSEMBLY__ */ |
| 105 | #endif /* CONFIG_SMP */ | 107 | #endif /* CONFIG_SMP */ |
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h index 780560b330d9..d7966e0f7698 100644 --- a/arch/mn10300/include/asm/uaccess.h +++ b/arch/mn10300/include/asm/uaccess.h | |||
| @@ -161,7 +161,7 @@ struct __large_struct { unsigned long buf[100]; }; | |||
| 161 | 161 | ||
| 162 | #define __get_user_check(x, ptr, size) \ | 162 | #define __get_user_check(x, ptr, size) \ |
| 163 | ({ \ | 163 | ({ \ |
| 164 | const __typeof__(ptr) __guc_ptr = (ptr); \ | 164 | const __typeof__(*(ptr))* __guc_ptr = (ptr); \ |
| 165 | int _e; \ | 165 | int _e; \ |
| 166 | if (likely(__access_ok((unsigned long) __guc_ptr, (size)))) \ | 166 | if (likely(__access_ok((unsigned long) __guc_ptr, (size)))) \ |
| 167 | _e = __get_user_nocheck((x), __guc_ptr, (size)); \ | 167 | _e = __get_user_nocheck((x), __guc_ptr, (size)); \ |
diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c index 33c3bd1e5c6d..ebac9c11f796 100644 --- a/arch/mn10300/kernel/setup.c +++ b/arch/mn10300/kernel/setup.c | |||
| @@ -38,6 +38,7 @@ struct mn10300_cpuinfo boot_cpu_data; | |||
| 38 | /* For PCI or other memory-mapped resources */ | 38 | /* For PCI or other memory-mapped resources */ |
| 39 | unsigned long pci_mem_start = 0x18000000; | 39 | unsigned long pci_mem_start = 0x18000000; |
| 40 | 40 | ||
| 41 | static char __initdata cmd_line[COMMAND_LINE_SIZE]; | ||
| 41 | char redboot_command_line[COMMAND_LINE_SIZE] = | 42 | char redboot_command_line[COMMAND_LINE_SIZE] = |
| 42 | "console=ttyS0,115200 root=/dev/mtdblock3 rw"; | 43 | "console=ttyS0,115200 root=/dev/mtdblock3 rw"; |
| 43 | 44 | ||
| @@ -74,45 +75,19 @@ static const char *const mn10300_cputypes[] = { | |||
| 74 | }; | 75 | }; |
| 75 | 76 | ||
| 76 | /* | 77 | /* |
| 77 | * | 78 | * Pick out the memory size. We look for mem=size, |
| 79 | * where size is "size[KkMm]" | ||
| 78 | */ | 80 | */ |
| 79 | static void __init parse_mem_cmdline(char **cmdline_p) | 81 | static int __init early_mem(char *p) |
| 80 | { | 82 | { |
| 81 | char *from, *to, c; | 83 | memory_size = memparse(p, &p); |
| 82 | |||
| 83 | /* save unparsed command line copy for /proc/cmdline */ | ||
| 84 | strcpy(boot_command_line, redboot_command_line); | ||
| 85 | |||
| 86 | /* see if there's an explicit memory size option */ | ||
| 87 | from = redboot_command_line; | ||
| 88 | to = redboot_command_line; | ||
| 89 | c = ' '; | ||
| 90 | |||
| 91 | for (;;) { | ||
| 92 | if (c == ' ' && !memcmp(from, "mem=", 4)) { | ||
| 93 | if (to != redboot_command_line) | ||
| 94 | to--; | ||
| 95 | memory_size = memparse(from + 4, &from); | ||
| 96 | } | ||
| 97 | |||
| 98 | c = *(from++); | ||
| 99 | if (!c) | ||
| 100 | break; | ||
| 101 | |||
| 102 | *(to++) = c; | ||
| 103 | } | ||
| 104 | |||
| 105 | *to = '\0'; | ||
| 106 | *cmdline_p = redboot_command_line; | ||
| 107 | 84 | ||
| 108 | if (memory_size == 0) | 85 | if (memory_size == 0) |
| 109 | panic("Memory size not known\n"); | 86 | panic("Memory size not known\n"); |
| 110 | 87 | ||
| 111 | memory_end = (unsigned long) CONFIG_KERNEL_RAM_BASE_ADDRESS + | 88 | return 0; |
| 112 | memory_size; | ||
| 113 | if (memory_end > phys_memory_end) | ||
| 114 | memory_end = phys_memory_end; | ||
| 115 | } | 89 | } |
| 90 | early_param("mem", early_mem); | ||
| 116 | 91 | ||
| 117 | /* | 92 | /* |
| 118 | * architecture specific setup | 93 | * architecture specific setup |
| @@ -125,7 +100,20 @@ void __init setup_arch(char **cmdline_p) | |||
| 125 | cpu_init(); | 100 | cpu_init(); |
| 126 | unit_setup(); | 101 | unit_setup(); |
| 127 | smp_init_cpus(); | 102 | smp_init_cpus(); |
| 128 | parse_mem_cmdline(cmdline_p); | 103 | |
| 104 | /* save unparsed command line copy for /proc/cmdline */ | ||
| 105 | strlcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE); | ||
| 106 | |||
| 107 | /* populate cmd_line too for later use, preserving boot_command_line */ | ||
| 108 | strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); | ||
| 109 | *cmdline_p = cmd_line; | ||
| 110 | |||
| 111 | parse_early_param(); | ||
| 112 | |||
| 113 | memory_end = (unsigned long) CONFIG_KERNEL_RAM_BASE_ADDRESS + | ||
| 114 | memory_size; | ||
| 115 | if (memory_end > phys_memory_end) | ||
| 116 | memory_end = phys_memory_end; | ||
| 129 | 117 | ||
| 130 | init_mm.start_code = (unsigned long)&_text; | 118 | init_mm.start_code = (unsigned long)&_text; |
| 131 | init_mm.end_code = (unsigned long) &_etext; | 119 | init_mm.end_code = (unsigned long) &_etext; |
diff --git a/arch/parisc/include/asm/mmzone.h b/arch/parisc/include/asm/mmzone.h index cc50d33b7b88..b6b34a0987e7 100644 --- a/arch/parisc/include/asm/mmzone.h +++ b/arch/parisc/include/asm/mmzone.h | |||
| @@ -27,7 +27,7 @@ extern struct node_map_data node_data[]; | |||
| 27 | 27 | ||
| 28 | #define PFNNID_SHIFT (30 - PAGE_SHIFT) | 28 | #define PFNNID_SHIFT (30 - PAGE_SHIFT) |
| 29 | #define PFNNID_MAP_MAX 512 /* support 512GB */ | 29 | #define PFNNID_MAP_MAX 512 /* support 512GB */ |
| 30 | extern unsigned char pfnnid_map[PFNNID_MAP_MAX]; | 30 | extern signed char pfnnid_map[PFNNID_MAP_MAX]; |
| 31 | 31 | ||
| 32 | #ifndef CONFIG_64BIT | 32 | #ifndef CONFIG_64BIT |
| 33 | #define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT)) | 33 | #define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT)) |
| @@ -46,7 +46,7 @@ static inline int pfn_to_nid(unsigned long pfn) | |||
| 46 | i = pfn >> PFNNID_SHIFT; | 46 | i = pfn >> PFNNID_SHIFT; |
| 47 | BUG_ON(i >= ARRAY_SIZE(pfnnid_map)); | 47 | BUG_ON(i >= ARRAY_SIZE(pfnnid_map)); |
| 48 | 48 | ||
| 49 | return (int)pfnnid_map[i]; | 49 | return pfnnid_map[i]; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static inline int pfn_valid(int pfn) | 52 | static inline int pfn_valid(int pfn) |
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index 3234f492d575..465154076d23 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h | |||
| @@ -225,4 +225,9 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
| 225 | return channel ? 15 : 14; | 225 | return channel ? 15 : 14; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | #define HAVE_PCI_MMAP | ||
| 229 | |||
| 230 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||
| 231 | enum pci_mmap_state mmap_state, int write_combine); | ||
| 232 | |||
| 228 | #endif /* __ASM_PARISC_PCI_H */ | 233 | #endif /* __ASM_PARISC_PCI_H */ |
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index 9e2d2e408529..872275659d98 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c | |||
| @@ -1205,6 +1205,7 @@ static struct hp_hardware hp_hardware_list[] = { | |||
| 1205 | {HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, | 1205 | {HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"}, |
| 1206 | {HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, | 1206 | {HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"}, |
| 1207 | {HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, | 1207 | {HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"}, |
| 1208 | {HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"}, | ||
| 1208 | {HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, | 1209 | {HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"}, |
| 1209 | {HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, | 1210 | {HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"}, |
| 1210 | {HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, | 1211 | {HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"}, |
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 36d7f402e48e..b743a80eaba0 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S | |||
| @@ -860,7 +860,7 @@ ENTRY(flush_dcache_page_asm) | |||
| 860 | #endif | 860 | #endif |
| 861 | 861 | ||
| 862 | ldil L%dcache_stride, %r1 | 862 | ldil L%dcache_stride, %r1 |
| 863 | ldw R%dcache_stride(%r1), %r1 | 863 | ldw R%dcache_stride(%r1), r31 |
| 864 | 864 | ||
| 865 | #ifdef CONFIG_64BIT | 865 | #ifdef CONFIG_64BIT |
| 866 | depdi,z 1, 63-PAGE_SHIFT,1, %r25 | 866 | depdi,z 1, 63-PAGE_SHIFT,1, %r25 |
| @@ -868,26 +868,26 @@ ENTRY(flush_dcache_page_asm) | |||
| 868 | depwi,z 1, 31-PAGE_SHIFT,1, %r25 | 868 | depwi,z 1, 31-PAGE_SHIFT,1, %r25 |
| 869 | #endif | 869 | #endif |
| 870 | add %r28, %r25, %r25 | 870 | add %r28, %r25, %r25 |
| 871 | sub %r25, %r1, %r25 | 871 | sub %r25, r31, %r25 |
| 872 | 872 | ||
| 873 | 873 | ||
| 874 | 1: fdc,m %r1(%r28) | 874 | 1: fdc,m r31(%r28) |
| 875 | fdc,m %r1(%r28) | 875 | fdc,m r31(%r28) |
| 876 | fdc,m %r1(%r28) | 876 | fdc,m r31(%r28) |
| 877 | fdc,m %r1(%r28) | 877 | fdc,m r31(%r28) |
| 878 | fdc,m %r1(%r28) | 878 | fdc,m r31(%r28) |
| 879 | fdc,m %r1(%r28) | 879 | fdc,m r31(%r28) |
| 880 | fdc,m %r1(%r28) | 880 | fdc,m r31(%r28) |
| 881 | fdc,m %r1(%r28) | 881 | fdc,m r31(%r28) |
| 882 | fdc,m %r1(%r28) | 882 | fdc,m r31(%r28) |
| 883 | fdc,m %r1(%r28) | 883 | fdc,m r31(%r28) |
| 884 | fdc,m %r1(%r28) | 884 | fdc,m r31(%r28) |
| 885 | fdc,m %r1(%r28) | 885 | fdc,m r31(%r28) |
| 886 | fdc,m %r1(%r28) | 886 | fdc,m r31(%r28) |
| 887 | fdc,m %r1(%r28) | 887 | fdc,m r31(%r28) |
| 888 | fdc,m %r1(%r28) | 888 | fdc,m r31(%r28) |
| 889 | cmpb,COND(<<) %r28, %r25,1b | 889 | cmpb,COND(<<) %r28, %r25,1b |
| 890 | fdc,m %r1(%r28) | 890 | fdc,m r31(%r28) |
| 891 | 891 | ||
| 892 | sync | 892 | sync |
| 893 | 893 | ||
| @@ -936,7 +936,7 @@ ENTRY(flush_icache_page_asm) | |||
| 936 | #endif | 936 | #endif |
| 937 | 937 | ||
| 938 | ldil L%icache_stride, %r1 | 938 | ldil L%icache_stride, %r1 |
| 939 | ldw R%icache_stride(%r1), %r1 | 939 | ldw R%icache_stride(%r1), %r31 |
| 940 | 940 | ||
| 941 | #ifdef CONFIG_64BIT | 941 | #ifdef CONFIG_64BIT |
| 942 | depdi,z 1, 63-PAGE_SHIFT,1, %r25 | 942 | depdi,z 1, 63-PAGE_SHIFT,1, %r25 |
| @@ -944,28 +944,28 @@ ENTRY(flush_icache_page_asm) | |||
| 944 | depwi,z 1, 31-PAGE_SHIFT,1, %r25 | 944 | depwi,z 1, 31-PAGE_SHIFT,1, %r25 |
| 945 | #endif | 945 | #endif |
| 946 | add %r28, %r25, %r25 | 946 | add %r28, %r25, %r25 |
| 947 | sub %r25, %r1, %r25 | 947 | sub %r25, %r31, %r25 |
| 948 | 948 | ||
| 949 | 949 | ||
| 950 | /* fic only has the type 26 form on PA1.1, requiring an | 950 | /* fic only has the type 26 form on PA1.1, requiring an |
| 951 | * explicit space specification, so use %sr4 */ | 951 | * explicit space specification, so use %sr4 */ |
| 952 | 1: fic,m %r1(%sr4,%r28) | 952 | 1: fic,m %r31(%sr4,%r28) |
| 953 | fic,m %r1(%sr4,%r28) | 953 | fic,m %r31(%sr4,%r28) |
| 954 | fic,m %r1(%sr4,%r28) | 954 | fic,m %r31(%sr4,%r28) |
| 955 | fic,m %r1(%sr4,%r28) | 955 | fic,m %r31(%sr4,%r28) |
| 956 | fic,m %r1(%sr4,%r28) | 956 | fic,m %r31(%sr4,%r28) |
| 957 | fic,m %r1(%sr4,%r28) | 957 | fic,m %r31(%sr4,%r28) |
| 958 | fic,m %r1(%sr4,%r28) | 958 | fic,m %r31(%sr4,%r28) |
| 959 | fic,m %r1(%sr4,%r28) | 959 | fic,m %r31(%sr4,%r28) |
| 960 | fic,m %r1(%sr4,%r28) | 960 | fic,m %r31(%sr4,%r28) |
| 961 | fic,m %r1(%sr4,%r28) | 961 | fic,m %r31(%sr4,%r28) |
| 962 | fic,m %r1(%sr4,%r28) | 962 | fic,m %r31(%sr4,%r28) |
| 963 | fic,m %r1(%sr4,%r28) | 963 | fic,m %r31(%sr4,%r28) |
| 964 | fic,m %r1(%sr4,%r28) | 964 | fic,m %r31(%sr4,%r28) |
| 965 | fic,m %r1(%sr4,%r28) | 965 | fic,m %r31(%sr4,%r28) |
| 966 | fic,m %r1(%sr4,%r28) | 966 | fic,m %r31(%sr4,%r28) |
| 967 | cmpb,COND(<<) %r28, %r25,1b | 967 | cmpb,COND(<<) %r28, %r25,1b |
| 968 | fic,m %r1(%sr4,%r28) | 968 | fic,m %r31(%sr4,%r28) |
| 969 | 969 | ||
| 970 | sync | 970 | sync |
| 971 | 971 | ||
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 60309051875e..64f2764a8cef 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
| @@ -220,6 +220,33 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | 222 | ||
| 223 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | ||
| 224 | enum pci_mmap_state mmap_state, int write_combine) | ||
| 225 | { | ||
| 226 | unsigned long prot; | ||
| 227 | |||
| 228 | /* | ||
| 229 | * I/O space can be accessed via normal processor loads and stores on | ||
| 230 | * this platform but for now we elect not to do this and portable | ||
| 231 | * drivers should not do this anyway. | ||
| 232 | */ | ||
| 233 | if (mmap_state == pci_mmap_io) | ||
| 234 | return -EINVAL; | ||
| 235 | |||
| 236 | if (write_combine) | ||
| 237 | return -EINVAL; | ||
| 238 | |||
| 239 | /* | ||
| 240 | * Ignore write-combine; for now only return uncached mappings. | ||
| 241 | */ | ||
| 242 | prot = pgprot_val(vma->vm_page_prot); | ||
| 243 | prot |= _PAGE_NO_CACHE; | ||
| 244 | vma->vm_page_prot = __pgprot(prot); | ||
| 245 | |||
| 246 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | ||
| 247 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | ||
| 248 | } | ||
| 249 | |||
| 223 | /* | 250 | /* |
| 224 | * A driver is enabling the device. We make sure that all the appropriate | 251 | * A driver is enabling the device. We make sure that all the appropriate |
| 225 | * bits are set to allow the device to operate as the driver is expecting. | 252 | * bits are set to allow the device to operate as the driver is expecting. |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 1c965642068b..505b56c6b9b9 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
| @@ -47,7 +47,7 @@ pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pt | |||
| 47 | 47 | ||
| 48 | #ifdef CONFIG_DISCONTIGMEM | 48 | #ifdef CONFIG_DISCONTIGMEM |
| 49 | struct node_map_data node_data[MAX_NUMNODES] __read_mostly; | 49 | struct node_map_data node_data[MAX_NUMNODES] __read_mostly; |
| 50 | unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; | 50 | signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; |
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | static struct resource data_resource = { | 53 | static struct resource data_resource = { |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 5cd7ad0c1176..1a1b51189773 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
| @@ -673,7 +673,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
| 673 | ret = s; | 673 | ret = s; |
| 674 | goto out; | 674 | goto out; |
| 675 | } | 675 | } |
| 676 | kvmppc_lazy_ee_enable(); | ||
| 677 | 676 | ||
| 678 | kvm_guest_enter(); | 677 | kvm_guest_enter(); |
| 679 | 678 | ||
| @@ -699,6 +698,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
| 699 | kvmppc_load_guest_fp(vcpu); | 698 | kvmppc_load_guest_fp(vcpu); |
| 700 | #endif | 699 | #endif |
| 701 | 700 | ||
| 701 | kvmppc_lazy_ee_enable(); | ||
| 702 | |||
| 702 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); | 703 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); |
| 703 | 704 | ||
| 704 | /* No need for kvm_guest_exit. It's done in handle_exit. | 705 | /* No need for kvm_guest_exit. It's done in handle_exit. |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 237c8e5f2640..77fdd2cef33b 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
| @@ -592,8 +592,14 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, | |||
| 592 | do { | 592 | do { |
| 593 | pmd = pmd_offset(pud, addr); | 593 | pmd = pmd_offset(pud, addr); |
| 594 | next = pmd_addr_end(addr, end); | 594 | next = pmd_addr_end(addr, end); |
| 595 | if (pmd_none_or_clear_bad(pmd)) | 595 | if (!is_hugepd(pmd)) { |
| 596 | /* | ||
| 597 | * if it is not hugepd pointer, we should already find | ||
| 598 | * it cleared. | ||
| 599 | */ | ||
| 600 | WARN_ON(!pmd_none_or_clear_bad(pmd)); | ||
| 596 | continue; | 601 | continue; |
| 602 | } | ||
| 597 | #ifdef CONFIG_PPC_FSL_BOOK3E | 603 | #ifdef CONFIG_PPC_FSL_BOOK3E |
| 598 | /* | 604 | /* |
| 599 | * Increment next by the size of the huge mapping since | 605 | * Increment next by the size of the huge mapping since |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 028ac1f71b51..46ac1ddea683 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -97,22 +97,14 @@ static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 97 | return indirect_read_config(bus, devfn, offset, len, val); | 97 | return indirect_read_config(bus, devfn, offset, len, val); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static struct pci_ops fsl_indirect_pci_ops = | 100 | #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) |
| 101 | |||
| 102 | static struct pci_ops fsl_indirect_pcie_ops = | ||
| 101 | { | 103 | { |
| 102 | .read = fsl_indirect_read_config, | 104 | .read = fsl_indirect_read_config, |
| 103 | .write = indirect_write_config, | 105 | .write = indirect_write_config, |
| 104 | }; | 106 | }; |
| 105 | 107 | ||
| 106 | static void __init fsl_setup_indirect_pci(struct pci_controller* hose, | ||
| 107 | resource_size_t cfg_addr, | ||
| 108 | resource_size_t cfg_data, u32 flags) | ||
| 109 | { | ||
| 110 | setup_indirect_pci(hose, cfg_addr, cfg_data, flags); | ||
| 111 | hose->ops = &fsl_indirect_pci_ops; | ||
| 112 | } | ||
| 113 | |||
| 114 | #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) | ||
| 115 | |||
| 116 | #define MAX_PHYS_ADDR_BITS 40 | 108 | #define MAX_PHYS_ADDR_BITS 40 |
| 117 | static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS; | 109 | static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS; |
| 118 | 110 | ||
| @@ -504,13 +496,15 @@ int __init fsl_add_bridge(struct platform_device *pdev, int is_primary) | |||
| 504 | if (!hose->private_data) | 496 | if (!hose->private_data) |
| 505 | goto no_bridge; | 497 | goto no_bridge; |
| 506 | 498 | ||
| 507 | fsl_setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, | 499 | setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4, |
| 508 | PPC_INDIRECT_TYPE_BIG_ENDIAN); | 500 | PPC_INDIRECT_TYPE_BIG_ENDIAN); |
| 509 | 501 | ||
| 510 | if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) | 502 | if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) |
| 511 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; | 503 | hose->indirect_type |= PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK; |
| 512 | 504 | ||
| 513 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { | 505 | if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { |
| 506 | /* use fsl_indirect_read_config for PCIe */ | ||
| 507 | hose->ops = &fsl_indirect_pcie_ops; | ||
| 514 | /* For PCIE read HEADER_TYPE to identify controler mode */ | 508 | /* For PCIE read HEADER_TYPE to identify controler mode */ |
| 515 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); | 509 | early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); |
| 516 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) | 510 | if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) |
| @@ -814,8 +808,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) | |||
| 814 | if (ret) | 808 | if (ret) |
| 815 | goto err0; | 809 | goto err0; |
| 816 | } else { | 810 | } else { |
| 817 | fsl_setup_indirect_pci(hose, rsrc_cfg.start, | 811 | setup_indirect_pci(hose, rsrc_cfg.start, |
| 818 | rsrc_cfg.start + 4, 0); | 812 | rsrc_cfg.start + 4, 0); |
| 819 | } | 813 | } |
| 820 | 814 | ||
| 821 | printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " | 815 | printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " |
diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h index 886ac7d4937a..2f8c1abeb086 100644 --- a/arch/s390/include/asm/dma-mapping.h +++ b/arch/s390/include/asm/dma-mapping.h | |||
| @@ -50,9 +50,10 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
| 50 | { | 50 | { |
| 51 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 51 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
| 52 | 52 | ||
| 53 | debug_dma_mapping_error(dev, dma_addr); | ||
| 53 | if (dma_ops->mapping_error) | 54 | if (dma_ops->mapping_error) |
| 54 | return dma_ops->mapping_error(dev, dma_addr); | 55 | return dma_ops->mapping_error(dev, dma_addr); |
| 55 | return (dma_addr == 0UL); | 56 | return (dma_addr == DMA_ERROR_CODE); |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 59 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index d8a6a385d048..feb719d3c851 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -754,9 +754,9 @@ static struct bin_attribute sys_reipl_fcp_scp_data_attr = { | |||
| 754 | .write = reipl_fcp_scpdata_write, | 754 | .write = reipl_fcp_scpdata_write, |
| 755 | }; | 755 | }; |
| 756 | 756 | ||
| 757 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", | 757 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n", |
| 758 | reipl_block_fcp->ipl_info.fcp.wwpn); | 758 | reipl_block_fcp->ipl_info.fcp.wwpn); |
| 759 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", | 759 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n", |
| 760 | reipl_block_fcp->ipl_info.fcp.lun); | 760 | reipl_block_fcp->ipl_info.fcp.lun); |
| 761 | DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", | 761 | DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n", |
| 762 | reipl_block_fcp->ipl_info.fcp.bootprog); | 762 | reipl_block_fcp->ipl_info.fcp.bootprog); |
| @@ -1323,9 +1323,9 @@ static struct shutdown_action __refdata reipl_action = { | |||
| 1323 | 1323 | ||
| 1324 | /* FCP dump device attributes */ | 1324 | /* FCP dump device attributes */ |
| 1325 | 1325 | ||
| 1326 | DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n", | 1326 | DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n", |
| 1327 | dump_block_fcp->ipl_info.fcp.wwpn); | 1327 | dump_block_fcp->ipl_info.fcp.wwpn); |
| 1328 | DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n", | 1328 | DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n", |
| 1329 | dump_block_fcp->ipl_info.fcp.lun); | 1329 | dump_block_fcp->ipl_info.fcp.lun); |
| 1330 | DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", | 1330 | DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n", |
| 1331 | dump_block_fcp->ipl_info.fcp.bootprog); | 1331 | dump_block_fcp->ipl_info.fcp.bootprog); |
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 408e866ae548..dd3c1994b8bd 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
| @@ -312,6 +312,7 @@ void measurement_alert_subclass_unregister(void) | |||
| 312 | } | 312 | } |
| 313 | EXPORT_SYMBOL(measurement_alert_subclass_unregister); | 313 | EXPORT_SYMBOL(measurement_alert_subclass_unregister); |
| 314 | 314 | ||
| 315 | #ifdef CONFIG_SMP | ||
| 315 | void synchronize_irq(unsigned int irq) | 316 | void synchronize_irq(unsigned int irq) |
| 316 | { | 317 | { |
| 317 | /* | 318 | /* |
| @@ -320,6 +321,7 @@ void synchronize_irq(unsigned int irq) | |||
| 320 | */ | 321 | */ |
| 321 | } | 322 | } |
| 322 | EXPORT_SYMBOL_GPL(synchronize_irq); | 323 | EXPORT_SYMBOL_GPL(synchronize_irq); |
| 324 | #endif | ||
| 323 | 325 | ||
| 324 | #ifndef CONFIG_PCI | 326 | #ifndef CONFIG_PCI |
| 325 | 327 | ||
diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c index 3cbd3b8bf311..cca388253a39 100644 --- a/arch/s390/mm/mem_detect.c +++ b/arch/s390/mm/mem_detect.c | |||
| @@ -123,7 +123,8 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr, | |||
| 123 | continue; | 123 | continue; |
| 124 | } else if ((addr <= chunk->addr) && | 124 | } else if ((addr <= chunk->addr) && |
| 125 | (addr + size >= chunk->addr + chunk->size)) { | 125 | (addr + size >= chunk->addr + chunk->size)) { |
| 126 | memset(chunk, 0 , sizeof(*chunk)); | 126 | memmove(chunk, chunk + 1, (MEMORY_CHUNKS-i-1) * sizeof(*chunk)); |
| 127 | memset(&mem_chunk[MEMORY_CHUNKS-1], 0, sizeof(*chunk)); | ||
| 127 | } else if (addr + size < chunk->addr + chunk->size) { | 128 | } else if (addr + size < chunk->addr + chunk->size) { |
| 128 | chunk->size = chunk->addr + chunk->size - addr - size; | 129 | chunk->size = chunk->addr + chunk->size - addr - size; |
| 129 | chunk->addr = addr + size; | 130 | chunk->addr = addr + size; |
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index ff18e3cfb6b1..7e4a97fbded4 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
| @@ -6,6 +6,7 @@ generic-y += cputime.h | |||
| 6 | generic-y += div64.h | 6 | generic-y += div64.h |
| 7 | generic-y += emergency-restart.h | 7 | generic-y += emergency-restart.h |
| 8 | generic-y += exec.h | 8 | generic-y += exec.h |
| 9 | generic-y += linkage.h | ||
| 9 | generic-y += local64.h | 10 | generic-y += local64.h |
| 10 | generic-y += mutex.h | 11 | generic-y += mutex.h |
| 11 | generic-y += irq_regs.h | 12 | generic-y += irq_regs.h |
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 15a716934e4d..b836e9297f2a 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h | |||
| @@ -135,7 +135,7 @@ static inline int sparc_leon3_cpuid(void) | |||
| 135 | 135 | ||
| 136 | #ifdef CONFIG_SMP | 136 | #ifdef CONFIG_SMP |
| 137 | # define LEON3_IRQ_IPI_DEFAULT 13 | 137 | # define LEON3_IRQ_IPI_DEFAULT 13 |
| 138 | # define LEON3_IRQ_TICKER (leon3_ticker_irq) | 138 | # define LEON3_IRQ_TICKER (leon3_gptimer_irq) |
| 139 | # define LEON3_IRQ_CROSS_CALL 15 | 139 | # define LEON3_IRQ_CROSS_CALL 15 |
| 140 | #endif | 140 | #endif |
| 141 | 141 | ||
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h index f3034eddf468..24ec48c3ff90 100644 --- a/arch/sparc/include/asm/leon_amba.h +++ b/arch/sparc/include/asm/leon_amba.h | |||
| @@ -47,6 +47,7 @@ struct amba_prom_registers { | |||
| 47 | #define LEON3_GPTIMER_LD 4 | 47 | #define LEON3_GPTIMER_LD 4 |
| 48 | #define LEON3_GPTIMER_IRQEN 8 | 48 | #define LEON3_GPTIMER_IRQEN 8 |
| 49 | #define LEON3_GPTIMER_SEPIRQ 8 | 49 | #define LEON3_GPTIMER_SEPIRQ 8 |
| 50 | #define LEON3_GPTIMER_TIMERS 0x7 | ||
| 50 | 51 | ||
| 51 | #define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */ | 52 | #define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */ |
| 52 | /* 0 = hold scalar and counter */ | 53 | /* 0 = hold scalar and counter */ |
diff --git a/arch/sparc/include/asm/linkage.h b/arch/sparc/include/asm/linkage.h deleted file mode 100644 index 291c2d01c44f..000000000000 --- a/arch/sparc/include/asm/linkage.h +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | #ifndef __ASM_LINKAGE_H | ||
| 2 | #define __ASM_LINKAGE_H | ||
| 3 | |||
| 4 | /* Nothing to see here... */ | ||
| 5 | |||
| 6 | #endif | ||
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 75bb608c423e..5ef48dab5636 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c | |||
| @@ -843,7 +843,8 @@ void ldom_reboot(const char *boot_command) | |||
| 843 | unsigned long len; | 843 | unsigned long len; |
| 844 | 844 | ||
| 845 | strcpy(full_boot_str, "boot "); | 845 | strcpy(full_boot_str, "boot "); |
| 846 | strcpy(full_boot_str + strlen("boot "), boot_command); | 846 | strlcpy(full_boot_str + strlen("boot "), boot_command, |
| 847 | sizeof(full_boot_str + strlen("boot "))); | ||
| 847 | len = strlen(full_boot_str); | 848 | len = strlen(full_boot_str); |
| 848 | 849 | ||
| 849 | if (reboot_data_supported) { | 850 | if (reboot_data_supported) { |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 7c0231dabe44..b7c68976cbc7 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
| @@ -38,7 +38,6 @@ static DEFINE_SPINLOCK(leon_irq_lock); | |||
| 38 | 38 | ||
| 39 | unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ | 39 | unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ |
| 40 | unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ | 40 | unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ |
| 41 | int leon3_ticker_irq; /* Timer ticker IRQ */ | ||
| 42 | unsigned int sparc_leon_eirq; | 41 | unsigned int sparc_leon_eirq; |
| 43 | #define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu]) | 42 | #define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu]) |
| 44 | #define LEON_IACK (&leon3_irqctrl_regs->iclear) | 43 | #define LEON_IACK (&leon3_irqctrl_regs->iclear) |
| @@ -278,6 +277,9 @@ irqreturn_t leon_percpu_timer_ce_interrupt(int irq, void *unused) | |||
| 278 | 277 | ||
| 279 | leon_clear_profile_irq(cpu); | 278 | leon_clear_profile_irq(cpu); |
| 280 | 279 | ||
| 280 | if (cpu == boot_cpu_id) | ||
| 281 | timer_interrupt(irq, NULL); | ||
| 282 | |||
| 281 | ce = &per_cpu(sparc32_clockevent, cpu); | 283 | ce = &per_cpu(sparc32_clockevent, cpu); |
| 282 | 284 | ||
| 283 | irq_enter(); | 285 | irq_enter(); |
| @@ -299,6 +301,7 @@ void __init leon_init_timers(void) | |||
| 299 | int icsel; | 301 | int icsel; |
| 300 | int ampopts; | 302 | int ampopts; |
| 301 | int err; | 303 | int err; |
| 304 | u32 config; | ||
| 302 | 305 | ||
| 303 | sparc_config.get_cycles_offset = leon_cycles_offset; | 306 | sparc_config.get_cycles_offset = leon_cycles_offset; |
| 304 | sparc_config.cs_period = 1000000 / HZ; | 307 | sparc_config.cs_period = 1000000 / HZ; |
| @@ -377,23 +380,6 @@ void __init leon_init_timers(void) | |||
| 377 | LEON3_BYPASS_STORE_PA( | 380 | LEON3_BYPASS_STORE_PA( |
| 378 | &leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0); | 381 | &leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0); |
| 379 | 382 | ||
| 380 | #ifdef CONFIG_SMP | ||
| 381 | leon3_ticker_irq = leon3_gptimer_irq + 1 + leon3_gptimer_idx; | ||
| 382 | |||
| 383 | if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & | ||
| 384 | (1<<LEON3_GPTIMER_SEPIRQ))) { | ||
| 385 | printk(KERN_ERR "timer not configured with separate irqs\n"); | ||
| 386 | BUG(); | ||
| 387 | } | ||
| 388 | |||
| 389 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, | ||
| 390 | 0); | ||
| 391 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, | ||
| 392 | (((1000000/HZ) - 1))); | ||
| 393 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, | ||
| 394 | 0); | ||
| 395 | #endif | ||
| 396 | |||
| 397 | /* | 383 | /* |
| 398 | * The IRQ controller may (if implemented) consist of multiple | 384 | * The IRQ controller may (if implemented) consist of multiple |
| 399 | * IRQ controllers, each mapped on a 4Kb boundary. | 385 | * IRQ controllers, each mapped on a 4Kb boundary. |
| @@ -416,13 +402,6 @@ void __init leon_init_timers(void) | |||
| 416 | if (eirq != 0) | 402 | if (eirq != 0) |
| 417 | leon_eirq_setup(eirq); | 403 | leon_eirq_setup(eirq); |
| 418 | 404 | ||
| 419 | irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx); | ||
| 420 | err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); | ||
| 421 | if (err) { | ||
| 422 | printk(KERN_ERR "unable to attach timer IRQ%d\n", irq); | ||
| 423 | prom_halt(); | ||
| 424 | } | ||
| 425 | |||
| 426 | #ifdef CONFIG_SMP | 405 | #ifdef CONFIG_SMP |
| 427 | { | 406 | { |
| 428 | unsigned long flags; | 407 | unsigned long flags; |
| @@ -439,30 +418,31 @@ void __init leon_init_timers(void) | |||
| 439 | } | 418 | } |
| 440 | #endif | 419 | #endif |
| 441 | 420 | ||
| 442 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, | 421 | config = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config); |
| 443 | LEON3_GPTIMER_EN | | 422 | if (config & (1 << LEON3_GPTIMER_SEPIRQ)) |
| 444 | LEON3_GPTIMER_RL | | 423 | leon3_gptimer_irq += leon3_gptimer_idx; |
| 445 | LEON3_GPTIMER_LD | | 424 | else if ((config & LEON3_GPTIMER_TIMERS) > 1) |
| 446 | LEON3_GPTIMER_IRQEN); | 425 | pr_warn("GPTIMER uses shared irqs, using other timers of the same core will fail.\n"); |
| 447 | 426 | ||
| 448 | #ifdef CONFIG_SMP | 427 | #ifdef CONFIG_SMP |
| 449 | /* Install per-cpu IRQ handler for broadcasted ticker */ | 428 | /* Install per-cpu IRQ handler for broadcasted ticker */ |
| 450 | irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq, | 429 | irq = leon_build_device_irq(leon3_gptimer_irq, handle_percpu_irq, |
| 451 | "per-cpu", 0); | 430 | "per-cpu", 0); |
| 452 | err = request_irq(irq, leon_percpu_timer_ce_interrupt, | 431 | err = request_irq(irq, leon_percpu_timer_ce_interrupt, |
| 453 | IRQF_PERCPU | IRQF_TIMER, "ticker", | 432 | IRQF_PERCPU | IRQF_TIMER, "timer", NULL); |
| 454 | NULL); | 433 | #else |
| 434 | irq = _leon_build_device_irq(NULL, leon3_gptimer_irq); | ||
| 435 | err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL); | ||
| 436 | #endif | ||
| 455 | if (err) { | 437 | if (err) { |
| 456 | printk(KERN_ERR "unable to attach ticker IRQ%d\n", irq); | 438 | pr_err("Unable to attach timer IRQ%d\n", irq); |
| 457 | prom_halt(); | 439 | prom_halt(); |
| 458 | } | 440 | } |
| 459 | 441 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, | |
| 460 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, | ||
| 461 | LEON3_GPTIMER_EN | | 442 | LEON3_GPTIMER_EN | |
| 462 | LEON3_GPTIMER_RL | | 443 | LEON3_GPTIMER_RL | |
| 463 | LEON3_GPTIMER_LD | | 444 | LEON3_GPTIMER_LD | |
| 464 | LEON3_GPTIMER_IRQEN); | 445 | LEON3_GPTIMER_IRQEN); |
| 465 | #endif | ||
| 466 | return; | 446 | return; |
| 467 | bad: | 447 | bad: |
| 468 | printk(KERN_ERR "No Timer/irqctrl found\n"); | 448 | printk(KERN_ERR "No Timer/irqctrl found\n"); |
diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c index 7739a54315e2..6df26e37f879 100644 --- a/arch/sparc/kernel/leon_pci_grpci1.c +++ b/arch/sparc/kernel/leon_pci_grpci1.c | |||
| @@ -536,11 +536,9 @@ static int grpci1_of_probe(struct platform_device *ofdev) | |||
| 536 | 536 | ||
| 537 | /* find device register base address */ | 537 | /* find device register base address */ |
| 538 | res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); | 538 | res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); |
| 539 | regs = devm_request_and_ioremap(&ofdev->dev, res); | 539 | regs = devm_ioremap_resource(&ofdev->dev, res); |
| 540 | if (!regs) { | 540 | if (IS_ERR(regs)) |
| 541 | dev_err(&ofdev->dev, "io-regs mapping failed\n"); | 541 | return PTR_ERR(regs); |
| 542 | return -EADDRNOTAVAIL; | ||
| 543 | } | ||
| 544 | 542 | ||
| 545 | /* | 543 | /* |
| 546 | * check that we're in Host Slot and that we can act as a Host Bridge | 544 | * check that we're in Host Slot and that we can act as a Host Bridge |
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index bdf53d9a8d46..b0b3967a2dd2 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c | |||
| @@ -47,6 +47,10 @@ void pmc_leon_idle_fixup(void) | |||
| 47 | * MMU does not get a TLB miss here by using the MMU BYPASS ASI. | 47 | * MMU does not get a TLB miss here by using the MMU BYPASS ASI. |
| 48 | */ | 48 | */ |
| 49 | register unsigned int address = (unsigned int)leon3_irqctrl_regs; | 49 | register unsigned int address = (unsigned int)leon3_irqctrl_regs; |
| 50 | |||
| 51 | /* Interrupts need to be enabled to not hang the CPU */ | ||
| 52 | local_irq_enable(); | ||
| 53 | |||
| 50 | __asm__ __volatile__ ( | 54 | __asm__ __volatile__ ( |
| 51 | "wr %%g0, %%asr19\n" | 55 | "wr %%g0, %%asr19\n" |
| 52 | "lda [%0] %1, %%g0\n" | 56 | "lda [%0] %1, %%g0\n" |
| @@ -60,6 +64,9 @@ void pmc_leon_idle_fixup(void) | |||
| 60 | */ | 64 | */ |
| 61 | void pmc_leon_idle(void) | 65 | void pmc_leon_idle(void) |
| 62 | { | 66 | { |
| 67 | /* Interrupts need to be enabled to not hang the CPU */ | ||
| 68 | local_irq_enable(); | ||
| 69 | |||
| 63 | /* For systems without power-down, this will be no-op */ | 70 | /* For systems without power-down, this will be no-op */ |
| 64 | __asm__ __volatile__ ("wr %g0, %asr19\n\t"); | 71 | __asm__ __volatile__ ("wr %g0, %asr19\n\t"); |
| 65 | } | 72 | } |
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 38bf80a22f02..1434526970a6 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c | |||
| @@ -304,7 +304,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 304 | 304 | ||
| 305 | /* Initialize PROM console and command line. */ | 305 | /* Initialize PROM console and command line. */ |
| 306 | *cmdline_p = prom_getbootargs(); | 306 | *cmdline_p = prom_getbootargs(); |
| 307 | strcpy(boot_command_line, *cmdline_p); | 307 | strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); |
| 308 | parse_early_param(); | 308 | parse_early_param(); |
| 309 | 309 | ||
| 310 | boot_flags_init(*cmdline_p); | 310 | boot_flags_init(*cmdline_p); |
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 88a127b9c69e..13785547e435 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
| @@ -555,7 +555,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 555 | { | 555 | { |
| 556 | /* Initialize PROM console and command line. */ | 556 | /* Initialize PROM console and command line. */ |
| 557 | *cmdline_p = prom_getbootargs(); | 557 | *cmdline_p = prom_getbootargs(); |
| 558 | strcpy(boot_command_line, *cmdline_p); | 558 | strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); |
| 559 | parse_early_param(); | 559 | parse_early_param(); |
| 560 | 560 | ||
| 561 | boot_flags_init(*cmdline_p); | 561 | boot_flags_init(*cmdline_p); |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index a7171997adfd..04fd55a6e461 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
| @@ -1098,7 +1098,14 @@ static int __init grab_mblocks(struct mdesc_handle *md) | |||
| 1098 | m->size = *val; | 1098 | m->size = *val; |
| 1099 | val = mdesc_get_property(md, node, | 1099 | val = mdesc_get_property(md, node, |
| 1100 | "address-congruence-offset", NULL); | 1100 | "address-congruence-offset", NULL); |
| 1101 | m->offset = *val; | 1101 | |
| 1102 | /* The address-congruence-offset property is optional. | ||
| 1103 | * Explicity zero it be identifty this. | ||
| 1104 | */ | ||
| 1105 | if (val) | ||
| 1106 | m->offset = *val; | ||
| 1107 | else | ||
| 1108 | m->offset = 0UL; | ||
| 1102 | 1109 | ||
| 1103 | numadbg("MBLOCK[%d]: base[%llx] size[%llx] offset[%llx]\n", | 1110 | numadbg("MBLOCK[%d]: base[%llx] size[%llx] offset[%llx]\n", |
| 1104 | count - 1, m->base, m->size, m->offset); | 1111 | count - 1, m->base, m->size, m->offset); |
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 83d89bcb44af..37e7bc4c95b3 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
| @@ -85,8 +85,8 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | |||
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | if (!tb->active) { | 87 | if (!tb->active) { |
| 88 | global_flush_tlb_page(mm, vaddr); | ||
| 89 | flush_tsb_user_page(mm, vaddr); | 88 | flush_tsb_user_page(mm, vaddr); |
| 89 | global_flush_tlb_page(mm, vaddr); | ||
| 90 | goto out; | 90 | goto out; |
| 91 | } | 91 | } |
| 92 | 92 | ||
diff --git a/arch/sparc/prom/bootstr_32.c b/arch/sparc/prom/bootstr_32.c index f5ec32e0d419..d2b49d2365e7 100644 --- a/arch/sparc/prom/bootstr_32.c +++ b/arch/sparc/prom/bootstr_32.c | |||
| @@ -23,23 +23,25 @@ prom_getbootargs(void) | |||
| 23 | return barg_buf; | 23 | return barg_buf; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | switch(prom_vers) { | 26 | switch (prom_vers) { |
| 27 | case PROM_V0: | 27 | case PROM_V0: |
| 28 | cp = barg_buf; | 28 | cp = barg_buf; |
| 29 | /* Start from 1 and go over fd(0,0,0)kernel */ | 29 | /* Start from 1 and go over fd(0,0,0)kernel */ |
| 30 | for(iter = 1; iter < 8; iter++) { | 30 | for (iter = 1; iter < 8; iter++) { |
| 31 | arg = (*(romvec->pv_v0bootargs))->argv[iter]; | 31 | arg = (*(romvec->pv_v0bootargs))->argv[iter]; |
| 32 | if (arg == NULL) | 32 | if (arg == NULL) |
| 33 | break; | 33 | break; |
| 34 | while(*arg != 0) { | 34 | while (*arg != 0) { |
| 35 | /* Leave place for space and null. */ | 35 | /* Leave place for space and null. */ |
| 36 | if(cp >= barg_buf + BARG_LEN-2){ | 36 | if (cp >= barg_buf + BARG_LEN - 2) |
| 37 | /* We might issue a warning here. */ | 37 | /* We might issue a warning here. */ |
| 38 | break; | 38 | break; |
| 39 | } | ||
| 40 | *cp++ = *arg++; | 39 | *cp++ = *arg++; |
| 41 | } | 40 | } |
| 42 | *cp++ = ' '; | 41 | *cp++ = ' '; |
| 42 | if (cp >= barg_buf + BARG_LEN - 1) | ||
| 43 | /* We might issue a warning here. */ | ||
| 44 | break; | ||
| 43 | } | 45 | } |
| 44 | *cp = 0; | 46 | *cp = 0; |
| 45 | break; | 47 | break; |
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 92204c3800b5..bd1b2a3ac34e 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
| @@ -39,7 +39,7 @@ inline phandle __prom_getchild(phandle node) | |||
| 39 | return prom_node_to_node("child", node); | 39 | return prom_node_to_node("child", node); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | inline phandle prom_getchild(phandle node) | 42 | phandle prom_getchild(phandle node) |
| 43 | { | 43 | { |
| 44 | phandle cnode; | 44 | phandle cnode; |
| 45 | 45 | ||
| @@ -72,7 +72,7 @@ inline phandle __prom_getsibling(phandle node) | |||
| 72 | return prom_node_to_node(prom_peer_name, node); | 72 | return prom_node_to_node(prom_peer_name, node); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | inline phandle prom_getsibling(phandle node) | 75 | phandle prom_getsibling(phandle node) |
| 76 | { | 76 | { |
| 77 | phandle sibnode; | 77 | phandle sibnode; |
| 78 | 78 | ||
| @@ -89,7 +89,7 @@ EXPORT_SYMBOL(prom_getsibling); | |||
| 89 | /* Return the length in bytes of property 'prop' at node 'node'. | 89 | /* Return the length in bytes of property 'prop' at node 'node'. |
| 90 | * Return -1 on error. | 90 | * Return -1 on error. |
| 91 | */ | 91 | */ |
| 92 | inline int prom_getproplen(phandle node, const char *prop) | 92 | int prom_getproplen(phandle node, const char *prop) |
| 93 | { | 93 | { |
| 94 | unsigned long args[6]; | 94 | unsigned long args[6]; |
| 95 | 95 | ||
| @@ -113,8 +113,8 @@ EXPORT_SYMBOL(prom_getproplen); | |||
| 113 | * 'buffer' which has a size of 'bufsize'. If the acquisition | 113 | * 'buffer' which has a size of 'bufsize'. If the acquisition |
| 114 | * was successful the length will be returned, else -1 is returned. | 114 | * was successful the length will be returned, else -1 is returned. |
| 115 | */ | 115 | */ |
| 116 | inline int prom_getproperty(phandle node, const char *prop, | 116 | int prom_getproperty(phandle node, const char *prop, |
| 117 | char *buffer, int bufsize) | 117 | char *buffer, int bufsize) |
| 118 | { | 118 | { |
| 119 | unsigned long args[8]; | 119 | unsigned long args[8]; |
| 120 | int plen; | 120 | int plen; |
| @@ -141,7 +141,7 @@ EXPORT_SYMBOL(prom_getproperty); | |||
| 141 | /* Acquire an integer property and return its value. Returns -1 | 141 | /* Acquire an integer property and return its value. Returns -1 |
| 142 | * on failure. | 142 | * on failure. |
| 143 | */ | 143 | */ |
| 144 | inline int prom_getint(phandle node, const char *prop) | 144 | int prom_getint(phandle node, const char *prop) |
| 145 | { | 145 | { |
| 146 | int intprop; | 146 | int intprop; |
| 147 | 147 | ||
| @@ -235,7 +235,7 @@ static const char *prom_nextprop_name = "nextprop"; | |||
| 235 | /* Return the first property type for node 'node'. | 235 | /* Return the first property type for node 'node'. |
| 236 | * buffer should be at least 32B in length | 236 | * buffer should be at least 32B in length |
| 237 | */ | 237 | */ |
| 238 | inline char *prom_firstprop(phandle node, char *buffer) | 238 | char *prom_firstprop(phandle node, char *buffer) |
| 239 | { | 239 | { |
| 240 | unsigned long args[7]; | 240 | unsigned long args[7]; |
| 241 | 241 | ||
| @@ -261,7 +261,7 @@ EXPORT_SYMBOL(prom_firstprop); | |||
| 261 | * at node 'node' . Returns NULL string if no more | 261 | * at node 'node' . Returns NULL string if no more |
| 262 | * property types for this node. | 262 | * property types for this node. |
| 263 | */ | 263 | */ |
| 264 | inline char *prom_nextprop(phandle node, const char *oprop, char *buffer) | 264 | char *prom_nextprop(phandle node, const char *oprop, char *buffer) |
| 265 | { | 265 | { |
| 266 | unsigned long args[7]; | 266 | unsigned long args[7]; |
| 267 | char buf[32]; | 267 | char buf[32]; |
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c index 4385cb6fa00a..a93b02a25222 100644 --- a/arch/tile/lib/exports.c +++ b/arch/tile/lib/exports.c | |||
| @@ -84,4 +84,6 @@ uint64_t __ashrdi3(uint64_t, unsigned int); | |||
| 84 | EXPORT_SYMBOL(__ashrdi3); | 84 | EXPORT_SYMBOL(__ashrdi3); |
| 85 | uint64_t __ashldi3(uint64_t, unsigned int); | 85 | uint64_t __ashldi3(uint64_t, unsigned int); |
| 86 | EXPORT_SYMBOL(__ashldi3); | 86 | EXPORT_SYMBOL(__ashldi3); |
| 87 | int __ffsdi2(uint64_t); | ||
| 88 | EXPORT_SYMBOL(__ffsdi2); | ||
| 87 | #endif | 89 | #endif |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 685692c94f05..fe120da25625 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -2265,6 +2265,7 @@ source "fs/Kconfig.binfmt" | |||
| 2265 | config IA32_EMULATION | 2265 | config IA32_EMULATION |
| 2266 | bool "IA32 Emulation" | 2266 | bool "IA32 Emulation" |
| 2267 | depends on X86_64 | 2267 | depends on X86_64 |
| 2268 | select BINFMT_ELF | ||
| 2268 | select COMPAT_BINFMT_ELF | 2269 | select COMPAT_BINFMT_ELF |
| 2269 | select HAVE_UID16 | 2270 | select HAVE_UID16 |
| 2270 | ---help--- | 2271 | ---help--- |
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 62fe22cd4cba..477e9d75149b 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S | |||
| @@ -2681,56 +2681,68 @@ ENTRY(aesni_xts_crypt8) | |||
| 2681 | addq %rcx, KEYP | 2681 | addq %rcx, KEYP |
| 2682 | 2682 | ||
| 2683 | movdqa IV, STATE1 | 2683 | movdqa IV, STATE1 |
| 2684 | pxor 0x00(INP), STATE1 | 2684 | movdqu 0x00(INP), INC |
| 2685 | pxor INC, STATE1 | ||
| 2685 | movdqu IV, 0x00(OUTP) | 2686 | movdqu IV, 0x00(OUTP) |
| 2686 | 2687 | ||
| 2687 | _aesni_gf128mul_x_ble() | 2688 | _aesni_gf128mul_x_ble() |
| 2688 | movdqa IV, STATE2 | 2689 | movdqa IV, STATE2 |
| 2689 | pxor 0x10(INP), STATE2 | 2690 | movdqu 0x10(INP), INC |
| 2691 | pxor INC, STATE2 | ||
| 2690 | movdqu IV, 0x10(OUTP) | 2692 | movdqu IV, 0x10(OUTP) |
| 2691 | 2693 | ||
| 2692 | _aesni_gf128mul_x_ble() | 2694 | _aesni_gf128mul_x_ble() |
| 2693 | movdqa IV, STATE3 | 2695 | movdqa IV, STATE3 |
| 2694 | pxor 0x20(INP), STATE3 | 2696 | movdqu 0x20(INP), INC |
| 2697 | pxor INC, STATE3 | ||
| 2695 | movdqu IV, 0x20(OUTP) | 2698 | movdqu IV, 0x20(OUTP) |
| 2696 | 2699 | ||
| 2697 | _aesni_gf128mul_x_ble() | 2700 | _aesni_gf128mul_x_ble() |
| 2698 | movdqa IV, STATE4 | 2701 | movdqa IV, STATE4 |
| 2699 | pxor 0x30(INP), STATE4 | 2702 | movdqu 0x30(INP), INC |
| 2703 | pxor INC, STATE4 | ||
| 2700 | movdqu IV, 0x30(OUTP) | 2704 | movdqu IV, 0x30(OUTP) |
| 2701 | 2705 | ||
| 2702 | call *%r11 | 2706 | call *%r11 |
| 2703 | 2707 | ||
| 2704 | pxor 0x00(OUTP), STATE1 | 2708 | movdqu 0x00(OUTP), INC |
| 2709 | pxor INC, STATE1 | ||
| 2705 | movdqu STATE1, 0x00(OUTP) | 2710 | movdqu STATE1, 0x00(OUTP) |
| 2706 | 2711 | ||
| 2707 | _aesni_gf128mul_x_ble() | 2712 | _aesni_gf128mul_x_ble() |
| 2708 | movdqa IV, STATE1 | 2713 | movdqa IV, STATE1 |
| 2709 | pxor 0x40(INP), STATE1 | 2714 | movdqu 0x40(INP), INC |
| 2715 | pxor INC, STATE1 | ||
| 2710 | movdqu IV, 0x40(OUTP) | 2716 | movdqu IV, 0x40(OUTP) |
| 2711 | 2717 | ||
| 2712 | pxor 0x10(OUTP), STATE2 | 2718 | movdqu 0x10(OUTP), INC |
| 2719 | pxor INC, STATE2 | ||
| 2713 | movdqu STATE2, 0x10(OUTP) | 2720 | movdqu STATE2, 0x10(OUTP) |
| 2714 | 2721 | ||
| 2715 | _aesni_gf128mul_x_ble() | 2722 | _aesni_gf128mul_x_ble() |
| 2716 | movdqa IV, STATE2 | 2723 | movdqa IV, STATE2 |
| 2717 | pxor 0x50(INP), STATE2 | 2724 | movdqu 0x50(INP), INC |
| 2725 | pxor INC, STATE2 | ||
| 2718 | movdqu IV, 0x50(OUTP) | 2726 | movdqu IV, 0x50(OUTP) |
| 2719 | 2727 | ||
| 2720 | pxor 0x20(OUTP), STATE3 | 2728 | movdqu 0x20(OUTP), INC |
| 2729 | pxor INC, STATE3 | ||
| 2721 | movdqu STATE3, 0x20(OUTP) | 2730 | movdqu STATE3, 0x20(OUTP) |
| 2722 | 2731 | ||
| 2723 | _aesni_gf128mul_x_ble() | 2732 | _aesni_gf128mul_x_ble() |
| 2724 | movdqa IV, STATE3 | 2733 | movdqa IV, STATE3 |
| 2725 | pxor 0x60(INP), STATE3 | 2734 | movdqu 0x60(INP), INC |
| 2735 | pxor INC, STATE3 | ||
| 2726 | movdqu IV, 0x60(OUTP) | 2736 | movdqu IV, 0x60(OUTP) |
| 2727 | 2737 | ||
| 2728 | pxor 0x30(OUTP), STATE4 | 2738 | movdqu 0x30(OUTP), INC |
| 2739 | pxor INC, STATE4 | ||
| 2729 | movdqu STATE4, 0x30(OUTP) | 2740 | movdqu STATE4, 0x30(OUTP) |
| 2730 | 2741 | ||
| 2731 | _aesni_gf128mul_x_ble() | 2742 | _aesni_gf128mul_x_ble() |
| 2732 | movdqa IV, STATE4 | 2743 | movdqa IV, STATE4 |
| 2733 | pxor 0x70(INP), STATE4 | 2744 | movdqu 0x70(INP), INC |
| 2745 | pxor INC, STATE4 | ||
| 2734 | movdqu IV, 0x70(OUTP) | 2746 | movdqu IV, 0x70(OUTP) |
| 2735 | 2747 | ||
| 2736 | _aesni_gf128mul_x_ble() | 2748 | _aesni_gf128mul_x_ble() |
| @@ -2738,16 +2750,20 @@ ENTRY(aesni_xts_crypt8) | |||
| 2738 | 2750 | ||
| 2739 | call *%r11 | 2751 | call *%r11 |
| 2740 | 2752 | ||
| 2741 | pxor 0x40(OUTP), STATE1 | 2753 | movdqu 0x40(OUTP), INC |
| 2754 | pxor INC, STATE1 | ||
| 2742 | movdqu STATE1, 0x40(OUTP) | 2755 | movdqu STATE1, 0x40(OUTP) |
| 2743 | 2756 | ||
| 2744 | pxor 0x50(OUTP), STATE2 | 2757 | movdqu 0x50(OUTP), INC |
| 2758 | pxor INC, STATE2 | ||
| 2745 | movdqu STATE2, 0x50(OUTP) | 2759 | movdqu STATE2, 0x50(OUTP) |
| 2746 | 2760 | ||
| 2747 | pxor 0x60(OUTP), STATE3 | 2761 | movdqu 0x60(OUTP), INC |
| 2762 | pxor INC, STATE3 | ||
| 2748 | movdqu STATE3, 0x60(OUTP) | 2763 | movdqu STATE3, 0x60(OUTP) |
| 2749 | 2764 | ||
| 2750 | pxor 0x70(OUTP), STATE4 | 2765 | movdqu 0x70(OUTP), INC |
| 2766 | pxor INC, STATE4 | ||
| 2751 | movdqu STATE4, 0x70(OUTP) | 2767 | movdqu STATE4, 0x70(OUTP) |
| 2752 | 2768 | ||
| 2753 | ret | 2769 | ret |
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index ba870bb6dd8e..57873beb3292 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h | |||
| @@ -41,4 +41,9 @@ extern int vector_used_by_percpu_irq(unsigned int vector); | |||
| 41 | 41 | ||
| 42 | extern void init_ISA_irqs(void); | 42 | extern void init_ISA_irqs(void); |
| 43 | 43 | ||
| 44 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 45 | void arch_trigger_all_cpu_backtrace(void); | ||
| 46 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace | ||
| 47 | #endif | ||
| 48 | |||
| 44 | #endif /* _ASM_X86_IRQ_H */ | 49 | #endif /* _ASM_X86_IRQ_H */ |
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 6825e2efd1b4..6bc3985ee473 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h | |||
| @@ -60,11 +60,11 @@ static inline void __exit exit_amd_microcode(void) {} | |||
| 60 | #ifdef CONFIG_MICROCODE_EARLY | 60 | #ifdef CONFIG_MICROCODE_EARLY |
| 61 | #define MAX_UCODE_COUNT 128 | 61 | #define MAX_UCODE_COUNT 128 |
| 62 | extern void __init load_ucode_bsp(void); | 62 | extern void __init load_ucode_bsp(void); |
| 63 | extern __init void load_ucode_ap(void); | 63 | extern void __cpuinit load_ucode_ap(void); |
| 64 | extern int __init save_microcode_in_initrd(void); | 64 | extern int __init save_microcode_in_initrd(void); |
| 65 | #else | 65 | #else |
| 66 | static inline void __init load_ucode_bsp(void) {} | 66 | static inline void __init load_ucode_bsp(void) {} |
| 67 | static inline __init void load_ucode_ap(void) {} | 67 | static inline void __cpuinit load_ucode_ap(void) {} |
| 68 | static inline int __init save_microcode_in_initrd(void) | 68 | static inline int __init save_microcode_in_initrd(void) |
| 69 | { | 69 | { |
| 70 | return 0; | 70 | return 0; |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index c0fa356e90de..86f9301903c8 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
| @@ -18,9 +18,7 @@ extern int proc_nmi_enabled(struct ctl_table *, int , | |||
| 18 | void __user *, size_t *, loff_t *); | 18 | void __user *, size_t *, loff_t *); |
| 19 | extern int unknown_nmi_panic; | 19 | extern int unknown_nmi_panic; |
| 20 | 20 | ||
| 21 | void arch_trigger_all_cpu_backtrace(void); | 21 | #endif /* CONFIG_X86_LOCAL_APIC */ |
| 22 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace | ||
| 23 | #endif | ||
| 24 | 22 | ||
| 25 | #define NMI_FLAG_FIRST 1 | 23 | #define NMI_FLAG_FIRST 1 |
| 26 | 24 | ||
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index 31cb9ae992b7..a698d7165c96 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | #include <asm/apic.h> | 11 | #include <asm/apic.h> |
| 12 | #include <asm/nmi.h> | ||
| 12 | 13 | ||
| 13 | #include <linux/cpumask.h> | 14 | #include <linux/cpumask.h> |
| 14 | #include <linux/kdebug.h> | 15 | #include <linux/kdebug.h> |
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 35ffda5d0727..5f90b85ff22e 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c | |||
| @@ -714,15 +714,15 @@ int __init mtrr_cleanup(unsigned address_bits) | |||
| 714 | if (mtrr_tom2) | 714 | if (mtrr_tom2) |
| 715 | x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base; | 715 | x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base; |
| 716 | 716 | ||
| 717 | nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size); | ||
| 718 | /* | 717 | /* |
| 719 | * [0, 1M) should always be covered by var mtrr with WB | 718 | * [0, 1M) should always be covered by var mtrr with WB |
| 720 | * and fixed mtrrs should take effect before var mtrr for it: | 719 | * and fixed mtrrs should take effect before var mtrr for it: |
| 721 | */ | 720 | */ |
| 722 | nr_range = add_range_with_merge(range, RANGE_NUM, nr_range, 0, | 721 | nr_range = add_range_with_merge(range, RANGE_NUM, 0, 0, |
| 723 | 1ULL<<(20 - PAGE_SHIFT)); | 722 | 1ULL<<(20 - PAGE_SHIFT)); |
| 724 | /* Sort the ranges: */ | 723 | /* add from var mtrr at last */ |
| 725 | sort_range(range, nr_range); | 724 | nr_range = x86_get_mtrr_mem_range(range, nr_range, |
| 725 | x_remove_base, x_remove_size); | ||
| 726 | 726 | ||
| 727 | range_sums = sum_ranges(range, nr_range); | 727 | range_sums = sum_ranges(range, nr_range); |
| 728 | printk(KERN_INFO "total RAM covered: %ldM\n", | 728 | printk(KERN_INFO "total RAM covered: %ldM\n", |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index f60d41ff9a97..a9e22073bd56 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
| @@ -165,13 +165,13 @@ static struct extra_reg intel_snb_extra_regs[] __read_mostly = { | |||
| 165 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), | 165 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), |
| 166 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), | 166 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), |
| 167 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | 167 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), |
| 168 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | ||
| 169 | EVENT_EXTRA_END | 168 | EVENT_EXTRA_END |
| 170 | }; | 169 | }; |
| 171 | 170 | ||
| 172 | static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { | 171 | static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { |
| 173 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), | 172 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), |
| 174 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), | 173 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), |
| 174 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | ||
| 175 | EVENT_EXTRA_END | 175 | EVENT_EXTRA_END |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 9895a9a41380..211bce445522 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
| @@ -365,10 +365,14 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) | |||
| 365 | return insn.length; | 365 | return insn.length; |
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | static void __kprobes arch_copy_kprobe(struct kprobe *p) | 368 | static int __kprobes arch_copy_kprobe(struct kprobe *p) |
| 369 | { | 369 | { |
| 370 | int ret; | ||
| 371 | |||
| 370 | /* Copy an instruction with recovering if other optprobe modifies it.*/ | 372 | /* Copy an instruction with recovering if other optprobe modifies it.*/ |
| 371 | __copy_instruction(p->ainsn.insn, p->addr); | 373 | ret = __copy_instruction(p->ainsn.insn, p->addr); |
| 374 | if (!ret) | ||
| 375 | return -EINVAL; | ||
| 372 | 376 | ||
| 373 | /* | 377 | /* |
| 374 | * __copy_instruction can modify the displacement of the instruction, | 378 | * __copy_instruction can modify the displacement of the instruction, |
| @@ -384,6 +388,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p) | |||
| 384 | 388 | ||
| 385 | /* Also, displacement change doesn't affect the first byte */ | 389 | /* Also, displacement change doesn't affect the first byte */ |
| 386 | p->opcode = p->ainsn.insn[0]; | 390 | p->opcode = p->ainsn.insn[0]; |
| 391 | |||
| 392 | return 0; | ||
| 387 | } | 393 | } |
| 388 | 394 | ||
| 389 | int __kprobes arch_prepare_kprobe(struct kprobe *p) | 395 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
| @@ -397,8 +403,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
| 397 | p->ainsn.insn = get_insn_slot(); | 403 | p->ainsn.insn = get_insn_slot(); |
| 398 | if (!p->ainsn.insn) | 404 | if (!p->ainsn.insn) |
| 399 | return -ENOMEM; | 405 | return -ENOMEM; |
| 400 | arch_copy_kprobe(p); | 406 | |
| 401 | return 0; | 407 | return arch_copy_kprobe(p); |
| 402 | } | 408 | } |
| 403 | 409 | ||
| 404 | void __kprobes arch_arm_kprobe(struct kprobe *p) | 410 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index d2c381280e3c..3dd37ebd591b 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
| @@ -242,6 +242,7 @@ void __init kvmclock_init(void) | |||
| 242 | if (!mem) | 242 | if (!mem) |
| 243 | return; | 243 | return; |
| 244 | hv_clock = __va(mem); | 244 | hv_clock = __va(mem); |
| 245 | memset(hv_clock, 0, size); | ||
| 245 | 246 | ||
| 246 | if (kvm_register_clock("boot clock")) { | 247 | if (kvm_register_clock("boot clock")) { |
| 247 | hv_clock = NULL; | 248 | hv_clock = NULL; |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 4e7a37ff03ab..81a5f5e8f142 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -277,18 +277,6 @@ void exit_idle(void) | |||
| 277 | } | 277 | } |
| 278 | #endif | 278 | #endif |
| 279 | 279 | ||
| 280 | void arch_cpu_idle_prepare(void) | ||
| 281 | { | ||
| 282 | /* | ||
| 283 | * If we're the non-boot CPU, nothing set the stack canary up | ||
| 284 | * for us. CPU0 already has it initialized but no harm in | ||
| 285 | * doing it again. This is a good place for updating it, as | ||
| 286 | * we wont ever return from this function (so the invalid | ||
| 287 | * canaries already on the stack wont ever trigger). | ||
| 288 | */ | ||
| 289 | boot_init_stack_canary(); | ||
| 290 | } | ||
| 291 | |||
| 292 | void arch_cpu_idle_enter(void) | 280 | void arch_cpu_idle_enter(void) |
| 293 | { | 281 | { |
| 294 | local_touch_nmi(); | 282 | local_touch_nmi(); |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9c73b51817e4..bfd348e99369 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -372,15 +372,15 @@ static bool __cpuinit match_mc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) | |||
| 372 | 372 | ||
| 373 | void __cpuinit set_cpu_sibling_map(int cpu) | 373 | void __cpuinit set_cpu_sibling_map(int cpu) |
| 374 | { | 374 | { |
| 375 | bool has_mc = boot_cpu_data.x86_max_cores > 1; | ||
| 376 | bool has_smt = smp_num_siblings > 1; | 375 | bool has_smt = smp_num_siblings > 1; |
| 376 | bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1; | ||
| 377 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 377 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 378 | struct cpuinfo_x86 *o; | 378 | struct cpuinfo_x86 *o; |
| 379 | int i; | 379 | int i; |
| 380 | 380 | ||
| 381 | cpumask_set_cpu(cpu, cpu_sibling_setup_mask); | 381 | cpumask_set_cpu(cpu, cpu_sibling_setup_mask); |
| 382 | 382 | ||
| 383 | if (!has_smt && !has_mc) { | 383 | if (!has_mp) { |
| 384 | cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); | 384 | cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); |
| 385 | cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu)); | 385 | cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu)); |
| 386 | cpumask_set_cpu(cpu, cpu_core_mask(cpu)); | 386 | cpumask_set_cpu(cpu, cpu_core_mask(cpu)); |
| @@ -394,7 +394,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
| 394 | if ((i == cpu) || (has_smt && match_smt(c, o))) | 394 | if ((i == cpu) || (has_smt && match_smt(c, o))) |
| 395 | link_mask(sibling, cpu, i); | 395 | link_mask(sibling, cpu, i); |
| 396 | 396 | ||
| 397 | if ((i == cpu) || (has_mc && match_llc(c, o))) | 397 | if ((i == cpu) || (has_mp && match_llc(c, o))) |
| 398 | link_mask(llc_shared, cpu, i); | 398 | link_mask(llc_shared, cpu, i); |
| 399 | 399 | ||
| 400 | } | 400 | } |
| @@ -406,7 +406,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) | |||
| 406 | for_each_cpu(i, cpu_sibling_setup_mask) { | 406 | for_each_cpu(i, cpu_sibling_setup_mask) { |
| 407 | o = &cpu_data(i); | 407 | o = &cpu_data(i); |
| 408 | 408 | ||
| 409 | if ((i == cpu) || (has_mc && match_mc(c, o))) { | 409 | if ((i == cpu) || (has_mp && match_mc(c, o))) { |
| 410 | link_mask(core, cpu, i); | 410 | link_mask(core, cpu, i); |
| 411 | 411 | ||
| 412 | /* | 412 | /* |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 094b5d96ab14..e8ba99c34180 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -582,8 +582,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) | |||
| 582 | if (index != XCR_XFEATURE_ENABLED_MASK) | 582 | if (index != XCR_XFEATURE_ENABLED_MASK) |
| 583 | return 1; | 583 | return 1; |
| 584 | xcr0 = xcr; | 584 | xcr0 = xcr; |
| 585 | if (kvm_x86_ops->get_cpl(vcpu) != 0) | ||
| 586 | return 1; | ||
| 587 | if (!(xcr0 & XSTATE_FP)) | 585 | if (!(xcr0 & XSTATE_FP)) |
| 588 | return 1; | 586 | return 1; |
| 589 | if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) | 587 | if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) |
| @@ -597,7 +595,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) | |||
| 597 | 595 | ||
| 598 | int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) | 596 | int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
| 599 | { | 597 | { |
| 600 | if (__kvm_set_xcr(vcpu, index, xcr)) { | 598 | if (kvm_x86_ops->get_cpl(vcpu) != 0 || |
| 599 | __kvm_set_xcr(vcpu, index, xcr)) { | ||
| 601 | kvm_inject_gp(vcpu, 0); | 600 | kvm_inject_gp(vcpu, 0); |
| 602 | return 1; | 601 | return 1; |
| 603 | } | 602 | } |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 5ae2eb09419e..d2fbcedcf6ea 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
| @@ -1069,7 +1069,10 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | |||
| 1069 | * that by attempting to use more space than is available. | 1069 | * that by attempting to use more space than is available. |
| 1070 | */ | 1070 | */ |
| 1071 | unsigned long dummy_size = remaining_size + 1024; | 1071 | unsigned long dummy_size = remaining_size + 1024; |
| 1072 | void *dummy = kmalloc(dummy_size, GFP_ATOMIC); | 1072 | void *dummy = kzalloc(dummy_size, GFP_ATOMIC); |
| 1073 | |||
| 1074 | if (!dummy) | ||
| 1075 | return EFI_OUT_OF_RESOURCES; | ||
| 1073 | 1076 | ||
| 1074 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | 1077 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
| 1075 | EFI_VARIABLE_NON_VOLATILE | | 1078 | EFI_VARIABLE_NON_VOLATILE | |
| @@ -1089,6 +1092,8 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | |||
| 1089 | 0, dummy); | 1092 | 0, dummy); |
| 1090 | } | 1093 | } |
| 1091 | 1094 | ||
| 1095 | kfree(dummy); | ||
| 1096 | |||
| 1092 | /* | 1097 | /* |
| 1093 | * The runtime code may now have triggered a garbage collection | 1098 | * The runtime code may now have triggered a garbage collection |
| 1094 | * run, so check the variable info again | 1099 | * run, so check the variable info again |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 652fd5ce303c..cab13f2fc28e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
| @@ -164,15 +164,24 @@ static int acpi_lpss_create_device(struct acpi_device *adev, | |||
| 164 | if (dev_desc->clk_required) { | 164 | if (dev_desc->clk_required) { |
| 165 | ret = register_device_clock(adev, pdata); | 165 | ret = register_device_clock(adev, pdata); |
| 166 | if (ret) { | 166 | if (ret) { |
| 167 | /* | 167 | /* Skip the device, but continue the namespace scan. */ |
| 168 | * Skip the device, but don't terminate the namespace | 168 | ret = 0; |
| 169 | * scan. | 169 | goto err_out; |
| 170 | */ | ||
| 171 | kfree(pdata); | ||
| 172 | return 0; | ||
| 173 | } | 170 | } |
| 174 | } | 171 | } |
| 175 | 172 | ||
| 173 | /* | ||
| 174 | * This works around a known issue in ACPI tables where LPSS devices | ||
| 175 | * have _PS0 and _PS3 without _PSC (and no power resources), so | ||
| 176 | * acpi_bus_init_power() will assume that the BIOS has put them into D0. | ||
| 177 | */ | ||
| 178 | ret = acpi_device_fix_up_power(adev); | ||
| 179 | if (ret) { | ||
| 180 | /* Skip the device, but continue the namespace scan. */ | ||
| 181 | ret = 0; | ||
| 182 | goto err_out; | ||
| 183 | } | ||
| 184 | |||
| 176 | adev->driver_data = pdata; | 185 | adev->driver_data = pdata; |
| 177 | ret = acpi_create_platform_device(adev, id); | 186 | ret = acpi_create_platform_device(adev, id); |
| 178 | if (ret > 0) | 187 | if (ret > 0) |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 318fa32a141e..31c217a42839 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
| @@ -290,6 +290,26 @@ int acpi_bus_init_power(struct acpi_device *device) | |||
| 290 | return 0; | 290 | return 0; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | /** | ||
| 294 | * acpi_device_fix_up_power - Force device with missing _PSC into D0. | ||
| 295 | * @device: Device object whose power state is to be fixed up. | ||
| 296 | * | ||
| 297 | * Devices without power resources and _PSC, but having _PS0 and _PS3 defined, | ||
| 298 | * are assumed to be put into D0 by the BIOS. However, in some cases that may | ||
| 299 | * not be the case and this function should be used then. | ||
| 300 | */ | ||
| 301 | int acpi_device_fix_up_power(struct acpi_device *device) | ||
| 302 | { | ||
| 303 | int ret = 0; | ||
| 304 | |||
| 305 | if (!device->power.flags.power_resources | ||
| 306 | && !device->power.flags.explicit_get | ||
| 307 | && device->power.state == ACPI_STATE_D0) | ||
| 308 | ret = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0); | ||
| 309 | |||
| 310 | return ret; | ||
| 311 | } | ||
| 312 | |||
| 293 | int acpi_bus_update_power(acpi_handle handle, int *state_p) | 313 | int acpi_bus_update_power(acpi_handle handle, int *state_p) |
| 294 | { | 314 | { |
| 295 | struct acpi_device *device; | 315 | struct acpi_device *device; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 4fdea381ef21..14de9f46972e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
| @@ -66,20 +66,21 @@ struct dock_station { | |||
| 66 | spinlock_t dd_lock; | 66 | spinlock_t dd_lock; |
| 67 | struct mutex hp_lock; | 67 | struct mutex hp_lock; |
| 68 | struct list_head dependent_devices; | 68 | struct list_head dependent_devices; |
| 69 | struct list_head hotplug_devices; | ||
| 70 | 69 | ||
| 71 | struct list_head sibling; | 70 | struct list_head sibling; |
| 72 | struct platform_device *dock_device; | 71 | struct platform_device *dock_device; |
| 73 | }; | 72 | }; |
| 74 | static LIST_HEAD(dock_stations); | 73 | static LIST_HEAD(dock_stations); |
| 75 | static int dock_station_count; | 74 | static int dock_station_count; |
| 75 | static DEFINE_MUTEX(hotplug_lock); | ||
| 76 | 76 | ||
| 77 | struct dock_dependent_device { | 77 | struct dock_dependent_device { |
| 78 | struct list_head list; | 78 | struct list_head list; |
| 79 | struct list_head hotplug_list; | ||
| 80 | acpi_handle handle; | 79 | acpi_handle handle; |
| 81 | const struct acpi_dock_ops *ops; | 80 | const struct acpi_dock_ops *hp_ops; |
| 82 | void *context; | 81 | void *hp_context; |
| 82 | unsigned int hp_refcount; | ||
| 83 | void (*hp_release)(void *); | ||
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| 85 | #define DOCK_DOCKING 0x00000001 | 86 | #define DOCK_DOCKING 0x00000001 |
| @@ -111,7 +112,6 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | |||
| 111 | 112 | ||
| 112 | dd->handle = handle; | 113 | dd->handle = handle; |
| 113 | INIT_LIST_HEAD(&dd->list); | 114 | INIT_LIST_HEAD(&dd->list); |
| 114 | INIT_LIST_HEAD(&dd->hotplug_list); | ||
| 115 | 115 | ||
| 116 | spin_lock(&ds->dd_lock); | 116 | spin_lock(&ds->dd_lock); |
| 117 | list_add_tail(&dd->list, &ds->dependent_devices); | 117 | list_add_tail(&dd->list, &ds->dependent_devices); |
| @@ -121,35 +121,90 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | |||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /** | 123 | /** |
| 124 | * dock_add_hotplug_device - associate a hotplug handler with the dock station | 124 | * dock_init_hotplug - Initialize a hotplug device on a docking station. |
| 125 | * @ds: The dock station | 125 | * @dd: Dock-dependent device. |
| 126 | * @dd: The dependent device struct | 126 | * @ops: Dock operations to attach to the dependent device. |
| 127 | * | 127 | * @context: Data to pass to the @ops callbacks and @release. |
| 128 | * Add the dependent device to the dock's hotplug device list | 128 | * @init: Optional initialization routine to run after setting up context. |
| 129 | * @release: Optional release routine to run on removal. | ||
| 129 | */ | 130 | */ |
| 130 | static void | 131 | static int dock_init_hotplug(struct dock_dependent_device *dd, |
| 131 | dock_add_hotplug_device(struct dock_station *ds, | 132 | const struct acpi_dock_ops *ops, void *context, |
| 132 | struct dock_dependent_device *dd) | 133 | void (*init)(void *), void (*release)(void *)) |
| 133 | { | 134 | { |
| 134 | mutex_lock(&ds->hp_lock); | 135 | int ret = 0; |
| 135 | list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); | 136 | |
| 136 | mutex_unlock(&ds->hp_lock); | 137 | mutex_lock(&hotplug_lock); |
| 138 | |||
| 139 | if (dd->hp_context) { | ||
| 140 | ret = -EEXIST; | ||
| 141 | } else { | ||
| 142 | dd->hp_refcount = 1; | ||
| 143 | dd->hp_ops = ops; | ||
| 144 | dd->hp_context = context; | ||
| 145 | dd->hp_release = release; | ||
| 146 | } | ||
| 147 | |||
| 148 | if (!WARN_ON(ret) && init) | ||
| 149 | init(context); | ||
| 150 | |||
| 151 | mutex_unlock(&hotplug_lock); | ||
| 152 | return ret; | ||
| 137 | } | 153 | } |
| 138 | 154 | ||
| 139 | /** | 155 | /** |
| 140 | * dock_del_hotplug_device - remove a hotplug handler from the dock station | 156 | * dock_release_hotplug - Decrement hotplug reference counter of dock device. |
| 141 | * @ds: The dock station | 157 | * @dd: Dock-dependent device. |
| 142 | * @dd: the dependent device struct | ||
| 143 | * | 158 | * |
| 144 | * Delete the dependent device from the dock's hotplug device list | 159 | * Decrement the reference counter of @dd and if 0, detach its hotplug |
| 160 | * operations from it, reset its context pointer and run the optional release | ||
| 161 | * routine if present. | ||
| 145 | */ | 162 | */ |
| 146 | static void | 163 | static void dock_release_hotplug(struct dock_dependent_device *dd) |
| 147 | dock_del_hotplug_device(struct dock_station *ds, | ||
| 148 | struct dock_dependent_device *dd) | ||
| 149 | { | 164 | { |
| 150 | mutex_lock(&ds->hp_lock); | 165 | void (*release)(void *) = NULL; |
| 151 | list_del(&dd->hotplug_list); | 166 | void *context = NULL; |
| 152 | mutex_unlock(&ds->hp_lock); | 167 | |
| 168 | mutex_lock(&hotplug_lock); | ||
| 169 | |||
| 170 | if (dd->hp_context && !--dd->hp_refcount) { | ||
| 171 | dd->hp_ops = NULL; | ||
| 172 | context = dd->hp_context; | ||
| 173 | dd->hp_context = NULL; | ||
| 174 | release = dd->hp_release; | ||
| 175 | dd->hp_release = NULL; | ||
| 176 | } | ||
| 177 | |||
| 178 | if (release && context) | ||
| 179 | release(context); | ||
| 180 | |||
| 181 | mutex_unlock(&hotplug_lock); | ||
| 182 | } | ||
| 183 | |||
| 184 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | ||
| 185 | bool uevent) | ||
| 186 | { | ||
| 187 | acpi_notify_handler cb = NULL; | ||
| 188 | bool run = false; | ||
| 189 | |||
| 190 | mutex_lock(&hotplug_lock); | ||
| 191 | |||
| 192 | if (dd->hp_context) { | ||
| 193 | run = true; | ||
| 194 | dd->hp_refcount++; | ||
| 195 | if (dd->hp_ops) | ||
| 196 | cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler; | ||
| 197 | } | ||
| 198 | |||
| 199 | mutex_unlock(&hotplug_lock); | ||
| 200 | |||
| 201 | if (!run) | ||
| 202 | return; | ||
| 203 | |||
| 204 | if (cb) | ||
| 205 | cb(dd->handle, event, dd->hp_context); | ||
| 206 | |||
| 207 | dock_release_hotplug(dd); | ||
| 153 | } | 208 | } |
| 154 | 209 | ||
| 155 | /** | 210 | /** |
| @@ -360,9 +415,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
| 360 | /* | 415 | /* |
| 361 | * First call driver specific hotplug functions | 416 | * First call driver specific hotplug functions |
| 362 | */ | 417 | */ |
| 363 | list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) | 418 | list_for_each_entry(dd, &ds->dependent_devices, list) |
| 364 | if (dd->ops && dd->ops->handler) | 419 | dock_hotplug_event(dd, event, false); |
| 365 | dd->ops->handler(dd->handle, event, dd->context); | ||
| 366 | 420 | ||
| 367 | /* | 421 | /* |
| 368 | * Now make sure that an acpi_device is created for each | 422 | * Now make sure that an acpi_device is created for each |
| @@ -398,9 +452,8 @@ static void dock_event(struct dock_station *ds, u32 event, int num) | |||
| 398 | if (num == DOCK_EVENT) | 452 | if (num == DOCK_EVENT) |
| 399 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 453 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
| 400 | 454 | ||
| 401 | list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) | 455 | list_for_each_entry(dd, &ds->dependent_devices, list) |
| 402 | if (dd->ops && dd->ops->uevent) | 456 | dock_hotplug_event(dd, event, true); |
| 403 | dd->ops->uevent(dd->handle, event, dd->context); | ||
| 404 | 457 | ||
| 405 | if (num != DOCK_EVENT) | 458 | if (num != DOCK_EVENT) |
| 406 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 459 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
| @@ -570,19 +623,24 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier); | |||
| 570 | * @handle: the handle of the device | 623 | * @handle: the handle of the device |
| 571 | * @ops: handlers to call after docking | 624 | * @ops: handlers to call after docking |
| 572 | * @context: device specific data | 625 | * @context: device specific data |
| 626 | * @init: Optional initialization routine to run after registration | ||
| 627 | * @release: Optional release routine to run on unregistration | ||
| 573 | * | 628 | * |
| 574 | * If a driver would like to perform a hotplug operation after a dock | 629 | * If a driver would like to perform a hotplug operation after a dock |
| 575 | * event, they can register an acpi_notifiy_handler to be called by | 630 | * event, they can register an acpi_notifiy_handler to be called by |
| 576 | * the dock driver after _DCK is executed. | 631 | * the dock driver after _DCK is executed. |
| 577 | */ | 632 | */ |
| 578 | int | 633 | int register_hotplug_dock_device(acpi_handle handle, |
| 579 | register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, | 634 | const struct acpi_dock_ops *ops, void *context, |
| 580 | void *context) | 635 | void (*init)(void *), void (*release)(void *)) |
| 581 | { | 636 | { |
| 582 | struct dock_dependent_device *dd; | 637 | struct dock_dependent_device *dd; |
| 583 | struct dock_station *dock_station; | 638 | struct dock_station *dock_station; |
| 584 | int ret = -EINVAL; | 639 | int ret = -EINVAL; |
| 585 | 640 | ||
| 641 | if (WARN_ON(!context)) | ||
| 642 | return -EINVAL; | ||
| 643 | |||
| 586 | if (!dock_station_count) | 644 | if (!dock_station_count) |
| 587 | return -ENODEV; | 645 | return -ENODEV; |
| 588 | 646 | ||
| @@ -597,12 +655,8 @@ register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops | |||
| 597 | * ops | 655 | * ops |
| 598 | */ | 656 | */ |
| 599 | dd = find_dock_dependent_device(dock_station, handle); | 657 | dd = find_dock_dependent_device(dock_station, handle); |
| 600 | if (dd) { | 658 | if (dd && !dock_init_hotplug(dd, ops, context, init, release)) |
| 601 | dd->ops = ops; | ||
| 602 | dd->context = context; | ||
| 603 | dock_add_hotplug_device(dock_station, dd); | ||
| 604 | ret = 0; | 659 | ret = 0; |
| 605 | } | ||
| 606 | } | 660 | } |
| 607 | 661 | ||
| 608 | return ret; | 662 | return ret; |
| @@ -624,7 +678,7 @@ void unregister_hotplug_dock_device(acpi_handle handle) | |||
| 624 | list_for_each_entry(dock_station, &dock_stations, sibling) { | 678 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
| 625 | dd = find_dock_dependent_device(dock_station, handle); | 679 | dd = find_dock_dependent_device(dock_station, handle); |
| 626 | if (dd) | 680 | if (dd) |
| 627 | dock_del_hotplug_device(dock_station, dd); | 681 | dock_release_hotplug(dd); |
| 628 | } | 682 | } |
| 629 | } | 683 | } |
| 630 | EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); | 684 | EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); |
| @@ -868,8 +922,10 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, | |||
| 868 | if (!count) | 922 | if (!count) |
| 869 | return -EINVAL; | 923 | return -EINVAL; |
| 870 | 924 | ||
| 925 | acpi_scan_lock_acquire(); | ||
| 871 | begin_undock(dock_station); | 926 | begin_undock(dock_station); |
| 872 | ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); | 927 | ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); |
| 928 | acpi_scan_lock_release(); | ||
| 873 | return ret ? ret: count; | 929 | return ret ? ret: count; |
| 874 | } | 930 | } |
| 875 | static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); | 931 | static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); |
| @@ -951,7 +1007,6 @@ static int __init dock_add(acpi_handle handle) | |||
| 951 | mutex_init(&dock_station->hp_lock); | 1007 | mutex_init(&dock_station->hp_lock); |
| 952 | spin_lock_init(&dock_station->dd_lock); | 1008 | spin_lock_init(&dock_station->dd_lock); |
| 953 | INIT_LIST_HEAD(&dock_station->sibling); | 1009 | INIT_LIST_HEAD(&dock_station->sibling); |
| 954 | INIT_LIST_HEAD(&dock_station->hotplug_devices); | ||
| 955 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 1010 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
| 956 | INIT_LIST_HEAD(&dock_station->dependent_devices); | 1011 | INIT_LIST_HEAD(&dock_station->dependent_devices); |
| 957 | 1012 | ||
| @@ -992,30 +1047,6 @@ err_unregister: | |||
| 992 | } | 1047 | } |
| 993 | 1048 | ||
| 994 | /** | 1049 | /** |
| 995 | * dock_remove - free up resources related to the dock station | ||
| 996 | */ | ||
| 997 | static int dock_remove(struct dock_station *ds) | ||
| 998 | { | ||
| 999 | struct dock_dependent_device *dd, *tmp; | ||
| 1000 | struct platform_device *dock_device = ds->dock_device; | ||
| 1001 | |||
| 1002 | if (!dock_station_count) | ||
| 1003 | return 0; | ||
| 1004 | |||
| 1005 | /* remove dependent devices */ | ||
| 1006 | list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list) | ||
| 1007 | kfree(dd); | ||
| 1008 | |||
| 1009 | list_del(&ds->sibling); | ||
| 1010 | |||
| 1011 | /* cleanup sysfs */ | ||
| 1012 | sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); | ||
| 1013 | platform_device_unregister(dock_device); | ||
| 1014 | |||
| 1015 | return 0; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | /** | ||
| 1019 | * find_dock_and_bay - look for dock stations and bays | 1050 | * find_dock_and_bay - look for dock stations and bays |
| 1020 | * @handle: acpi handle of a device | 1051 | * @handle: acpi handle of a device |
| 1021 | * @lvl: unused | 1052 | * @lvl: unused |
| @@ -1033,7 +1064,7 @@ find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 1033 | return AE_OK; | 1064 | return AE_OK; |
| 1034 | } | 1065 | } |
| 1035 | 1066 | ||
| 1036 | static int __init dock_init(void) | 1067 | int __init acpi_dock_init(void) |
| 1037 | { | 1068 | { |
| 1038 | if (acpi_disabled) | 1069 | if (acpi_disabled) |
| 1039 | return 0; | 1070 | return 0; |
| @@ -1052,19 +1083,3 @@ static int __init dock_init(void) | |||
| 1052 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); | 1083 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); |
| 1053 | return 0; | 1084 | return 0; |
| 1054 | } | 1085 | } |
| 1055 | |||
| 1056 | static void __exit dock_exit(void) | ||
| 1057 | { | ||
| 1058 | struct dock_station *tmp, *dock_station; | ||
| 1059 | |||
| 1060 | unregister_acpi_bus_notifier(&dock_acpi_notifier); | ||
| 1061 | list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) | ||
| 1062 | dock_remove(dock_station); | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | /* | ||
| 1066 | * Must be called before drivers of devices in dock, otherwise we can't know | ||
| 1067 | * which devices are in a dock | ||
| 1068 | */ | ||
| 1069 | subsys_initcall(dock_init); | ||
| 1070 | module_exit(dock_exit); | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 297cbf456f86..c610a76d92c4 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -40,6 +40,11 @@ void acpi_container_init(void); | |||
| 40 | #else | 40 | #else |
| 41 | static inline void acpi_container_init(void) {} | 41 | static inline void acpi_container_init(void) {} |
| 42 | #endif | 42 | #endif |
| 43 | #ifdef CONFIG_ACPI_DOCK | ||
| 44 | void acpi_dock_init(void); | ||
| 45 | #else | ||
| 46 | static inline void acpi_dock_init(void) {} | ||
| 47 | #endif | ||
| 43 | #ifdef CONFIG_ACPI_HOTPLUG_MEMORY | 48 | #ifdef CONFIG_ACPI_HOTPLUG_MEMORY |
| 44 | void acpi_memory_hotplug_init(void); | 49 | void acpi_memory_hotplug_init(void); |
| 45 | #else | 50 | #else |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f962047c6c85..288bb270f8ed 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
| @@ -885,6 +885,7 @@ int acpi_add_power_resource(acpi_handle handle) | |||
| 885 | ACPI_STA_DEFAULT); | 885 | ACPI_STA_DEFAULT); |
| 886 | mutex_init(&resource->resource_lock); | 886 | mutex_init(&resource->resource_lock); |
| 887 | INIT_LIST_HEAD(&resource->dependent); | 887 | INIT_LIST_HEAD(&resource->dependent); |
| 888 | INIT_LIST_HEAD(&resource->list_node); | ||
| 888 | resource->name = device->pnp.bus_id; | 889 | resource->name = device->pnp.bus_id; |
| 889 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); | 890 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
| 890 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); | 891 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index a3868f6c222a..3322b47ab7ca 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
| @@ -304,7 +304,8 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) | |||
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, | 306 | static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, |
| 307 | u8 triggering, u8 polarity, u8 shareable) | 307 | u8 triggering, u8 polarity, u8 shareable, |
| 308 | bool legacy) | ||
| 308 | { | 309 | { |
| 309 | int irq, p, t; | 310 | int irq, p, t; |
| 310 | 311 | ||
| @@ -317,14 +318,19 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, | |||
| 317 | * In IO-APIC mode, use overrided attribute. Two reasons: | 318 | * In IO-APIC mode, use overrided attribute. Two reasons: |
| 318 | * 1. BIOS bug in DSDT | 319 | * 1. BIOS bug in DSDT |
| 319 | * 2. BIOS uses IO-APIC mode Interrupt Source Override | 320 | * 2. BIOS uses IO-APIC mode Interrupt Source Override |
| 321 | * | ||
| 322 | * We do this only if we are dealing with IRQ() or IRQNoFlags() | ||
| 323 | * resource (the legacy ISA resources). With modern ACPI 5 devices | ||
| 324 | * using extended IRQ descriptors we take the IRQ configuration | ||
| 325 | * from _CRS directly. | ||
| 320 | */ | 326 | */ |
| 321 | if (!acpi_get_override_irq(gsi, &t, &p)) { | 327 | if (legacy && !acpi_get_override_irq(gsi, &t, &p)) { |
| 322 | u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; | 328 | u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; |
| 323 | u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; | 329 | u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; |
| 324 | 330 | ||
| 325 | if (triggering != trig || polarity != pol) { | 331 | if (triggering != trig || polarity != pol) { |
| 326 | pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi, | 332 | pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi, |
| 327 | t ? "edge" : "level", p ? "low" : "high"); | 333 | t ? "level" : "edge", p ? "low" : "high"); |
| 328 | triggering = trig; | 334 | triggering = trig; |
| 329 | polarity = pol; | 335 | polarity = pol; |
| 330 | } | 336 | } |
| @@ -373,7 +379,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, | |||
| 373 | } | 379 | } |
| 374 | acpi_dev_get_irqresource(res, irq->interrupts[index], | 380 | acpi_dev_get_irqresource(res, irq->interrupts[index], |
| 375 | irq->triggering, irq->polarity, | 381 | irq->triggering, irq->polarity, |
| 376 | irq->sharable); | 382 | irq->sharable, true); |
| 377 | break; | 383 | break; |
| 378 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | 384 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
| 379 | ext_irq = &ares->data.extended_irq; | 385 | ext_irq = &ares->data.extended_irq; |
| @@ -383,7 +389,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, | |||
| 383 | } | 389 | } |
| 384 | acpi_dev_get_irqresource(res, ext_irq->interrupts[index], | 390 | acpi_dev_get_irqresource(res, ext_irq->interrupts[index], |
| 385 | ext_irq->triggering, ext_irq->polarity, | 391 | ext_irq->triggering, ext_irq->polarity, |
| 386 | ext_irq->sharable); | 392 | ext_irq->sharable, false); |
| 387 | break; | 393 | break; |
| 388 | default: | 394 | default: |
| 389 | return false; | 395 | return false; |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b14ac46948c9..27da63061e11 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -2042,6 +2042,7 @@ int __init acpi_scan_init(void) | |||
| 2042 | acpi_lpss_init(); | 2042 | acpi_lpss_init(); |
| 2043 | acpi_container_init(); | 2043 | acpi_container_init(); |
| 2044 | acpi_memory_hotplug_init(); | 2044 | acpi_memory_hotplug_init(); |
| 2045 | acpi_dock_init(); | ||
| 2045 | 2046 | ||
| 2046 | mutex_lock(&acpi_scan_lock); | 2047 | mutex_lock(&acpi_scan_lock); |
| 2047 | /* | 2048 | /* |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 87f2f395d79a..cf4e7020adac 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
| @@ -156,8 +156,10 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | |||
| 156 | 156 | ||
| 157 | spin_unlock_irqrestore(ap->lock, flags); | 157 | spin_unlock_irqrestore(ap->lock, flags); |
| 158 | 158 | ||
| 159 | if (wait) | 159 | if (wait) { |
| 160 | ata_port_wait_eh(ap); | 160 | ata_port_wait_eh(ap); |
| 161 | flush_work(&ap->hotplug_task.work); | ||
| 162 | } | ||
| 161 | } | 163 | } |
| 162 | 164 | ||
| 163 | static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) | 165 | static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) |
| @@ -214,6 +216,39 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = { | |||
| 214 | .uevent = ata_acpi_ap_uevent, | 216 | .uevent = ata_acpi_ap_uevent, |
| 215 | }; | 217 | }; |
| 216 | 218 | ||
| 219 | void ata_acpi_hotplug_init(struct ata_host *host) | ||
| 220 | { | ||
| 221 | int i; | ||
| 222 | |||
| 223 | for (i = 0; i < host->n_ports; i++) { | ||
| 224 | struct ata_port *ap = host->ports[i]; | ||
| 225 | acpi_handle handle; | ||
| 226 | struct ata_device *dev; | ||
| 227 | |||
| 228 | if (!ap) | ||
| 229 | continue; | ||
| 230 | |||
| 231 | handle = ata_ap_acpi_handle(ap); | ||
| 232 | if (handle) { | ||
| 233 | /* we might be on a docking station */ | ||
| 234 | register_hotplug_dock_device(handle, | ||
| 235 | &ata_acpi_ap_dock_ops, ap, | ||
| 236 | NULL, NULL); | ||
| 237 | } | ||
| 238 | |||
| 239 | ata_for_each_dev(dev, &ap->link, ALL) { | ||
| 240 | handle = ata_dev_acpi_handle(dev); | ||
| 241 | if (!handle) | ||
| 242 | continue; | ||
| 243 | |||
| 244 | /* we might be on a docking station */ | ||
| 245 | register_hotplug_dock_device(handle, | ||
| 246 | &ata_acpi_dev_dock_ops, | ||
| 247 | dev, NULL, NULL); | ||
| 248 | } | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 217 | /** | 252 | /** |
| 218 | * ata_acpi_dissociate - dissociate ATA host from ACPI objects | 253 | * ata_acpi_dissociate - dissociate ATA host from ACPI objects |
| 219 | * @host: target ATA host | 254 | * @host: target ATA host |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f2184276539d..adf002a3c584 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -6148,6 +6148,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) | |||
| 6148 | if (rc) | 6148 | if (rc) |
| 6149 | goto err_tadd; | 6149 | goto err_tadd; |
| 6150 | 6150 | ||
| 6151 | ata_acpi_hotplug_init(host); | ||
| 6152 | |||
| 6151 | /* set cable, sata_spd_limit and report */ | 6153 | /* set cable, sata_spd_limit and report */ |
| 6152 | for (i = 0; i < host->n_ports; i++) { | 6154 | for (i = 0; i < host->n_ports; i++) { |
| 6153 | struct ata_port *ap = host->ports[i]; | 6155 | struct ata_port *ap = host->ports[i]; |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index c949dd311b2e..577d902bc4de 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
| @@ -122,6 +122,7 @@ extern int ata_acpi_register(void); | |||
| 122 | extern void ata_acpi_unregister(void); | 122 | extern void ata_acpi_unregister(void); |
| 123 | extern void ata_acpi_bind(struct ata_device *dev); | 123 | extern void ata_acpi_bind(struct ata_device *dev); |
| 124 | extern void ata_acpi_unbind(struct ata_device *dev); | 124 | extern void ata_acpi_unbind(struct ata_device *dev); |
| 125 | extern void ata_acpi_hotplug_init(struct ata_host *host); | ||
| 125 | #else | 126 | #else |
| 126 | static inline void ata_acpi_dissociate(struct ata_host *host) { } | 127 | static inline void ata_acpi_dissociate(struct ata_host *host) { } |
| 127 | static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } | 128 | static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } |
| @@ -134,6 +135,7 @@ static inline int ata_acpi_register(void) { return 0; } | |||
| 134 | static inline void ata_acpi_unregister(void) { } | 135 | static inline void ata_acpi_unregister(void) { } |
| 135 | static inline void ata_acpi_bind(struct ata_device *dev) { } | 136 | static inline void ata_acpi_bind(struct ata_device *dev) { } |
| 136 | static inline void ata_acpi_unbind(struct ata_device *dev) { } | 137 | static inline void ata_acpi_unbind(struct ata_device *dev) { } |
| 138 | static inline void ata_acpi_hotplug_init(struct ata_host *host) {} | ||
| 137 | #endif | 139 | #endif |
| 138 | 140 | ||
| 139 | /* libata-scsi.c */ | 141 | /* libata-scsi.c */ |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4b1f9265887f..01e21037d8fe 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
| @@ -450,8 +450,18 @@ static void fw_load_abort(struct firmware_priv *fw_priv) | |||
| 450 | { | 450 | { |
| 451 | struct firmware_buf *buf = fw_priv->buf; | 451 | struct firmware_buf *buf = fw_priv->buf; |
| 452 | 452 | ||
| 453 | /* | ||
| 454 | * There is a small window in which user can write to 'loading' | ||
| 455 | * between loading done and disappearance of 'loading' | ||
| 456 | */ | ||
| 457 | if (test_bit(FW_STATUS_DONE, &buf->status)) | ||
| 458 | return; | ||
| 459 | |||
| 453 | set_bit(FW_STATUS_ABORT, &buf->status); | 460 | set_bit(FW_STATUS_ABORT, &buf->status); |
| 454 | complete_all(&buf->completion); | 461 | complete_all(&buf->completion); |
| 462 | |||
| 463 | /* avoid user action after loading abort */ | ||
| 464 | fw_priv->buf = NULL; | ||
| 455 | } | 465 | } |
| 456 | 466 | ||
| 457 | #define is_fw_load_aborted(buf) \ | 467 | #define is_fw_load_aborted(buf) \ |
| @@ -528,7 +538,12 @@ static ssize_t firmware_loading_show(struct device *dev, | |||
| 528 | struct device_attribute *attr, char *buf) | 538 | struct device_attribute *attr, char *buf) |
| 529 | { | 539 | { |
| 530 | struct firmware_priv *fw_priv = to_firmware_priv(dev); | 540 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
| 531 | int loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); | 541 | int loading = 0; |
| 542 | |||
| 543 | mutex_lock(&fw_lock); | ||
| 544 | if (fw_priv->buf) | ||
| 545 | loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); | ||
| 546 | mutex_unlock(&fw_lock); | ||
| 532 | 547 | ||
| 533 | return sprintf(buf, "%d\n", loading); | 548 | return sprintf(buf, "%d\n", loading); |
| 534 | } | 549 | } |
| @@ -570,12 +585,12 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
| 570 | const char *buf, size_t count) | 585 | const char *buf, size_t count) |
| 571 | { | 586 | { |
| 572 | struct firmware_priv *fw_priv = to_firmware_priv(dev); | 587 | struct firmware_priv *fw_priv = to_firmware_priv(dev); |
| 573 | struct firmware_buf *fw_buf = fw_priv->buf; | 588 | struct firmware_buf *fw_buf; |
| 574 | int loading = simple_strtol(buf, NULL, 10); | 589 | int loading = simple_strtol(buf, NULL, 10); |
| 575 | int i; | 590 | int i; |
| 576 | 591 | ||
| 577 | mutex_lock(&fw_lock); | 592 | mutex_lock(&fw_lock); |
| 578 | 593 | fw_buf = fw_priv->buf; | |
| 579 | if (!fw_buf) | 594 | if (!fw_buf) |
| 580 | goto out; | 595 | goto out; |
| 581 | 596 | ||
| @@ -777,10 +792,6 @@ static void firmware_class_timeout_work(struct work_struct *work) | |||
| 777 | struct firmware_priv, timeout_work.work); | 792 | struct firmware_priv, timeout_work.work); |
| 778 | 793 | ||
| 779 | mutex_lock(&fw_lock); | 794 | mutex_lock(&fw_lock); |
| 780 | if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) { | ||
| 781 | mutex_unlock(&fw_lock); | ||
| 782 | return; | ||
| 783 | } | ||
| 784 | fw_load_abort(fw_priv); | 795 | fw_load_abort(fw_priv); |
| 785 | mutex_unlock(&fw_lock); | 796 | mutex_unlock(&fw_lock); |
| 786 | } | 797 | } |
| @@ -861,8 +872,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
| 861 | 872 | ||
| 862 | cancel_delayed_work_sync(&fw_priv->timeout_work); | 873 | cancel_delayed_work_sync(&fw_priv->timeout_work); |
| 863 | 874 | ||
| 864 | fw_priv->buf = NULL; | ||
| 865 | |||
| 866 | device_remove_file(f_dev, &dev_attr_loading); | 875 | device_remove_file(f_dev, &dev_attr_loading); |
| 867 | err_del_bin_attr: | 876 | err_del_bin_attr: |
| 868 | device_remove_bin_file(f_dev, &firmware_attr_data); | 877 | device_remove_bin_file(f_dev, &firmware_attr_data); |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 3063452e55da..247bf3099731 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -1036,12 +1036,16 @@ static const char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset) | |||
| 1036 | char *name; | 1036 | char *name; |
| 1037 | u64 segment; | 1037 | u64 segment; |
| 1038 | int ret; | 1038 | int ret; |
| 1039 | char *name_format; | ||
| 1039 | 1040 | ||
| 1040 | name = kmem_cache_alloc(rbd_segment_name_cache, GFP_NOIO); | 1041 | name = kmem_cache_alloc(rbd_segment_name_cache, GFP_NOIO); |
| 1041 | if (!name) | 1042 | if (!name) |
| 1042 | return NULL; | 1043 | return NULL; |
| 1043 | segment = offset >> rbd_dev->header.obj_order; | 1044 | segment = offset >> rbd_dev->header.obj_order; |
| 1044 | ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, "%s.%012llx", | 1045 | name_format = "%s.%012llx"; |
| 1046 | if (rbd_dev->image_format == 2) | ||
| 1047 | name_format = "%s.%016llx"; | ||
| 1048 | ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, name_format, | ||
| 1045 | rbd_dev->header.object_prefix, segment); | 1049 | rbd_dev->header.object_prefix, segment); |
| 1046 | if (ret < 0 || ret > MAX_OBJ_NAME_SIZE) { | 1050 | if (ret < 0 || ret > MAX_OBJ_NAME_SIZE) { |
| 1047 | pr_err("error formatting segment name for #%llu (%d)\n", | 1051 | pr_err("error formatting segment name for #%llu (%d)\n", |
| @@ -4239,6 +4243,10 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) | |||
| 4239 | 4243 | ||
| 4240 | down_write(&rbd_dev->header_rwsem); | 4244 | down_write(&rbd_dev->header_rwsem); |
| 4241 | 4245 | ||
| 4246 | ret = rbd_dev_v2_image_size(rbd_dev); | ||
| 4247 | if (ret) | ||
| 4248 | goto out; | ||
| 4249 | |||
| 4242 | if (first_time) { | 4250 | if (first_time) { |
| 4243 | ret = rbd_dev_v2_header_onetime(rbd_dev); | 4251 | ret = rbd_dev_v2_header_onetime(rbd_dev); |
| 4244 | if (ret) | 4252 | if (ret) |
| @@ -4272,10 +4280,6 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) | |||
| 4272 | "is EXPERIMENTAL!"); | 4280 | "is EXPERIMENTAL!"); |
| 4273 | } | 4281 | } |
| 4274 | 4282 | ||
| 4275 | ret = rbd_dev_v2_image_size(rbd_dev); | ||
| 4276 | if (ret) | ||
| 4277 | goto out; | ||
| 4278 | |||
| 4279 | if (rbd_dev->spec->snap_id == CEPH_NOSNAP) | 4283 | if (rbd_dev->spec->snap_id == CEPH_NOSNAP) |
| 4280 | if (rbd_dev->mapping.size != rbd_dev->header.image_size) | 4284 | if (rbd_dev->mapping.size != rbd_dev->header.image_size) |
| 4281 | rbd_dev->mapping.size = rbd_dev->header.image_size; | 4285 | rbd_dev->mapping.size = rbd_dev->header.image_size; |
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 3a4343b3bd6d..9a9f51875df5 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c | |||
| @@ -498,6 +498,10 @@ static int btmrvl_service_main_thread(void *data) | |||
| 498 | add_wait_queue(&thread->wait_q, &wait); | 498 | add_wait_queue(&thread->wait_q, &wait); |
| 499 | 499 | ||
| 500 | set_current_state(TASK_INTERRUPTIBLE); | 500 | set_current_state(TASK_INTERRUPTIBLE); |
| 501 | if (kthread_should_stop()) { | ||
| 502 | BT_DBG("main_thread: break from main thread"); | ||
| 503 | break; | ||
| 504 | } | ||
| 501 | 505 | ||
| 502 | if (adapter->wakeup_tries || | 506 | if (adapter->wakeup_tries || |
| 503 | ((!adapter->int_count) && | 507 | ((!adapter->int_count) && |
| @@ -513,11 +517,6 @@ static int btmrvl_service_main_thread(void *data) | |||
| 513 | 517 | ||
| 514 | BT_DBG("main_thread woke up"); | 518 | BT_DBG("main_thread woke up"); |
| 515 | 519 | ||
| 516 | if (kthread_should_stop()) { | ||
| 517 | BT_DBG("main_thread: break from main thread"); | ||
| 518 | break; | ||
| 519 | } | ||
| 520 | |||
| 521 | spin_lock_irqsave(&priv->driver_lock, flags); | 520 | spin_lock_irqsave(&priv->driver_lock, flags); |
| 522 | if (adapter->int_count) { | 521 | if (adapter->int_count) { |
| 523 | adapter->int_count = 0; | 522 | adapter->int_count = 0; |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 934cfd18f72d..1144e8c7579d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
| @@ -1955,6 +1955,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) | |||
| 1955 | /* XXX the notifier code should handle this better */ | 1955 | /* XXX the notifier code should handle this better */ |
| 1956 | if (!cn->notifier_head.head) { | 1956 | if (!cn->notifier_head.head) { |
| 1957 | srcu_cleanup_notifier_head(&cn->notifier_head); | 1957 | srcu_cleanup_notifier_head(&cn->notifier_head); |
| 1958 | list_del(&cn->node); | ||
| 1958 | kfree(cn); | 1959 | kfree(cn); |
| 1959 | } | 1960 | } |
| 1960 | 1961 | ||
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 5c97e75924a8..22d7699e7ced 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c | |||
| @@ -155,7 +155,7 @@ static __initdata unsigned long exynos5250_clk_regs[] = { | |||
| 155 | 155 | ||
| 156 | /* list of all parent clock list */ | 156 | /* list of all parent clock list */ |
| 157 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; | 157 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; |
| 158 | PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; | 158 | PNAME(mout_cpu_p) = { "mout_apll", "sclk_mpll", }; |
| 159 | PNAME(mout_mpll_fout_p) = { "fout_mplldiv2", "fout_mpll" }; | 159 | PNAME(mout_mpll_fout_p) = { "fout_mplldiv2", "fout_mpll" }; |
| 160 | PNAME(mout_mpll_p) = { "fin_pll", "mout_mpll_fout" }; | 160 | PNAME(mout_mpll_p) = { "fin_pll", "mout_mpll_fout" }; |
| 161 | PNAME(mout_bpll_fout_p) = { "fout_bplldiv2", "fout_bpll" }; | 161 | PNAME(mout_bpll_fout_p) = { "fout_bplldiv2", "fout_bpll" }; |
| @@ -208,10 +208,10 @@ struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { | |||
| 208 | }; | 208 | }; |
| 209 | 209 | ||
| 210 | struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { | 210 | struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { |
| 211 | MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), | 211 | MUX_A(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, "mout_apll"), |
| 212 | MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), | 212 | MUX_A(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"), |
| 213 | MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), | 213 | MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), |
| 214 | MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1), | 214 | MUX_A(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"), |
| 215 | MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), | 215 | MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), |
| 216 | MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), | 216 | MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), |
| 217 | MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), | 217 | MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), |
| @@ -378,7 +378,7 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { | |||
| 378 | GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0), | 378 | GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0), |
| 379 | GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0), | 379 | GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0), |
| 380 | GATE(sysreg, "sysreg", "aclk66", GATE_IP_PERIS, 1, 0, 0), | 380 | GATE(sysreg, "sysreg", "aclk66", GATE_IP_PERIS, 1, 0, 0), |
| 381 | GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, 0, 0), | 381 | GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED, 0), |
| 382 | GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0), | 382 | GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0), |
| 383 | GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0), | 383 | GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0), |
| 384 | GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0), | 384 | GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0), |
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 89135f6be116..362f12dcd944 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c | |||
| @@ -111,7 +111,8 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, | |||
| 111 | unsigned long parent_rate) | 111 | unsigned long parent_rate) |
| 112 | { | 112 | { |
| 113 | struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw); | 113 | struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw); |
| 114 | u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; | 114 | u32 mdiv, pdiv, sdiv, pll_con0, pll_con1; |
| 115 | s16 kdiv; | ||
| 115 | u64 fvco = parent_rate; | 116 | u64 fvco = parent_rate; |
| 116 | 117 | ||
| 117 | pll_con0 = __raw_readl(pll->con_reg); | 118 | pll_con0 = __raw_readl(pll->con_reg); |
| @@ -119,7 +120,7 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, | |||
| 119 | mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; | 120 | mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; |
| 120 | pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; | 121 | pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; |
| 121 | sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; | 122 | sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; |
| 122 | kdiv = pll_con1 & PLL36XX_KDIV_MASK; | 123 | kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK); |
| 123 | 124 | ||
| 124 | fvco *= (mdiv << 16) + kdiv; | 125 | fvco *= (mdiv << 16) + kdiv; |
| 125 | do_div(fvco, (pdiv << sdiv)); | 126 | do_div(fvco, (pdiv << sdiv)); |
diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index f9ec43fd1320..080c3c5e33f6 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c | |||
| @@ -369,7 +369,7 @@ static void __init spear320_clk_init(void __iomem *soc_config_base) | |||
| 369 | clk_register_clkdev(clk, NULL, "60100000.serial"); | 369 | clk_register_clkdev(clk, NULL, "60100000.serial"); |
| 370 | } | 370 | } |
| 371 | #else | 371 | #else |
| 372 | static inline void spear320_clk_init(void) { } | 372 | static inline void spear320_clk_init(void __iomem *soc_config_base) { } |
| 373 | #endif | 373 | #endif |
| 374 | 374 | ||
| 375 | void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_base) | 375 | void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_base) |
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index c6921f538e28..ba99e3844106 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c | |||
| @@ -1598,6 +1598,12 @@ static void __init tegra30_periph_clk_init(void) | |||
| 1598 | clk_register_clkdev(clk, "afi", "tegra-pcie"); | 1598 | clk_register_clkdev(clk, "afi", "tegra-pcie"); |
| 1599 | clks[afi] = clk; | 1599 | clks[afi] = clk; |
| 1600 | 1600 | ||
| 1601 | /* pciex */ | ||
| 1602 | clk = tegra_clk_register_periph_gate("pciex", "pll_e", 0, clk_base, 0, | ||
| 1603 | 74, &periph_u_regs, periph_clk_enb_refcnt); | ||
| 1604 | clk_register_clkdev(clk, "pciex", "tegra-pcie"); | ||
| 1605 | clks[pciex] = clk; | ||
| 1606 | |||
| 1601 | /* kfuse */ | 1607 | /* kfuse */ |
| 1602 | clk = tegra_clk_register_periph_gate("kfuse", "clk_m", | 1608 | clk = tegra_clk_register_periph_gate("kfuse", "clk_m", |
| 1603 | TEGRA_PERIPH_ON_APB, | 1609 | TEGRA_PERIPH_ON_APB, |
| @@ -1716,11 +1722,6 @@ static void __init tegra30_fixed_clk_init(void) | |||
| 1716 | 1, 0, &cml_lock); | 1722 | 1, 0, &cml_lock); |
| 1717 | clk_register_clkdev(clk, "cml1", NULL); | 1723 | clk_register_clkdev(clk, "cml1", NULL); |
| 1718 | clks[cml1] = clk; | 1724 | clks[cml1] = clk; |
| 1719 | |||
| 1720 | /* pciex */ | ||
| 1721 | clk = clk_register_fixed_rate(NULL, "pciex", "pll_e", 0, 100000000); | ||
| 1722 | clk_register_clkdev(clk, "pciex", NULL); | ||
| 1723 | clks[pciex] = clk; | ||
| 1724 | } | 1725 | } |
| 1725 | 1726 | ||
| 1726 | static void __init tegra30_osc_clk_init(void) | 1727 | static void __init tegra30_osc_clk_init(void) |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 4b9bb5def6f1..93eb5cbcc1f6 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
| @@ -47,6 +47,8 @@ static struct od_ops od_ops; | |||
| 47 | static struct cpufreq_governor cpufreq_gov_ondemand; | 47 | static struct cpufreq_governor cpufreq_gov_ondemand; |
| 48 | #endif | 48 | #endif |
| 49 | 49 | ||
| 50 | static unsigned int default_powersave_bias; | ||
| 51 | |||
| 50 | static void ondemand_powersave_bias_init_cpu(int cpu) | 52 | static void ondemand_powersave_bias_init_cpu(int cpu) |
| 51 | { | 53 | { |
| 52 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); | 54 | struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); |
| @@ -543,7 +545,7 @@ static int od_init(struct dbs_data *dbs_data) | |||
| 543 | 545 | ||
| 544 | tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; | 546 | tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; |
| 545 | tuners->ignore_nice = 0; | 547 | tuners->ignore_nice = 0; |
| 546 | tuners->powersave_bias = 0; | 548 | tuners->powersave_bias = default_powersave_bias; |
| 547 | tuners->io_is_busy = should_io_be_busy(); | 549 | tuners->io_is_busy = should_io_be_busy(); |
| 548 | 550 | ||
| 549 | dbs_data->tuners = tuners; | 551 | dbs_data->tuners = tuners; |
| @@ -585,6 +587,7 @@ static void od_set_powersave_bias(unsigned int powersave_bias) | |||
| 585 | unsigned int cpu; | 587 | unsigned int cpu; |
| 586 | cpumask_t done; | 588 | cpumask_t done; |
| 587 | 589 | ||
| 590 | default_powersave_bias = powersave_bias; | ||
| 588 | cpumask_clear(&done); | 591 | cpumask_clear(&done); |
| 589 | 592 | ||
| 590 | get_online_cpus(); | 593 | get_online_cpus(); |
| @@ -593,11 +596,17 @@ static void od_set_powersave_bias(unsigned int powersave_bias) | |||
| 593 | continue; | 596 | continue; |
| 594 | 597 | ||
| 595 | policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy; | 598 | policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy; |
| 596 | dbs_data = policy->governor_data; | 599 | if (!policy) |
| 597 | od_tuners = dbs_data->tuners; | 600 | continue; |
| 598 | od_tuners->powersave_bias = powersave_bias; | ||
| 599 | 601 | ||
| 600 | cpumask_or(&done, &done, policy->cpus); | 602 | cpumask_or(&done, &done, policy->cpus); |
| 603 | |||
| 604 | if (policy->governor != &cpufreq_gov_ondemand) | ||
| 605 | continue; | ||
| 606 | |||
| 607 | dbs_data = policy->governor_data; | ||
| 608 | od_tuners = dbs_data->tuners; | ||
| 609 | od_tuners->powersave_bias = default_powersave_bias; | ||
| 601 | } | 610 | } |
| 602 | put_online_cpus(); | 611 | put_online_cpus(); |
| 603 | } | 612 | } |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d3f7d2db870f..4a430360af5a 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -1094,6 +1094,9 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
| 1094 | const struct omap_gpio_platform_data *pdata; | 1094 | const struct omap_gpio_platform_data *pdata; |
| 1095 | struct resource *res; | 1095 | struct resource *res; |
| 1096 | struct gpio_bank *bank; | 1096 | struct gpio_bank *bank; |
| 1097 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 1098 | int irq_base; | ||
| 1099 | #endif | ||
| 1097 | 1100 | ||
| 1098 | match = of_match_device(of_match_ptr(omap_gpio_match), dev); | 1101 | match = of_match_device(of_match_ptr(omap_gpio_match), dev); |
| 1099 | 1102 | ||
| @@ -1135,11 +1138,28 @@ static int omap_gpio_probe(struct platform_device *pdev) | |||
| 1135 | pdata->get_context_loss_count; | 1138 | pdata->get_context_loss_count; |
| 1136 | } | 1139 | } |
| 1137 | 1140 | ||
| 1141 | #ifdef CONFIG_ARCH_OMAP1 | ||
| 1142 | /* | ||
| 1143 | * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop | ||
| 1144 | * irq_alloc_descs() and irq_domain_add_legacy() and just use a | ||
| 1145 | * linear IRQ domain mapping for all OMAP platforms. | ||
| 1146 | */ | ||
| 1147 | irq_base = irq_alloc_descs(-1, 0, bank->width, 0); | ||
| 1148 | if (irq_base < 0) { | ||
| 1149 | dev_err(dev, "Couldn't allocate IRQ numbers\n"); | ||
| 1150 | return -ENODEV; | ||
| 1151 | } | ||
| 1138 | 1152 | ||
| 1153 | bank->domain = irq_domain_add_legacy(node, bank->width, irq_base, | ||
| 1154 | 0, &irq_domain_simple_ops, NULL); | ||
| 1155 | #else | ||
| 1139 | bank->domain = irq_domain_add_linear(node, bank->width, | 1156 | bank->domain = irq_domain_add_linear(node, bank->width, |
| 1140 | &irq_domain_simple_ops, NULL); | 1157 | &irq_domain_simple_ops, NULL); |
| 1141 | if (!bank->domain) | 1158 | #endif |
| 1159 | if (!bank->domain) { | ||
| 1160 | dev_err(dev, "Couldn't register an IRQ domain\n"); | ||
| 1142 | return -ENODEV; | 1161 | return -ENODEV; |
| 1162 | } | ||
| 1143 | 1163 | ||
| 1144 | if (bank->regs->set_dataout && bank->regs->clr_dataout) | 1164 | if (bank->regs->set_dataout && bank->regs->clr_dataout) |
| 1145 | bank->set_dataout = _set_gpio_dataout_reg; | 1165 | bank->set_dataout = _set_gpio_dataout_reg; |
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index dcde35231e25..5b7b9110254b 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c | |||
| @@ -190,8 +190,7 @@ struct dma_buf *drm_gem_prime_export(struct drm_device *dev, | |||
| 190 | if (ret) | 190 | if (ret) |
| 191 | return ERR_PTR(ret); | 191 | return ERR_PTR(ret); |
| 192 | } | 192 | } |
| 193 | return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, | 193 | return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags); |
| 194 | 0600); | ||
| 195 | } | 194 | } |
| 196 | EXPORT_SYMBOL(drm_gem_prime_export); | 195 | EXPORT_SYMBOL(drm_gem_prime_export); |
| 197 | 196 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b9d00dcf9a2d..9669a0b8b440 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -1697,6 +1697,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, | |||
| 1697 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, | 1697 | struct dma_buf *i915_gem_prime_export(struct drm_device *dev, |
| 1698 | struct drm_gem_object *gem_obj, int flags); | 1698 | struct drm_gem_object *gem_obj, int flags); |
| 1699 | 1699 | ||
| 1700 | void i915_gem_restore_fences(struct drm_device *dev); | ||
| 1701 | |||
| 1700 | /* i915_gem_context.c */ | 1702 | /* i915_gem_context.c */ |
| 1701 | void i915_gem_context_init(struct drm_device *dev); | 1703 | void i915_gem_context_init(struct drm_device *dev); |
| 1702 | void i915_gem_context_fini(struct drm_device *dev); | 1704 | void i915_gem_context_fini(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 970ad17c99ab..9e35dafc5807 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1801,7 +1801,14 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 1801 | gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD; | 1801 | gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD; |
| 1802 | gfp &= ~(__GFP_IO | __GFP_WAIT); | 1802 | gfp &= ~(__GFP_IO | __GFP_WAIT); |
| 1803 | } | 1803 | } |
| 1804 | 1804 | #ifdef CONFIG_SWIOTLB | |
| 1805 | if (swiotlb_nr_tbl()) { | ||
| 1806 | st->nents++; | ||
| 1807 | sg_set_page(sg, page, PAGE_SIZE, 0); | ||
| 1808 | sg = sg_next(sg); | ||
| 1809 | continue; | ||
| 1810 | } | ||
| 1811 | #endif | ||
| 1805 | if (!i || page_to_pfn(page) != last_pfn + 1) { | 1812 | if (!i || page_to_pfn(page) != last_pfn + 1) { |
| 1806 | if (i) | 1813 | if (i) |
| 1807 | sg = sg_next(sg); | 1814 | sg = sg_next(sg); |
| @@ -1812,8 +1819,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 1812 | } | 1819 | } |
| 1813 | last_pfn = page_to_pfn(page); | 1820 | last_pfn = page_to_pfn(page); |
| 1814 | } | 1821 | } |
| 1815 | 1822 | #ifdef CONFIG_SWIOTLB | |
| 1816 | sg_mark_end(sg); | 1823 | if (!swiotlb_nr_tbl()) |
| 1824 | #endif | ||
| 1825 | sg_mark_end(sg); | ||
| 1817 | obj->pages = st; | 1826 | obj->pages = st; |
| 1818 | 1827 | ||
| 1819 | if (i915_gem_object_needs_bit17_swizzle(obj)) | 1828 | if (i915_gem_object_needs_bit17_swizzle(obj)) |
| @@ -2117,25 +2126,15 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, | |||
| 2117 | } | 2126 | } |
| 2118 | } | 2127 | } |
| 2119 | 2128 | ||
| 2120 | static void i915_gem_reset_fences(struct drm_device *dev) | 2129 | void i915_gem_restore_fences(struct drm_device *dev) |
| 2121 | { | 2130 | { |
| 2122 | struct drm_i915_private *dev_priv = dev->dev_private; | 2131 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2123 | int i; | 2132 | int i; |
| 2124 | 2133 | ||
| 2125 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 2134 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
| 2126 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 2135 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
| 2127 | 2136 | i915_gem_write_fence(dev, i, reg->obj); | |
| 2128 | if (reg->obj) | ||
| 2129 | i915_gem_object_fence_lost(reg->obj); | ||
| 2130 | |||
| 2131 | i915_gem_write_fence(dev, i, NULL); | ||
| 2132 | |||
| 2133 | reg->pin_count = 0; | ||
| 2134 | reg->obj = NULL; | ||
| 2135 | INIT_LIST_HEAD(®->lru_list); | ||
| 2136 | } | 2137 | } |
| 2137 | |||
| 2138 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | ||
| 2139 | } | 2138 | } |
| 2140 | 2139 | ||
| 2141 | void i915_gem_reset(struct drm_device *dev) | 2140 | void i915_gem_reset(struct drm_device *dev) |
| @@ -2158,8 +2157,7 @@ void i915_gem_reset(struct drm_device *dev) | |||
| 2158 | obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; | 2157 | obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; |
| 2159 | } | 2158 | } |
| 2160 | 2159 | ||
| 2161 | /* The fence registers are invalidated so clear them out */ | 2160 | i915_gem_restore_fences(dev); |
| 2162 | i915_gem_reset_fences(dev); | ||
| 2163 | } | 2161 | } |
| 2164 | 2162 | ||
| 2165 | /** | 2163 | /** |
| @@ -3865,8 +3863,6 @@ i915_gem_idle(struct drm_device *dev) | |||
| 3865 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 3863 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 3866 | i915_gem_evict_everything(dev); | 3864 | i915_gem_evict_everything(dev); |
| 3867 | 3865 | ||
| 3868 | i915_gem_reset_fences(dev); | ||
| 3869 | |||
| 3870 | /* Hack! Don't let anybody do execbuf while we don't control the chip. | 3866 | /* Hack! Don't let anybody do execbuf while we don't control the chip. |
| 3871 | * We need to replace this with a semaphore, or something. | 3867 | * We need to replace this with a semaphore, or something. |
| 3872 | * And not confound mm.suspended! | 3868 | * And not confound mm.suspended! |
| @@ -4193,7 +4189,8 @@ i915_gem_load(struct drm_device *dev) | |||
| 4193 | dev_priv->num_fence_regs = 8; | 4189 | dev_priv->num_fence_regs = 8; |
| 4194 | 4190 | ||
| 4195 | /* Initialize fence registers to zero */ | 4191 | /* Initialize fence registers to zero */ |
| 4196 | i915_gem_reset_fences(dev); | 4192 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
| 4193 | i915_gem_restore_fences(dev); | ||
| 4197 | 4194 | ||
| 4198 | i915_gem_detect_bit_6_swizzle(dev); | 4195 | i915_gem_detect_bit_6_swizzle(dev); |
| 4199 | init_waitqueue_head(&dev_priv->pending_flip_queue); | 4196 | init_waitqueue_head(&dev_priv->pending_flip_queue); |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 41f0fdecfbdc..369b3d8776ab 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
| @@ -384,6 +384,7 @@ int i915_restore_state(struct drm_device *dev) | |||
| 384 | 384 | ||
| 385 | mutex_lock(&dev->struct_mutex); | 385 | mutex_lock(&dev->struct_mutex); |
| 386 | 386 | ||
| 387 | i915_gem_restore_fences(dev); | ||
| 387 | i915_restore_display(dev); | 388 | i915_restore_display(dev); |
| 388 | 389 | ||
| 389 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 390 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 0e5341695922..6948eb88c2b7 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -2687,6 +2687,9 @@ void r600_uvd_rbc_stop(struct radeon_device *rdev) | |||
| 2687 | int r600_uvd_init(struct radeon_device *rdev) | 2687 | int r600_uvd_init(struct radeon_device *rdev) |
| 2688 | { | 2688 | { |
| 2689 | int i, j, r; | 2689 | int i, j, r; |
| 2690 | /* disable byte swapping */ | ||
| 2691 | u32 lmi_swap_cntl = 0; | ||
| 2692 | u32 mp_swap_cntl = 0; | ||
| 2690 | 2693 | ||
| 2691 | /* raise clocks while booting up the VCPU */ | 2694 | /* raise clocks while booting up the VCPU */ |
| 2692 | radeon_set_uvd_clocks(rdev, 53300, 40000); | 2695 | radeon_set_uvd_clocks(rdev, 53300, 40000); |
| @@ -2711,9 +2714,13 @@ int r600_uvd_init(struct radeon_device *rdev) | |||
| 2711 | WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | | 2714 | WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) | |
| 2712 | (1 << 21) | (1 << 9) | (1 << 20)); | 2715 | (1 << 21) | (1 << 9) | (1 << 20)); |
| 2713 | 2716 | ||
| 2714 | /* disable byte swapping */ | 2717 | #ifdef __BIG_ENDIAN |
| 2715 | WREG32(UVD_LMI_SWAP_CNTL, 0); | 2718 | /* swap (8 in 32) RB and IB */ |
| 2716 | WREG32(UVD_MP_SWAP_CNTL, 0); | 2719 | lmi_swap_cntl = 0xa; |
| 2720 | mp_swap_cntl = 0; | ||
| 2721 | #endif | ||
| 2722 | WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl); | ||
| 2723 | WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl); | ||
| 2717 | 2724 | ||
| 2718 | WREG32(UVD_MPC_SET_MUXA0, 0x40c2040); | 2725 | WREG32(UVD_MPC_SET_MUXA0, 0x40c2040); |
| 2719 | WREG32(UVD_MPC_SET_MUXA1, 0x0); | 2726 | WREG32(UVD_MPC_SET_MUXA1, 0x0); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 189973836cff..b0dc0b6cb4e0 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -244,16 +244,6 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) | |||
| 244 | */ | 244 | */ |
| 245 | void radeon_wb_disable(struct radeon_device *rdev) | 245 | void radeon_wb_disable(struct radeon_device *rdev) |
| 246 | { | 246 | { |
| 247 | int r; | ||
| 248 | |||
| 249 | if (rdev->wb.wb_obj) { | ||
| 250 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | ||
| 251 | if (unlikely(r != 0)) | ||
| 252 | return; | ||
| 253 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
| 254 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
| 255 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
| 256 | } | ||
| 257 | rdev->wb.enabled = false; | 247 | rdev->wb.enabled = false; |
| 258 | } | 248 | } |
| 259 | 249 | ||
| @@ -269,6 +259,11 @@ void radeon_wb_fini(struct radeon_device *rdev) | |||
| 269 | { | 259 | { |
| 270 | radeon_wb_disable(rdev); | 260 | radeon_wb_disable(rdev); |
| 271 | if (rdev->wb.wb_obj) { | 261 | if (rdev->wb.wb_obj) { |
| 262 | if (!radeon_bo_reserve(rdev->wb.wb_obj, false)) { | ||
| 263 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
| 264 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
| 265 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
| 266 | } | ||
| 272 | radeon_bo_unref(&rdev->wb.wb_obj); | 267 | radeon_bo_unref(&rdev->wb.wb_obj); |
| 273 | rdev->wb.wb = NULL; | 268 | rdev->wb.wb = NULL; |
| 274 | rdev->wb.wb_obj = NULL; | 269 | rdev->wb.wb_obj = NULL; |
| @@ -295,26 +290,26 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
| 295 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); | 290 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
| 296 | return r; | 291 | return r; |
| 297 | } | 292 | } |
| 298 | } | 293 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
| 299 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); | 294 | if (unlikely(r != 0)) { |
| 300 | if (unlikely(r != 0)) { | 295 | radeon_wb_fini(rdev); |
| 301 | radeon_wb_fini(rdev); | 296 | return r; |
| 302 | return r; | 297 | } |
| 303 | } | 298 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, |
| 304 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | 299 | &rdev->wb.gpu_addr); |
| 305 | &rdev->wb.gpu_addr); | 300 | if (r) { |
| 306 | if (r) { | 301 | radeon_bo_unreserve(rdev->wb.wb_obj); |
| 302 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | ||
| 303 | radeon_wb_fini(rdev); | ||
| 304 | return r; | ||
| 305 | } | ||
| 306 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | ||
| 307 | radeon_bo_unreserve(rdev->wb.wb_obj); | 307 | radeon_bo_unreserve(rdev->wb.wb_obj); |
| 308 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | 308 | if (r) { |
| 309 | radeon_wb_fini(rdev); | 309 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); |
| 310 | return r; | 310 | radeon_wb_fini(rdev); |
| 311 | } | 311 | return r; |
| 312 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | 312 | } |
| 313 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
| 314 | if (r) { | ||
| 315 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); | ||
| 316 | radeon_wb_fini(rdev); | ||
| 317 | return r; | ||
| 318 | } | 313 | } |
| 319 | 314 | ||
| 320 | /* clear wb memory */ | 315 | /* clear wb memory */ |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 5b937dfe6f65..ddb8f8e04eb5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
| @@ -63,7 +63,9 @@ static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) | |||
| 63 | { | 63 | { |
| 64 | struct radeon_fence_driver *drv = &rdev->fence_drv[ring]; | 64 | struct radeon_fence_driver *drv = &rdev->fence_drv[ring]; |
| 65 | if (likely(rdev->wb.enabled || !drv->scratch_reg)) { | 65 | if (likely(rdev->wb.enabled || !drv->scratch_reg)) { |
| 66 | *drv->cpu_addr = cpu_to_le32(seq); | 66 | if (drv->cpu_addr) { |
| 67 | *drv->cpu_addr = cpu_to_le32(seq); | ||
| 68 | } | ||
| 67 | } else { | 69 | } else { |
| 68 | WREG32(drv->scratch_reg, seq); | 70 | WREG32(drv->scratch_reg, seq); |
| 69 | } | 71 | } |
| @@ -84,7 +86,11 @@ static u32 radeon_fence_read(struct radeon_device *rdev, int ring) | |||
| 84 | u32 seq = 0; | 86 | u32 seq = 0; |
| 85 | 87 | ||
| 86 | if (likely(rdev->wb.enabled || !drv->scratch_reg)) { | 88 | if (likely(rdev->wb.enabled || !drv->scratch_reg)) { |
| 87 | seq = le32_to_cpu(*drv->cpu_addr); | 89 | if (drv->cpu_addr) { |
| 90 | seq = le32_to_cpu(*drv->cpu_addr); | ||
| 91 | } else { | ||
| 92 | seq = lower_32_bits(atomic64_read(&drv->last_seq)); | ||
| 93 | } | ||
| 88 | } else { | 94 | } else { |
| 89 | seq = RREG32(drv->scratch_reg); | 95 | seq = RREG32(drv->scratch_reg); |
| 90 | } | 96 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 2c1341f63dc5..43ec4a401f07 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -1197,11 +1197,13 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 1197 | int radeon_vm_bo_rmv(struct radeon_device *rdev, | 1197 | int radeon_vm_bo_rmv(struct radeon_device *rdev, |
| 1198 | struct radeon_bo_va *bo_va) | 1198 | struct radeon_bo_va *bo_va) |
| 1199 | { | 1199 | { |
| 1200 | int r; | 1200 | int r = 0; |
| 1201 | 1201 | ||
| 1202 | mutex_lock(&rdev->vm_manager.lock); | 1202 | mutex_lock(&rdev->vm_manager.lock); |
| 1203 | mutex_lock(&bo_va->vm->mutex); | 1203 | mutex_lock(&bo_va->vm->mutex); |
| 1204 | r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); | 1204 | if (bo_va->soffset) { |
| 1205 | r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); | ||
| 1206 | } | ||
| 1205 | mutex_unlock(&rdev->vm_manager.lock); | 1207 | mutex_unlock(&rdev->vm_manager.lock); |
| 1206 | list_del(&bo_va->vm_list); | 1208 | list_del(&bo_va->vm_list); |
| 1207 | mutex_unlock(&bo_va->vm->mutex); | 1209 | mutex_unlock(&bo_va->vm->mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index e17faa7cf732..82434018cbe8 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
| @@ -402,6 +402,13 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi | |||
| 402 | return -ENOMEM; | 402 | return -ENOMEM; |
| 403 | /* Align requested size with padding so unlock_commit can | 403 | /* Align requested size with padding so unlock_commit can |
| 404 | * pad safely */ | 404 | * pad safely */ |
| 405 | radeon_ring_free_size(rdev, ring); | ||
| 406 | if (ring->ring_free_dw == (ring->ring_size / 4)) { | ||
| 407 | /* This is an empty ring update lockup info to avoid | ||
| 408 | * false positive. | ||
| 409 | */ | ||
| 410 | radeon_ring_lockup_update(ring); | ||
| 411 | } | ||
| 405 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; | 412 | ndw = (ndw + ring->align_mask) & ~ring->align_mask; |
| 406 | while (ndw > (ring->ring_free_dw - 1)) { | 413 | while (ndw > (ring->ring_free_dw - 1)) { |
| 407 | radeon_ring_free_size(rdev, ring); | 414 | radeon_ring_free_size(rdev, ring); |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 906e5c0ca3b9..cad735dd02c6 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
| @@ -159,7 +159,17 @@ int radeon_uvd_suspend(struct radeon_device *rdev) | |||
| 159 | if (!r) { | 159 | if (!r) { |
| 160 | radeon_bo_kunmap(rdev->uvd.vcpu_bo); | 160 | radeon_bo_kunmap(rdev->uvd.vcpu_bo); |
| 161 | radeon_bo_unpin(rdev->uvd.vcpu_bo); | 161 | radeon_bo_unpin(rdev->uvd.vcpu_bo); |
| 162 | rdev->uvd.cpu_addr = NULL; | ||
| 163 | if (!radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_CPU, NULL)) { | ||
| 164 | radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr); | ||
| 165 | } | ||
| 162 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); | 166 | radeon_bo_unreserve(rdev->uvd.vcpu_bo); |
| 167 | |||
| 168 | if (rdev->uvd.cpu_addr) { | ||
| 169 | radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); | ||
| 170 | } else { | ||
| 171 | rdev->fence_drv[R600_RING_TYPE_UVD_INDEX].cpu_addr = NULL; | ||
| 172 | } | ||
| 163 | } | 173 | } |
| 164 | return r; | 174 | return r; |
| 165 | } | 175 | } |
| @@ -178,6 +188,10 @@ int radeon_uvd_resume(struct radeon_device *rdev) | |||
| 178 | return r; | 188 | return r; |
| 179 | } | 189 | } |
| 180 | 190 | ||
| 191 | /* Have been pin in cpu unmap unpin */ | ||
| 192 | radeon_bo_kunmap(rdev->uvd.vcpu_bo); | ||
| 193 | radeon_bo_unpin(rdev->uvd.vcpu_bo); | ||
| 194 | |||
| 181 | r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, | 195 | r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, |
| 182 | &rdev->uvd.gpu_addr); | 196 | &rdev->uvd.gpu_addr); |
| 183 | if (r) { | 197 | if (r) { |
| @@ -613,19 +627,19 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, | |||
| 613 | } | 627 | } |
| 614 | 628 | ||
| 615 | /* stitch together an UVD create msg */ | 629 | /* stitch together an UVD create msg */ |
| 616 | msg[0] = 0x00000de4; | 630 | msg[0] = cpu_to_le32(0x00000de4); |
| 617 | msg[1] = 0x00000000; | 631 | msg[1] = cpu_to_le32(0x00000000); |
| 618 | msg[2] = handle; | 632 | msg[2] = cpu_to_le32(handle); |
| 619 | msg[3] = 0x00000000; | 633 | msg[3] = cpu_to_le32(0x00000000); |
| 620 | msg[4] = 0x00000000; | 634 | msg[4] = cpu_to_le32(0x00000000); |
| 621 | msg[5] = 0x00000000; | 635 | msg[5] = cpu_to_le32(0x00000000); |
| 622 | msg[6] = 0x00000000; | 636 | msg[6] = cpu_to_le32(0x00000000); |
| 623 | msg[7] = 0x00000780; | 637 | msg[7] = cpu_to_le32(0x00000780); |
| 624 | msg[8] = 0x00000440; | 638 | msg[8] = cpu_to_le32(0x00000440); |
| 625 | msg[9] = 0x00000000; | 639 | msg[9] = cpu_to_le32(0x00000000); |
| 626 | msg[10] = 0x01b37000; | 640 | msg[10] = cpu_to_le32(0x01b37000); |
| 627 | for (i = 11; i < 1024; ++i) | 641 | for (i = 11; i < 1024; ++i) |
| 628 | msg[i] = 0x0; | 642 | msg[i] = cpu_to_le32(0x0); |
| 629 | 643 | ||
| 630 | radeon_bo_kunmap(bo); | 644 | radeon_bo_kunmap(bo); |
| 631 | radeon_bo_unreserve(bo); | 645 | radeon_bo_unreserve(bo); |
| @@ -659,12 +673,12 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, | |||
| 659 | } | 673 | } |
| 660 | 674 | ||
| 661 | /* stitch together an UVD destroy msg */ | 675 | /* stitch together an UVD destroy msg */ |
| 662 | msg[0] = 0x00000de4; | 676 | msg[0] = cpu_to_le32(0x00000de4); |
| 663 | msg[1] = 0x00000002; | 677 | msg[1] = cpu_to_le32(0x00000002); |
| 664 | msg[2] = handle; | 678 | msg[2] = cpu_to_le32(handle); |
| 665 | msg[3] = 0x00000000; | 679 | msg[3] = cpu_to_le32(0x00000000); |
| 666 | for (i = 4; i < 1024; ++i) | 680 | for (i = 4; i < 1024; ++i) |
| 667 | msg[i] = 0x0; | 681 | msg[i] = cpu_to_le32(0x0); |
| 668 | 682 | ||
| 669 | radeon_bo_kunmap(bo); | 683 | radeon_bo_kunmap(bo); |
| 670 | radeon_bo_unreserve(bo); | 684 | radeon_bo_unreserve(bo); |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d6cbfe9df218..fa061d46527f 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
| @@ -137,7 +137,7 @@ static const struct xpad_device { | |||
| 137 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 137 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 138 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, | 138 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, |
| 139 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, | 139 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
| 140 | { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", XTYPE_XBOX360 }, | 140 | { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
| 141 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, | 141 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
| 142 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 142 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 143 | { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, | 143 | { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 62a2c0e4cc99..7ac9c9818d55 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -431,6 +431,7 @@ config KEYBOARD_TEGRA | |||
| 431 | 431 | ||
| 432 | config KEYBOARD_OPENCORES | 432 | config KEYBOARD_OPENCORES |
| 433 | tristate "OpenCores Keyboard Controller" | 433 | tristate "OpenCores Keyboard Controller" |
| 434 | depends on HAS_IOMEM | ||
| 434 | help | 435 | help |
| 435 | Say Y here if you want to use the OpenCores Keyboard Controller | 436 | Say Y here if you want to use the OpenCores Keyboard Controller |
| 436 | http://www.opencores.org/project,keyboardcontroller | 437 | http://www.opencores.org/project,keyboardcontroller |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index aebfe3ecb945..1bda828f4b55 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
| @@ -205,6 +205,7 @@ config SERIO_XILINX_XPS_PS2 | |||
| 205 | 205 | ||
| 206 | config SERIO_ALTERA_PS2 | 206 | config SERIO_ALTERA_PS2 |
| 207 | tristate "Altera UP PS/2 controller" | 207 | tristate "Altera UP PS/2 controller" |
| 208 | depends on HAS_IOMEM | ||
| 208 | help | 209 | help |
| 209 | Say Y here if you have Altera University Program PS/2 ports. | 210 | Say Y here if you have Altera University Program PS/2 ports. |
| 210 | 211 | ||
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 518282da6d85..384fbcd0cee0 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -363,6 +363,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 363 | case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ | 363 | case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ |
| 364 | case 0x160802: /* Cintiq 13HD Pro Pen */ | 364 | case 0x160802: /* Cintiq 13HD Pro Pen */ |
| 365 | case 0x180802: /* DTH2242 Pen */ | 365 | case 0x180802: /* DTH2242 Pen */ |
| 366 | case 0x100802: /* Intuos4/5 13HD/24HD General Pen */ | ||
| 366 | wacom->tool[idx] = BTN_TOOL_PEN; | 367 | wacom->tool[idx] = BTN_TOOL_PEN; |
| 367 | break; | 368 | break; |
| 368 | 369 | ||
| @@ -401,6 +402,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
| 401 | case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ | 402 | case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ |
| 402 | case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ | 403 | case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ |
| 403 | case 0x18080a: /* DTH2242 Eraser */ | 404 | case 0x18080a: /* DTH2242 Eraser */ |
| 405 | case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */ | ||
| 404 | wacom->tool[idx] = BTN_TOOL_RUBBER; | 406 | wacom->tool[idx] = BTN_TOOL_RUBBER; |
| 405 | break; | 407 | break; |
| 406 | 408 | ||
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index 8e60437ac85b..ae89d2609ab0 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c | |||
| @@ -116,6 +116,15 @@ static int ttsp_send_command(struct cyttsp *ts, u8 cmd) | |||
| 116 | return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); | 116 | return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | static int cyttsp_handshake(struct cyttsp *ts) | ||
| 120 | { | ||
| 121 | if (ts->pdata->use_hndshk) | ||
| 122 | return ttsp_send_command(ts, | ||
| 123 | ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 119 | static int cyttsp_load_bl_regs(struct cyttsp *ts) | 128 | static int cyttsp_load_bl_regs(struct cyttsp *ts) |
| 120 | { | 129 | { |
| 121 | memset(&ts->bl_data, 0, sizeof(ts->bl_data)); | 130 | memset(&ts->bl_data, 0, sizeof(ts->bl_data)); |
| @@ -133,7 +142,7 @@ static int cyttsp_exit_bl_mode(struct cyttsp *ts) | |||
| 133 | memcpy(bl_cmd, bl_command, sizeof(bl_command)); | 142 | memcpy(bl_cmd, bl_command, sizeof(bl_command)); |
| 134 | if (ts->pdata->bl_keys) | 143 | if (ts->pdata->bl_keys) |
| 135 | memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], | 144 | memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], |
| 136 | ts->pdata->bl_keys, sizeof(bl_command)); | 145 | ts->pdata->bl_keys, CY_NUM_BL_KEYS); |
| 137 | 146 | ||
| 138 | error = ttsp_write_block_data(ts, CY_REG_BASE, | 147 | error = ttsp_write_block_data(ts, CY_REG_BASE, |
| 139 | sizeof(bl_cmd), bl_cmd); | 148 | sizeof(bl_cmd), bl_cmd); |
| @@ -167,6 +176,10 @@ static int cyttsp_set_operational_mode(struct cyttsp *ts) | |||
| 167 | if (error) | 176 | if (error) |
| 168 | return error; | 177 | return error; |
| 169 | 178 | ||
| 179 | error = cyttsp_handshake(ts); | ||
| 180 | if (error) | ||
| 181 | return error; | ||
| 182 | |||
| 170 | return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; | 183 | return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; |
| 171 | } | 184 | } |
| 172 | 185 | ||
| @@ -188,6 +201,10 @@ static int cyttsp_set_sysinfo_mode(struct cyttsp *ts) | |||
| 188 | if (error) | 201 | if (error) |
| 189 | return error; | 202 | return error; |
| 190 | 203 | ||
| 204 | error = cyttsp_handshake(ts); | ||
| 205 | if (error) | ||
| 206 | return error; | ||
| 207 | |||
| 191 | if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) | 208 | if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) |
| 192 | return -EIO; | 209 | return -EIO; |
| 193 | 210 | ||
| @@ -344,12 +361,9 @@ static irqreturn_t cyttsp_irq(int irq, void *handle) | |||
| 344 | goto out; | 361 | goto out; |
| 345 | 362 | ||
| 346 | /* provide flow control handshake */ | 363 | /* provide flow control handshake */ |
| 347 | if (ts->pdata->use_hndshk) { | 364 | error = cyttsp_handshake(ts); |
| 348 | error = ttsp_send_command(ts, | 365 | if (error) |
| 349 | ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); | 366 | goto out; |
| 350 | if (error) | ||
| 351 | goto out; | ||
| 352 | } | ||
| 353 | 367 | ||
| 354 | if (unlikely(ts->state == CY_IDLE_STATE)) | 368 | if (unlikely(ts->state == CY_IDLE_STATE)) |
| 355 | goto out; | 369 | goto out; |
diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h index 1aa3c6967e70..f1ebde369f86 100644 --- a/drivers/input/touchscreen/cyttsp_core.h +++ b/drivers/input/touchscreen/cyttsp_core.h | |||
| @@ -67,8 +67,8 @@ struct cyttsp_xydata { | |||
| 67 | /* TTSP System Information interface definition */ | 67 | /* TTSP System Information interface definition */ |
| 68 | struct cyttsp_sysinfo_data { | 68 | struct cyttsp_sysinfo_data { |
| 69 | u8 hst_mode; | 69 | u8 hst_mode; |
| 70 | u8 mfg_cmd; | ||
| 71 | u8 mfg_stat; | 70 | u8 mfg_stat; |
| 71 | u8 mfg_cmd; | ||
| 72 | u8 cid[3]; | 72 | u8 cid[3]; |
| 73 | u8 tt_undef1; | 73 | u8 tt_undef1; |
| 74 | u8 uid[8]; | 74 | u8 uid[8]; |
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 1760ceb68b7b..19ceaa60e0f4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
| @@ -705,7 +705,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, | |||
| 705 | static int __cpuinit gic_secondary_init(struct notifier_block *nfb, | 705 | static int __cpuinit gic_secondary_init(struct notifier_block *nfb, |
| 706 | unsigned long action, void *hcpu) | 706 | unsigned long action, void *hcpu) |
| 707 | { | 707 | { |
| 708 | if (action == CPU_STARTING) | 708 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) |
| 709 | gic_cpu_init(&gic_data[0]); | 709 | gic_cpu_init(&gic_data[0]); |
| 710 | return NOTIFY_OK; | 710 | return NOTIFY_OK; |
| 711 | } | 711 | } |
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 7f5a7cac6dc7..8270388e2a0d 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
| @@ -136,9 +136,9 @@ config DVB_NET | |||
| 136 | 136 | ||
| 137 | # This Kconfig option is used by both PCI and USB drivers | 137 | # This Kconfig option is used by both PCI and USB drivers |
| 138 | config TTPCI_EEPROM | 138 | config TTPCI_EEPROM |
| 139 | tristate | 139 | tristate |
| 140 | depends on I2C | 140 | depends on I2C |
| 141 | default n | 141 | default n |
| 142 | 142 | ||
| 143 | source "drivers/media/dvb-core/Kconfig" | 143 | source "drivers/media/dvb-core/Kconfig" |
| 144 | 144 | ||
| @@ -189,6 +189,12 @@ config MEDIA_SUBDRV_AUTOSELECT | |||
| 189 | 189 | ||
| 190 | If unsure say Y. | 190 | If unsure say Y. |
| 191 | 191 | ||
| 192 | config MEDIA_ATTACH | ||
| 193 | bool | ||
| 194 | depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT | ||
| 195 | depends on MODULES | ||
| 196 | default MODULES | ||
| 197 | |||
| 192 | source "drivers/media/i2c/Kconfig" | 198 | source "drivers/media/i2c/Kconfig" |
| 193 | source "drivers/media/tuners/Kconfig" | 199 | source "drivers/media/tuners/Kconfig" |
| 194 | source "drivers/media/dvb-frontends/Kconfig" | 200 | source "drivers/media/dvb-frontends/Kconfig" |
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index cb52438e53ac..9eac5310942f 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c | |||
| @@ -956,7 +956,7 @@ static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd, | |||
| 956 | 956 | ||
| 957 | if (fie->pad != OIF_SOURCE_PAD) | 957 | if (fie->pad != OIF_SOURCE_PAD) |
| 958 | return -EINVAL; | 958 | return -EINVAL; |
| 959 | if (fie->index > ARRAY_SIZE(s5c73m3_intervals)) | 959 | if (fie->index >= ARRAY_SIZE(s5c73m3_intervals)) |
| 960 | return -EINVAL; | 960 | return -EINVAL; |
| 961 | 961 | ||
| 962 | mutex_lock(&state->lock); | 962 | mutex_lock(&state->lock); |
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 27d62623274b..aba5b1c649e6 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c | |||
| @@ -615,7 +615,7 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, | |||
| 615 | int changed = 0; | 615 | int changed = 0; |
| 616 | u32 old; | 616 | u32 old; |
| 617 | 617 | ||
| 618 | if (core->board.audio_chip == V4L2_IDENT_WM8775) | 618 | if (core->sd_wm8775) |
| 619 | snd_cx88_wm8775_volume_put(kcontrol, value); | 619 | snd_cx88_wm8775_volume_put(kcontrol, value); |
| 620 | 620 | ||
| 621 | left = value->value.integer.value[0] & 0x3f; | 621 | left = value->value.integer.value[0] & 0x3f; |
| @@ -682,8 +682,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, | |||
| 682 | vol ^= bit; | 682 | vol ^= bit; |
| 683 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); | 683 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); |
| 684 | /* Pass mute onto any WM8775 */ | 684 | /* Pass mute onto any WM8775 */ |
| 685 | if ((core->board.audio_chip == V4L2_IDENT_WM8775) && | 685 | if (core->sd_wm8775 && ((1<<6) == bit)) |
| 686 | ((1<<6) == bit)) | ||
| 687 | wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); | 686 | wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); |
| 688 | ret = 1; | 687 | ret = 1; |
| 689 | } | 688 | } |
| @@ -903,7 +902,7 @@ static int cx88_audio_initdev(struct pci_dev *pci, | |||
| 903 | goto error; | 902 | goto error; |
| 904 | 903 | ||
| 905 | /* If there's a wm8775 then add a Line-In ALC switch */ | 904 | /* If there's a wm8775 then add a Line-In ALC switch */ |
| 906 | if (core->board.audio_chip == V4L2_IDENT_WM8775) | 905 | if (core->sd_wm8775) |
| 907 | snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip)); | 906 | snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip)); |
| 908 | 907 | ||
| 909 | strcpy (card->driver, "CX88x"); | 908 | strcpy (card->driver, "CX88x"); |
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 1b00615fd395..c7a9be1065c0 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c | |||
| @@ -385,8 +385,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) | |||
| 385 | /* The wm8775 module has the "2" route hardwired into | 385 | /* The wm8775 module has the "2" route hardwired into |
| 386 | the initialization. Some boards may use different | 386 | the initialization. Some boards may use different |
| 387 | routes for different inputs. HVR-1300 surely does */ | 387 | routes for different inputs. HVR-1300 surely does */ |
| 388 | if (core->board.audio_chip && | 388 | if (core->sd_wm8775) { |
| 389 | core->board.audio_chip == V4L2_IDENT_WM8775) { | ||
| 390 | call_all(core, audio, s_routing, | 389 | call_all(core, audio, s_routing, |
| 391 | INPUT(input).audioroute, 0, 0); | 390 | INPUT(input).audioroute, 0, 0); |
| 392 | } | 391 | } |
| @@ -771,8 +770,7 @@ static int video_open(struct file *file) | |||
| 771 | cx_write(MO_GP1_IO, core->board.radio.gpio1); | 770 | cx_write(MO_GP1_IO, core->board.radio.gpio1); |
| 772 | cx_write(MO_GP2_IO, core->board.radio.gpio2); | 771 | cx_write(MO_GP2_IO, core->board.radio.gpio2); |
| 773 | if (core->board.radio.audioroute) { | 772 | if (core->board.radio.audioroute) { |
| 774 | if(core->board.audio_chip && | 773 | if (core->sd_wm8775) { |
| 775 | core->board.audio_chip == V4L2_IDENT_WM8775) { | ||
| 776 | call_all(core, audio, s_routing, | 774 | call_all(core, audio, s_routing, |
| 777 | core->board.radio.audioroute, 0, 0); | 775 | core->board.radio.audioroute, 0, 0); |
| 778 | } | 776 | } |
| @@ -959,7 +957,7 @@ static int cx8800_s_aud_ctrl(struct v4l2_ctrl *ctrl) | |||
| 959 | u32 value,mask; | 957 | u32 value,mask; |
| 960 | 958 | ||
| 961 | /* Pass changes onto any WM8775 */ | 959 | /* Pass changes onto any WM8775 */ |
| 962 | if (core->board.audio_chip == V4L2_IDENT_WM8775) { | 960 | if (core->sd_wm8775) { |
| 963 | switch (ctrl->id) { | 961 | switch (ctrl->id) { |
| 964 | case V4L2_CID_AUDIO_MUTE: | 962 | case V4L2_CID_AUDIO_MUTE: |
| 965 | wm8775_s_ctrl(core, ctrl->id, ctrl->val); | 963 | wm8775_s_ctrl(core, ctrl->id, ctrl->val); |
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 48b8d7af386d..9d1481a60bd9 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c | |||
| @@ -576,6 +576,14 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | |||
| 576 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); | 576 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | static int vidioc_create_bufs(struct file *file, void *priv, | ||
| 580 | struct v4l2_create_buffers *create) | ||
| 581 | { | ||
| 582 | struct coda_ctx *ctx = fh_to_ctx(priv); | ||
| 583 | |||
| 584 | return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create); | ||
| 585 | } | ||
| 586 | |||
| 579 | static int vidioc_streamon(struct file *file, void *priv, | 587 | static int vidioc_streamon(struct file *file, void *priv, |
| 580 | enum v4l2_buf_type type) | 588 | enum v4l2_buf_type type) |
| 581 | { | 589 | { |
| @@ -610,6 +618,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { | |||
| 610 | 618 | ||
| 611 | .vidioc_qbuf = vidioc_qbuf, | 619 | .vidioc_qbuf = vidioc_qbuf, |
| 612 | .vidioc_dqbuf = vidioc_dqbuf, | 620 | .vidioc_dqbuf = vidioc_dqbuf, |
| 621 | .vidioc_create_bufs = vidioc_create_bufs, | ||
| 613 | 622 | ||
| 614 | .vidioc_streamon = vidioc_streamon, | 623 | .vidioc_streamon = vidioc_streamon, |
| 615 | .vidioc_streamoff = vidioc_streamoff, | 624 | .vidioc_streamoff = vidioc_streamoff, |
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 1802f11e939f..d0b375cf565f 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c | |||
| @@ -916,6 +916,21 @@ static int vpbe_display_s_fmt(struct file *file, void *priv, | |||
| 916 | other video window */ | 916 | other video window */ |
| 917 | 917 | ||
| 918 | layer->pix_fmt = *pixfmt; | 918 | layer->pix_fmt = *pixfmt; |
| 919 | if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12) { | ||
| 920 | struct vpbe_layer *otherlayer; | ||
| 921 | |||
| 922 | otherlayer = _vpbe_display_get_other_win_layer(disp_dev, layer); | ||
| 923 | /* if other layer is available, only | ||
| 924 | * claim it, do not configure it | ||
| 925 | */ | ||
| 926 | ret = osd_device->ops.request_layer(osd_device, | ||
| 927 | otherlayer->layer_info.id); | ||
| 928 | if (ret < 0) { | ||
| 929 | v4l2_err(&vpbe_dev->v4l2_dev, | ||
| 930 | "Display Manager failed to allocate layer\n"); | ||
| 931 | return -EBUSY; | ||
| 932 | } | ||
| 933 | } | ||
| 919 | 934 | ||
| 920 | /* Get osd layer config */ | 935 | /* Get osd layer config */ |
| 921 | osd_device->ops.get_layer_config(osd_device, | 936 | osd_device->ops.get_layer_config(osd_device, |
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 8c50d3074866..93609091cb23 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c | |||
| @@ -1837,7 +1837,7 @@ static int vpfe_probe(struct platform_device *pdev) | |||
| 1837 | if (NULL == ccdc_cfg) { | 1837 | if (NULL == ccdc_cfg) { |
| 1838 | v4l2_err(pdev->dev.driver, | 1838 | v4l2_err(pdev->dev.driver, |
| 1839 | "Memory allocation failed for ccdc_cfg\n"); | 1839 | "Memory allocation failed for ccdc_cfg\n"); |
| 1840 | goto probe_free_lock; | 1840 | goto probe_free_dev_mem; |
| 1841 | } | 1841 | } |
| 1842 | 1842 | ||
| 1843 | mutex_lock(&ccdc_lock); | 1843 | mutex_lock(&ccdc_lock); |
| @@ -1991,7 +1991,6 @@ probe_out_release_irq: | |||
| 1991 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); | 1991 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); |
| 1992 | probe_free_ccdc_cfg_mem: | 1992 | probe_free_ccdc_cfg_mem: |
| 1993 | kfree(ccdc_cfg); | 1993 | kfree(ccdc_cfg); |
| 1994 | probe_free_lock: | ||
| 1995 | mutex_unlock(&ccdc_lock); | 1994 | mutex_unlock(&ccdc_lock); |
| 1996 | probe_free_dev_mem: | 1995 | probe_free_dev_mem: |
| 1997 | kfree(vpfe_dev); | 1996 | kfree(vpfe_dev); |
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c index b0ff67bc1b05..d05eaa2c8490 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-regs.c +++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c | |||
| @@ -174,7 +174,7 @@ int fimc_is_hw_change_mode(struct fimc_is *is) | |||
| 174 | HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO, | 174 | HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO, |
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | if (WARN_ON(is->config_index > ARRAY_SIZE(cmd))) | 177 | if (WARN_ON(is->config_index >= ARRAY_SIZE(cmd))) |
| 178 | return -EINVAL; | 178 | return -EINVAL; |
| 179 | 179 | ||
| 180 | mcuctl_write(cmd[is->config_index], is, MCUCTL_REG_ISSR(0)); | 180 | mcuctl_write(cmd[is->config_index], is, MCUCTL_REG_ISSR(0)); |
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 47c6363d04e2..0741945b79ed 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c | |||
| @@ -48,7 +48,6 @@ static char *fimc_is_clocks[ISS_CLKS_MAX] = { | |||
| 48 | [ISS_CLK_LITE0] = "lite0", | 48 | [ISS_CLK_LITE0] = "lite0", |
| 49 | [ISS_CLK_LITE1] = "lite1", | 49 | [ISS_CLK_LITE1] = "lite1", |
| 50 | [ISS_CLK_MPLL] = "mpll", | 50 | [ISS_CLK_MPLL] = "mpll", |
| 51 | [ISS_CLK_SYSREG] = "sysreg", | ||
| 52 | [ISS_CLK_ISP] = "isp", | 51 | [ISS_CLK_ISP] = "isp", |
| 53 | [ISS_CLK_DRC] = "drc", | 52 | [ISS_CLK_DRC] = "drc", |
| 54 | [ISS_CLK_FD] = "fd", | 53 | [ISS_CLK_FD] = "fd", |
| @@ -71,7 +70,6 @@ static void fimc_is_put_clocks(struct fimc_is *is) | |||
| 71 | for (i = 0; i < ISS_CLKS_MAX; i++) { | 70 | for (i = 0; i < ISS_CLKS_MAX; i++) { |
| 72 | if (IS_ERR(is->clocks[i])) | 71 | if (IS_ERR(is->clocks[i])) |
| 73 | continue; | 72 | continue; |
| 74 | clk_unprepare(is->clocks[i]); | ||
| 75 | clk_put(is->clocks[i]); | 73 | clk_put(is->clocks[i]); |
| 76 | is->clocks[i] = ERR_PTR(-EINVAL); | 74 | is->clocks[i] = ERR_PTR(-EINVAL); |
| 77 | } | 75 | } |
| @@ -90,12 +88,6 @@ static int fimc_is_get_clocks(struct fimc_is *is) | |||
| 90 | ret = PTR_ERR(is->clocks[i]); | 88 | ret = PTR_ERR(is->clocks[i]); |
| 91 | goto err; | 89 | goto err; |
| 92 | } | 90 | } |
| 93 | ret = clk_prepare(is->clocks[i]); | ||
| 94 | if (ret < 0) { | ||
| 95 | clk_put(is->clocks[i]); | ||
| 96 | is->clocks[i] = ERR_PTR(-EINVAL); | ||
| 97 | goto err; | ||
| 98 | } | ||
| 99 | } | 91 | } |
| 100 | 92 | ||
| 101 | return 0; | 93 | return 0; |
| @@ -103,7 +95,7 @@ err: | |||
| 103 | fimc_is_put_clocks(is); | 95 | fimc_is_put_clocks(is); |
| 104 | dev_err(&is->pdev->dev, "failed to get clock: %s\n", | 96 | dev_err(&is->pdev->dev, "failed to get clock: %s\n", |
| 105 | fimc_is_clocks[i]); | 97 | fimc_is_clocks[i]); |
| 106 | return -ENXIO; | 98 | return ret; |
| 107 | } | 99 | } |
| 108 | 100 | ||
| 109 | static int fimc_is_setup_clocks(struct fimc_is *is) | 101 | static int fimc_is_setup_clocks(struct fimc_is *is) |
| @@ -144,7 +136,7 @@ int fimc_is_enable_clocks(struct fimc_is *is) | |||
| 144 | for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { | 136 | for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { |
| 145 | if (IS_ERR(is->clocks[i])) | 137 | if (IS_ERR(is->clocks[i])) |
| 146 | continue; | 138 | continue; |
| 147 | ret = clk_enable(is->clocks[i]); | 139 | ret = clk_prepare_enable(is->clocks[i]); |
| 148 | if (ret < 0) { | 140 | if (ret < 0) { |
| 149 | dev_err(&is->pdev->dev, "clock %s enable failed\n", | 141 | dev_err(&is->pdev->dev, "clock %s enable failed\n", |
| 150 | fimc_is_clocks[i]); | 142 | fimc_is_clocks[i]); |
| @@ -163,7 +155,7 @@ void fimc_is_disable_clocks(struct fimc_is *is) | |||
| 163 | 155 | ||
| 164 | for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { | 156 | for (i = 0; i < ISS_GATE_CLKS_MAX; i++) { |
| 165 | if (!IS_ERR(is->clocks[i])) { | 157 | if (!IS_ERR(is->clocks[i])) { |
| 166 | clk_disable(is->clocks[i]); | 158 | clk_disable_unprepare(is->clocks[i]); |
| 167 | pr_debug("disabled clock: %s\n", fimc_is_clocks[i]); | 159 | pr_debug("disabled clock: %s\n", fimc_is_clocks[i]); |
| 168 | } | 160 | } |
| 169 | } | 161 | } |
| @@ -326,6 +318,11 @@ int fimc_is_start_firmware(struct fimc_is *is) | |||
| 326 | struct device *dev = &is->pdev->dev; | 318 | struct device *dev = &is->pdev->dev; |
| 327 | int ret; | 319 | int ret; |
| 328 | 320 | ||
| 321 | if (is->fw.f_w == NULL) { | ||
| 322 | dev_err(dev, "firmware is not loaded\n"); | ||
| 323 | return -EINVAL; | ||
| 324 | } | ||
| 325 | |||
| 329 | memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size); | 326 | memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size); |
| 330 | wmb(); | 327 | wmb(); |
| 331 | 328 | ||
| @@ -837,23 +834,11 @@ static int fimc_is_probe(struct platform_device *pdev) | |||
| 837 | goto err_clk; | 834 | goto err_clk; |
| 838 | } | 835 | } |
| 839 | pm_runtime_enable(dev); | 836 | pm_runtime_enable(dev); |
| 840 | /* | ||
| 841 | * Enable only the ISP power domain, keep FIMC-IS clocks off until | ||
| 842 | * the whole clock tree is configured. The ISP power domain needs | ||
| 843 | * be active in order to acces any CMU_ISP clock registers. | ||
| 844 | */ | ||
| 845 | ret = pm_runtime_get_sync(dev); | ||
| 846 | if (ret < 0) | ||
| 847 | goto err_irq; | ||
| 848 | |||
| 849 | ret = fimc_is_setup_clocks(is); | ||
| 850 | pm_runtime_put_sync(dev); | ||
| 851 | 837 | ||
| 838 | ret = pm_runtime_get_sync(dev); | ||
| 852 | if (ret < 0) | 839 | if (ret < 0) |
| 853 | goto err_irq; | 840 | goto err_irq; |
| 854 | 841 | ||
| 855 | is->clk_init = true; | ||
| 856 | |||
| 857 | is->alloc_ctx = vb2_dma_contig_init_ctx(dev); | 842 | is->alloc_ctx = vb2_dma_contig_init_ctx(dev); |
| 858 | if (IS_ERR(is->alloc_ctx)) { | 843 | if (IS_ERR(is->alloc_ctx)) { |
| 859 | ret = PTR_ERR(is->alloc_ctx); | 844 | ret = PTR_ERR(is->alloc_ctx); |
| @@ -875,6 +860,8 @@ static int fimc_is_probe(struct platform_device *pdev) | |||
| 875 | if (ret < 0) | 860 | if (ret < 0) |
| 876 | goto err_dfs; | 861 | goto err_dfs; |
| 877 | 862 | ||
| 863 | pm_runtime_put_sync(dev); | ||
| 864 | |||
| 878 | dev_dbg(dev, "FIMC-IS registered successfully\n"); | 865 | dev_dbg(dev, "FIMC-IS registered successfully\n"); |
| 879 | return 0; | 866 | return 0; |
| 880 | 867 | ||
| @@ -894,9 +881,11 @@ err_clk: | |||
| 894 | static int fimc_is_runtime_resume(struct device *dev) | 881 | static int fimc_is_runtime_resume(struct device *dev) |
| 895 | { | 882 | { |
| 896 | struct fimc_is *is = dev_get_drvdata(dev); | 883 | struct fimc_is *is = dev_get_drvdata(dev); |
| 884 | int ret; | ||
| 897 | 885 | ||
| 898 | if (!is->clk_init) | 886 | ret = fimc_is_setup_clocks(is); |
| 899 | return 0; | 887 | if (ret) |
| 888 | return ret; | ||
| 900 | 889 | ||
| 901 | return fimc_is_enable_clocks(is); | 890 | return fimc_is_enable_clocks(is); |
| 902 | } | 891 | } |
| @@ -905,9 +894,7 @@ static int fimc_is_runtime_suspend(struct device *dev) | |||
| 905 | { | 894 | { |
| 906 | struct fimc_is *is = dev_get_drvdata(dev); | 895 | struct fimc_is *is = dev_get_drvdata(dev); |
| 907 | 896 | ||
| 908 | if (is->clk_init) | 897 | fimc_is_disable_clocks(is); |
| 909 | fimc_is_disable_clocks(is); | ||
| 910 | |||
| 911 | return 0; | 898 | return 0; |
| 912 | } | 899 | } |
| 913 | 900 | ||
| @@ -941,7 +928,8 @@ static int fimc_is_remove(struct platform_device *pdev) | |||
| 941 | vb2_dma_contig_cleanup_ctx(is->alloc_ctx); | 928 | vb2_dma_contig_cleanup_ctx(is->alloc_ctx); |
| 942 | fimc_is_put_clocks(is); | 929 | fimc_is_put_clocks(is); |
| 943 | fimc_is_debugfs_remove(is); | 930 | fimc_is_debugfs_remove(is); |
| 944 | release_firmware(is->fw.f_w); | 931 | if (is->fw.f_w) |
| 932 | release_firmware(is->fw.f_w); | ||
| 945 | fimc_is_free_cpu_memory(is); | 933 | fimc_is_free_cpu_memory(is); |
| 946 | 934 | ||
| 947 | return 0; | 935 | return 0; |
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h index f5275a5b0156..d7db133b493f 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.h +++ b/drivers/media/platform/exynos4-is/fimc-is.h | |||
| @@ -73,7 +73,6 @@ enum { | |||
| 73 | ISS_CLK_LITE0, | 73 | ISS_CLK_LITE0, |
| 74 | ISS_CLK_LITE1, | 74 | ISS_CLK_LITE1, |
| 75 | ISS_CLK_MPLL, | 75 | ISS_CLK_MPLL, |
| 76 | ISS_CLK_SYSREG, | ||
| 77 | ISS_CLK_ISP, | 76 | ISS_CLK_ISP, |
| 78 | ISS_CLK_DRC, | 77 | ISS_CLK_DRC, |
| 79 | ISS_CLK_FD, | 78 | ISS_CLK_FD, |
| @@ -265,7 +264,6 @@ struct fimc_is { | |||
| 265 | spinlock_t slock; | 264 | spinlock_t slock; |
| 266 | 265 | ||
| 267 | struct clk *clocks[ISS_CLKS_MAX]; | 266 | struct clk *clocks[ISS_CLKS_MAX]; |
| 268 | bool clk_init; | ||
| 269 | void __iomem *regs; | 267 | void __iomem *regs; |
| 270 | void __iomem *pmu_regs; | 268 | void __iomem *pmu_regs; |
| 271 | int irq; | 269 | int irq; |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index d63947f7b302..7ede30b5910f 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c | |||
| @@ -138,7 +138,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, | |||
| 138 | return 0; | 138 | return 0; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | mf->colorspace = V4L2_COLORSPACE_JPEG; | 141 | mf->colorspace = V4L2_COLORSPACE_SRGB; |
| 142 | 142 | ||
| 143 | mutex_lock(&isp->subdev_lock); | 143 | mutex_lock(&isp->subdev_lock); |
| 144 | __is_get_frame_size(is, &cur_fmt); | 144 | __is_get_frame_size(is, &cur_fmt); |
| @@ -194,7 +194,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, | |||
| 194 | v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n", | 194 | v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n", |
| 195 | __func__, fmt->pad, mf->code, mf->width, mf->height); | 195 | __func__, fmt->pad, mf->code, mf->width, mf->height); |
| 196 | 196 | ||
| 197 | mf->colorspace = V4L2_COLORSPACE_JPEG; | 197 | mf->colorspace = V4L2_COLORSPACE_SRGB; |
| 198 | 198 | ||
| 199 | mutex_lock(&isp->subdev_lock); | 199 | mutex_lock(&isp->subdev_lock); |
| 200 | __isp_subdev_try_format(isp, fmt); | 200 | __isp_subdev_try_format(isp, fmt); |
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index a2eda9d5ac87..254d70fe762a 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c | |||
| @@ -746,7 +746,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, | |||
| 746 | node = v4l2_of_get_next_endpoint(node, NULL); | 746 | node = v4l2_of_get_next_endpoint(node, NULL); |
| 747 | if (!node) { | 747 | if (!node) { |
| 748 | dev_err(&pdev->dev, "No port node at %s\n", | 748 | dev_err(&pdev->dev, "No port node at %s\n", |
| 749 | node->full_name); | 749 | pdev->dev.of_node->full_name); |
| 750 | return -EINVAL; | 750 | return -EINVAL; |
| 751 | } | 751 | } |
| 752 | /* Get port node and validate MIPI-CSI channel id. */ | 752 | /* Get port node and validate MIPI-CSI channel id. */ |
diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h index 261134baa655..35d2fcdc0036 100644 --- a/drivers/media/platform/s3c-camif/camif-core.h +++ b/drivers/media/platform/s3c-camif/camif-core.h | |||
| @@ -229,7 +229,7 @@ struct camif_vp { | |||
| 229 | unsigned int state; | 229 | unsigned int state; |
| 230 | u16 fmt_flags; | 230 | u16 fmt_flags; |
| 231 | u8 id; | 231 | u8 id; |
| 232 | u8 rotation; | 232 | u16 rotation; |
| 233 | u8 hflip; | 233 | u8 hflip; |
| 234 | u8 vflip; | 234 | u8 vflip; |
| 235 | unsigned int offset; | 235 | unsigned int offset; |
diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile index ddc2900d88a2..d18cb5edd2d5 100644 --- a/drivers/media/platform/s5p-jpeg/Makefile +++ b/drivers/media/platform/s5p-jpeg/Makefile | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | s5p-jpeg-objs := jpeg-core.o | 1 | s5p-jpeg-objs := jpeg-core.o |
| 2 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) := s5p-jpeg.o | 2 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o |
diff --git a/drivers/media/platform/s5p-mfc/Makefile b/drivers/media/platform/s5p-mfc/Makefile index 379008c6d09a..15f59b324fef 100644 --- a/drivers/media/platform/s5p-mfc/Makefile +++ b/drivers/media/platform/s5p-mfc/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o | 1 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc.o |
| 2 | s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o | 2 | s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o |
| 3 | s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o | 3 | s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o |
| 4 | s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o | 4 | s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_pm.o |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 01f9ae0dadb0..d12faa691af8 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
| @@ -397,7 +397,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
| 397 | leave_handle_frame: | 397 | leave_handle_frame: |
| 398 | spin_unlock_irqrestore(&dev->irqlock, flags); | 398 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 399 | if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING) | 399 | if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING) |
| 400 | || ctx->dst_queue_cnt < ctx->dpb_count) | 400 | || ctx->dst_queue_cnt < ctx->pb_count) |
| 401 | clear_work_bit(ctx); | 401 | clear_work_bit(ctx); |
| 402 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); | 402 | s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); |
| 403 | wake_up_ctx(ctx, reason, err); | 403 | wake_up_ctx(ctx, reason, err); |
| @@ -473,7 +473,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
| 473 | 473 | ||
| 474 | s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx); | 474 | s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx); |
| 475 | 475 | ||
| 476 | ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, | 476 | ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, |
| 477 | dev); | 477 | dev); |
| 478 | ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count, | 478 | ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count, |
| 479 | dev); | 479 | dev); |
| @@ -562,7 +562,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx, | |||
| 562 | struct s5p_mfc_dev *dev = ctx->dev; | 562 | struct s5p_mfc_dev *dev = ctx->dev; |
| 563 | struct s5p_mfc_buf *mb_entry; | 563 | struct s5p_mfc_buf *mb_entry; |
| 564 | 564 | ||
| 565 | mfc_debug(2, "Stream completed"); | 565 | mfc_debug(2, "Stream completed\n"); |
| 566 | 566 | ||
| 567 | s5p_mfc_clear_int_flags(dev); | 567 | s5p_mfc_clear_int_flags(dev); |
| 568 | ctx->int_type = reason; | 568 | ctx->int_type = reason; |
| @@ -1362,7 +1362,6 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = { | |||
| 1362 | .port_num = MFC_NUM_PORTS, | 1362 | .port_num = MFC_NUM_PORTS, |
| 1363 | .buf_size = &buf_size_v5, | 1363 | .buf_size = &buf_size_v5, |
| 1364 | .buf_align = &mfc_buf_align_v5, | 1364 | .buf_align = &mfc_buf_align_v5, |
| 1365 | .mclk_name = "sclk_mfc", | ||
| 1366 | .fw_name = "s5p-mfc.fw", | 1365 | .fw_name = "s5p-mfc.fw", |
| 1367 | }; | 1366 | }; |
| 1368 | 1367 | ||
| @@ -1389,7 +1388,6 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = { | |||
| 1389 | .port_num = MFC_NUM_PORTS_V6, | 1388 | .port_num = MFC_NUM_PORTS_V6, |
| 1390 | .buf_size = &buf_size_v6, | 1389 | .buf_size = &buf_size_v6, |
| 1391 | .buf_align = &mfc_buf_align_v6, | 1390 | .buf_align = &mfc_buf_align_v6, |
| 1392 | .mclk_name = "aclk_333", | ||
| 1393 | .fw_name = "s5p-mfc-v6.fw", | 1391 | .fw_name = "s5p-mfc-v6.fw", |
| 1394 | }; | 1392 | }; |
| 1395 | 1393 | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 202d1d7a37a8..ef4074cd5316 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h | |||
| @@ -138,6 +138,7 @@ enum s5p_mfc_inst_state { | |||
| 138 | MFCINST_INIT = 100, | 138 | MFCINST_INIT = 100, |
| 139 | MFCINST_GOT_INST, | 139 | MFCINST_GOT_INST, |
| 140 | MFCINST_HEAD_PARSED, | 140 | MFCINST_HEAD_PARSED, |
| 141 | MFCINST_HEAD_PRODUCED, | ||
| 141 | MFCINST_BUFS_SET, | 142 | MFCINST_BUFS_SET, |
| 142 | MFCINST_RUNNING, | 143 | MFCINST_RUNNING, |
| 143 | MFCINST_FINISHING, | 144 | MFCINST_FINISHING, |
| @@ -231,7 +232,6 @@ struct s5p_mfc_variant { | |||
| 231 | unsigned int port_num; | 232 | unsigned int port_num; |
| 232 | struct s5p_mfc_buf_size *buf_size; | 233 | struct s5p_mfc_buf_size *buf_size; |
| 233 | struct s5p_mfc_buf_align *buf_align; | 234 | struct s5p_mfc_buf_align *buf_align; |
| 234 | char *mclk_name; | ||
| 235 | char *fw_name; | 235 | char *fw_name; |
| 236 | }; | 236 | }; |
| 237 | 237 | ||
| @@ -438,7 +438,7 @@ struct s5p_mfc_enc_params { | |||
| 438 | u32 rc_framerate_num; | 438 | u32 rc_framerate_num; |
| 439 | u32 rc_framerate_denom; | 439 | u32 rc_framerate_denom; |
| 440 | 440 | ||
| 441 | union { | 441 | struct { |
| 442 | struct s5p_mfc_h264_enc_params h264; | 442 | struct s5p_mfc_h264_enc_params h264; |
| 443 | struct s5p_mfc_mpeg4_enc_params mpeg4; | 443 | struct s5p_mfc_mpeg4_enc_params mpeg4; |
| 444 | } codec; | 444 | } codec; |
| @@ -602,7 +602,7 @@ struct s5p_mfc_ctx { | |||
| 602 | int after_packed_pb; | 602 | int after_packed_pb; |
| 603 | int sei_fp_parse; | 603 | int sei_fp_parse; |
| 604 | 604 | ||
| 605 | int dpb_count; | 605 | int pb_count; |
| 606 | int total_dpb_count; | 606 | int total_dpb_count; |
| 607 | int mv_count; | 607 | int mv_count; |
| 608 | /* Buffers */ | 608 | /* Buffers */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 2e5f30b40dea..dc1fc94a488d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | |||
| @@ -38,7 +38,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev) | |||
| 38 | dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size, | 38 | dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size, |
| 39 | &dev->bank1, GFP_KERNEL); | 39 | &dev->bank1, GFP_KERNEL); |
| 40 | 40 | ||
| 41 | if (IS_ERR(dev->fw_virt_addr)) { | 41 | if (IS_ERR_OR_NULL(dev->fw_virt_addr)) { |
| 42 | dev->fw_virt_addr = NULL; | 42 | dev->fw_virt_addr = NULL; |
| 43 | mfc_err("Allocating bitprocessor buffer failed\n"); | 43 | mfc_err("Allocating bitprocessor buffer failed\n"); |
| 44 | return -ENOMEM; | 44 | return -ENOMEM; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h index bd5cd4ae993c..8e608f5aa0d7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_debug.h | |||
| @@ -30,8 +30,8 @@ extern int debug; | |||
| 30 | #define mfc_debug(level, fmt, args...) | 30 | #define mfc_debug(level, fmt, args...) |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | #define mfc_debug_enter() mfc_debug(5, "enter") | 33 | #define mfc_debug_enter() mfc_debug(5, "enter\n") |
| 34 | #define mfc_debug_leave() mfc_debug(5, "leave") | 34 | #define mfc_debug_leave() mfc_debug(5, "leave\n") |
| 35 | 35 | ||
| 36 | #define mfc_err(fmt, args...) \ | 36 | #define mfc_err(fmt, args...) \ |
| 37 | do { \ | 37 | do { \ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 4af53bd2f182..00b07032f4f0 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
| @@ -210,11 +210,11 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) | |||
| 210 | /* Context is to decode a frame */ | 210 | /* Context is to decode a frame */ |
| 211 | if (ctx->src_queue_cnt >= 1 && | 211 | if (ctx->src_queue_cnt >= 1 && |
| 212 | ctx->state == MFCINST_RUNNING && | 212 | ctx->state == MFCINST_RUNNING && |
| 213 | ctx->dst_queue_cnt >= ctx->dpb_count) | 213 | ctx->dst_queue_cnt >= ctx->pb_count) |
| 214 | return 1; | 214 | return 1; |
| 215 | /* Context is to return last frame */ | 215 | /* Context is to return last frame */ |
| 216 | if (ctx->state == MFCINST_FINISHING && | 216 | if (ctx->state == MFCINST_FINISHING && |
| 217 | ctx->dst_queue_cnt >= ctx->dpb_count) | 217 | ctx->dst_queue_cnt >= ctx->pb_count) |
| 218 | return 1; | 218 | return 1; |
| 219 | /* Context is to set buffers */ | 219 | /* Context is to set buffers */ |
| 220 | if (ctx->src_queue_cnt >= 1 && | 220 | if (ctx->src_queue_cnt >= 1 && |
| @@ -224,7 +224,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) | |||
| 224 | /* Resolution change */ | 224 | /* Resolution change */ |
| 225 | if ((ctx->state == MFCINST_RES_CHANGE_INIT || | 225 | if ((ctx->state == MFCINST_RES_CHANGE_INIT || |
| 226 | ctx->state == MFCINST_RES_CHANGE_FLUSH) && | 226 | ctx->state == MFCINST_RES_CHANGE_FLUSH) && |
| 227 | ctx->dst_queue_cnt >= ctx->dpb_count) | 227 | ctx->dst_queue_cnt >= ctx->pb_count) |
| 228 | return 1; | 228 | return 1; |
| 229 | if (ctx->state == MFCINST_RES_CHANGE_END && | 229 | if (ctx->state == MFCINST_RES_CHANGE_END && |
| 230 | ctx->src_queue_cnt >= 1) | 230 | ctx->src_queue_cnt >= 1) |
| @@ -537,7 +537,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
| 537 | mfc_err("vb2_reqbufs on capture failed\n"); | 537 | mfc_err("vb2_reqbufs on capture failed\n"); |
| 538 | return ret; | 538 | return ret; |
| 539 | } | 539 | } |
| 540 | if (reqbufs->count < ctx->dpb_count) { | 540 | if (reqbufs->count < ctx->pb_count) { |
| 541 | mfc_err("Not enough buffers allocated\n"); | 541 | mfc_err("Not enough buffers allocated\n"); |
| 542 | reqbufs->count = 0; | 542 | reqbufs->count = 0; |
| 543 | s5p_mfc_clock_on(); | 543 | s5p_mfc_clock_on(); |
| @@ -751,7 +751,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) | |||
| 751 | case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: | 751 | case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: |
| 752 | if (ctx->state >= MFCINST_HEAD_PARSED && | 752 | if (ctx->state >= MFCINST_HEAD_PARSED && |
| 753 | ctx->state < MFCINST_ABORT) { | 753 | ctx->state < MFCINST_ABORT) { |
| 754 | ctrl->val = ctx->dpb_count; | 754 | ctrl->val = ctx->pb_count; |
| 755 | break; | 755 | break; |
| 756 | } else if (ctx->state != MFCINST_INIT) { | 756 | } else if (ctx->state != MFCINST_INIT) { |
| 757 | v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); | 757 | v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); |
| @@ -763,7 +763,7 @@ static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl) | |||
| 763 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); | 763 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); |
| 764 | if (ctx->state >= MFCINST_HEAD_PARSED && | 764 | if (ctx->state >= MFCINST_HEAD_PARSED && |
| 765 | ctx->state < MFCINST_ABORT) { | 765 | ctx->state < MFCINST_ABORT) { |
| 766 | ctrl->val = ctx->dpb_count; | 766 | ctrl->val = ctx->pb_count; |
| 767 | } else { | 767 | } else { |
| 768 | v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); | 768 | v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n"); |
| 769 | return -EINVAL; | 769 | return -EINVAL; |
| @@ -924,10 +924,10 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq, | |||
| 924 | /* Output plane count is 2 - one for Y and one for CbCr */ | 924 | /* Output plane count is 2 - one for Y and one for CbCr */ |
| 925 | *plane_count = 2; | 925 | *plane_count = 2; |
| 926 | /* Setup buffer count */ | 926 | /* Setup buffer count */ |
| 927 | if (*buf_count < ctx->dpb_count) | 927 | if (*buf_count < ctx->pb_count) |
| 928 | *buf_count = ctx->dpb_count; | 928 | *buf_count = ctx->pb_count; |
| 929 | if (*buf_count > ctx->dpb_count + MFC_MAX_EXTRA_DPB) | 929 | if (*buf_count > ctx->pb_count + MFC_MAX_EXTRA_DPB) |
| 930 | *buf_count = ctx->dpb_count + MFC_MAX_EXTRA_DPB; | 930 | *buf_count = ctx->pb_count + MFC_MAX_EXTRA_DPB; |
| 931 | if (*buf_count > MFC_MAX_BUFFERS) | 931 | if (*buf_count > MFC_MAX_BUFFERS) |
| 932 | *buf_count = MFC_MAX_BUFFERS; | 932 | *buf_count = MFC_MAX_BUFFERS; |
| 933 | } else { | 933 | } else { |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 4f6b553c4b2d..2549967b2f85 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
| @@ -592,7 +592,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx) | |||
| 592 | return 1; | 592 | return 1; |
| 593 | /* context is ready to encode a frame */ | 593 | /* context is ready to encode a frame */ |
| 594 | if ((ctx->state == MFCINST_RUNNING || | 594 | if ((ctx->state == MFCINST_RUNNING || |
| 595 | ctx->state == MFCINST_HEAD_PARSED) && | 595 | ctx->state == MFCINST_HEAD_PRODUCED) && |
| 596 | ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1) | 596 | ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1) |
| 597 | return 1; | 597 | return 1; |
| 598 | /* context is ready to encode remaining frames */ | 598 | /* context is ready to encode remaining frames */ |
| @@ -649,6 +649,7 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) | |||
| 649 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 649 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 650 | struct s5p_mfc_buf *dst_mb; | 650 | struct s5p_mfc_buf *dst_mb; |
| 651 | unsigned long flags; | 651 | unsigned long flags; |
| 652 | unsigned int enc_pb_count; | ||
| 652 | 653 | ||
| 653 | if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { | 654 | if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { |
| 654 | spin_lock_irqsave(&dev->irqlock, flags); | 655 | spin_lock_irqsave(&dev->irqlock, flags); |
| @@ -661,18 +662,19 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) | |||
| 661 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); | 662 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); |
| 662 | spin_unlock_irqrestore(&dev->irqlock, flags); | 663 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 663 | } | 664 | } |
| 664 | if (IS_MFCV6(dev)) { | 665 | |
| 665 | ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */ | 666 | if (!IS_MFCV6(dev)) { |
| 666 | } else { | ||
| 667 | ctx->state = MFCINST_RUNNING; | 667 | ctx->state = MFCINST_RUNNING; |
| 668 | if (s5p_mfc_ctx_ready(ctx)) | 668 | if (s5p_mfc_ctx_ready(ctx)) |
| 669 | set_work_bit_irqsave(ctx); | 669 | set_work_bit_irqsave(ctx); |
| 670 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | 670 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
| 671 | } | 671 | } else { |
| 672 | 672 | enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops, | |
| 673 | if (IS_MFCV6(dev)) | ||
| 674 | ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, | ||
| 675 | get_enc_dpb_count, dev); | 673 | get_enc_dpb_count, dev); |
| 674 | if (ctx->pb_count < enc_pb_count) | ||
| 675 | ctx->pb_count = enc_pb_count; | ||
| 676 | ctx->state = MFCINST_HEAD_PRODUCED; | ||
| 677 | } | ||
| 676 | 678 | ||
| 677 | return 0; | 679 | return 0; |
| 678 | } | 680 | } |
| @@ -717,9 +719,9 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) | |||
| 717 | 719 | ||
| 718 | slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); | 720 | slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); |
| 719 | strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); | 721 | strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); |
| 720 | mfc_debug(2, "Encoded slice type: %d", slice_type); | 722 | mfc_debug(2, "Encoded slice type: %d\n", slice_type); |
| 721 | mfc_debug(2, "Encoded stream size: %d", strm_size); | 723 | mfc_debug(2, "Encoded stream size: %d\n", strm_size); |
| 722 | mfc_debug(2, "Display order: %d", | 724 | mfc_debug(2, "Display order: %d\n", |
| 723 | mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); | 725 | mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); |
| 724 | spin_lock_irqsave(&dev->irqlock, flags); | 726 | spin_lock_irqsave(&dev->irqlock, flags); |
| 725 | if (slice_type >= 0) { | 727 | if (slice_type >= 0) { |
| @@ -1055,15 +1057,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
| 1055 | } | 1057 | } |
| 1056 | ctx->capture_state = QUEUE_BUFS_REQUESTED; | 1058 | ctx->capture_state = QUEUE_BUFS_REQUESTED; |
| 1057 | 1059 | ||
| 1058 | if (!IS_MFCV6(dev)) { | 1060 | ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, |
| 1059 | ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, | 1061 | alloc_codec_buffers, ctx); |
| 1060 | alloc_codec_buffers, ctx); | 1062 | if (ret) { |
| 1061 | if (ret) { | 1063 | mfc_err("Failed to allocate encoding buffers\n"); |
| 1062 | mfc_err("Failed to allocate encoding buffers\n"); | 1064 | reqbufs->count = 0; |
| 1063 | reqbufs->count = 0; | 1065 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); |
| 1064 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | 1066 | return -ENOMEM; |
| 1065 | return -ENOMEM; | ||
| 1066 | } | ||
| 1067 | } | 1067 | } |
| 1068 | } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 1068 | } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
| 1069 | if (ctx->output_state != QUEUE_FREE) { | 1069 | if (ctx->output_state != QUEUE_FREE) { |
| @@ -1071,6 +1071,19 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
| 1071 | ctx->output_state); | 1071 | ctx->output_state); |
| 1072 | return -EINVAL; | 1072 | return -EINVAL; |
| 1073 | } | 1073 | } |
| 1074 | |||
| 1075 | if (IS_MFCV6(dev)) { | ||
| 1076 | /* Check for min encoder buffers */ | ||
| 1077 | if (ctx->pb_count && | ||
| 1078 | (reqbufs->count < ctx->pb_count)) { | ||
| 1079 | reqbufs->count = ctx->pb_count; | ||
| 1080 | mfc_debug(2, "Minimum %d output buffers needed\n", | ||
| 1081 | ctx->pb_count); | ||
| 1082 | } else { | ||
| 1083 | ctx->pb_count = reqbufs->count; | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | |||
| 1074 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); | 1087 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); |
| 1075 | if (ret != 0) { | 1088 | if (ret != 0) { |
| 1076 | mfc_err("error in vb2_reqbufs() for E(S)\n"); | 1089 | mfc_err("error in vb2_reqbufs() for E(S)\n"); |
| @@ -1533,14 +1546,14 @@ int vidioc_encoder_cmd(struct file *file, void *priv, | |||
| 1533 | 1546 | ||
| 1534 | spin_lock_irqsave(&dev->irqlock, flags); | 1547 | spin_lock_irqsave(&dev->irqlock, flags); |
| 1535 | if (list_empty(&ctx->src_queue)) { | 1548 | if (list_empty(&ctx->src_queue)) { |
| 1536 | mfc_debug(2, "EOS: empty src queue, entering finishing state"); | 1549 | mfc_debug(2, "EOS: empty src queue, entering finishing state\n"); |
| 1537 | ctx->state = MFCINST_FINISHING; | 1550 | ctx->state = MFCINST_FINISHING; |
| 1538 | if (s5p_mfc_ctx_ready(ctx)) | 1551 | if (s5p_mfc_ctx_ready(ctx)) |
| 1539 | set_work_bit_irqsave(ctx); | 1552 | set_work_bit_irqsave(ctx); |
| 1540 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1553 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1541 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | 1554 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
| 1542 | } else { | 1555 | } else { |
| 1543 | mfc_debug(2, "EOS: marking last buffer of stream"); | 1556 | mfc_debug(2, "EOS: marking last buffer of stream\n"); |
| 1544 | buf = list_entry(ctx->src_queue.prev, | 1557 | buf = list_entry(ctx->src_queue.prev, |
| 1545 | struct s5p_mfc_buf, list); | 1558 | struct s5p_mfc_buf, list); |
| 1546 | if (buf->flags & MFC_BUF_FLAG_USED) | 1559 | if (buf->flags & MFC_BUF_FLAG_USED) |
| @@ -1609,9 +1622,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) | |||
| 1609 | mfc_err("failed to get plane cookie\n"); | 1622 | mfc_err("failed to get plane cookie\n"); |
| 1610 | return -EINVAL; | 1623 | return -EINVAL; |
| 1611 | } | 1624 | } |
| 1612 | mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx", | 1625 | mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx\n", |
| 1613 | vb->v4l2_buf.index, i, | 1626 | vb->v4l2_buf.index, i, |
| 1614 | vb2_dma_contig_plane_dma_addr(vb, i)); | 1627 | vb2_dma_contig_plane_dma_addr(vb, i)); |
| 1615 | } | 1628 | } |
| 1616 | return 0; | 1629 | return 0; |
| 1617 | } | 1630 | } |
| @@ -1760,11 +1773,27 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 1760 | struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); | 1773 | struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); |
| 1761 | struct s5p_mfc_dev *dev = ctx->dev; | 1774 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1762 | 1775 | ||
| 1763 | v4l2_ctrl_handler_setup(&ctx->ctrl_handler); | 1776 | if (IS_MFCV6(dev) && (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) { |
| 1777 | |||
| 1778 | if ((ctx->state == MFCINST_GOT_INST) && | ||
| 1779 | (dev->curr_ctx == ctx->num) && dev->hw_lock) { | ||
| 1780 | s5p_mfc_wait_for_done_ctx(ctx, | ||
| 1781 | S5P_MFC_R2H_CMD_SEQ_DONE_RET, | ||
| 1782 | 0); | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | if (ctx->src_bufs_cnt < ctx->pb_count) { | ||
| 1786 | mfc_err("Need minimum %d OUTPUT buffers\n", | ||
| 1787 | ctx->pb_count); | ||
| 1788 | return -EINVAL; | ||
| 1789 | } | ||
| 1790 | } | ||
| 1791 | |||
| 1764 | /* If context is ready then dev = work->data;schedule it to run */ | 1792 | /* If context is ready then dev = work->data;schedule it to run */ |
| 1765 | if (s5p_mfc_ctx_ready(ctx)) | 1793 | if (s5p_mfc_ctx_ready(ctx)) |
| 1766 | set_work_bit_irqsave(ctx); | 1794 | set_work_bit_irqsave(ctx); |
| 1767 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | 1795 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
| 1796 | |||
| 1768 | return 0; | 1797 | return 0; |
| 1769 | } | 1798 | } |
| 1770 | 1799 | ||
| @@ -1920,6 +1949,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx) | |||
| 1920 | if (controls[i].is_volatile && ctx->ctrls[i]) | 1949 | if (controls[i].is_volatile && ctx->ctrls[i]) |
| 1921 | ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE; | 1950 | ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE; |
| 1922 | } | 1951 | } |
| 1952 | v4l2_ctrl_handler_setup(&ctx->ctrl_handler); | ||
| 1923 | return 0; | 1953 | return 0; |
| 1924 | } | 1954 | } |
| 1925 | 1955 | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index 0af05a2d1cd4..368582b091bf 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | |||
| @@ -1275,8 +1275,8 @@ static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
| 1275 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1275 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1276 | dev->curr_ctx = ctx->num; | 1276 | dev->curr_ctx = ctx->num; |
| 1277 | s5p_mfc_clean_ctx_int_flags(ctx); | 1277 | s5p_mfc_clean_ctx_int_flags(ctx); |
| 1278 | mfc_debug(2, "encoding buffer with index=%d state=%d", | 1278 | mfc_debug(2, "encoding buffer with index=%d state=%d\n", |
| 1279 | src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); | 1279 | src_mb ? src_mb->b->v4l2_buf.index : -1, ctx->state); |
| 1280 | s5p_mfc_encode_one_frame_v5(ctx); | 1280 | s5p_mfc_encode_one_frame_v5(ctx); |
| 1281 | return 0; | 1281 | return 0; |
| 1282 | } | 1282 | } |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 7e76fce2e524..66f0d042357f 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | |||
| @@ -62,12 +62,6 @@ static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 62 | /* NOP */ | 62 | /* NOP */ |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) | ||
| 66 | { | ||
| 67 | /* NOP */ | ||
| 68 | return -1; | ||
| 69 | } | ||
| 70 | |||
| 71 | /* Allocate codec buffers */ | 65 | /* Allocate codec buffers */ |
| 72 | static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | 66 | static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) |
| 73 | { | 67 | { |
| @@ -167,7 +161,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 167 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 161 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
| 168 | ctx->bank1.size = | 162 | ctx->bank1.size = |
| 169 | ctx->scratch_buf_size + ctx->tmv_buffer_size + | 163 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
| 170 | (ctx->dpb_count * (ctx->luma_dpb_size + | 164 | (ctx->pb_count * (ctx->luma_dpb_size + |
| 171 | ctx->chroma_dpb_size + ctx->me_buffer_size)); | 165 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
| 172 | ctx->bank2.size = 0; | 166 | ctx->bank2.size = 0; |
| 173 | break; | 167 | break; |
| @@ -181,7 +175,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 181 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 175 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
| 182 | ctx->bank1.size = | 176 | ctx->bank1.size = |
| 183 | ctx->scratch_buf_size + ctx->tmv_buffer_size + | 177 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
| 184 | (ctx->dpb_count * (ctx->luma_dpb_size + | 178 | (ctx->pb_count * (ctx->luma_dpb_size + |
| 185 | ctx->chroma_dpb_size + ctx->me_buffer_size)); | 179 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
| 186 | ctx->bank2.size = 0; | 180 | ctx->bank2.size = 0; |
| 187 | break; | 181 | break; |
| @@ -198,7 +192,6 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 198 | } | 192 | } |
| 199 | BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); | 193 | BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); |
| 200 | } | 194 | } |
| 201 | |||
| 202 | return 0; | 195 | return 0; |
| 203 | } | 196 | } |
| 204 | 197 | ||
| @@ -449,8 +442,8 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 449 | WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */ | 442 | WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */ |
| 450 | WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); | 443 | WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); |
| 451 | 444 | ||
| 452 | mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d", | 445 | mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n", |
| 453 | addr, size); | 446 | addr, size); |
| 454 | 447 | ||
| 455 | return 0; | 448 | return 0; |
| 456 | } | 449 | } |
| @@ -463,8 +456,8 @@ static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 463 | WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); /* 256B align */ | 456 | WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); /* 256B align */ |
| 464 | WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); | 457 | WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); |
| 465 | 458 | ||
| 466 | mfc_debug(2, "enc src y buf addr: 0x%08lx", y_addr); | 459 | mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr); |
| 467 | mfc_debug(2, "enc src c buf addr: 0x%08lx", c_addr); | 460 | mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr); |
| 468 | } | 461 | } |
| 469 | 462 | ||
| 470 | static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, | 463 | static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, |
| @@ -479,8 +472,8 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 479 | enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); | 472 | enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); |
| 480 | enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); | 473 | enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); |
| 481 | 474 | ||
| 482 | mfc_debug(2, "recon y addr: 0x%08lx", enc_recon_y_addr); | 475 | mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr); |
| 483 | mfc_debug(2, "recon c addr: 0x%08lx", enc_recon_c_addr); | 476 | mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr); |
| 484 | } | 477 | } |
| 485 | 478 | ||
| 486 | /* Set encoding ref & codec buffer */ | 479 | /* Set encoding ref & codec buffer */ |
| @@ -497,7 +490,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 497 | 490 | ||
| 498 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); | 491 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); |
| 499 | 492 | ||
| 500 | for (i = 0; i < ctx->dpb_count; i++) { | 493 | for (i = 0; i < ctx->pb_count; i++) { |
| 501 | WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i)); | 494 | WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i)); |
| 502 | buf_addr1 += ctx->luma_dpb_size; | 495 | buf_addr1 += ctx->luma_dpb_size; |
| 503 | WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i)); | 496 | WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i)); |
| @@ -520,7 +513,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 520 | buf_size1 -= ctx->tmv_buffer_size; | 513 | buf_size1 -= ctx->tmv_buffer_size; |
| 521 | 514 | ||
| 522 | mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n", | 515 | mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n", |
| 523 | buf_addr1, buf_size1, ctx->dpb_count); | 516 | buf_addr1, buf_size1, ctx->pb_count); |
| 524 | if (buf_size1 < 0) { | 517 | if (buf_size1 < 0) { |
| 525 | mfc_debug(2, "Not enough memory has been allocated.\n"); | 518 | mfc_debug(2, "Not enough memory has been allocated.\n"); |
| 526 | return -ENOMEM; | 519 | return -ENOMEM; |
| @@ -1431,8 +1424,8 @@ static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |||
| 1431 | src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0); | 1424 | src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0); |
| 1432 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1); | 1425 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1); |
| 1433 | 1426 | ||
| 1434 | mfc_debug(2, "enc src y addr: 0x%08lx", src_y_addr); | 1427 | mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr); |
| 1435 | mfc_debug(2, "enc src c addr: 0x%08lx", src_c_addr); | 1428 | mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr); |
| 1436 | 1429 | ||
| 1437 | s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr); | 1430 | s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr); |
| 1438 | 1431 | ||
| @@ -1522,22 +1515,6 @@ static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) | |||
| 1522 | struct s5p_mfc_dev *dev = ctx->dev; | 1515 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1523 | int ret; | 1516 | int ret; |
| 1524 | 1517 | ||
| 1525 | ret = s5p_mfc_alloc_codec_buffers_v6(ctx); | ||
| 1526 | if (ret) { | ||
| 1527 | mfc_err("Failed to allocate encoding buffers.\n"); | ||
| 1528 | return -ENOMEM; | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | /* Header was generated now starting processing | ||
| 1532 | * First set the reference frame buffers | ||
| 1533 | */ | ||
| 1534 | if (ctx->capture_state != QUEUE_BUFS_REQUESTED) { | ||
| 1535 | mfc_err("It seems that destionation buffers were not\n" | ||
| 1536 | "requested.MFC requires that header should be generated\n" | ||
| 1537 | "before allocating codec buffer.\n"); | ||
| 1538 | return -EAGAIN; | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | dev->curr_ctx = ctx->num; | 1518 | dev->curr_ctx = ctx->num; |
| 1542 | s5p_mfc_clean_ctx_int_flags(ctx); | 1519 | s5p_mfc_clean_ctx_int_flags(ctx); |
| 1543 | ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); | 1520 | ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); |
| @@ -1582,7 +1559,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) | |||
| 1582 | mfc_debug(1, "Seting new context to %p\n", ctx); | 1559 | mfc_debug(1, "Seting new context to %p\n", ctx); |
| 1583 | /* Got context to run in ctx */ | 1560 | /* Got context to run in ctx */ |
| 1584 | mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n", | 1561 | mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n", |
| 1585 | ctx->dst_queue_cnt, ctx->dpb_count, ctx->src_queue_cnt); | 1562 | ctx->dst_queue_cnt, ctx->pb_count, ctx->src_queue_cnt); |
| 1586 | mfc_debug(1, "ctx->state=%d\n", ctx->state); | 1563 | mfc_debug(1, "ctx->state=%d\n", ctx->state); |
| 1587 | /* Last frame has already been sent to MFC | 1564 | /* Last frame has already been sent to MFC |
| 1588 | * Now obtaining frames from MFC buffer */ | 1565 | * Now obtaining frames from MFC buffer */ |
| @@ -1647,7 +1624,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) | |||
| 1647 | case MFCINST_GOT_INST: | 1624 | case MFCINST_GOT_INST: |
| 1648 | s5p_mfc_run_init_enc(ctx); | 1625 | s5p_mfc_run_init_enc(ctx); |
| 1649 | break; | 1626 | break; |
| 1650 | case MFCINST_HEAD_PARSED: /* Only for MFC6.x */ | 1627 | case MFCINST_HEAD_PRODUCED: |
| 1651 | ret = s5p_mfc_run_init_enc_buffers(ctx); | 1628 | ret = s5p_mfc_run_init_enc_buffers(ctx); |
| 1652 | break; | 1629 | break; |
| 1653 | default: | 1630 | default: |
| @@ -1730,7 +1707,7 @@ static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) | |||
| 1730 | return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6); | 1707 | return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6); |
| 1731 | } | 1708 | } |
| 1732 | 1709 | ||
| 1733 | static int s5p_mfc_get_decoded_status_v6(struct s5p_mfc_dev *dev) | 1710 | static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) |
| 1734 | { | 1711 | { |
| 1735 | return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6); | 1712 | return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6); |
| 1736 | } | 1713 | } |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 6aa38a56aaf2..11d5f1dada32 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | |||
| @@ -50,19 +50,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) | |||
| 50 | goto err_p_ip_clk; | 50 | goto err_p_ip_clk; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | pm->clock = clk_get(&dev->plat_dev->dev, dev->variant->mclk_name); | ||
| 54 | if (IS_ERR(pm->clock)) { | ||
| 55 | mfc_err("Failed to get MFC clock\n"); | ||
| 56 | ret = PTR_ERR(pm->clock); | ||
| 57 | goto err_g_ip_clk_2; | ||
| 58 | } | ||
| 59 | |||
| 60 | ret = clk_prepare(pm->clock); | ||
| 61 | if (ret) { | ||
| 62 | mfc_err("Failed to prepare MFC clock\n"); | ||
| 63 | goto err_p_ip_clk_2; | ||
| 64 | } | ||
| 65 | |||
| 66 | atomic_set(&pm->power, 0); | 53 | atomic_set(&pm->power, 0); |
| 67 | #ifdef CONFIG_PM_RUNTIME | 54 | #ifdef CONFIG_PM_RUNTIME |
| 68 | pm->device = &dev->plat_dev->dev; | 55 | pm->device = &dev->plat_dev->dev; |
| @@ -72,10 +59,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) | |||
| 72 | atomic_set(&clk_ref, 0); | 59 | atomic_set(&clk_ref, 0); |
| 73 | #endif | 60 | #endif |
| 74 | return 0; | 61 | return 0; |
| 75 | err_p_ip_clk_2: | ||
| 76 | clk_put(pm->clock); | ||
| 77 | err_g_ip_clk_2: | ||
| 78 | clk_unprepare(pm->clock_gate); | ||
| 79 | err_p_ip_clk: | 62 | err_p_ip_clk: |
| 80 | clk_put(pm->clock_gate); | 63 | clk_put(pm->clock_gate); |
| 81 | err_g_ip_clk: | 64 | err_g_ip_clk: |
| @@ -86,8 +69,6 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) | |||
| 86 | { | 69 | { |
| 87 | clk_unprepare(pm->clock_gate); | 70 | clk_unprepare(pm->clock_gate); |
| 88 | clk_put(pm->clock_gate); | 71 | clk_put(pm->clock_gate); |
| 89 | clk_unprepare(pm->clock); | ||
| 90 | clk_put(pm->clock); | ||
| 91 | #ifdef CONFIG_PM_RUNTIME | 72 | #ifdef CONFIG_PM_RUNTIME |
| 92 | pm_runtime_disable(pm->device); | 73 | pm_runtime_disable(pm->device); |
| 93 | #endif | 74 | #endif |
| @@ -98,7 +79,7 @@ int s5p_mfc_clock_on(void) | |||
| 98 | int ret; | 79 | int ret; |
| 99 | #ifdef CLK_DEBUG | 80 | #ifdef CLK_DEBUG |
| 100 | atomic_inc(&clk_ref); | 81 | atomic_inc(&clk_ref); |
| 101 | mfc_debug(3, "+ %d", atomic_read(&clk_ref)); | 82 | mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); |
| 102 | #endif | 83 | #endif |
| 103 | ret = clk_enable(pm->clock_gate); | 84 | ret = clk_enable(pm->clock_gate); |
| 104 | return ret; | 85 | return ret; |
| @@ -108,7 +89,7 @@ void s5p_mfc_clock_off(void) | |||
| 108 | { | 89 | { |
| 109 | #ifdef CLK_DEBUG | 90 | #ifdef CLK_DEBUG |
| 110 | atomic_dec(&clk_ref); | 91 | atomic_dec(&clk_ref); |
| 111 | mfc_debug(3, "- %d", atomic_read(&clk_ref)); | 92 | mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); |
| 112 | #endif | 93 | #endif |
| 113 | clk_disable(pm->clock_gate); | 94 | clk_disable(pm->clock_gate); |
| 114 | } | 95 | } |
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index 0b32cc3f6a47..59a9deefb242 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c | |||
| @@ -905,11 +905,11 @@ static int sh_veu_queue_setup(struct vb2_queue *vq, | |||
| 905 | if (ftmp.fmt.pix.width != pix->width || | 905 | if (ftmp.fmt.pix.width != pix->width || |
| 906 | ftmp.fmt.pix.height != pix->height) | 906 | ftmp.fmt.pix.height != pix->height) |
| 907 | return -EINVAL; | 907 | return -EINVAL; |
| 908 | size = pix->bytesperline ? pix->bytesperline * pix->height : | 908 | size = pix->bytesperline ? pix->bytesperline * pix->height * fmt->depth / fmt->ydepth : |
| 909 | pix->width * pix->height * fmt->depth >> 3; | 909 | pix->width * pix->height * fmt->depth / fmt->ydepth; |
| 910 | } else { | 910 | } else { |
| 911 | vfmt = sh_veu_get_vfmt(veu, vq->type); | 911 | vfmt = sh_veu_get_vfmt(veu, vq->type); |
| 912 | size = vfmt->bytesperline * vfmt->frame.height; | 912 | size = vfmt->bytesperline * vfmt->frame.height * vfmt->fmt->depth / vfmt->fmt->ydepth; |
| 913 | } | 913 | } |
| 914 | 914 | ||
| 915 | if (count < 2) | 915 | if (count < 2) |
| @@ -1033,8 +1033,6 @@ static int sh_veu_release(struct file *file) | |||
| 1033 | 1033 | ||
| 1034 | dev_dbg(veu->dev, "Releasing instance %p\n", veu_file); | 1034 | dev_dbg(veu->dev, "Releasing instance %p\n", veu_file); |
| 1035 | 1035 | ||
| 1036 | pm_runtime_put(veu->dev); | ||
| 1037 | |||
| 1038 | if (veu_file == veu->capture) { | 1036 | if (veu_file == veu->capture) { |
| 1039 | veu->capture = NULL; | 1037 | veu->capture = NULL; |
| 1040 | vb2_queue_release(v4l2_m2m_get_vq(veu->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)); | 1038 | vb2_queue_release(v4l2_m2m_get_vq(veu->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE)); |
| @@ -1050,6 +1048,8 @@ static int sh_veu_release(struct file *file) | |||
| 1050 | veu->m2m_ctx = NULL; | 1048 | veu->m2m_ctx = NULL; |
| 1051 | } | 1049 | } |
| 1052 | 1050 | ||
| 1051 | pm_runtime_put(veu->dev); | ||
| 1052 | |||
| 1053 | kfree(veu_file); | 1053 | kfree(veu_file); |
| 1054 | 1054 | ||
| 1055 | return 0; | 1055 | return 0; |
| @@ -1138,10 +1138,7 @@ static irqreturn_t sh_veu_isr(int irq, void *dev_id) | |||
| 1138 | 1138 | ||
| 1139 | veu->xaction++; | 1139 | veu->xaction++; |
| 1140 | 1140 | ||
| 1141 | if (!veu->aborting) | 1141 | return IRQ_WAKE_THREAD; |
| 1142 | return IRQ_WAKE_THREAD; | ||
| 1143 | |||
| 1144 | return IRQ_HANDLED; | ||
| 1145 | } | 1142 | } |
| 1146 | 1143 | ||
| 1147 | static int sh_veu_probe(struct platform_device *pdev) | 1144 | static int sh_veu_probe(struct platform_device *pdev) |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index eea832c5fd01..3a4efbdc7668 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
| @@ -643,9 +643,9 @@ static int soc_camera_close(struct file *file) | |||
| 643 | 643 | ||
| 644 | if (ici->ops->init_videobuf2) | 644 | if (ici->ops->init_videobuf2) |
| 645 | vb2_queue_release(&icd->vb2_vidq); | 645 | vb2_queue_release(&icd->vb2_vidq); |
| 646 | ici->ops->remove(icd); | ||
| 647 | |||
| 648 | __soc_camera_power_off(icd); | 646 | __soc_camera_power_off(icd); |
| 647 | |||
| 648 | ici->ops->remove(icd); | ||
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | if (icd->streamer == file) | 651 | if (icd->streamer == file) |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index c0beee2fa37c..d529ba788f41 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
| @@ -22,6 +22,7 @@ config RADIO_SI476X | |||
| 22 | tristate "Silicon Laboratories Si476x I2C FM Radio" | 22 | tristate "Silicon Laboratories Si476x I2C FM Radio" |
| 23 | depends on I2C && VIDEO_V4L2 | 23 | depends on I2C && VIDEO_V4L2 |
| 24 | depends on MFD_SI476X_CORE | 24 | depends on MFD_SI476X_CORE |
| 25 | depends on SND_SOC | ||
| 25 | select SND_SOC_SI476X | 26 | select SND_SOC_SI476X |
| 26 | ---help--- | 27 | ---help--- |
| 27 | Choose Y here if you have this FM radio chip. | 28 | Choose Y here if you have this FM radio chip. |
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c index 9430c6a29937..9dc8bafe6486 100644 --- a/drivers/media/radio/radio-si476x.c +++ b/drivers/media/radio/radio-si476x.c | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | #define FREQ_MUL (10000000 / 625) | 45 | #define FREQ_MUL (10000000 / 625) |
| 46 | 46 | ||
| 47 | #define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0b10000000 & (status)) | 47 | #define SI476X_PHDIV_STATUS_LINK_LOCKED(status) (0x80 & (status)) |
| 48 | 48 | ||
| 49 | #define DRIVER_NAME "si476x-radio" | 49 | #define DRIVER_NAME "si476x-radio" |
| 50 | #define DRIVER_CARD "SI476x AM/FM Receiver" | 50 | #define DRIVER_CARD "SI476x AM/FM Receiver" |
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index f6768cad001a..15665debc572 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig | |||
| @@ -1,23 +1,3 @@ | |||
| 1 | config MEDIA_ATTACH | ||
| 2 | bool "Load and attach frontend and tuner driver modules as needed" | ||
| 3 | depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT | ||
| 4 | depends on MODULES | ||
| 5 | default y if !EXPERT | ||
| 6 | help | ||
| 7 | Remove the static dependency of DVB card drivers on all | ||
| 8 | frontend modules for all possible card variants. Instead, | ||
| 9 | allow the card drivers to only load the frontend modules | ||
| 10 | they require. | ||
| 11 | |||
| 12 | Also, tuner module will automatically load a tuner driver | ||
| 13 | when needed, for analog mode. | ||
| 14 | |||
| 15 | This saves several KBytes of memory. | ||
| 16 | |||
| 17 | Note: You will need module-init-tools v3.2 or later for this feature. | ||
| 18 | |||
| 19 | If unsure say Y. | ||
| 20 | |||
| 21 | # Analog TV tuners, auto-loaded via tuner.ko | 1 | # Analog TV tuners, auto-loaded via tuner.ko |
| 22 | config MEDIA_TUNER | 2 | config MEDIA_TUNER |
| 23 | tristate | 3 | tristate |
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 22015fe1a0f3..2cc8ec70e3b6 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
| @@ -376,7 +376,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) | |||
| 376 | struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; | 376 | struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; |
| 377 | struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; | 377 | struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; |
| 378 | struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; | 378 | struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; |
| 379 | struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 5, buf}; | 379 | struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; |
| 380 | 380 | ||
| 381 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | 381 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
| 382 | 382 | ||
| @@ -481,9 +481,9 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) | |||
| 481 | goto found; | 481 | goto found; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | /* check R820T by reading tuner stats at I2C addr 0x1a */ | 484 | /* check R820T ID register; reg=00 val=69 */ |
| 485 | ret = rtl28xxu_ctrl_msg(d, &req_r820t); | 485 | ret = rtl28xxu_ctrl_msg(d, &req_r820t); |
| 486 | if (ret == 0) { | 486 | if (ret == 0 && buf[0] == 0x69) { |
| 487 | priv->tuner = TUNER_RTL2832_R820T; | 487 | priv->tuner = TUNER_RTL2832_R820T; |
| 488 | priv->tuner_name = "R820T"; | 488 | priv->tuner_name = "R820T"; |
| 489 | goto found; | 489 | goto found; |
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index 3fe207e038c7..d7ff3b9687c5 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c | |||
| @@ -1159,6 +1159,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 1159 | regs[0x01] = 0x44; /* Select 24 Mhz clock */ | 1159 | regs[0x01] = 0x44; /* Select 24 Mhz clock */ |
| 1160 | regs[0x12] = 0x02; /* Set hstart to 2 */ | 1160 | regs[0x12] = 0x02; /* Set hstart to 2 */ |
| 1161 | } | 1161 | } |
| 1162 | break; | ||
| 1163 | case SENSOR_PAS202: | ||
| 1164 | /* For some unknown reason we need to increase hstart by 1 on | ||
| 1165 | the sn9c103, otherwise we get wrong colors (bayer shift). */ | ||
| 1166 | if (sd->bridge == BRIDGE_103) | ||
| 1167 | regs[0x12] += 1; | ||
| 1168 | break; | ||
| 1162 | } | 1169 | } |
| 1163 | /* Disable compression when the raw bayer format has been selected */ | 1170 | /* Disable compression when the raw bayer format has been selected */ |
| 1164 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) | 1171 | if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) |
diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h index 7a6a0d39c2c6..81b017a554bc 100644 --- a/drivers/media/usb/pwc/pwc.h +++ b/drivers/media/usb/pwc/pwc.h | |||
| @@ -226,7 +226,7 @@ struct pwc_device | |||
| 226 | struct list_head queued_bufs; | 226 | struct list_head queued_bufs; |
| 227 | spinlock_t queued_bufs_lock; /* Protects queued_bufs */ | 227 | spinlock_t queued_bufs_lock; /* Protects queued_bufs */ |
| 228 | 228 | ||
| 229 | /* Note if taking both locks v4l2_lock must always be locked first! */ | 229 | /* If taking both locks vb_queue_lock must always be locked first! */ |
| 230 | struct mutex v4l2_lock; /* Protects everything else */ | 230 | struct mutex v4l2_lock; /* Protects everything else */ |
| 231 | struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */ | 231 | struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */ |
| 232 | 232 | ||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index ebb8e48619a2..fccd08b66d1a 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | |||
| @@ -1835,6 +1835,8 @@ bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl) | |||
| 1835 | { | 1835 | { |
| 1836 | if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) | 1836 | if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) |
| 1837 | return true; | 1837 | return true; |
| 1838 | if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_RX) | ||
| 1839 | return true; | ||
| 1838 | switch (ctrl->id) { | 1840 | switch (ctrl->id) { |
| 1839 | case V4L2_CID_AUDIO_MUTE: | 1841 | case V4L2_CID_AUDIO_MUTE: |
| 1840 | case V4L2_CID_AUDIO_VOLUME: | 1842 | case V4L2_CID_AUDIO_VOLUME: |
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index f81bda1a48ec..7658586fe5f4 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
| @@ -243,7 +243,6 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
| 243 | const struct v4l2_vbi_format *vbi; | 243 | const struct v4l2_vbi_format *vbi; |
| 244 | const struct v4l2_sliced_vbi_format *sliced; | 244 | const struct v4l2_sliced_vbi_format *sliced; |
| 245 | const struct v4l2_window *win; | 245 | const struct v4l2_window *win; |
| 246 | const struct v4l2_clip *clip; | ||
| 247 | unsigned i; | 246 | unsigned i; |
| 248 | 247 | ||
| 249 | pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); | 248 | pr_cont("type=%s", prt_names(p->type, v4l2_type_names)); |
| @@ -253,7 +252,7 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
| 253 | pix = &p->fmt.pix; | 252 | pix = &p->fmt.pix; |
| 254 | pr_cont(", width=%u, height=%u, " | 253 | pr_cont(", width=%u, height=%u, " |
| 255 | "pixelformat=%c%c%c%c, field=%s, " | 254 | "pixelformat=%c%c%c%c, field=%s, " |
| 256 | "bytesperline=%u sizeimage=%u, colorspace=%d\n", | 255 | "bytesperline=%u, sizeimage=%u, colorspace=%d\n", |
| 257 | pix->width, pix->height, | 256 | pix->width, pix->height, |
| 258 | (pix->pixelformat & 0xff), | 257 | (pix->pixelformat & 0xff), |
| 259 | (pix->pixelformat >> 8) & 0xff, | 258 | (pix->pixelformat >> 8) & 0xff, |
| @@ -284,20 +283,14 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
| 284 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 283 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| 285 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 284 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
| 286 | win = &p->fmt.win; | 285 | win = &p->fmt.win; |
| 287 | pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, " | 286 | /* Note: we can't print the clip list here since the clips |
| 288 | "chromakey=0x%08x, bitmap=%p, " | 287 | * pointer is a userspace pointer, not a kernelspace |
| 289 | "global_alpha=0x%02x\n", | 288 | * pointer. */ |
| 290 | win->w.width, win->w.height, | 289 | pr_cont(", wxh=%dx%d, x,y=%d,%d, field=%s, chromakey=0x%08x, clipcount=%u, clips=%p, bitmap=%p, global_alpha=0x%02x\n", |
| 291 | win->w.left, win->w.top, | 290 | win->w.width, win->w.height, win->w.left, win->w.top, |
| 292 | prt_names(win->field, v4l2_field_names), | 291 | prt_names(win->field, v4l2_field_names), |
| 293 | win->chromakey, win->bitmap, win->global_alpha); | 292 | win->chromakey, win->clipcount, win->clips, |
| 294 | clip = win->clips; | 293 | win->bitmap, win->global_alpha); |
| 295 | for (i = 0; i < win->clipcount; i++) { | ||
| 296 | printk(KERN_DEBUG "clip %u: wxh=%dx%d, x,y=%d,%d\n", | ||
| 297 | i, clip->c.width, clip->c.height, | ||
| 298 | clip->c.left, clip->c.top); | ||
| 299 | clip = clip->next; | ||
| 300 | } | ||
| 301 | break; | 294 | break; |
| 302 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 295 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
| 303 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 296 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
| @@ -332,7 +325,7 @@ static void v4l_print_framebuffer(const void *arg, bool write_only) | |||
| 332 | 325 | ||
| 333 | pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, " | 326 | pr_cont("capability=0x%x, flags=0x%x, base=0x%p, width=%u, " |
| 334 | "height=%u, pixelformat=%c%c%c%c, " | 327 | "height=%u, pixelformat=%c%c%c%c, " |
| 335 | "bytesperline=%u sizeimage=%u, colorspace=%d\n", | 328 | "bytesperline=%u, sizeimage=%u, colorspace=%d\n", |
| 336 | p->capability, p->flags, p->base, | 329 | p->capability, p->flags, p->base, |
| 337 | p->fmt.width, p->fmt.height, | 330 | p->fmt.width, p->fmt.height, |
| 338 | (p->fmt.pixelformat & 0xff), | 331 | (p->fmt.pixelformat & 0xff), |
| @@ -353,7 +346,7 @@ static void v4l_print_modulator(const void *arg, bool write_only) | |||
| 353 | const struct v4l2_modulator *p = arg; | 346 | const struct v4l2_modulator *p = arg; |
| 354 | 347 | ||
| 355 | if (write_only) | 348 | if (write_only) |
| 356 | pr_cont("index=%u, txsubchans=0x%x", p->index, p->txsubchans); | 349 | pr_cont("index=%u, txsubchans=0x%x\n", p->index, p->txsubchans); |
| 357 | else | 350 | else |
| 358 | pr_cont("index=%u, name=%.*s, capability=0x%x, " | 351 | pr_cont("index=%u, name=%.*s, capability=0x%x, " |
| 359 | "rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", | 352 | "rangelow=%u, rangehigh=%u, txsubchans=0x%x\n", |
| @@ -445,13 +438,13 @@ static void v4l_print_buffer(const void *arg, bool write_only) | |||
| 445 | for (i = 0; i < p->length; ++i) { | 438 | for (i = 0; i < p->length; ++i) { |
| 446 | plane = &p->m.planes[i]; | 439 | plane = &p->m.planes[i]; |
| 447 | printk(KERN_DEBUG | 440 | printk(KERN_DEBUG |
| 448 | "plane %d: bytesused=%d, data_offset=0x%08x " | 441 | "plane %d: bytesused=%d, data_offset=0x%08x, " |
| 449 | "offset/userptr=0x%lx, length=%d\n", | 442 | "offset/userptr=0x%lx, length=%d\n", |
| 450 | i, plane->bytesused, plane->data_offset, | 443 | i, plane->bytesused, plane->data_offset, |
| 451 | plane->m.userptr, plane->length); | 444 | plane->m.userptr, plane->length); |
| 452 | } | 445 | } |
| 453 | } else { | 446 | } else { |
| 454 | pr_cont("bytesused=%d, offset/userptr=0x%lx, length=%d\n", | 447 | pr_cont(", bytesused=%d, offset/userptr=0x%lx, length=%d\n", |
| 455 | p->bytesused, p->m.userptr, p->length); | 448 | p->bytesused, p->m.userptr, p->length); |
| 456 | } | 449 | } |
| 457 | 450 | ||
| @@ -504,6 +497,8 @@ static void v4l_print_streamparm(const void *arg, bool write_only) | |||
| 504 | c->capability, c->outputmode, | 497 | c->capability, c->outputmode, |
| 505 | c->timeperframe.numerator, c->timeperframe.denominator, | 498 | c->timeperframe.numerator, c->timeperframe.denominator, |
| 506 | c->extendedmode, c->writebuffers); | 499 | c->extendedmode, c->writebuffers); |
| 500 | } else { | ||
| 501 | pr_cont("\n"); | ||
| 507 | } | 502 | } |
| 508 | } | 503 | } |
| 509 | 504 | ||
| @@ -734,11 +729,11 @@ static void v4l_print_frmsizeenum(const void *arg, bool write_only) | |||
| 734 | p->type); | 729 | p->type); |
| 735 | switch (p->type) { | 730 | switch (p->type) { |
| 736 | case V4L2_FRMSIZE_TYPE_DISCRETE: | 731 | case V4L2_FRMSIZE_TYPE_DISCRETE: |
| 737 | pr_cont(" wxh=%ux%u\n", | 732 | pr_cont(", wxh=%ux%u\n", |
| 738 | p->discrete.width, p->discrete.height); | 733 | p->discrete.width, p->discrete.height); |
| 739 | break; | 734 | break; |
| 740 | case V4L2_FRMSIZE_TYPE_STEPWISE: | 735 | case V4L2_FRMSIZE_TYPE_STEPWISE: |
| 741 | pr_cont(" min=%ux%u, max=%ux%u, step=%ux%u\n", | 736 | pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n", |
| 742 | p->stepwise.min_width, p->stepwise.min_height, | 737 | p->stepwise.min_width, p->stepwise.min_height, |
| 743 | p->stepwise.step_width, p->stepwise.step_height, | 738 | p->stepwise.step_width, p->stepwise.step_height, |
| 744 | p->stepwise.max_width, p->stepwise.max_height); | 739 | p->stepwise.max_width, p->stepwise.max_height); |
| @@ -764,12 +759,12 @@ static void v4l_print_frmivalenum(const void *arg, bool write_only) | |||
| 764 | p->width, p->height, p->type); | 759 | p->width, p->height, p->type); |
| 765 | switch (p->type) { | 760 | switch (p->type) { |
| 766 | case V4L2_FRMIVAL_TYPE_DISCRETE: | 761 | case V4L2_FRMIVAL_TYPE_DISCRETE: |
| 767 | pr_cont(" fps=%d/%d\n", | 762 | pr_cont(", fps=%d/%d\n", |
| 768 | p->discrete.numerator, | 763 | p->discrete.numerator, |
| 769 | p->discrete.denominator); | 764 | p->discrete.denominator); |
| 770 | break; | 765 | break; |
| 771 | case V4L2_FRMIVAL_TYPE_STEPWISE: | 766 | case V4L2_FRMIVAL_TYPE_STEPWISE: |
| 772 | pr_cont(" min=%d/%d, max=%d/%d, step=%d/%d\n", | 767 | pr_cont(", min=%d/%d, max=%d/%d, step=%d/%d\n", |
| 773 | p->stepwise.min.numerator, | 768 | p->stepwise.min.numerator, |
| 774 | p->stepwise.min.denominator, | 769 | p->stepwise.min.denominator, |
| 775 | p->stepwise.max.numerator, | 770 | p->stepwise.max.numerator, |
| @@ -807,8 +802,8 @@ static void v4l_print_event(const void *arg, bool write_only) | |||
| 807 | pr_cont("value64=%lld, ", c->value64); | 802 | pr_cont("value64=%lld, ", c->value64); |
| 808 | else | 803 | else |
| 809 | pr_cont("value=%d, ", c->value); | 804 | pr_cont("value=%d, ", c->value); |
| 810 | pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d," | 805 | pr_cont("flags=0x%x, minimum=%d, maximum=%d, step=%d, " |
| 811 | " default_value=%d\n", | 806 | "default_value=%d\n", |
| 812 | c->flags, c->minimum, c->maximum, | 807 | c->flags, c->minimum, c->maximum, |
| 813 | c->step, c->default_value); | 808 | c->step, c->default_value); |
| 814 | break; | 809 | break; |
| @@ -845,7 +840,7 @@ static void v4l_print_freq_band(const void *arg, bool write_only) | |||
| 845 | const struct v4l2_frequency_band *p = arg; | 840 | const struct v4l2_frequency_band *p = arg; |
| 846 | 841 | ||
| 847 | pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, " | 842 | pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, " |
| 848 | "rangelow=%u, rangehigh=%u, modulation=0x%x\n", | 843 | "rangelow=%u, rangehigh=%u, modulation=0x%x\n", |
| 849 | p->tuner, p->type, p->index, | 844 | p->tuner, p->type, p->index, |
| 850 | p->capability, p->rangelow, | 845 | p->capability, p->rangelow, |
| 851 | p->rangehigh, p->modulation); | 846 | p->rangehigh, p->modulation); |
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 66f599fcb829..e96497f7c3ed 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | |||
| @@ -205,7 +205,7 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) | |||
| 205 | static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) | 205 | static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) |
| 206 | { | 206 | { |
| 207 | struct v4l2_m2m_dev *m2m_dev; | 207 | struct v4l2_m2m_dev *m2m_dev; |
| 208 | unsigned long flags_job, flags; | 208 | unsigned long flags_job, flags_out, flags_cap; |
| 209 | 209 | ||
| 210 | m2m_dev = m2m_ctx->m2m_dev; | 210 | m2m_dev = m2m_ctx->m2m_dev; |
| 211 | dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx); | 211 | dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx); |
| @@ -223,23 +223,26 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) | |||
| 223 | return; | 223 | return; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); | 226 | spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); |
| 227 | if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) { | 227 | if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) { |
| 228 | spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); | 228 | spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, |
| 229 | flags_out); | ||
| 229 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | 230 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); |
| 230 | dprintk("No input buffers available\n"); | 231 | dprintk("No input buffers available\n"); |
| 231 | return; | 232 | return; |
| 232 | } | 233 | } |
| 233 | spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); | 234 | spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); |
| 234 | if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) { | 235 | if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) { |
| 235 | spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); | 236 | spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, |
| 236 | spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); | 237 | flags_cap); |
| 238 | spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, | ||
| 239 | flags_out); | ||
| 237 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | 240 | spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); |
| 238 | dprintk("No output buffers available\n"); | 241 | dprintk("No output buffers available\n"); |
| 239 | return; | 242 | return; |
| 240 | } | 243 | } |
| 241 | spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); | 244 | spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); |
| 242 | spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); | 245 | spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); |
| 243 | 246 | ||
| 244 | if (m2m_dev->m2m_ops->job_ready | 247 | if (m2m_dev->m2m_ops->job_ready |
| 245 | && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { | 248 | && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { |
| @@ -372,6 +375,20 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | |||
| 372 | EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); | 375 | EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); |
| 373 | 376 | ||
| 374 | /** | 377 | /** |
| 378 | * v4l2_m2m_create_bufs() - create a source or destination buffer, depending | ||
| 379 | * on the type | ||
| 380 | */ | ||
| 381 | int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | ||
| 382 | struct v4l2_create_buffers *create) | ||
| 383 | { | ||
| 384 | struct vb2_queue *vq; | ||
| 385 | |||
| 386 | vq = v4l2_m2m_get_vq(m2m_ctx, create->format.type); | ||
| 387 | return vb2_create_bufs(vq, create); | ||
| 388 | } | ||
| 389 | EXPORT_SYMBOL_GPL(v4l2_m2m_create_bufs); | ||
| 390 | |||
| 391 | /** | ||
| 375 | * v4l2_m2m_expbuf() - export a source or destination buffer, depending on | 392 | * v4l2_m2m_expbuf() - export a source or destination buffer, depending on |
| 376 | * the type | 393 | * the type |
| 377 | */ | 394 | */ |
| @@ -486,8 +503,10 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | |||
| 486 | if (m2m_ctx->m2m_dev->m2m_ops->unlock) | 503 | if (m2m_ctx->m2m_dev->m2m_ops->unlock) |
| 487 | m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv); | 504 | m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv); |
| 488 | 505 | ||
| 489 | poll_wait(file, &src_q->done_wq, wait); | 506 | if (list_empty(&src_q->done_list)) |
| 490 | poll_wait(file, &dst_q->done_wq, wait); | 507 | poll_wait(file, &src_q->done_wq, wait); |
| 508 | if (list_empty(&dst_q->done_list)) | ||
| 509 | poll_wait(file, &dst_q->done_wq, wait); | ||
| 491 | 510 | ||
| 492 | if (m2m_ctx->m2m_dev->m2m_ops->lock) | 511 | if (m2m_ctx->m2m_dev->m2m_ops->lock) |
| 493 | m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); | 512 | m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); |
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7d833eefaf4e..e3bdc3be91e1 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
| @@ -2014,7 +2014,8 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) | |||
| 2014 | if (list_empty(&q->queued_list)) | 2014 | if (list_empty(&q->queued_list)) |
| 2015 | return res | POLLERR; | 2015 | return res | POLLERR; |
| 2016 | 2016 | ||
| 2017 | poll_wait(file, &q->done_wq, wait); | 2017 | if (list_empty(&q->done_list)) |
| 2018 | poll_wait(file, &q->done_wq, wait); | ||
| 2018 | 2019 | ||
| 2019 | /* | 2020 | /* |
| 2020 | * Take first buffer available for dequeuing. | 2021 | * Take first buffer available for dequeuing. |
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 721b9186a5d1..4b93ed4d5cd6 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
| @@ -107,7 +107,7 @@ static struct mfd_cell tps6586x_cell[] = { | |||
| 107 | .name = "tps6586x-gpio", | 107 | .name = "tps6586x-gpio", |
| 108 | }, | 108 | }, |
| 109 | { | 109 | { |
| 110 | .name = "tps6586x-pmic", | 110 | .name = "tps6586x-regulator", |
| 111 | }, | 111 | }, |
| 112 | { | 112 | { |
| 113 | .name = "tps6586x-rtc", | 113 | .name = "tps6586x-rtc", |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 02d9ae7d527e..f97569613526 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -2413,7 +2413,8 @@ static void bond_miimon_commit(struct bonding *bond) | |||
| 2413 | 2413 | ||
| 2414 | pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", | 2414 | pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", |
| 2415 | bond->dev->name, slave->dev->name, | 2415 | bond->dev->name, slave->dev->name, |
| 2416 | slave->speed, slave->duplex ? "full" : "half"); | 2416 | slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, |
| 2417 | slave->duplex ? "full" : "half"); | ||
| 2417 | 2418 | ||
| 2418 | /* notify ad that the link status has changed */ | 2419 | /* notify ad that the link status has changed */ |
| 2419 | if (bond->params.mode == BOND_MODE_8023AD) | 2420 | if (bond->params.mode == BOND_MODE_8023AD) |
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index 6e15ef08f301..cbd388eea682 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c | |||
| @@ -977,7 +977,7 @@ static int usb_8dev_probe(struct usb_interface *intf, | |||
| 977 | err = usb_8dev_cmd_version(priv, &version); | 977 | err = usb_8dev_cmd_version(priv, &version); |
| 978 | if (err) { | 978 | if (err) { |
| 979 | netdev_err(netdev, "can't get firmware version\n"); | 979 | netdev_err(netdev, "can't get firmware version\n"); |
| 980 | goto cleanup_cmd_msg_buffer; | 980 | goto cleanup_unregister_candev; |
| 981 | } else { | 981 | } else { |
| 982 | netdev_info(netdev, | 982 | netdev_info(netdev, |
| 983 | "firmware: %d.%d, hardware: %d.%d\n", | 983 | "firmware: %d.%d, hardware: %d.%d\n", |
| @@ -989,6 +989,9 @@ static int usb_8dev_probe(struct usb_interface *intf, | |||
| 989 | 989 | ||
| 990 | return 0; | 990 | return 0; |
| 991 | 991 | ||
| 992 | cleanup_unregister_candev: | ||
| 993 | unregister_netdev(priv->netdev); | ||
| 994 | |||
| 992 | cleanup_cmd_msg_buffer: | 995 | cleanup_cmd_msg_buffer: |
| 993 | kfree(priv->cmd_msg_buffer); | 996 | kfree(priv->cmd_msg_buffer); |
| 994 | 997 | ||
diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig index 36d6abd1cfff..ad6aa1e98348 100644 --- a/drivers/net/ethernet/atheros/Kconfig +++ b/drivers/net/ethernet/atheros/Kconfig | |||
| @@ -67,4 +67,22 @@ config ATL1C | |||
| 67 | To compile this driver as a module, choose M here. The module | 67 | To compile this driver as a module, choose M here. The module |
| 68 | will be called atl1c. | 68 | will be called atl1c. |
| 69 | 69 | ||
| 70 | config ALX | ||
| 71 | tristate "Qualcomm Atheros AR816x/AR817x support" | ||
| 72 | depends on PCI | ||
| 73 | select CRC32 | ||
| 74 | select NET_CORE | ||
| 75 | select MDIO | ||
| 76 | help | ||
| 77 | This driver supports the Qualcomm Atheros L1F ethernet adapter, | ||
| 78 | i.e. the following chipsets: | ||
| 79 | |||
| 80 | 1969:1091 - AR8161 Gigabit Ethernet | ||
| 81 | 1969:1090 - AR8162 Fast Ethernet | ||
| 82 | 1969:10A1 - AR8171 Gigabit Ethernet | ||
| 83 | 1969:10A0 - AR8172 Fast Ethernet | ||
| 84 | |||
| 85 | To compile this driver as a module, choose M here. The module | ||
| 86 | will be called alx. | ||
| 87 | |||
| 70 | endif # NET_VENDOR_ATHEROS | 88 | endif # NET_VENDOR_ATHEROS |
diff --git a/drivers/net/ethernet/atheros/Makefile b/drivers/net/ethernet/atheros/Makefile index e7e76fb576ff..5cf1c65bbce9 100644 --- a/drivers/net/ethernet/atheros/Makefile +++ b/drivers/net/ethernet/atheros/Makefile | |||
| @@ -6,3 +6,4 @@ obj-$(CONFIG_ATL1) += atlx/ | |||
| 6 | obj-$(CONFIG_ATL2) += atlx/ | 6 | obj-$(CONFIG_ATL2) += atlx/ |
| 7 | obj-$(CONFIG_ATL1E) += atl1e/ | 7 | obj-$(CONFIG_ATL1E) += atl1e/ |
| 8 | obj-$(CONFIG_ATL1C) += atl1c/ | 8 | obj-$(CONFIG_ATL1C) += atl1c/ |
| 9 | obj-$(CONFIG_ALX) += alx/ | ||
diff --git a/drivers/net/ethernet/atheros/alx/Makefile b/drivers/net/ethernet/atheros/alx/Makefile new file mode 100644 index 000000000000..5901fa407d52 --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/Makefile | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | obj-$(CONFIG_ALX) += alx.o | ||
| 2 | alx-objs := main.o ethtool.o hw.o | ||
| 3 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/ethernet/atheros/alx/alx.h b/drivers/net/ethernet/atheros/alx/alx.h new file mode 100644 index 000000000000..50b3ae2b143d --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/alx.h | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> | ||
| 3 | * | ||
| 4 | * This file is free software: you may copy, redistribute and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation, either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This file is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | * | ||
| 17 | * This file incorporates work covered by the following copyright and | ||
| 18 | * permission notice: | ||
| 19 | * | ||
| 20 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
| 21 | * | ||
| 22 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 23 | * purpose with or without fee is hereby granted, provided that the above | ||
| 24 | * copyright notice and this permission notice appear in all copies. | ||
| 25 | * | ||
| 26 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 27 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 29 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 30 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 31 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 32 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #ifndef _ALX_H_ | ||
| 36 | #define _ALX_H_ | ||
| 37 | |||
| 38 | #include <linux/types.h> | ||
| 39 | #include <linux/etherdevice.h> | ||
| 40 | #include <linux/dma-mapping.h> | ||
| 41 | #include <linux/spinlock.h> | ||
| 42 | #include "hw.h" | ||
| 43 | |||
| 44 | #define ALX_WATCHDOG_TIME (5 * HZ) | ||
| 45 | |||
| 46 | struct alx_buffer { | ||
| 47 | struct sk_buff *skb; | ||
| 48 | DEFINE_DMA_UNMAP_ADDR(dma); | ||
| 49 | DEFINE_DMA_UNMAP_LEN(size); | ||
| 50 | }; | ||
| 51 | |||
| 52 | struct alx_rx_queue { | ||
| 53 | struct alx_rrd *rrd; | ||
| 54 | dma_addr_t rrd_dma; | ||
| 55 | |||
| 56 | struct alx_rfd *rfd; | ||
| 57 | dma_addr_t rfd_dma; | ||
| 58 | |||
| 59 | struct alx_buffer *bufs; | ||
| 60 | |||
| 61 | u16 write_idx, read_idx; | ||
| 62 | u16 rrd_read_idx; | ||
| 63 | }; | ||
| 64 | #define ALX_RX_ALLOC_THRESH 32 | ||
| 65 | |||
| 66 | struct alx_tx_queue { | ||
| 67 | struct alx_txd *tpd; | ||
| 68 | dma_addr_t tpd_dma; | ||
| 69 | struct alx_buffer *bufs; | ||
| 70 | u16 write_idx, read_idx; | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define ALX_DEFAULT_TX_WORK 128 | ||
| 74 | |||
| 75 | enum alx_device_quirks { | ||
| 76 | ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG = BIT(0), | ||
| 77 | }; | ||
| 78 | |||
| 79 | struct alx_priv { | ||
| 80 | struct net_device *dev; | ||
| 81 | |||
| 82 | struct alx_hw hw; | ||
| 83 | |||
| 84 | /* all descriptor memory */ | ||
| 85 | struct { | ||
| 86 | dma_addr_t dma; | ||
| 87 | void *virt; | ||
| 88 | int size; | ||
| 89 | } descmem; | ||
| 90 | |||
| 91 | /* protect int_mask updates */ | ||
| 92 | spinlock_t irq_lock; | ||
| 93 | u32 int_mask; | ||
| 94 | |||
| 95 | int tx_ringsz; | ||
| 96 | int rx_ringsz; | ||
| 97 | int rxbuf_size; | ||
| 98 | |||
| 99 | struct napi_struct napi; | ||
| 100 | struct alx_tx_queue txq; | ||
| 101 | struct alx_rx_queue rxq; | ||
| 102 | |||
| 103 | struct work_struct link_check_wk; | ||
| 104 | struct work_struct reset_wk; | ||
| 105 | |||
| 106 | u16 msg_enable; | ||
| 107 | |||
| 108 | bool msi; | ||
| 109 | }; | ||
| 110 | |||
| 111 | extern const struct ethtool_ops alx_ethtool_ops; | ||
| 112 | extern const char alx_drv_name[]; | ||
| 113 | |||
| 114 | #endif | ||
diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c new file mode 100644 index 000000000000..6fa2aec2bc81 --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/ethtool.c | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> | ||
| 3 | * | ||
| 4 | * This file is free software: you may copy, redistribute and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation, either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This file is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | * | ||
| 17 | * This file incorporates work covered by the following copyright and | ||
| 18 | * permission notice: | ||
| 19 | * | ||
| 20 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
| 21 | * | ||
| 22 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 23 | * purpose with or without fee is hereby granted, provided that the above | ||
| 24 | * copyright notice and this permission notice appear in all copies. | ||
| 25 | * | ||
| 26 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 27 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 29 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 30 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 31 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 32 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/pci.h> | ||
| 36 | #include <linux/ip.h> | ||
| 37 | #include <linux/tcp.h> | ||
| 38 | #include <linux/netdevice.h> | ||
| 39 | #include <linux/etherdevice.h> | ||
| 40 | #include <linux/ethtool.h> | ||
| 41 | #include <linux/mdio.h> | ||
| 42 | #include <linux/interrupt.h> | ||
| 43 | #include <asm/byteorder.h> | ||
| 44 | |||
| 45 | #include "alx.h" | ||
| 46 | #include "reg.h" | ||
| 47 | #include "hw.h" | ||
| 48 | |||
| 49 | |||
| 50 | static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | ||
| 51 | { | ||
| 52 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 53 | struct alx_hw *hw = &alx->hw; | ||
| 54 | |||
| 55 | ecmd->supported = SUPPORTED_10baseT_Half | | ||
| 56 | SUPPORTED_10baseT_Full | | ||
| 57 | SUPPORTED_100baseT_Half | | ||
| 58 | SUPPORTED_100baseT_Full | | ||
| 59 | SUPPORTED_Autoneg | | ||
| 60 | SUPPORTED_TP | | ||
| 61 | SUPPORTED_Pause; | ||
| 62 | if (alx_hw_giga(hw)) | ||
| 63 | ecmd->supported |= SUPPORTED_1000baseT_Full; | ||
| 64 | |||
| 65 | ecmd->advertising = ADVERTISED_TP; | ||
| 66 | if (hw->adv_cfg & ADVERTISED_Autoneg) | ||
| 67 | ecmd->advertising |= hw->adv_cfg; | ||
| 68 | |||
| 69 | ecmd->port = PORT_TP; | ||
| 70 | ecmd->phy_address = 0; | ||
| 71 | if (hw->adv_cfg & ADVERTISED_Autoneg) | ||
| 72 | ecmd->autoneg = AUTONEG_ENABLE; | ||
| 73 | else | ||
| 74 | ecmd->autoneg = AUTONEG_DISABLE; | ||
| 75 | ecmd->transceiver = XCVR_INTERNAL; | ||
| 76 | |||
| 77 | if (hw->flowctrl & ALX_FC_ANEG && hw->adv_cfg & ADVERTISED_Autoneg) { | ||
| 78 | if (hw->flowctrl & ALX_FC_RX) { | ||
| 79 | ecmd->advertising |= ADVERTISED_Pause; | ||
| 80 | |||
| 81 | if (!(hw->flowctrl & ALX_FC_TX)) | ||
| 82 | ecmd->advertising |= ADVERTISED_Asym_Pause; | ||
| 83 | } else if (hw->flowctrl & ALX_FC_TX) { | ||
| 84 | ecmd->advertising |= ADVERTISED_Asym_Pause; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | if (hw->link_speed != SPEED_UNKNOWN) { | ||
| 89 | ethtool_cmd_speed_set(ecmd, | ||
| 90 | hw->link_speed - hw->link_speed % 10); | ||
| 91 | ecmd->duplex = hw->link_speed % 10; | ||
| 92 | } else { | ||
| 93 | ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); | ||
| 94 | ecmd->duplex = DUPLEX_UNKNOWN; | ||
| 95 | } | ||
| 96 | |||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | ||
| 101 | { | ||
| 102 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 103 | struct alx_hw *hw = &alx->hw; | ||
| 104 | u32 adv_cfg; | ||
| 105 | |||
| 106 | ASSERT_RTNL(); | ||
| 107 | |||
| 108 | if (ecmd->autoneg == AUTONEG_ENABLE) { | ||
| 109 | if (ecmd->advertising & ADVERTISED_1000baseT_Half) | ||
| 110 | return -EINVAL; | ||
| 111 | adv_cfg = ecmd->advertising | ADVERTISED_Autoneg; | ||
| 112 | } else { | ||
| 113 | int speed = ethtool_cmd_speed(ecmd); | ||
| 114 | |||
| 115 | switch (speed + ecmd->duplex) { | ||
| 116 | case SPEED_10 + DUPLEX_HALF: | ||
| 117 | adv_cfg = ADVERTISED_10baseT_Half; | ||
| 118 | break; | ||
| 119 | case SPEED_10 + DUPLEX_FULL: | ||
| 120 | adv_cfg = ADVERTISED_10baseT_Full; | ||
| 121 | break; | ||
| 122 | case SPEED_100 + DUPLEX_HALF: | ||
| 123 | adv_cfg = ADVERTISED_100baseT_Half; | ||
| 124 | break; | ||
| 125 | case SPEED_100 + DUPLEX_FULL: | ||
| 126 | adv_cfg = ADVERTISED_100baseT_Full; | ||
| 127 | break; | ||
| 128 | default: | ||
| 129 | return -EINVAL; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | hw->adv_cfg = adv_cfg; | ||
| 134 | return alx_setup_speed_duplex(hw, adv_cfg, hw->flowctrl); | ||
| 135 | } | ||
| 136 | |||
| 137 | static void alx_get_pauseparam(struct net_device *netdev, | ||
| 138 | struct ethtool_pauseparam *pause) | ||
| 139 | { | ||
| 140 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 141 | struct alx_hw *hw = &alx->hw; | ||
| 142 | |||
| 143 | if (hw->flowctrl & ALX_FC_ANEG && | ||
| 144 | hw->adv_cfg & ADVERTISED_Autoneg) | ||
| 145 | pause->autoneg = AUTONEG_ENABLE; | ||
| 146 | else | ||
| 147 | pause->autoneg = AUTONEG_DISABLE; | ||
| 148 | |||
| 149 | if (hw->flowctrl & ALX_FC_TX) | ||
| 150 | pause->tx_pause = 1; | ||
| 151 | else | ||
| 152 | pause->tx_pause = 0; | ||
| 153 | |||
| 154 | if (hw->flowctrl & ALX_FC_RX) | ||
| 155 | pause->rx_pause = 1; | ||
| 156 | else | ||
| 157 | pause->rx_pause = 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | |||
| 161 | static int alx_set_pauseparam(struct net_device *netdev, | ||
| 162 | struct ethtool_pauseparam *pause) | ||
| 163 | { | ||
| 164 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 165 | struct alx_hw *hw = &alx->hw; | ||
| 166 | int err = 0; | ||
| 167 | bool reconfig_phy = false; | ||
| 168 | u8 fc = 0; | ||
| 169 | |||
| 170 | if (pause->tx_pause) | ||
| 171 | fc |= ALX_FC_TX; | ||
| 172 | if (pause->rx_pause) | ||
| 173 | fc |= ALX_FC_RX; | ||
| 174 | if (pause->autoneg) | ||
| 175 | fc |= ALX_FC_ANEG; | ||
| 176 | |||
| 177 | ASSERT_RTNL(); | ||
| 178 | |||
| 179 | /* restart auto-neg for auto-mode */ | ||
| 180 | if (hw->adv_cfg & ADVERTISED_Autoneg) { | ||
| 181 | if (!((fc ^ hw->flowctrl) & ALX_FC_ANEG)) | ||
| 182 | reconfig_phy = true; | ||
| 183 | if (fc & hw->flowctrl & ALX_FC_ANEG && | ||
| 184 | (fc ^ hw->flowctrl) & (ALX_FC_RX | ALX_FC_TX)) | ||
| 185 | reconfig_phy = true; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (reconfig_phy) { | ||
| 189 | err = alx_setup_speed_duplex(hw, hw->adv_cfg, fc); | ||
| 190 | return err; | ||
| 191 | } | ||
| 192 | |||
| 193 | /* flow control on mac */ | ||
| 194 | if ((fc ^ hw->flowctrl) & (ALX_FC_RX | ALX_FC_TX)) | ||
| 195 | alx_cfg_mac_flowcontrol(hw, fc); | ||
| 196 | |||
| 197 | hw->flowctrl = fc; | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | static u32 alx_get_msglevel(struct net_device *netdev) | ||
| 203 | { | ||
| 204 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 205 | |||
| 206 | return alx->msg_enable; | ||
| 207 | } | ||
| 208 | |||
| 209 | static void alx_set_msglevel(struct net_device *netdev, u32 data) | ||
| 210 | { | ||
| 211 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 212 | |||
| 213 | alx->msg_enable = data; | ||
| 214 | } | ||
| 215 | |||
| 216 | static void alx_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | ||
| 217 | { | ||
| 218 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 219 | struct alx_hw *hw = &alx->hw; | ||
| 220 | |||
| 221 | wol->supported = WAKE_MAGIC | WAKE_PHY; | ||
| 222 | wol->wolopts = 0; | ||
| 223 | |||
| 224 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC) | ||
| 225 | wol->wolopts |= WAKE_MAGIC; | ||
| 226 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) | ||
| 227 | wol->wolopts |= WAKE_PHY; | ||
| 228 | } | ||
| 229 | |||
| 230 | static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | ||
| 231 | { | ||
| 232 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 233 | struct alx_hw *hw = &alx->hw; | ||
| 234 | |||
| 235 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | | ||
| 236 | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) | ||
| 237 | return -EOPNOTSUPP; | ||
| 238 | |||
| 239 | hw->sleep_ctrl = 0; | ||
| 240 | |||
| 241 | if (wol->wolopts & WAKE_MAGIC) | ||
| 242 | hw->sleep_ctrl |= ALX_SLEEP_WOL_MAGIC; | ||
| 243 | if (wol->wolopts & WAKE_PHY) | ||
| 244 | hw->sleep_ctrl |= ALX_SLEEP_WOL_PHY; | ||
| 245 | |||
| 246 | device_set_wakeup_enable(&alx->hw.pdev->dev, hw->sleep_ctrl); | ||
| 247 | |||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | static void alx_get_drvinfo(struct net_device *netdev, | ||
| 252 | struct ethtool_drvinfo *drvinfo) | ||
| 253 | { | ||
| 254 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 255 | |||
| 256 | strlcpy(drvinfo->driver, alx_drv_name, sizeof(drvinfo->driver)); | ||
| 257 | strlcpy(drvinfo->bus_info, pci_name(alx->hw.pdev), | ||
| 258 | sizeof(drvinfo->bus_info)); | ||
| 259 | } | ||
| 260 | |||
| 261 | const struct ethtool_ops alx_ethtool_ops = { | ||
| 262 | .get_settings = alx_get_settings, | ||
| 263 | .set_settings = alx_set_settings, | ||
| 264 | .get_pauseparam = alx_get_pauseparam, | ||
| 265 | .set_pauseparam = alx_set_pauseparam, | ||
| 266 | .get_drvinfo = alx_get_drvinfo, | ||
| 267 | .get_msglevel = alx_get_msglevel, | ||
| 268 | .set_msglevel = alx_set_msglevel, | ||
| 269 | .get_wol = alx_get_wol, | ||
| 270 | .set_wol = alx_set_wol, | ||
| 271 | .get_link = ethtool_op_get_link, | ||
| 272 | }; | ||
diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c new file mode 100644 index 000000000000..220a16ad0e49 --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/hw.c | |||
| @@ -0,0 +1,1226 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> | ||
| 3 | * | ||
| 4 | * This file is free software: you may copy, redistribute and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation, either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This file is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | * | ||
| 17 | * This file incorporates work covered by the following copyright and | ||
| 18 | * permission notice: | ||
| 19 | * | ||
| 20 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
| 21 | * | ||
| 22 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 23 | * purpose with or without fee is hereby granted, provided that the above | ||
| 24 | * copyright notice and this permission notice appear in all copies. | ||
| 25 | * | ||
| 26 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 27 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 29 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 30 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 31 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 32 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 33 | */ | ||
| 34 | #include <linux/etherdevice.h> | ||
| 35 | #include <linux/delay.h> | ||
| 36 | #include <linux/pci.h> | ||
| 37 | #include <linux/mdio.h> | ||
| 38 | #include "reg.h" | ||
| 39 | #include "hw.h" | ||
| 40 | |||
| 41 | static inline bool alx_is_rev_a(u8 rev) | ||
| 42 | { | ||
| 43 | return rev == ALX_REV_A0 || rev == ALX_REV_A1; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int alx_wait_mdio_idle(struct alx_hw *hw) | ||
| 47 | { | ||
| 48 | u32 val; | ||
| 49 | int i; | ||
| 50 | |||
| 51 | for (i = 0; i < ALX_MDIO_MAX_AC_TO; i++) { | ||
| 52 | val = alx_read_mem32(hw, ALX_MDIO); | ||
| 53 | if (!(val & ALX_MDIO_BUSY)) | ||
| 54 | return 0; | ||
| 55 | udelay(10); | ||
| 56 | } | ||
| 57 | |||
| 58 | return -ETIMEDOUT; | ||
| 59 | } | ||
| 60 | |||
| 61 | static int alx_read_phy_core(struct alx_hw *hw, bool ext, u8 dev, | ||
| 62 | u16 reg, u16 *phy_data) | ||
| 63 | { | ||
| 64 | u32 val, clk_sel; | ||
| 65 | int err; | ||
| 66 | |||
| 67 | *phy_data = 0; | ||
| 68 | |||
| 69 | /* use slow clock when it's in hibernation status */ | ||
| 70 | clk_sel = hw->link_speed != SPEED_UNKNOWN ? | ||
| 71 | ALX_MDIO_CLK_SEL_25MD4 : | ||
| 72 | ALX_MDIO_CLK_SEL_25MD128; | ||
| 73 | |||
| 74 | if (ext) { | ||
| 75 | val = dev << ALX_MDIO_EXTN_DEVAD_SHIFT | | ||
| 76 | reg << ALX_MDIO_EXTN_REG_SHIFT; | ||
| 77 | alx_write_mem32(hw, ALX_MDIO_EXTN, val); | ||
| 78 | |||
| 79 | val = ALX_MDIO_SPRES_PRMBL | ALX_MDIO_START | | ||
| 80 | ALX_MDIO_MODE_EXT | ALX_MDIO_OP_READ | | ||
| 81 | clk_sel << ALX_MDIO_CLK_SEL_SHIFT; | ||
| 82 | } else { | ||
| 83 | val = ALX_MDIO_SPRES_PRMBL | | ||
| 84 | clk_sel << ALX_MDIO_CLK_SEL_SHIFT | | ||
| 85 | reg << ALX_MDIO_REG_SHIFT | | ||
| 86 | ALX_MDIO_START | ALX_MDIO_OP_READ; | ||
| 87 | } | ||
| 88 | alx_write_mem32(hw, ALX_MDIO, val); | ||
| 89 | |||
| 90 | err = alx_wait_mdio_idle(hw); | ||
| 91 | if (err) | ||
| 92 | return err; | ||
| 93 | val = alx_read_mem32(hw, ALX_MDIO); | ||
| 94 | *phy_data = ALX_GET_FIELD(val, ALX_MDIO_DATA); | ||
| 95 | return 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | static int alx_write_phy_core(struct alx_hw *hw, bool ext, u8 dev, | ||
| 99 | u16 reg, u16 phy_data) | ||
| 100 | { | ||
| 101 | u32 val, clk_sel; | ||
| 102 | |||
| 103 | /* use slow clock when it's in hibernation status */ | ||
| 104 | clk_sel = hw->link_speed != SPEED_UNKNOWN ? | ||
| 105 | ALX_MDIO_CLK_SEL_25MD4 : | ||
| 106 | ALX_MDIO_CLK_SEL_25MD128; | ||
| 107 | |||
| 108 | if (ext) { | ||
| 109 | val = dev << ALX_MDIO_EXTN_DEVAD_SHIFT | | ||
| 110 | reg << ALX_MDIO_EXTN_REG_SHIFT; | ||
| 111 | alx_write_mem32(hw, ALX_MDIO_EXTN, val); | ||
| 112 | |||
| 113 | val = ALX_MDIO_SPRES_PRMBL | | ||
| 114 | clk_sel << ALX_MDIO_CLK_SEL_SHIFT | | ||
| 115 | phy_data << ALX_MDIO_DATA_SHIFT | | ||
| 116 | ALX_MDIO_START | ALX_MDIO_MODE_EXT; | ||
| 117 | } else { | ||
| 118 | val = ALX_MDIO_SPRES_PRMBL | | ||
| 119 | clk_sel << ALX_MDIO_CLK_SEL_SHIFT | | ||
| 120 | reg << ALX_MDIO_REG_SHIFT | | ||
| 121 | phy_data << ALX_MDIO_DATA_SHIFT | | ||
| 122 | ALX_MDIO_START; | ||
| 123 | } | ||
| 124 | alx_write_mem32(hw, ALX_MDIO, val); | ||
| 125 | |||
| 126 | return alx_wait_mdio_idle(hw); | ||
| 127 | } | ||
| 128 | |||
| 129 | static int __alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data) | ||
| 130 | { | ||
| 131 | return alx_read_phy_core(hw, false, 0, reg, phy_data); | ||
| 132 | } | ||
| 133 | |||
| 134 | static int __alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data) | ||
| 135 | { | ||
| 136 | return alx_write_phy_core(hw, false, 0, reg, phy_data); | ||
| 137 | } | ||
| 138 | |||
| 139 | static int __alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata) | ||
| 140 | { | ||
| 141 | return alx_read_phy_core(hw, true, dev, reg, pdata); | ||
| 142 | } | ||
| 143 | |||
| 144 | static int __alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data) | ||
| 145 | { | ||
| 146 | return alx_write_phy_core(hw, true, dev, reg, data); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int __alx_read_phy_dbg(struct alx_hw *hw, u16 reg, u16 *pdata) | ||
| 150 | { | ||
| 151 | int err; | ||
| 152 | |||
| 153 | err = __alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, reg); | ||
| 154 | if (err) | ||
| 155 | return err; | ||
| 156 | |||
| 157 | return __alx_read_phy_reg(hw, ALX_MII_DBG_DATA, pdata); | ||
| 158 | } | ||
| 159 | |||
| 160 | static int __alx_write_phy_dbg(struct alx_hw *hw, u16 reg, u16 data) | ||
| 161 | { | ||
| 162 | int err; | ||
| 163 | |||
| 164 | err = __alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, reg); | ||
| 165 | if (err) | ||
| 166 | return err; | ||
| 167 | |||
| 168 | return __alx_write_phy_reg(hw, ALX_MII_DBG_DATA, data); | ||
| 169 | } | ||
| 170 | |||
| 171 | int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data) | ||
| 172 | { | ||
| 173 | int err; | ||
| 174 | |||
| 175 | spin_lock(&hw->mdio_lock); | ||
| 176 | err = __alx_read_phy_reg(hw, reg, phy_data); | ||
| 177 | spin_unlock(&hw->mdio_lock); | ||
| 178 | |||
| 179 | return err; | ||
| 180 | } | ||
| 181 | |||
| 182 | int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data) | ||
| 183 | { | ||
| 184 | int err; | ||
| 185 | |||
| 186 | spin_lock(&hw->mdio_lock); | ||
| 187 | err = __alx_write_phy_reg(hw, reg, phy_data); | ||
| 188 | spin_unlock(&hw->mdio_lock); | ||
| 189 | |||
| 190 | return err; | ||
| 191 | } | ||
| 192 | |||
| 193 | int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata) | ||
| 194 | { | ||
| 195 | int err; | ||
| 196 | |||
| 197 | spin_lock(&hw->mdio_lock); | ||
| 198 | err = __alx_read_phy_ext(hw, dev, reg, pdata); | ||
| 199 | spin_unlock(&hw->mdio_lock); | ||
| 200 | |||
| 201 | return err; | ||
| 202 | } | ||
| 203 | |||
| 204 | int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data) | ||
| 205 | { | ||
| 206 | int err; | ||
| 207 | |||
| 208 | spin_lock(&hw->mdio_lock); | ||
| 209 | err = __alx_write_phy_ext(hw, dev, reg, data); | ||
| 210 | spin_unlock(&hw->mdio_lock); | ||
| 211 | |||
| 212 | return err; | ||
| 213 | } | ||
| 214 | |||
| 215 | static int alx_read_phy_dbg(struct alx_hw *hw, u16 reg, u16 *pdata) | ||
| 216 | { | ||
| 217 | int err; | ||
| 218 | |||
| 219 | spin_lock(&hw->mdio_lock); | ||
| 220 | err = __alx_read_phy_dbg(hw, reg, pdata); | ||
| 221 | spin_unlock(&hw->mdio_lock); | ||
| 222 | |||
| 223 | return err; | ||
| 224 | } | ||
| 225 | |||
| 226 | static int alx_write_phy_dbg(struct alx_hw *hw, u16 reg, u16 data) | ||
| 227 | { | ||
| 228 | int err; | ||
| 229 | |||
| 230 | spin_lock(&hw->mdio_lock); | ||
| 231 | err = __alx_write_phy_dbg(hw, reg, data); | ||
| 232 | spin_unlock(&hw->mdio_lock); | ||
| 233 | |||
| 234 | return err; | ||
| 235 | } | ||
| 236 | |||
| 237 | static u16 alx_get_phy_config(struct alx_hw *hw) | ||
| 238 | { | ||
| 239 | u32 val; | ||
| 240 | u16 phy_val; | ||
| 241 | |||
| 242 | val = alx_read_mem32(hw, ALX_PHY_CTRL); | ||
| 243 | /* phy in reset */ | ||
| 244 | if ((val & ALX_PHY_CTRL_DSPRST_OUT) == 0) | ||
| 245 | return ALX_DRV_PHY_UNKNOWN; | ||
| 246 | |||
| 247 | val = alx_read_mem32(hw, ALX_DRV); | ||
| 248 | val = ALX_GET_FIELD(val, ALX_DRV_PHY); | ||
| 249 | if (ALX_DRV_PHY_UNKNOWN == val) | ||
| 250 | return ALX_DRV_PHY_UNKNOWN; | ||
| 251 | |||
| 252 | alx_read_phy_reg(hw, ALX_MII_DBG_ADDR, &phy_val); | ||
| 253 | if (ALX_PHY_INITED == phy_val) | ||
| 254 | return val; | ||
| 255 | |||
| 256 | return ALX_DRV_PHY_UNKNOWN; | ||
| 257 | } | ||
| 258 | |||
| 259 | static bool alx_wait_reg(struct alx_hw *hw, u32 reg, u32 wait, u32 *val) | ||
| 260 | { | ||
| 261 | u32 read; | ||
| 262 | int i; | ||
| 263 | |||
| 264 | for (i = 0; i < ALX_SLD_MAX_TO; i++) { | ||
| 265 | read = alx_read_mem32(hw, reg); | ||
| 266 | if ((read & wait) == 0) { | ||
| 267 | if (val) | ||
| 268 | *val = read; | ||
| 269 | return true; | ||
| 270 | } | ||
| 271 | mdelay(1); | ||
| 272 | } | ||
| 273 | |||
| 274 | return false; | ||
| 275 | } | ||
| 276 | |||
| 277 | static bool alx_read_macaddr(struct alx_hw *hw, u8 *addr) | ||
| 278 | { | ||
| 279 | u32 mac0, mac1; | ||
| 280 | |||
| 281 | mac0 = alx_read_mem32(hw, ALX_STAD0); | ||
| 282 | mac1 = alx_read_mem32(hw, ALX_STAD1); | ||
| 283 | |||
| 284 | /* addr should be big-endian */ | ||
| 285 | *(__be32 *)(addr + 2) = cpu_to_be32(mac0); | ||
| 286 | *(__be16 *)addr = cpu_to_be16(mac1); | ||
| 287 | |||
| 288 | return is_valid_ether_addr(addr); | ||
| 289 | } | ||
| 290 | |||
| 291 | int alx_get_perm_macaddr(struct alx_hw *hw, u8 *addr) | ||
| 292 | { | ||
| 293 | u32 val; | ||
| 294 | |||
| 295 | /* try to get it from register first */ | ||
| 296 | if (alx_read_macaddr(hw, addr)) | ||
| 297 | return 0; | ||
| 298 | |||
| 299 | /* try to load from efuse */ | ||
| 300 | if (!alx_wait_reg(hw, ALX_SLD, ALX_SLD_STAT | ALX_SLD_START, &val)) | ||
| 301 | return -EIO; | ||
| 302 | alx_write_mem32(hw, ALX_SLD, val | ALX_SLD_START); | ||
| 303 | if (!alx_wait_reg(hw, ALX_SLD, ALX_SLD_START, NULL)) | ||
| 304 | return -EIO; | ||
| 305 | if (alx_read_macaddr(hw, addr)) | ||
| 306 | return 0; | ||
| 307 | |||
| 308 | /* try to load from flash/eeprom (if present) */ | ||
| 309 | val = alx_read_mem32(hw, ALX_EFLD); | ||
| 310 | if (val & (ALX_EFLD_F_EXIST | ALX_EFLD_E_EXIST)) { | ||
| 311 | if (!alx_wait_reg(hw, ALX_EFLD, | ||
| 312 | ALX_EFLD_STAT | ALX_EFLD_START, &val)) | ||
| 313 | return -EIO; | ||
| 314 | alx_write_mem32(hw, ALX_EFLD, val | ALX_EFLD_START); | ||
| 315 | if (!alx_wait_reg(hw, ALX_EFLD, ALX_EFLD_START, NULL)) | ||
| 316 | return -EIO; | ||
| 317 | if (alx_read_macaddr(hw, addr)) | ||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | return -EIO; | ||
| 322 | } | ||
| 323 | |||
| 324 | void alx_set_macaddr(struct alx_hw *hw, const u8 *addr) | ||
| 325 | { | ||
| 326 | u32 val; | ||
| 327 | |||
| 328 | /* for example: 00-0B-6A-F6-00-DC * STAD0=6AF600DC, STAD1=000B */ | ||
| 329 | val = be32_to_cpu(*(__be32 *)(addr + 2)); | ||
| 330 | alx_write_mem32(hw, ALX_STAD0, val); | ||
| 331 | val = be16_to_cpu(*(__be16 *)addr); | ||
| 332 | alx_write_mem32(hw, ALX_STAD1, val); | ||
| 333 | } | ||
| 334 | |||
| 335 | static void alx_enable_osc(struct alx_hw *hw) | ||
| 336 | { | ||
| 337 | u32 val; | ||
| 338 | |||
| 339 | /* rising edge */ | ||
| 340 | val = alx_read_mem32(hw, ALX_MISC); | ||
| 341 | alx_write_mem32(hw, ALX_MISC, val & ~ALX_MISC_INTNLOSC_OPEN); | ||
| 342 | alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN); | ||
| 343 | } | ||
| 344 | |||
| 345 | static void alx_reset_osc(struct alx_hw *hw, u8 rev) | ||
| 346 | { | ||
| 347 | u32 val, val2; | ||
| 348 | |||
| 349 | /* clear Internal OSC settings, switching OSC by hw itself */ | ||
| 350 | val = alx_read_mem32(hw, ALX_MISC3); | ||
| 351 | alx_write_mem32(hw, ALX_MISC3, | ||
| 352 | (val & ~ALX_MISC3_25M_BY_SW) | | ||
| 353 | ALX_MISC3_25M_NOTO_INTNL); | ||
| 354 | |||
| 355 | /* 25M clk from chipset may be unstable 1s after de-assert of | ||
| 356 | * PERST, driver need re-calibrate before enter Sleep for WoL | ||
| 357 | */ | ||
| 358 | val = alx_read_mem32(hw, ALX_MISC); | ||
| 359 | if (rev >= ALX_REV_B0) { | ||
| 360 | /* restore over current protection def-val, | ||
| 361 | * this val could be reset by MAC-RST | ||
| 362 | */ | ||
| 363 | ALX_SET_FIELD(val, ALX_MISC_PSW_OCP, ALX_MISC_PSW_OCP_DEF); | ||
| 364 | /* a 0->1 change will update the internal val of osc */ | ||
| 365 | val &= ~ALX_MISC_INTNLOSC_OPEN; | ||
| 366 | alx_write_mem32(hw, ALX_MISC, val); | ||
| 367 | alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN); | ||
| 368 | /* hw will automatically dis OSC after cab. */ | ||
| 369 | val2 = alx_read_mem32(hw, ALX_MSIC2); | ||
| 370 | val2 &= ~ALX_MSIC2_CALB_START; | ||
| 371 | alx_write_mem32(hw, ALX_MSIC2, val2); | ||
| 372 | alx_write_mem32(hw, ALX_MSIC2, val2 | ALX_MSIC2_CALB_START); | ||
| 373 | } else { | ||
| 374 | val &= ~ALX_MISC_INTNLOSC_OPEN; | ||
| 375 | /* disable isolate for rev A devices */ | ||
| 376 | if (alx_is_rev_a(rev)) | ||
| 377 | val &= ~ALX_MISC_ISO_EN; | ||
| 378 | |||
| 379 | alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN); | ||
| 380 | alx_write_mem32(hw, ALX_MISC, val); | ||
| 381 | } | ||
| 382 | |||
| 383 | udelay(20); | ||
| 384 | } | ||
| 385 | |||
| 386 | static int alx_stop_mac(struct alx_hw *hw) | ||
| 387 | { | ||
| 388 | u32 rxq, txq, val; | ||
| 389 | u16 i; | ||
| 390 | |||
| 391 | rxq = alx_read_mem32(hw, ALX_RXQ0); | ||
| 392 | alx_write_mem32(hw, ALX_RXQ0, rxq & ~ALX_RXQ0_EN); | ||
| 393 | txq = alx_read_mem32(hw, ALX_TXQ0); | ||
| 394 | alx_write_mem32(hw, ALX_TXQ0, txq & ~ALX_TXQ0_EN); | ||
| 395 | |||
| 396 | udelay(40); | ||
| 397 | |||
| 398 | hw->rx_ctrl &= ~(ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN); | ||
| 399 | alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl); | ||
| 400 | |||
| 401 | for (i = 0; i < ALX_DMA_MAC_RST_TO; i++) { | ||
| 402 | val = alx_read_mem32(hw, ALX_MAC_STS); | ||
| 403 | if (!(val & ALX_MAC_STS_IDLE)) | ||
| 404 | return 0; | ||
| 405 | udelay(10); | ||
| 406 | } | ||
| 407 | |||
| 408 | return -ETIMEDOUT; | ||
| 409 | } | ||
| 410 | |||
| 411 | int alx_reset_mac(struct alx_hw *hw) | ||
| 412 | { | ||
| 413 | u32 val, pmctrl; | ||
| 414 | int i, ret; | ||
| 415 | u8 rev; | ||
| 416 | bool a_cr; | ||
| 417 | |||
| 418 | pmctrl = 0; | ||
| 419 | rev = alx_hw_revision(hw); | ||
| 420 | a_cr = alx_is_rev_a(rev) && alx_hw_with_cr(hw); | ||
| 421 | |||
| 422 | /* disable all interrupts, RXQ/TXQ */ | ||
| 423 | alx_write_mem32(hw, ALX_MSIX_MASK, 0xFFFFFFFF); | ||
| 424 | alx_write_mem32(hw, ALX_IMR, 0); | ||
| 425 | alx_write_mem32(hw, ALX_ISR, ALX_ISR_DIS); | ||
| 426 | |||
| 427 | ret = alx_stop_mac(hw); | ||
| 428 | if (ret) | ||
| 429 | return ret; | ||
| 430 | |||
| 431 | /* mac reset workaroud */ | ||
| 432 | alx_write_mem32(hw, ALX_RFD_PIDX, 1); | ||
| 433 | |||
| 434 | /* dis l0s/l1 before mac reset */ | ||
| 435 | if (a_cr) { | ||
| 436 | pmctrl = alx_read_mem32(hw, ALX_PMCTRL); | ||
| 437 | if (pmctrl & (ALX_PMCTRL_L1_EN | ALX_PMCTRL_L0S_EN)) | ||
| 438 | alx_write_mem32(hw, ALX_PMCTRL, | ||
| 439 | pmctrl & ~(ALX_PMCTRL_L1_EN | | ||
| 440 | ALX_PMCTRL_L0S_EN)); | ||
| 441 | } | ||
| 442 | |||
| 443 | /* reset whole mac safely */ | ||
| 444 | val = alx_read_mem32(hw, ALX_MASTER); | ||
| 445 | alx_write_mem32(hw, ALX_MASTER, | ||
| 446 | val | ALX_MASTER_DMA_MAC_RST | ALX_MASTER_OOB_DIS); | ||
| 447 | |||
| 448 | /* make sure it's real idle */ | ||
| 449 | udelay(10); | ||
| 450 | for (i = 0; i < ALX_DMA_MAC_RST_TO; i++) { | ||
| 451 | val = alx_read_mem32(hw, ALX_RFD_PIDX); | ||
| 452 | if (val == 0) | ||
| 453 | break; | ||
| 454 | udelay(10); | ||
| 455 | } | ||
| 456 | for (; i < ALX_DMA_MAC_RST_TO; i++) { | ||
| 457 | val = alx_read_mem32(hw, ALX_MASTER); | ||
| 458 | if ((val & ALX_MASTER_DMA_MAC_RST) == 0) | ||
| 459 | break; | ||
| 460 | udelay(10); | ||
| 461 | } | ||
| 462 | if (i == ALX_DMA_MAC_RST_TO) | ||
| 463 | return -EIO; | ||
| 464 | udelay(10); | ||
| 465 | |||
| 466 | if (a_cr) { | ||
| 467 | alx_write_mem32(hw, ALX_MASTER, val | ALX_MASTER_PCLKSEL_SRDS); | ||
| 468 | /* restore l0s / l1 */ | ||
| 469 | if (pmctrl & (ALX_PMCTRL_L1_EN | ALX_PMCTRL_L0S_EN)) | ||
| 470 | alx_write_mem32(hw, ALX_PMCTRL, pmctrl); | ||
| 471 | } | ||
| 472 | |||
| 473 | alx_reset_osc(hw, rev); | ||
| 474 | |||
| 475 | /* clear Internal OSC settings, switching OSC by hw itself, | ||
| 476 | * disable isolate for rev A devices | ||
| 477 | */ | ||
| 478 | val = alx_read_mem32(hw, ALX_MISC3); | ||
| 479 | alx_write_mem32(hw, ALX_MISC3, | ||
| 480 | (val & ~ALX_MISC3_25M_BY_SW) | | ||
| 481 | ALX_MISC3_25M_NOTO_INTNL); | ||
| 482 | val = alx_read_mem32(hw, ALX_MISC); | ||
| 483 | val &= ~ALX_MISC_INTNLOSC_OPEN; | ||
| 484 | if (alx_is_rev_a(rev)) | ||
| 485 | val &= ~ALX_MISC_ISO_EN; | ||
| 486 | alx_write_mem32(hw, ALX_MISC, val); | ||
| 487 | udelay(20); | ||
| 488 | |||
| 489 | /* driver control speed/duplex, hash-alg */ | ||
| 490 | alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl); | ||
| 491 | |||
| 492 | val = alx_read_mem32(hw, ALX_SERDES); | ||
| 493 | alx_write_mem32(hw, ALX_SERDES, | ||
| 494 | val | ALX_SERDES_MACCLK_SLWDWN | | ||
| 495 | ALX_SERDES_PHYCLK_SLWDWN); | ||
| 496 | |||
| 497 | return 0; | ||
| 498 | } | ||
| 499 | |||
| 500 | void alx_reset_phy(struct alx_hw *hw) | ||
| 501 | { | ||
| 502 | int i; | ||
| 503 | u32 val; | ||
| 504 | u16 phy_val; | ||
| 505 | |||
| 506 | /* (DSP)reset PHY core */ | ||
| 507 | val = alx_read_mem32(hw, ALX_PHY_CTRL); | ||
| 508 | val &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_IDDQ | | ||
| 509 | ALX_PHY_CTRL_GATE_25M | ALX_PHY_CTRL_POWER_DOWN | | ||
| 510 | ALX_PHY_CTRL_CLS); | ||
| 511 | val |= ALX_PHY_CTRL_RST_ANALOG; | ||
| 512 | |||
| 513 | val |= (ALX_PHY_CTRL_HIB_PULSE | ALX_PHY_CTRL_HIB_EN); | ||
| 514 | alx_write_mem32(hw, ALX_PHY_CTRL, val); | ||
| 515 | udelay(10); | ||
| 516 | alx_write_mem32(hw, ALX_PHY_CTRL, val | ALX_PHY_CTRL_DSPRST_OUT); | ||
| 517 | |||
| 518 | for (i = 0; i < ALX_PHY_CTRL_DSPRST_TO; i++) | ||
| 519 | udelay(10); | ||
| 520 | |||
| 521 | /* phy power saving & hib */ | ||
| 522 | alx_write_phy_dbg(hw, ALX_MIIDBG_LEGCYPS, ALX_LEGCYPS_DEF); | ||
| 523 | alx_write_phy_dbg(hw, ALX_MIIDBG_SYSMODCTRL, | ||
| 524 | ALX_SYSMODCTRL_IECHOADJ_DEF); | ||
| 525 | alx_write_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_VDRVBIAS, | ||
| 526 | ALX_VDRVBIAS_DEF); | ||
| 527 | |||
| 528 | /* EEE advertisement */ | ||
| 529 | val = alx_read_mem32(hw, ALX_LPI_CTRL); | ||
| 530 | alx_write_mem32(hw, ALX_LPI_CTRL, val & ~ALX_LPI_CTRL_EN); | ||
| 531 | alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_LOCAL_EEEADV, 0); | ||
| 532 | |||
| 533 | /* phy power saving */ | ||
| 534 | alx_write_phy_dbg(hw, ALX_MIIDBG_TST10BTCFG, ALX_TST10BTCFG_DEF); | ||
| 535 | alx_write_phy_dbg(hw, ALX_MIIDBG_SRDSYSMOD, ALX_SRDSYSMOD_DEF); | ||
| 536 | alx_write_phy_dbg(hw, ALX_MIIDBG_TST100BTCFG, ALX_TST100BTCFG_DEF); | ||
| 537 | alx_write_phy_dbg(hw, ALX_MIIDBG_ANACTRL, ALX_ANACTRL_DEF); | ||
| 538 | alx_read_phy_dbg(hw, ALX_MIIDBG_GREENCFG2, &phy_val); | ||
| 539 | alx_write_phy_dbg(hw, ALX_MIIDBG_GREENCFG2, | ||
| 540 | phy_val & ~ALX_GREENCFG2_GATE_DFSE_EN); | ||
| 541 | /* rtl8139c, 120m issue */ | ||
| 542 | alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_NLP78, | ||
| 543 | ALX_MIIEXT_NLP78_120M_DEF); | ||
| 544 | alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_S3DIG10, | ||
| 545 | ALX_MIIEXT_S3DIG10_DEF); | ||
| 546 | |||
| 547 | if (hw->lnk_patch) { | ||
| 548 | /* Turn off half amplitude */ | ||
| 549 | alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL3, | ||
| 550 | &phy_val); | ||
| 551 | alx_write_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL3, | ||
| 552 | phy_val | ALX_CLDCTRL3_BP_CABLE1TH_DET_GT); | ||
| 553 | /* Turn off Green feature */ | ||
| 554 | alx_read_phy_dbg(hw, ALX_MIIDBG_GREENCFG2, &phy_val); | ||
| 555 | alx_write_phy_dbg(hw, ALX_MIIDBG_GREENCFG2, | ||
| 556 | phy_val | ALX_GREENCFG2_BP_GREEN); | ||
| 557 | /* Turn off half Bias */ | ||
| 558 | alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL5, | ||
| 559 | &phy_val); | ||
| 560 | alx_write_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL5, | ||
| 561 | phy_val | ALX_CLDCTRL5_BP_VD_HLFBIAS); | ||
| 562 | } | ||
| 563 | |||
| 564 | /* set phy interrupt mask */ | ||
| 565 | alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP | ALX_IER_LINK_DOWN); | ||
| 566 | } | ||
| 567 | |||
| 568 | #define ALX_PCI_CMD (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO) | ||
| 569 | |||
| 570 | void alx_reset_pcie(struct alx_hw *hw) | ||
| 571 | { | ||
| 572 | u8 rev = alx_hw_revision(hw); | ||
| 573 | u32 val; | ||
| 574 | u16 val16; | ||
| 575 | |||
| 576 | /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */ | ||
| 577 | pci_read_config_word(hw->pdev, PCI_COMMAND, &val16); | ||
| 578 | if (!(val16 & ALX_PCI_CMD) || (val16 & PCI_COMMAND_INTX_DISABLE)) { | ||
| 579 | val16 = (val16 | ALX_PCI_CMD) & ~PCI_COMMAND_INTX_DISABLE; | ||
| 580 | pci_write_config_word(hw->pdev, PCI_COMMAND, val16); | ||
| 581 | } | ||
| 582 | |||
| 583 | /* clear WoL setting/status */ | ||
| 584 | val = alx_read_mem32(hw, ALX_WOL0); | ||
| 585 | alx_write_mem32(hw, ALX_WOL0, 0); | ||
| 586 | |||
| 587 | val = alx_read_mem32(hw, ALX_PDLL_TRNS1); | ||
| 588 | alx_write_mem32(hw, ALX_PDLL_TRNS1, val & ~ALX_PDLL_TRNS1_D3PLLOFF_EN); | ||
| 589 | |||
| 590 | /* mask some pcie error bits */ | ||
| 591 | val = alx_read_mem32(hw, ALX_UE_SVRT); | ||
| 592 | val &= ~(ALX_UE_SVRT_DLPROTERR | ALX_UE_SVRT_FCPROTERR); | ||
| 593 | alx_write_mem32(hw, ALX_UE_SVRT, val); | ||
| 594 | |||
| 595 | /* wol 25M & pclk */ | ||
| 596 | val = alx_read_mem32(hw, ALX_MASTER); | ||
| 597 | if (alx_is_rev_a(rev) && alx_hw_with_cr(hw)) { | ||
| 598 | if ((val & ALX_MASTER_WAKEN_25M) == 0 || | ||
| 599 | (val & ALX_MASTER_PCLKSEL_SRDS) == 0) | ||
| 600 | alx_write_mem32(hw, ALX_MASTER, | ||
| 601 | val | ALX_MASTER_PCLKSEL_SRDS | | ||
| 602 | ALX_MASTER_WAKEN_25M); | ||
| 603 | } else { | ||
| 604 | if ((val & ALX_MASTER_WAKEN_25M) == 0 || | ||
| 605 | (val & ALX_MASTER_PCLKSEL_SRDS) != 0) | ||
| 606 | alx_write_mem32(hw, ALX_MASTER, | ||
| 607 | (val & ~ALX_MASTER_PCLKSEL_SRDS) | | ||
| 608 | ALX_MASTER_WAKEN_25M); | ||
| 609 | } | ||
| 610 | |||
| 611 | /* ASPM setting */ | ||
| 612 | alx_enable_aspm(hw, true, true); | ||
| 613 | |||
| 614 | udelay(10); | ||
| 615 | } | ||
| 616 | |||
| 617 | void alx_start_mac(struct alx_hw *hw) | ||
| 618 | { | ||
| 619 | u32 mac, txq, rxq; | ||
| 620 | |||
| 621 | rxq = alx_read_mem32(hw, ALX_RXQ0); | ||
| 622 | alx_write_mem32(hw, ALX_RXQ0, rxq | ALX_RXQ0_EN); | ||
| 623 | txq = alx_read_mem32(hw, ALX_TXQ0); | ||
| 624 | alx_write_mem32(hw, ALX_TXQ0, txq | ALX_TXQ0_EN); | ||
| 625 | |||
| 626 | mac = hw->rx_ctrl; | ||
| 627 | if (hw->link_speed % 10 == DUPLEX_FULL) | ||
| 628 | mac |= ALX_MAC_CTRL_FULLD; | ||
| 629 | else | ||
| 630 | mac &= ~ALX_MAC_CTRL_FULLD; | ||
| 631 | ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, | ||
| 632 | hw->link_speed >= SPEED_1000 ? ALX_MAC_CTRL_SPEED_1000 : | ||
| 633 | ALX_MAC_CTRL_SPEED_10_100); | ||
| 634 | mac |= ALX_MAC_CTRL_TX_EN | ALX_MAC_CTRL_RX_EN; | ||
| 635 | hw->rx_ctrl = mac; | ||
| 636 | alx_write_mem32(hw, ALX_MAC_CTRL, mac); | ||
| 637 | } | ||
| 638 | |||
| 639 | void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc) | ||
| 640 | { | ||
| 641 | if (fc & ALX_FC_RX) | ||
| 642 | hw->rx_ctrl |= ALX_MAC_CTRL_RXFC_EN; | ||
| 643 | else | ||
| 644 | hw->rx_ctrl &= ~ALX_MAC_CTRL_RXFC_EN; | ||
| 645 | |||
| 646 | if (fc & ALX_FC_TX) | ||
| 647 | hw->rx_ctrl |= ALX_MAC_CTRL_TXFC_EN; | ||
| 648 | else | ||
| 649 | hw->rx_ctrl &= ~ALX_MAC_CTRL_TXFC_EN; | ||
| 650 | |||
| 651 | alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl); | ||
| 652 | } | ||
| 653 | |||
| 654 | void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en) | ||
| 655 | { | ||
| 656 | u32 pmctrl; | ||
| 657 | u8 rev = alx_hw_revision(hw); | ||
| 658 | |||
| 659 | pmctrl = alx_read_mem32(hw, ALX_PMCTRL); | ||
| 660 | |||
| 661 | ALX_SET_FIELD(pmctrl, ALX_PMCTRL_LCKDET_TIMER, | ||
| 662 | ALX_PMCTRL_LCKDET_TIMER_DEF); | ||
| 663 | pmctrl |= ALX_PMCTRL_RCVR_WT_1US | | ||
| 664 | ALX_PMCTRL_L1_CLKSW_EN | | ||
| 665 | ALX_PMCTRL_L1_SRDSRX_PWD; | ||
| 666 | ALX_SET_FIELD(pmctrl, ALX_PMCTRL_L1REQ_TO, ALX_PMCTRL_L1REG_TO_DEF); | ||
| 667 | ALX_SET_FIELD(pmctrl, ALX_PMCTRL_L1_TIMER, ALX_PMCTRL_L1_TIMER_16US); | ||
| 668 | pmctrl &= ~(ALX_PMCTRL_L1_SRDS_EN | | ||
| 669 | ALX_PMCTRL_L1_SRDSPLL_EN | | ||
| 670 | ALX_PMCTRL_L1_BUFSRX_EN | | ||
| 671 | ALX_PMCTRL_SADLY_EN | | ||
| 672 | ALX_PMCTRL_HOTRST_WTEN| | ||
| 673 | ALX_PMCTRL_L0S_EN | | ||
| 674 | ALX_PMCTRL_L1_EN | | ||
| 675 | ALX_PMCTRL_ASPM_FCEN | | ||
| 676 | ALX_PMCTRL_TXL1_AFTER_L0S | | ||
| 677 | ALX_PMCTRL_RXL1_AFTER_L0S); | ||
| 678 | if (alx_is_rev_a(rev) && alx_hw_with_cr(hw)) | ||
| 679 | pmctrl |= ALX_PMCTRL_L1_SRDS_EN | ALX_PMCTRL_L1_SRDSPLL_EN; | ||
| 680 | |||
| 681 | if (l0s_en) | ||
| 682 | pmctrl |= (ALX_PMCTRL_L0S_EN | ALX_PMCTRL_ASPM_FCEN); | ||
| 683 | if (l1_en) | ||
| 684 | pmctrl |= (ALX_PMCTRL_L1_EN | ALX_PMCTRL_ASPM_FCEN); | ||
| 685 | |||
| 686 | alx_write_mem32(hw, ALX_PMCTRL, pmctrl); | ||
| 687 | } | ||
| 688 | |||
| 689 | |||
| 690 | static u32 ethadv_to_hw_cfg(struct alx_hw *hw, u32 ethadv_cfg) | ||
| 691 | { | ||
| 692 | u32 cfg = 0; | ||
| 693 | |||
| 694 | if (ethadv_cfg & ADVERTISED_Autoneg) { | ||
| 695 | cfg |= ALX_DRV_PHY_AUTO; | ||
| 696 | if (ethadv_cfg & ADVERTISED_10baseT_Half) | ||
| 697 | cfg |= ALX_DRV_PHY_10; | ||
| 698 | if (ethadv_cfg & ADVERTISED_10baseT_Full) | ||
| 699 | cfg |= ALX_DRV_PHY_10 | ALX_DRV_PHY_DUPLEX; | ||
| 700 | if (ethadv_cfg & ADVERTISED_100baseT_Half) | ||
| 701 | cfg |= ALX_DRV_PHY_100; | ||
| 702 | if (ethadv_cfg & ADVERTISED_100baseT_Full) | ||
| 703 | cfg |= ALX_DRV_PHY_100 | ALX_DRV_PHY_DUPLEX; | ||
| 704 | if (ethadv_cfg & ADVERTISED_1000baseT_Half) | ||
| 705 | cfg |= ALX_DRV_PHY_1000; | ||
| 706 | if (ethadv_cfg & ADVERTISED_1000baseT_Full) | ||
| 707 | cfg |= ALX_DRV_PHY_100 | ALX_DRV_PHY_DUPLEX; | ||
| 708 | if (ethadv_cfg & ADVERTISED_Pause) | ||
| 709 | cfg |= ADVERTISE_PAUSE_CAP; | ||
| 710 | if (ethadv_cfg & ADVERTISED_Asym_Pause) | ||
| 711 | cfg |= ADVERTISE_PAUSE_ASYM; | ||
| 712 | } else { | ||
| 713 | switch (ethadv_cfg) { | ||
| 714 | case ADVERTISED_10baseT_Half: | ||
| 715 | cfg |= ALX_DRV_PHY_10; | ||
| 716 | break; | ||
| 717 | case ADVERTISED_100baseT_Half: | ||
| 718 | cfg |= ALX_DRV_PHY_100; | ||
| 719 | break; | ||
| 720 | case ADVERTISED_10baseT_Full: | ||
| 721 | cfg |= ALX_DRV_PHY_10 | ALX_DRV_PHY_DUPLEX; | ||
| 722 | break; | ||
| 723 | case ADVERTISED_100baseT_Full: | ||
| 724 | cfg |= ALX_DRV_PHY_100 | ALX_DRV_PHY_DUPLEX; | ||
| 725 | break; | ||
| 726 | } | ||
| 727 | } | ||
| 728 | |||
| 729 | return cfg; | ||
| 730 | } | ||
| 731 | |||
| 732 | int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl) | ||
| 733 | { | ||
| 734 | u16 adv, giga, cr; | ||
| 735 | u32 val; | ||
| 736 | int err = 0; | ||
| 737 | |||
| 738 | alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, 0); | ||
| 739 | val = alx_read_mem32(hw, ALX_DRV); | ||
| 740 | ALX_SET_FIELD(val, ALX_DRV_PHY, 0); | ||
| 741 | |||
| 742 | if (ethadv & ADVERTISED_Autoneg) { | ||
| 743 | adv = ADVERTISE_CSMA; | ||
| 744 | adv |= ethtool_adv_to_mii_adv_t(ethadv); | ||
| 745 | |||
| 746 | if (flowctrl & ALX_FC_ANEG) { | ||
| 747 | if (flowctrl & ALX_FC_RX) { | ||
| 748 | adv |= ADVERTISED_Pause; | ||
| 749 | if (!(flowctrl & ALX_FC_TX)) | ||
| 750 | adv |= ADVERTISED_Asym_Pause; | ||
| 751 | } else if (flowctrl & ALX_FC_TX) { | ||
| 752 | adv |= ADVERTISED_Asym_Pause; | ||
| 753 | } | ||
| 754 | } | ||
| 755 | giga = 0; | ||
| 756 | if (alx_hw_giga(hw)) | ||
| 757 | giga = ethtool_adv_to_mii_ctrl1000_t(ethadv); | ||
| 758 | |||
| 759 | cr = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART; | ||
| 760 | |||
| 761 | if (alx_write_phy_reg(hw, MII_ADVERTISE, adv) || | ||
| 762 | alx_write_phy_reg(hw, MII_CTRL1000, giga) || | ||
| 763 | alx_write_phy_reg(hw, MII_BMCR, cr)) | ||
| 764 | err = -EBUSY; | ||
| 765 | } else { | ||
| 766 | cr = BMCR_RESET; | ||
| 767 | if (ethadv == ADVERTISED_100baseT_Half || | ||
| 768 | ethadv == ADVERTISED_100baseT_Full) | ||
| 769 | cr |= BMCR_SPEED100; | ||
| 770 | if (ethadv == ADVERTISED_10baseT_Full || | ||
| 771 | ethadv == ADVERTISED_100baseT_Full) | ||
| 772 | cr |= BMCR_FULLDPLX; | ||
| 773 | |||
| 774 | err = alx_write_phy_reg(hw, MII_BMCR, cr); | ||
| 775 | } | ||
| 776 | |||
| 777 | if (!err) { | ||
| 778 | alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, ALX_PHY_INITED); | ||
| 779 | val |= ethadv_to_hw_cfg(hw, ethadv); | ||
| 780 | } | ||
| 781 | |||
| 782 | alx_write_mem32(hw, ALX_DRV, val); | ||
| 783 | |||
| 784 | return err; | ||
| 785 | } | ||
| 786 | |||
| 787 | |||
| 788 | void alx_post_phy_link(struct alx_hw *hw) | ||
| 789 | { | ||
| 790 | u16 phy_val, len, agc; | ||
| 791 | u8 revid = alx_hw_revision(hw); | ||
| 792 | bool adj_th = revid == ALX_REV_B0; | ||
| 793 | int speed; | ||
| 794 | |||
| 795 | if (hw->link_speed == SPEED_UNKNOWN) | ||
| 796 | speed = SPEED_UNKNOWN; | ||
| 797 | else | ||
| 798 | speed = hw->link_speed - hw->link_speed % 10; | ||
| 799 | |||
| 800 | if (revid != ALX_REV_B0 && !alx_is_rev_a(revid)) | ||
| 801 | return; | ||
| 802 | |||
| 803 | /* 1000BT/AZ, wrong cable length */ | ||
| 804 | if (speed != SPEED_UNKNOWN) { | ||
| 805 | alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL6, | ||
| 806 | &phy_val); | ||
| 807 | len = ALX_GET_FIELD(phy_val, ALX_CLDCTRL6_CAB_LEN); | ||
| 808 | alx_read_phy_dbg(hw, ALX_MIIDBG_AGC, &phy_val); | ||
| 809 | agc = ALX_GET_FIELD(phy_val, ALX_AGC_2_VGA); | ||
| 810 | |||
| 811 | if ((speed == SPEED_1000 && | ||
| 812 | (len > ALX_CLDCTRL6_CAB_LEN_SHORT1G || | ||
| 813 | (len == 0 && agc > ALX_AGC_LONG1G_LIMT))) || | ||
| 814 | (speed == SPEED_100 && | ||
| 815 | (len > ALX_CLDCTRL6_CAB_LEN_SHORT100M || | ||
| 816 | (len == 0 && agc > ALX_AGC_LONG100M_LIMT)))) { | ||
| 817 | alx_write_phy_dbg(hw, ALX_MIIDBG_AZ_ANADECT, | ||
| 818 | ALX_AZ_ANADECT_LONG); | ||
| 819 | alx_read_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE, | ||
| 820 | &phy_val); | ||
| 821 | alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE, | ||
| 822 | phy_val | ALX_AFE_10BT_100M_TH); | ||
| 823 | } else { | ||
| 824 | alx_write_phy_dbg(hw, ALX_MIIDBG_AZ_ANADECT, | ||
| 825 | ALX_AZ_ANADECT_DEF); | ||
| 826 | alx_read_phy_ext(hw, ALX_MIIEXT_ANEG, | ||
| 827 | ALX_MIIEXT_AFE, &phy_val); | ||
| 828 | alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE, | ||
| 829 | phy_val & ~ALX_AFE_10BT_100M_TH); | ||
| 830 | } | ||
| 831 | |||
| 832 | /* threshold adjust */ | ||
| 833 | if (adj_th && hw->lnk_patch) { | ||
| 834 | if (speed == SPEED_100) { | ||
| 835 | alx_write_phy_dbg(hw, ALX_MIIDBG_MSE16DB, | ||
| 836 | ALX_MSE16DB_UP); | ||
| 837 | } else if (speed == SPEED_1000) { | ||
| 838 | /* | ||
| 839 | * Giga link threshold, raise the tolerance of | ||
| 840 | * noise 50% | ||
| 841 | */ | ||
| 842 | alx_read_phy_dbg(hw, ALX_MIIDBG_MSE20DB, | ||
| 843 | &phy_val); | ||
| 844 | ALX_SET_FIELD(phy_val, ALX_MSE20DB_TH, | ||
| 845 | ALX_MSE20DB_TH_HI); | ||
| 846 | alx_write_phy_dbg(hw, ALX_MIIDBG_MSE20DB, | ||
| 847 | phy_val); | ||
| 848 | } | ||
| 849 | } | ||
| 850 | } else { | ||
| 851 | alx_read_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE, | ||
| 852 | &phy_val); | ||
| 853 | alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE, | ||
| 854 | phy_val & ~ALX_AFE_10BT_100M_TH); | ||
| 855 | |||
| 856 | if (adj_th && hw->lnk_patch) { | ||
| 857 | alx_write_phy_dbg(hw, ALX_MIIDBG_MSE16DB, | ||
| 858 | ALX_MSE16DB_DOWN); | ||
| 859 | alx_read_phy_dbg(hw, ALX_MIIDBG_MSE20DB, &phy_val); | ||
| 860 | ALX_SET_FIELD(phy_val, ALX_MSE20DB_TH, | ||
| 861 | ALX_MSE20DB_TH_DEF); | ||
| 862 | alx_write_phy_dbg(hw, ALX_MIIDBG_MSE20DB, phy_val); | ||
| 863 | } | ||
| 864 | } | ||
| 865 | } | ||
| 866 | |||
| 867 | |||
| 868 | /* NOTE: | ||
| 869 | * 1. phy link must be established before calling this function | ||
| 870 | * 2. wol option (pattern,magic,link,etc.) is configed before call it. | ||
| 871 | */ | ||
| 872 | int alx_pre_suspend(struct alx_hw *hw, int speed) | ||
| 873 | { | ||
| 874 | u32 master, mac, phy, val; | ||
| 875 | int err = 0; | ||
| 876 | |||
| 877 | master = alx_read_mem32(hw, ALX_MASTER); | ||
| 878 | master &= ~ALX_MASTER_PCLKSEL_SRDS; | ||
| 879 | mac = hw->rx_ctrl; | ||
| 880 | /* 10/100 half */ | ||
| 881 | ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, ALX_MAC_CTRL_SPEED_10_100); | ||
| 882 | mac &= ~(ALX_MAC_CTRL_FULLD | ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN); | ||
| 883 | |||
| 884 | phy = alx_read_mem32(hw, ALX_PHY_CTRL); | ||
| 885 | phy &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_CLS); | ||
| 886 | phy |= ALX_PHY_CTRL_RST_ANALOG | ALX_PHY_CTRL_HIB_PULSE | | ||
| 887 | ALX_PHY_CTRL_HIB_EN; | ||
| 888 | |||
| 889 | /* without any activity */ | ||
| 890 | if (!(hw->sleep_ctrl & ALX_SLEEP_ACTIVE)) { | ||
| 891 | err = alx_write_phy_reg(hw, ALX_MII_IER, 0); | ||
| 892 | if (err) | ||
| 893 | return err; | ||
| 894 | phy |= ALX_PHY_CTRL_IDDQ | ALX_PHY_CTRL_POWER_DOWN; | ||
| 895 | } else { | ||
| 896 | if (hw->sleep_ctrl & (ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_CIFS)) | ||
| 897 | mac |= ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_BRD_EN; | ||
| 898 | if (hw->sleep_ctrl & ALX_SLEEP_CIFS) | ||
| 899 | mac |= ALX_MAC_CTRL_TX_EN; | ||
| 900 | if (speed % 10 == DUPLEX_FULL) | ||
| 901 | mac |= ALX_MAC_CTRL_FULLD; | ||
| 902 | if (speed >= SPEED_1000) | ||
| 903 | ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, | ||
| 904 | ALX_MAC_CTRL_SPEED_1000); | ||
| 905 | phy |= ALX_PHY_CTRL_DSPRST_OUT; | ||
| 906 | err = alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, | ||
| 907 | ALX_MIIEXT_S3DIG10, | ||
| 908 | ALX_MIIEXT_S3DIG10_SL); | ||
| 909 | if (err) | ||
| 910 | return err; | ||
| 911 | } | ||
| 912 | |||
| 913 | alx_enable_osc(hw); | ||
| 914 | hw->rx_ctrl = mac; | ||
| 915 | alx_write_mem32(hw, ALX_MASTER, master); | ||
| 916 | alx_write_mem32(hw, ALX_MAC_CTRL, mac); | ||
| 917 | alx_write_mem32(hw, ALX_PHY_CTRL, phy); | ||
| 918 | |||
| 919 | /* set val of PDLL D3PLLOFF */ | ||
| 920 | val = alx_read_mem32(hw, ALX_PDLL_TRNS1); | ||
| 921 | val |= ALX_PDLL_TRNS1_D3PLLOFF_EN; | ||
| 922 | alx_write_mem32(hw, ALX_PDLL_TRNS1, val); | ||
| 923 | |||
| 924 | return 0; | ||
| 925 | } | ||
| 926 | |||
| 927 | bool alx_phy_configured(struct alx_hw *hw) | ||
| 928 | { | ||
| 929 | u32 cfg, hw_cfg; | ||
| 930 | |||
| 931 | cfg = ethadv_to_hw_cfg(hw, hw->adv_cfg); | ||
| 932 | cfg = ALX_GET_FIELD(cfg, ALX_DRV_PHY); | ||
| 933 | hw_cfg = alx_get_phy_config(hw); | ||
| 934 | |||
| 935 | if (hw_cfg == ALX_DRV_PHY_UNKNOWN) | ||
| 936 | return false; | ||
| 937 | |||
| 938 | return cfg == hw_cfg; | ||
| 939 | } | ||
| 940 | |||
| 941 | int alx_get_phy_link(struct alx_hw *hw, int *speed) | ||
| 942 | { | ||
| 943 | struct pci_dev *pdev = hw->pdev; | ||
| 944 | u16 bmsr, giga; | ||
| 945 | int err; | ||
| 946 | |||
| 947 | err = alx_read_phy_reg(hw, MII_BMSR, &bmsr); | ||
| 948 | if (err) | ||
| 949 | return err; | ||
| 950 | |||
| 951 | err = alx_read_phy_reg(hw, MII_BMSR, &bmsr); | ||
| 952 | if (err) | ||
| 953 | return err; | ||
| 954 | |||
| 955 | if (!(bmsr & BMSR_LSTATUS)) { | ||
| 956 | *speed = SPEED_UNKNOWN; | ||
| 957 | return 0; | ||
| 958 | } | ||
| 959 | |||
| 960 | /* speed/duplex result is saved in PHY Specific Status Register */ | ||
| 961 | err = alx_read_phy_reg(hw, ALX_MII_GIGA_PSSR, &giga); | ||
| 962 | if (err) | ||
| 963 | return err; | ||
| 964 | |||
| 965 | if (!(giga & ALX_GIGA_PSSR_SPD_DPLX_RESOLVED)) | ||
| 966 | goto wrong_speed; | ||
| 967 | |||
| 968 | switch (giga & ALX_GIGA_PSSR_SPEED) { | ||
| 969 | case ALX_GIGA_PSSR_1000MBS: | ||
| 970 | *speed = SPEED_1000; | ||
| 971 | break; | ||
| 972 | case ALX_GIGA_PSSR_100MBS: | ||
| 973 | *speed = SPEED_100; | ||
| 974 | break; | ||
| 975 | case ALX_GIGA_PSSR_10MBS: | ||
| 976 | *speed = SPEED_10; | ||
| 977 | break; | ||
| 978 | default: | ||
| 979 | goto wrong_speed; | ||
| 980 | } | ||
| 981 | |||
| 982 | *speed += (giga & ALX_GIGA_PSSR_DPLX) ? DUPLEX_FULL : DUPLEX_HALF; | ||
| 983 | return 1; | ||
| 984 | |||
| 985 | wrong_speed: | ||
| 986 | dev_err(&pdev->dev, "invalid PHY speed/duplex: 0x%x\n", giga); | ||
| 987 | return -EINVAL; | ||
| 988 | } | ||
| 989 | |||
| 990 | int alx_clear_phy_intr(struct alx_hw *hw) | ||
| 991 | { | ||
| 992 | u16 isr; | ||
| 993 | |||
| 994 | /* clear interrupt status by reading it */ | ||
| 995 | return alx_read_phy_reg(hw, ALX_MII_ISR, &isr); | ||
| 996 | } | ||
| 997 | |||
| 998 | int alx_config_wol(struct alx_hw *hw) | ||
| 999 | { | ||
| 1000 | u32 wol = 0; | ||
| 1001 | int err = 0; | ||
| 1002 | |||
| 1003 | /* turn on magic packet event */ | ||
| 1004 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC) | ||
| 1005 | wol |= ALX_WOL0_MAGIC_EN | ALX_WOL0_PME_MAGIC_EN; | ||
| 1006 | |||
| 1007 | /* turn on link up event */ | ||
| 1008 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) { | ||
| 1009 | wol |= ALX_WOL0_LINK_EN | ALX_WOL0_PME_LINK; | ||
| 1010 | /* only link up can wake up */ | ||
| 1011 | err = alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP); | ||
| 1012 | } | ||
| 1013 | alx_write_mem32(hw, ALX_WOL0, wol); | ||
| 1014 | |||
| 1015 | return err; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | void alx_disable_rss(struct alx_hw *hw) | ||
| 1019 | { | ||
| 1020 | u32 ctrl = alx_read_mem32(hw, ALX_RXQ0); | ||
| 1021 | |||
| 1022 | ctrl &= ~ALX_RXQ0_RSS_HASH_EN; | ||
| 1023 | alx_write_mem32(hw, ALX_RXQ0, ctrl); | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | void alx_configure_basic(struct alx_hw *hw) | ||
| 1027 | { | ||
| 1028 | u32 val, raw_mtu, max_payload; | ||
| 1029 | u16 val16; | ||
| 1030 | u8 chip_rev = alx_hw_revision(hw); | ||
| 1031 | |||
| 1032 | alx_set_macaddr(hw, hw->mac_addr); | ||
| 1033 | |||
| 1034 | alx_write_mem32(hw, ALX_CLK_GATE, ALX_CLK_GATE_ALL); | ||
| 1035 | |||
| 1036 | /* idle timeout to switch clk_125M */ | ||
| 1037 | if (chip_rev >= ALX_REV_B0) | ||
| 1038 | alx_write_mem32(hw, ALX_IDLE_DECISN_TIMER, | ||
| 1039 | ALX_IDLE_DECISN_TIMER_DEF); | ||
| 1040 | |||
| 1041 | alx_write_mem32(hw, ALX_SMB_TIMER, hw->smb_timer * 500UL); | ||
| 1042 | |||
| 1043 | val = alx_read_mem32(hw, ALX_MASTER); | ||
| 1044 | val |= ALX_MASTER_IRQMOD2_EN | | ||
| 1045 | ALX_MASTER_IRQMOD1_EN | | ||
| 1046 | ALX_MASTER_SYSALVTIMER_EN; | ||
| 1047 | alx_write_mem32(hw, ALX_MASTER, val); | ||
| 1048 | alx_write_mem32(hw, ALX_IRQ_MODU_TIMER, | ||
| 1049 | (hw->imt >> 1) << ALX_IRQ_MODU_TIMER1_SHIFT); | ||
| 1050 | /* intr re-trig timeout */ | ||
| 1051 | alx_write_mem32(hw, ALX_INT_RETRIG, ALX_INT_RETRIG_TO); | ||
| 1052 | /* tpd threshold to trig int */ | ||
| 1053 | alx_write_mem32(hw, ALX_TINT_TPD_THRSHLD, hw->ith_tpd); | ||
| 1054 | alx_write_mem32(hw, ALX_TINT_TIMER, hw->imt); | ||
| 1055 | |||
| 1056 | raw_mtu = hw->mtu + ETH_HLEN; | ||
| 1057 | alx_write_mem32(hw, ALX_MTU, raw_mtu + 8); | ||
| 1058 | if (raw_mtu > ALX_MTU_JUMBO_TH) | ||
| 1059 | hw->rx_ctrl &= ~ALX_MAC_CTRL_FAST_PAUSE; | ||
| 1060 | |||
| 1061 | if ((raw_mtu + 8) < ALX_TXQ1_JUMBO_TSO_TH) | ||
| 1062 | val = (raw_mtu + 8 + 7) >> 3; | ||
| 1063 | else | ||
| 1064 | val = ALX_TXQ1_JUMBO_TSO_TH >> 3; | ||
| 1065 | alx_write_mem32(hw, ALX_TXQ1, val | ALX_TXQ1_ERRLGPKT_DROP_EN); | ||
| 1066 | |||
| 1067 | max_payload = pcie_get_readrq(hw->pdev) >> 8; | ||
| 1068 | /* | ||
| 1069 | * if BIOS had changed the default dma read max length, | ||
| 1070 | * restore it to default value | ||
| 1071 | */ | ||
| 1072 | if (max_payload < ALX_DEV_CTRL_MAXRRS_MIN) | ||
| 1073 | pcie_set_readrq(hw->pdev, 128 << ALX_DEV_CTRL_MAXRRS_MIN); | ||
| 1074 | |||
| 1075 | val = ALX_TXQ_TPD_BURSTPREF_DEF << ALX_TXQ0_TPD_BURSTPREF_SHIFT | | ||
| 1076 | ALX_TXQ0_MODE_ENHANCE | ALX_TXQ0_LSO_8023_EN | | ||
| 1077 | ALX_TXQ0_SUPT_IPOPT | | ||
| 1078 | ALX_TXQ_TXF_BURST_PREF_DEF << ALX_TXQ0_TXF_BURST_PREF_SHIFT; | ||
| 1079 | alx_write_mem32(hw, ALX_TXQ0, val); | ||
| 1080 | val = ALX_TXQ_TPD_BURSTPREF_DEF << ALX_HQTPD_Q1_NUMPREF_SHIFT | | ||
| 1081 | ALX_TXQ_TPD_BURSTPREF_DEF << ALX_HQTPD_Q2_NUMPREF_SHIFT | | ||
| 1082 | ALX_TXQ_TPD_BURSTPREF_DEF << ALX_HQTPD_Q3_NUMPREF_SHIFT | | ||
| 1083 | ALX_HQTPD_BURST_EN; | ||
| 1084 | alx_write_mem32(hw, ALX_HQTPD, val); | ||
| 1085 | |||
| 1086 | /* rxq, flow control */ | ||
| 1087 | val = alx_read_mem32(hw, ALX_SRAM5); | ||
| 1088 | val = ALX_GET_FIELD(val, ALX_SRAM_RXF_LEN) << 3; | ||
| 1089 | if (val > ALX_SRAM_RXF_LEN_8K) { | ||
| 1090 | val16 = ALX_MTU_STD_ALGN >> 3; | ||
| 1091 | val = (val - ALX_RXQ2_RXF_FLOW_CTRL_RSVD) >> 3; | ||
| 1092 | } else { | ||
| 1093 | val16 = ALX_MTU_STD_ALGN >> 3; | ||
| 1094 | val = (val - ALX_MTU_STD_ALGN) >> 3; | ||
| 1095 | } | ||
| 1096 | alx_write_mem32(hw, ALX_RXQ2, | ||
| 1097 | val16 << ALX_RXQ2_RXF_XOFF_THRESH_SHIFT | | ||
| 1098 | val << ALX_RXQ2_RXF_XON_THRESH_SHIFT); | ||
| 1099 | val = ALX_RXQ0_NUM_RFD_PREF_DEF << ALX_RXQ0_NUM_RFD_PREF_SHIFT | | ||
| 1100 | ALX_RXQ0_RSS_MODE_DIS << ALX_RXQ0_RSS_MODE_SHIFT | | ||
| 1101 | ALX_RXQ0_IDT_TBL_SIZE_DEF << ALX_RXQ0_IDT_TBL_SIZE_SHIFT | | ||
| 1102 | ALX_RXQ0_RSS_HSTYP_ALL | ALX_RXQ0_RSS_HASH_EN | | ||
| 1103 | ALX_RXQ0_IPV6_PARSE_EN; | ||
| 1104 | |||
| 1105 | if (alx_hw_giga(hw)) | ||
| 1106 | ALX_SET_FIELD(val, ALX_RXQ0_ASPM_THRESH, | ||
| 1107 | ALX_RXQ0_ASPM_THRESH_100M); | ||
| 1108 | |||
| 1109 | alx_write_mem32(hw, ALX_RXQ0, val); | ||
| 1110 | |||
| 1111 | val = alx_read_mem32(hw, ALX_DMA); | ||
| 1112 | val = ALX_DMA_RORDER_MODE_OUT << ALX_DMA_RORDER_MODE_SHIFT | | ||
| 1113 | ALX_DMA_RREQ_PRI_DATA | | ||
| 1114 | max_payload << ALX_DMA_RREQ_BLEN_SHIFT | | ||
| 1115 | ALX_DMA_WDLY_CNT_DEF << ALX_DMA_WDLY_CNT_SHIFT | | ||
| 1116 | ALX_DMA_RDLY_CNT_DEF << ALX_DMA_RDLY_CNT_SHIFT | | ||
| 1117 | (hw->dma_chnl - 1) << ALX_DMA_RCHNL_SEL_SHIFT; | ||
| 1118 | alx_write_mem32(hw, ALX_DMA, val); | ||
| 1119 | |||
| 1120 | /* default multi-tx-q weights */ | ||
| 1121 | val = ALX_WRR_PRI_RESTRICT_NONE << ALX_WRR_PRI_SHIFT | | ||
| 1122 | 4 << ALX_WRR_PRI0_SHIFT | | ||
| 1123 | 4 << ALX_WRR_PRI1_SHIFT | | ||
| 1124 | 4 << ALX_WRR_PRI2_SHIFT | | ||
| 1125 | 4 << ALX_WRR_PRI3_SHIFT; | ||
| 1126 | alx_write_mem32(hw, ALX_WRR, val); | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | static inline u32 alx_speed_to_ethadv(int speed) | ||
| 1130 | { | ||
| 1131 | switch (speed) { | ||
| 1132 | case SPEED_1000 + DUPLEX_FULL: | ||
| 1133 | return ADVERTISED_1000baseT_Full; | ||
| 1134 | case SPEED_100 + DUPLEX_FULL: | ||
| 1135 | return ADVERTISED_100baseT_Full; | ||
| 1136 | case SPEED_100 + DUPLEX_HALF: | ||
| 1137 | return ADVERTISED_10baseT_Half; | ||
| 1138 | case SPEED_10 + DUPLEX_FULL: | ||
| 1139 | return ADVERTISED_10baseT_Full; | ||
| 1140 | case SPEED_10 + DUPLEX_HALF: | ||
| 1141 | return ADVERTISED_10baseT_Half; | ||
| 1142 | default: | ||
| 1143 | return 0; | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | int alx_select_powersaving_speed(struct alx_hw *hw, int *speed) | ||
| 1148 | { | ||
| 1149 | int i, err, spd; | ||
| 1150 | u16 lpa; | ||
| 1151 | |||
| 1152 | err = alx_get_phy_link(hw, &spd); | ||
| 1153 | if (err < 0) | ||
| 1154 | return err; | ||
| 1155 | |||
| 1156 | if (spd == SPEED_UNKNOWN) | ||
| 1157 | return 0; | ||
| 1158 | |||
| 1159 | err = alx_read_phy_reg(hw, MII_LPA, &lpa); | ||
| 1160 | if (err) | ||
| 1161 | return err; | ||
| 1162 | |||
| 1163 | if (!(lpa & LPA_LPACK)) { | ||
| 1164 | *speed = spd; | ||
| 1165 | return 0; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | if (lpa & LPA_10FULL) | ||
| 1169 | *speed = SPEED_10 + DUPLEX_FULL; | ||
| 1170 | else if (lpa & LPA_10HALF) | ||
| 1171 | *speed = SPEED_10 + DUPLEX_HALF; | ||
| 1172 | else if (lpa & LPA_100FULL) | ||
| 1173 | *speed = SPEED_100 + DUPLEX_FULL; | ||
| 1174 | else | ||
| 1175 | *speed = SPEED_100 + DUPLEX_HALF; | ||
| 1176 | |||
| 1177 | if (*speed != spd) { | ||
| 1178 | err = alx_write_phy_reg(hw, ALX_MII_IER, 0); | ||
| 1179 | if (err) | ||
| 1180 | return err; | ||
| 1181 | err = alx_setup_speed_duplex(hw, | ||
| 1182 | alx_speed_to_ethadv(*speed) | | ||
| 1183 | ADVERTISED_Autoneg, | ||
| 1184 | ALX_FC_ANEG | ALX_FC_RX | | ||
| 1185 | ALX_FC_TX); | ||
| 1186 | if (err) | ||
| 1187 | return err; | ||
| 1188 | |||
| 1189 | /* wait for linkup */ | ||
| 1190 | for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { | ||
| 1191 | int speed2; | ||
| 1192 | |||
| 1193 | msleep(100); | ||
| 1194 | |||
| 1195 | err = alx_get_phy_link(hw, &speed2); | ||
| 1196 | if (err < 0) | ||
| 1197 | return err; | ||
| 1198 | if (speed2 != SPEED_UNKNOWN) | ||
| 1199 | break; | ||
| 1200 | } | ||
| 1201 | if (i == ALX_MAX_SETUP_LNK_CYCLE) | ||
| 1202 | return -ETIMEDOUT; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | return 0; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | bool alx_get_phy_info(struct alx_hw *hw) | ||
| 1209 | { | ||
| 1210 | u16 devs1, devs2; | ||
| 1211 | |||
| 1212 | if (alx_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id[0]) || | ||
| 1213 | alx_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id[1])) | ||
| 1214 | return false; | ||
| 1215 | |||
| 1216 | /* since we haven't PMA/PMD status2 register, we can't | ||
| 1217 | * use mdio45_probe function for prtad and mmds. | ||
| 1218 | * use fixed MMD3 to get mmds. | ||
| 1219 | */ | ||
| 1220 | if (alx_read_phy_ext(hw, 3, MDIO_DEVS1, &devs1) || | ||
| 1221 | alx_read_phy_ext(hw, 3, MDIO_DEVS2, &devs2)) | ||
| 1222 | return false; | ||
| 1223 | hw->mdio.mmds = devs1 | devs2 << 16; | ||
| 1224 | |||
| 1225 | return true; | ||
| 1226 | } | ||
diff --git a/drivers/net/ethernet/atheros/alx/hw.h b/drivers/net/ethernet/atheros/alx/hw.h new file mode 100644 index 000000000000..65e723d2172a --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/hw.h | |||
| @@ -0,0 +1,499 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> | ||
| 3 | * | ||
| 4 | * This file is free software: you may copy, redistribute and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation, either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This file is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | * | ||
| 17 | * This file incorporates work covered by the following copyright and | ||
| 18 | * permission notice: | ||
| 19 | * | ||
| 20 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
| 21 | * | ||
| 22 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 23 | * purpose with or without fee is hereby granted, provided that the above | ||
| 24 | * copyright notice and this permission notice appear in all copies. | ||
| 25 | * | ||
| 26 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 27 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 29 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 30 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 31 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 32 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #ifndef ALX_HW_H_ | ||
| 36 | #define ALX_HW_H_ | ||
| 37 | #include <linux/types.h> | ||
| 38 | #include <linux/mdio.h> | ||
| 39 | #include <linux/pci.h> | ||
| 40 | #include "reg.h" | ||
| 41 | |||
| 42 | /* Transmit Packet Descriptor, contains 4 32-bit words. | ||
| 43 | * | ||
| 44 | * 31 16 0 | ||
| 45 | * +----------------+----------------+ | ||
| 46 | * | vlan-tag | buf length | | ||
| 47 | * +----------------+----------------+ | ||
| 48 | * | Word 1 | | ||
| 49 | * +----------------+----------------+ | ||
| 50 | * | Word 2: buf addr lo | | ||
| 51 | * +----------------+----------------+ | ||
| 52 | * | Word 3: buf addr hi | | ||
| 53 | * +----------------+----------------+ | ||
| 54 | * | ||
| 55 | * Word 2 and 3 combine to form a 64-bit buffer address | ||
| 56 | * | ||
| 57 | * Word 1 has three forms, depending on the state of bit 8/12/13: | ||
| 58 | * if bit8 =='1', the definition is just for custom checksum offload. | ||
| 59 | * if bit8 == '0' && bit12 == '1' && bit13 == '1', the *FIRST* descriptor | ||
| 60 | * for the skb is special for LSO V2, Word 2 become total skb length , | ||
| 61 | * Word 3 is meaningless. | ||
| 62 | * other condition, the definition is for general skb or ip/tcp/udp | ||
| 63 | * checksum or LSO(TSO) offload. | ||
| 64 | * | ||
| 65 | * Here is the depiction: | ||
| 66 | * | ||
| 67 | * 0-+ 0-+ | ||
| 68 | * 1 | 1 | | ||
| 69 | * 2 | 2 | | ||
| 70 | * 3 | Payload offset 3 | L4 header offset | ||
| 71 | * 4 | (7:0) 4 | (7:0) | ||
| 72 | * 5 | 5 | | ||
| 73 | * 6 | 6 | | ||
| 74 | * 7-+ 7-+ | ||
| 75 | * 8 Custom csum enable = 1 8 Custom csum enable = 0 | ||
| 76 | * 9 General IPv4 checksum 9 General IPv4 checksum | ||
| 77 | * 10 General TCP checksum 10 General TCP checksum | ||
| 78 | * 11 General UDP checksum 11 General UDP checksum | ||
| 79 | * 12 Large Send Segment enable 12 Large Send Segment enable | ||
| 80 | * 13 Large Send Segment type 13 Large Send Segment type | ||
| 81 | * 14 VLAN tagged 14 VLAN tagged | ||
| 82 | * 15 Insert VLAN tag 15 Insert VLAN tag | ||
| 83 | * 16 IPv4 packet 16 IPv4 packet | ||
| 84 | * 17 Ethernet frame type 17 Ethernet frame type | ||
| 85 | * 18-+ 18-+ | ||
| 86 | * 19 | 19 | | ||
| 87 | * 20 | 20 | | ||
| 88 | * 21 | Custom csum offset 21 | | ||
| 89 | * 22 | (25:18) 22 | | ||
| 90 | * 23 | 23 | MSS (30:18) | ||
| 91 | * 24 | 24 | | ||
| 92 | * 25-+ 25 | | ||
| 93 | * 26-+ 26 | | ||
| 94 | * 27 | 27 | | ||
| 95 | * 28 | Reserved 28 | | ||
| 96 | * 29 | 29 | | ||
| 97 | * 30-+ 30-+ | ||
| 98 | * 31 End of packet 31 End of packet | ||
| 99 | */ | ||
| 100 | struct alx_txd { | ||
| 101 | __le16 len; | ||
| 102 | __le16 vlan_tag; | ||
| 103 | __le32 word1; | ||
| 104 | union { | ||
| 105 | __le64 addr; | ||
| 106 | struct { | ||
| 107 | __le32 pkt_len; | ||
| 108 | __le32 resvd; | ||
| 109 | } l; | ||
| 110 | } adrl; | ||
| 111 | } __packed; | ||
| 112 | |||
| 113 | /* tpd word 1 */ | ||
| 114 | #define TPD_CXSUMSTART_MASK 0x00FF | ||
| 115 | #define TPD_CXSUMSTART_SHIFT 0 | ||
| 116 | #define TPD_L4HDROFFSET_MASK 0x00FF | ||
| 117 | #define TPD_L4HDROFFSET_SHIFT 0 | ||
| 118 | #define TPD_CXSUM_EN_MASK 0x0001 | ||
| 119 | #define TPD_CXSUM_EN_SHIFT 8 | ||
| 120 | #define TPD_IP_XSUM_MASK 0x0001 | ||
| 121 | #define TPD_IP_XSUM_SHIFT 9 | ||
| 122 | #define TPD_TCP_XSUM_MASK 0x0001 | ||
| 123 | #define TPD_TCP_XSUM_SHIFT 10 | ||
| 124 | #define TPD_UDP_XSUM_MASK 0x0001 | ||
| 125 | #define TPD_UDP_XSUM_SHIFT 11 | ||
| 126 | #define TPD_LSO_EN_MASK 0x0001 | ||
| 127 | #define TPD_LSO_EN_SHIFT 12 | ||
| 128 | #define TPD_LSO_V2_MASK 0x0001 | ||
| 129 | #define TPD_LSO_V2_SHIFT 13 | ||
| 130 | #define TPD_VLTAGGED_MASK 0x0001 | ||
| 131 | #define TPD_VLTAGGED_SHIFT 14 | ||
| 132 | #define TPD_INS_VLTAG_MASK 0x0001 | ||
| 133 | #define TPD_INS_VLTAG_SHIFT 15 | ||
| 134 | #define TPD_IPV4_MASK 0x0001 | ||
| 135 | #define TPD_IPV4_SHIFT 16 | ||
| 136 | #define TPD_ETHTYPE_MASK 0x0001 | ||
| 137 | #define TPD_ETHTYPE_SHIFT 17 | ||
| 138 | #define TPD_CXSUMOFFSET_MASK 0x00FF | ||
| 139 | #define TPD_CXSUMOFFSET_SHIFT 18 | ||
| 140 | #define TPD_MSS_MASK 0x1FFF | ||
| 141 | #define TPD_MSS_SHIFT 18 | ||
| 142 | #define TPD_EOP_MASK 0x0001 | ||
| 143 | #define TPD_EOP_SHIFT 31 | ||
| 144 | |||
| 145 | #define DESC_GET(_x, _name) ((_x) >> _name##SHIFT & _name##MASK) | ||
| 146 | |||
| 147 | /* Receive Free Descriptor */ | ||
| 148 | struct alx_rfd { | ||
| 149 | __le64 addr; /* data buffer address, length is | ||
| 150 | * declared in register --- every | ||
| 151 | * buffer has the same size | ||
| 152 | */ | ||
| 153 | } __packed; | ||
| 154 | |||
| 155 | /* Receive Return Descriptor, contains 4 32-bit words. | ||
| 156 | * | ||
| 157 | * 31 16 0 | ||
| 158 | * +----------------+----------------+ | ||
| 159 | * | Word 0 | | ||
| 160 | * +----------------+----------------+ | ||
| 161 | * | Word 1: RSS Hash value | | ||
| 162 | * +----------------+----------------+ | ||
| 163 | * | Word 2 | | ||
| 164 | * +----------------+----------------+ | ||
| 165 | * | Word 3 | | ||
| 166 | * +----------------+----------------+ | ||
| 167 | * | ||
| 168 | * Word 0 depiction & Word 2 depiction: | ||
| 169 | * | ||
| 170 | * 0--+ 0--+ | ||
| 171 | * 1 | 1 | | ||
| 172 | * 2 | 2 | | ||
| 173 | * 3 | 3 | | ||
| 174 | * 4 | 4 | | ||
| 175 | * 5 | 5 | | ||
| 176 | * 6 | 6 | | ||
| 177 | * 7 | IP payload checksum 7 | VLAN tag | ||
| 178 | * 8 | (15:0) 8 | (15:0) | ||
| 179 | * 9 | 9 | | ||
| 180 | * 10 | 10 | | ||
| 181 | * 11 | 11 | | ||
| 182 | * 12 | 12 | | ||
| 183 | * 13 | 13 | | ||
| 184 | * 14 | 14 | | ||
| 185 | * 15-+ 15-+ | ||
| 186 | * 16-+ 16-+ | ||
| 187 | * 17 | Number of RFDs 17 | | ||
| 188 | * 18 | (19:16) 18 | | ||
| 189 | * 19-+ 19 | Protocol ID | ||
| 190 | * 20-+ 20 | (23:16) | ||
| 191 | * 21 | 21 | | ||
| 192 | * 22 | 22 | | ||
| 193 | * 23 | 23-+ | ||
| 194 | * 24 | 24 | Reserved | ||
| 195 | * 25 | Start index of RFD-ring 25-+ | ||
| 196 | * 26 | (31:20) 26 | RSS Q-num (27:25) | ||
| 197 | * 27 | 27-+ | ||
| 198 | * 28 | 28-+ | ||
| 199 | * 29 | 29 | RSS Hash algorithm | ||
| 200 | * 30 | 30 | (31:28) | ||
| 201 | * 31-+ 31-+ | ||
| 202 | * | ||
| 203 | * Word 3 depiction: | ||
| 204 | * | ||
| 205 | * 0--+ | ||
| 206 | * 1 | | ||
| 207 | * 2 | | ||
| 208 | * 3 | | ||
| 209 | * 4 | | ||
| 210 | * 5 | | ||
| 211 | * 6 | | ||
| 212 | * 7 | Packet length (include FCS) | ||
| 213 | * 8 | (13:0) | ||
| 214 | * 9 | | ||
| 215 | * 10 | | ||
| 216 | * 11 | | ||
| 217 | * 12 | | ||
| 218 | * 13-+ | ||
| 219 | * 14 L4 Header checksum error | ||
| 220 | * 15 IPv4 checksum error | ||
| 221 | * 16 VLAN tagged | ||
| 222 | * 17-+ | ||
| 223 | * 18 | Protocol ID (19:17) | ||
| 224 | * 19-+ | ||
| 225 | * 20 Receive error summary | ||
| 226 | * 21 FCS(CRC) error | ||
| 227 | * 22 Frame alignment error | ||
| 228 | * 23 Truncated packet | ||
| 229 | * 24 Runt packet | ||
| 230 | * 25 Incomplete packet due to insufficient rx-desc | ||
| 231 | * 26 Broadcast packet | ||
| 232 | * 27 Multicast packet | ||
| 233 | * 28 Ethernet type (EII or 802.3) | ||
| 234 | * 29 FIFO overflow | ||
| 235 | * 30 Length error (for 802.3, length field mismatch with actual len) | ||
| 236 | * 31 Updated, indicate to driver that this RRD is refreshed. | ||
| 237 | */ | ||
| 238 | struct alx_rrd { | ||
| 239 | __le32 word0; | ||
| 240 | __le32 rss_hash; | ||
| 241 | __le32 word2; | ||
| 242 | __le32 word3; | ||
| 243 | } __packed; | ||
| 244 | |||
| 245 | /* rrd word 0 */ | ||
| 246 | #define RRD_XSUM_MASK 0xFFFF | ||
| 247 | #define RRD_XSUM_SHIFT 0 | ||
| 248 | #define RRD_NOR_MASK 0x000F | ||
| 249 | #define RRD_NOR_SHIFT 16 | ||
| 250 | #define RRD_SI_MASK 0x0FFF | ||
| 251 | #define RRD_SI_SHIFT 20 | ||
| 252 | |||
| 253 | /* rrd word 2 */ | ||
| 254 | #define RRD_VLTAG_MASK 0xFFFF | ||
| 255 | #define RRD_VLTAG_SHIFT 0 | ||
| 256 | #define RRD_PID_MASK 0x00FF | ||
| 257 | #define RRD_PID_SHIFT 16 | ||
| 258 | /* non-ip packet */ | ||
| 259 | #define RRD_PID_NONIP 0 | ||
| 260 | /* ipv4(only) */ | ||
| 261 | #define RRD_PID_IPV4 1 | ||
| 262 | /* tcp/ipv6 */ | ||
| 263 | #define RRD_PID_IPV6TCP 2 | ||
| 264 | /* tcp/ipv4 */ | ||
| 265 | #define RRD_PID_IPV4TCP 3 | ||
| 266 | /* udp/ipv6 */ | ||
| 267 | #define RRD_PID_IPV6UDP 4 | ||
| 268 | /* udp/ipv4 */ | ||
| 269 | #define RRD_PID_IPV4UDP 5 | ||
| 270 | /* ipv6(only) */ | ||
| 271 | #define RRD_PID_IPV6 6 | ||
| 272 | /* LLDP packet */ | ||
| 273 | #define RRD_PID_LLDP 7 | ||
| 274 | /* 1588 packet */ | ||
| 275 | #define RRD_PID_1588 8 | ||
| 276 | #define RRD_RSSQ_MASK 0x0007 | ||
| 277 | #define RRD_RSSQ_SHIFT 25 | ||
| 278 | #define RRD_RSSALG_MASK 0x000F | ||
| 279 | #define RRD_RSSALG_SHIFT 28 | ||
| 280 | #define RRD_RSSALG_TCPV6 0x1 | ||
| 281 | #define RRD_RSSALG_IPV6 0x2 | ||
| 282 | #define RRD_RSSALG_TCPV4 0x4 | ||
| 283 | #define RRD_RSSALG_IPV4 0x8 | ||
| 284 | |||
| 285 | /* rrd word 3 */ | ||
| 286 | #define RRD_PKTLEN_MASK 0x3FFF | ||
| 287 | #define RRD_PKTLEN_SHIFT 0 | ||
| 288 | #define RRD_ERR_L4_MASK 0x0001 | ||
| 289 | #define RRD_ERR_L4_SHIFT 14 | ||
| 290 | #define RRD_ERR_IPV4_MASK 0x0001 | ||
| 291 | #define RRD_ERR_IPV4_SHIFT 15 | ||
| 292 | #define RRD_VLTAGGED_MASK 0x0001 | ||
| 293 | #define RRD_VLTAGGED_SHIFT 16 | ||
| 294 | #define RRD_OLD_PID_MASK 0x0007 | ||
| 295 | #define RRD_OLD_PID_SHIFT 17 | ||
| 296 | #define RRD_ERR_RES_MASK 0x0001 | ||
| 297 | #define RRD_ERR_RES_SHIFT 20 | ||
| 298 | #define RRD_ERR_FCS_MASK 0x0001 | ||
| 299 | #define RRD_ERR_FCS_SHIFT 21 | ||
| 300 | #define RRD_ERR_FAE_MASK 0x0001 | ||
| 301 | #define RRD_ERR_FAE_SHIFT 22 | ||
| 302 | #define RRD_ERR_TRUNC_MASK 0x0001 | ||
| 303 | #define RRD_ERR_TRUNC_SHIFT 23 | ||
| 304 | #define RRD_ERR_RUNT_MASK 0x0001 | ||
| 305 | #define RRD_ERR_RUNT_SHIFT 24 | ||
| 306 | #define RRD_ERR_ICMP_MASK 0x0001 | ||
| 307 | #define RRD_ERR_ICMP_SHIFT 25 | ||
| 308 | #define RRD_BCAST_MASK 0x0001 | ||
| 309 | #define RRD_BCAST_SHIFT 26 | ||
| 310 | #define RRD_MCAST_MASK 0x0001 | ||
| 311 | #define RRD_MCAST_SHIFT 27 | ||
| 312 | #define RRD_ETHTYPE_MASK 0x0001 | ||
| 313 | #define RRD_ETHTYPE_SHIFT 28 | ||
| 314 | #define RRD_ERR_FIFOV_MASK 0x0001 | ||
| 315 | #define RRD_ERR_FIFOV_SHIFT 29 | ||
| 316 | #define RRD_ERR_LEN_MASK 0x0001 | ||
| 317 | #define RRD_ERR_LEN_SHIFT 30 | ||
| 318 | #define RRD_UPDATED_MASK 0x0001 | ||
| 319 | #define RRD_UPDATED_SHIFT 31 | ||
| 320 | |||
| 321 | |||
| 322 | #define ALX_MAX_SETUP_LNK_CYCLE 50 | ||
| 323 | |||
| 324 | /* for FlowControl */ | ||
| 325 | #define ALX_FC_RX 0x01 | ||
| 326 | #define ALX_FC_TX 0x02 | ||
| 327 | #define ALX_FC_ANEG 0x04 | ||
| 328 | |||
| 329 | /* for sleep control */ | ||
| 330 | #define ALX_SLEEP_WOL_PHY 0x00000001 | ||
| 331 | #define ALX_SLEEP_WOL_MAGIC 0x00000002 | ||
| 332 | #define ALX_SLEEP_CIFS 0x00000004 | ||
| 333 | #define ALX_SLEEP_ACTIVE (ALX_SLEEP_WOL_PHY | \ | ||
| 334 | ALX_SLEEP_WOL_MAGIC | \ | ||
| 335 | ALX_SLEEP_CIFS) | ||
| 336 | |||
| 337 | /* for RSS hash type */ | ||
| 338 | #define ALX_RSS_HASH_TYPE_IPV4 0x1 | ||
| 339 | #define ALX_RSS_HASH_TYPE_IPV4_TCP 0x2 | ||
| 340 | #define ALX_RSS_HASH_TYPE_IPV6 0x4 | ||
| 341 | #define ALX_RSS_HASH_TYPE_IPV6_TCP 0x8 | ||
| 342 | #define ALX_RSS_HASH_TYPE_ALL (ALX_RSS_HASH_TYPE_IPV4 | \ | ||
| 343 | ALX_RSS_HASH_TYPE_IPV4_TCP | \ | ||
| 344 | ALX_RSS_HASH_TYPE_IPV6 | \ | ||
| 345 | ALX_RSS_HASH_TYPE_IPV6_TCP) | ||
| 346 | #define ALX_DEF_RXBUF_SIZE 1536 | ||
| 347 | #define ALX_MAX_JUMBO_PKT_SIZE (9*1024) | ||
| 348 | #define ALX_MAX_TSO_PKT_SIZE (7*1024) | ||
| 349 | #define ALX_MAX_FRAME_SIZE ALX_MAX_JUMBO_PKT_SIZE | ||
| 350 | #define ALX_MIN_FRAME_SIZE 68 | ||
| 351 | #define ALX_RAW_MTU(_mtu) (_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN) | ||
| 352 | |||
| 353 | #define ALX_MAX_RX_QUEUES 8 | ||
| 354 | #define ALX_MAX_TX_QUEUES 4 | ||
| 355 | #define ALX_MAX_HANDLED_INTRS 5 | ||
| 356 | |||
| 357 | #define ALX_ISR_MISC (ALX_ISR_PCIE_LNKDOWN | \ | ||
| 358 | ALX_ISR_DMAW | \ | ||
| 359 | ALX_ISR_DMAR | \ | ||
| 360 | ALX_ISR_SMB | \ | ||
| 361 | ALX_ISR_MANU | \ | ||
| 362 | ALX_ISR_TIMER) | ||
| 363 | |||
| 364 | #define ALX_ISR_FATAL (ALX_ISR_PCIE_LNKDOWN | \ | ||
| 365 | ALX_ISR_DMAW | ALX_ISR_DMAR) | ||
| 366 | |||
| 367 | #define ALX_ISR_ALERT (ALX_ISR_RXF_OV | \ | ||
| 368 | ALX_ISR_TXF_UR | \ | ||
| 369 | ALX_ISR_RFD_UR) | ||
| 370 | |||
| 371 | #define ALX_ISR_ALL_QUEUES (ALX_ISR_TX_Q0 | \ | ||
| 372 | ALX_ISR_TX_Q1 | \ | ||
| 373 | ALX_ISR_TX_Q2 | \ | ||
| 374 | ALX_ISR_TX_Q3 | \ | ||
| 375 | ALX_ISR_RX_Q0 | \ | ||
| 376 | ALX_ISR_RX_Q1 | \ | ||
| 377 | ALX_ISR_RX_Q2 | \ | ||
| 378 | ALX_ISR_RX_Q3 | \ | ||
| 379 | ALX_ISR_RX_Q4 | \ | ||
| 380 | ALX_ISR_RX_Q5 | \ | ||
| 381 | ALX_ISR_RX_Q6 | \ | ||
| 382 | ALX_ISR_RX_Q7) | ||
| 383 | |||
| 384 | /* maximum interrupt vectors for msix */ | ||
| 385 | #define ALX_MAX_MSIX_INTRS 16 | ||
| 386 | |||
| 387 | #define ALX_GET_FIELD(_data, _field) \ | ||
| 388 | (((_data) >> _field ## _SHIFT) & _field ## _MASK) | ||
| 389 | |||
| 390 | #define ALX_SET_FIELD(_data, _field, _value) do { \ | ||
| 391 | (_data) &= ~(_field ## _MASK << _field ## _SHIFT); \ | ||
| 392 | (_data) |= ((_value) & _field ## _MASK) << _field ## _SHIFT;\ | ||
| 393 | } while (0) | ||
| 394 | |||
| 395 | struct alx_hw { | ||
| 396 | struct pci_dev *pdev; | ||
| 397 | u8 __iomem *hw_addr; | ||
| 398 | |||
| 399 | /* current & permanent mac addr */ | ||
| 400 | u8 mac_addr[ETH_ALEN]; | ||
| 401 | u8 perm_addr[ETH_ALEN]; | ||
| 402 | |||
| 403 | u16 mtu; | ||
| 404 | u16 imt; | ||
| 405 | u8 dma_chnl; | ||
| 406 | u8 max_dma_chnl; | ||
| 407 | /* tpd threshold to trig INT */ | ||
| 408 | u32 ith_tpd; | ||
| 409 | u32 rx_ctrl; | ||
| 410 | u32 mc_hash[2]; | ||
| 411 | |||
| 412 | u32 smb_timer; | ||
| 413 | /* SPEED_* + DUPLEX_*, SPEED_UNKNOWN if link is down */ | ||
| 414 | int link_speed; | ||
| 415 | |||
| 416 | /* auto-neg advertisement or force mode config */ | ||
| 417 | u32 adv_cfg; | ||
| 418 | u8 flowctrl; | ||
| 419 | |||
| 420 | u32 sleep_ctrl; | ||
| 421 | |||
| 422 | spinlock_t mdio_lock; | ||
| 423 | struct mdio_if_info mdio; | ||
| 424 | u16 phy_id[2]; | ||
| 425 | |||
| 426 | /* PHY link patch flag */ | ||
| 427 | bool lnk_patch; | ||
| 428 | }; | ||
| 429 | |||
| 430 | static inline int alx_hw_revision(struct alx_hw *hw) | ||
| 431 | { | ||
| 432 | return hw->pdev->revision >> ALX_PCI_REVID_SHIFT; | ||
| 433 | } | ||
| 434 | |||
| 435 | static inline bool alx_hw_with_cr(struct alx_hw *hw) | ||
| 436 | { | ||
| 437 | return hw->pdev->revision & 1; | ||
| 438 | } | ||
| 439 | |||
| 440 | static inline bool alx_hw_giga(struct alx_hw *hw) | ||
| 441 | { | ||
| 442 | return hw->pdev->device & 1; | ||
| 443 | } | ||
| 444 | |||
| 445 | static inline void alx_write_mem8(struct alx_hw *hw, u32 reg, u8 val) | ||
| 446 | { | ||
| 447 | writeb(val, hw->hw_addr + reg); | ||
| 448 | } | ||
| 449 | |||
| 450 | static inline void alx_write_mem16(struct alx_hw *hw, u32 reg, u16 val) | ||
| 451 | { | ||
| 452 | writew(val, hw->hw_addr + reg); | ||
| 453 | } | ||
| 454 | |||
| 455 | static inline u16 alx_read_mem16(struct alx_hw *hw, u32 reg) | ||
| 456 | { | ||
| 457 | return readw(hw->hw_addr + reg); | ||
| 458 | } | ||
| 459 | |||
| 460 | static inline void alx_write_mem32(struct alx_hw *hw, u32 reg, u32 val) | ||
| 461 | { | ||
| 462 | writel(val, hw->hw_addr + reg); | ||
| 463 | } | ||
| 464 | |||
| 465 | static inline u32 alx_read_mem32(struct alx_hw *hw, u32 reg) | ||
| 466 | { | ||
| 467 | return readl(hw->hw_addr + reg); | ||
| 468 | } | ||
| 469 | |||
| 470 | static inline void alx_post_write(struct alx_hw *hw) | ||
| 471 | { | ||
| 472 | readl(hw->hw_addr); | ||
| 473 | } | ||
| 474 | |||
| 475 | int alx_get_perm_macaddr(struct alx_hw *hw, u8 *addr); | ||
| 476 | void alx_reset_phy(struct alx_hw *hw); | ||
| 477 | void alx_reset_pcie(struct alx_hw *hw); | ||
| 478 | void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); | ||
| 479 | int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); | ||
| 480 | void alx_post_phy_link(struct alx_hw *hw); | ||
| 481 | int alx_pre_suspend(struct alx_hw *hw, int speed); | ||
| 482 | int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data); | ||
| 483 | int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data); | ||
| 484 | int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata); | ||
| 485 | int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data); | ||
| 486 | int alx_get_phy_link(struct alx_hw *hw, int *speed); | ||
| 487 | int alx_clear_phy_intr(struct alx_hw *hw); | ||
| 488 | int alx_config_wol(struct alx_hw *hw); | ||
| 489 | void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); | ||
| 490 | void alx_start_mac(struct alx_hw *hw); | ||
| 491 | int alx_reset_mac(struct alx_hw *hw); | ||
| 492 | void alx_set_macaddr(struct alx_hw *hw, const u8 *addr); | ||
| 493 | bool alx_phy_configured(struct alx_hw *hw); | ||
| 494 | void alx_configure_basic(struct alx_hw *hw); | ||
| 495 | void alx_disable_rss(struct alx_hw *hw); | ||
| 496 | int alx_select_powersaving_speed(struct alx_hw *hw, int *speed); | ||
| 497 | bool alx_get_phy_info(struct alx_hw *hw); | ||
| 498 | |||
| 499 | #endif | ||
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c new file mode 100644 index 000000000000..418de8b13165 --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
| @@ -0,0 +1,1625 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> | ||
| 3 | * | ||
| 4 | * This file is free software: you may copy, redistribute and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation, either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This file is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | * | ||
| 17 | * This file incorporates work covered by the following copyright and | ||
| 18 | * permission notice: | ||
| 19 | * | ||
| 20 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
| 21 | * | ||
| 22 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 23 | * purpose with or without fee is hereby granted, provided that the above | ||
| 24 | * copyright notice and this permission notice appear in all copies. | ||
| 25 | * | ||
| 26 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 27 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 29 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 30 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 31 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 32 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/module.h> | ||
| 36 | #include <linux/pci.h> | ||
| 37 | #include <linux/interrupt.h> | ||
| 38 | #include <linux/ip.h> | ||
| 39 | #include <linux/ipv6.h> | ||
| 40 | #include <linux/if_vlan.h> | ||
| 41 | #include <linux/mdio.h> | ||
| 42 | #include <linux/aer.h> | ||
| 43 | #include <linux/bitops.h> | ||
| 44 | #include <linux/netdevice.h> | ||
| 45 | #include <linux/etherdevice.h> | ||
| 46 | #include <net/ip6_checksum.h> | ||
| 47 | #include <linux/crc32.h> | ||
| 48 | #include "alx.h" | ||
| 49 | #include "hw.h" | ||
| 50 | #include "reg.h" | ||
| 51 | |||
| 52 | const char alx_drv_name[] = "alx"; | ||
| 53 | |||
| 54 | |||
| 55 | static void alx_free_txbuf(struct alx_priv *alx, int entry) | ||
| 56 | { | ||
| 57 | struct alx_buffer *txb = &alx->txq.bufs[entry]; | ||
| 58 | |||
| 59 | if (dma_unmap_len(txb, size)) { | ||
| 60 | dma_unmap_single(&alx->hw.pdev->dev, | ||
| 61 | dma_unmap_addr(txb, dma), | ||
| 62 | dma_unmap_len(txb, size), | ||
| 63 | DMA_TO_DEVICE); | ||
| 64 | dma_unmap_len_set(txb, size, 0); | ||
| 65 | } | ||
| 66 | |||
| 67 | if (txb->skb) { | ||
| 68 | dev_kfree_skb_any(txb->skb); | ||
| 69 | txb->skb = NULL; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp) | ||
| 74 | { | ||
| 75 | struct alx_rx_queue *rxq = &alx->rxq; | ||
| 76 | struct sk_buff *skb; | ||
| 77 | struct alx_buffer *cur_buf; | ||
| 78 | dma_addr_t dma; | ||
| 79 | u16 cur, next, count = 0; | ||
| 80 | |||
| 81 | next = cur = rxq->write_idx; | ||
| 82 | if (++next == alx->rx_ringsz) | ||
| 83 | next = 0; | ||
| 84 | cur_buf = &rxq->bufs[cur]; | ||
| 85 | |||
| 86 | while (!cur_buf->skb && next != rxq->read_idx) { | ||
| 87 | struct alx_rfd *rfd = &rxq->rfd[cur]; | ||
| 88 | |||
| 89 | skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp); | ||
| 90 | if (!skb) | ||
| 91 | break; | ||
| 92 | dma = dma_map_single(&alx->hw.pdev->dev, | ||
| 93 | skb->data, alx->rxbuf_size, | ||
| 94 | DMA_FROM_DEVICE); | ||
| 95 | if (dma_mapping_error(&alx->hw.pdev->dev, dma)) { | ||
| 96 | dev_kfree_skb(skb); | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | |||
| 100 | /* Unfortunately, RX descriptor buffers must be 4-byte | ||
| 101 | * aligned, so we can't use IP alignment. | ||
| 102 | */ | ||
| 103 | if (WARN_ON(dma & 3)) { | ||
| 104 | dev_kfree_skb(skb); | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | |||
| 108 | cur_buf->skb = skb; | ||
| 109 | dma_unmap_len_set(cur_buf, size, alx->rxbuf_size); | ||
| 110 | dma_unmap_addr_set(cur_buf, dma, dma); | ||
| 111 | rfd->addr = cpu_to_le64(dma); | ||
| 112 | |||
| 113 | cur = next; | ||
| 114 | if (++next == alx->rx_ringsz) | ||
| 115 | next = 0; | ||
| 116 | cur_buf = &rxq->bufs[cur]; | ||
| 117 | count++; | ||
| 118 | } | ||
| 119 | |||
| 120 | if (count) { | ||
| 121 | /* flush all updates before updating hardware */ | ||
| 122 | wmb(); | ||
| 123 | rxq->write_idx = cur; | ||
| 124 | alx_write_mem16(&alx->hw, ALX_RFD_PIDX, cur); | ||
| 125 | } | ||
| 126 | |||
| 127 | return count; | ||
| 128 | } | ||
| 129 | |||
| 130 | static inline int alx_tpd_avail(struct alx_priv *alx) | ||
| 131 | { | ||
| 132 | struct alx_tx_queue *txq = &alx->txq; | ||
| 133 | |||
| 134 | if (txq->write_idx >= txq->read_idx) | ||
| 135 | return alx->tx_ringsz + txq->read_idx - txq->write_idx - 1; | ||
| 136 | return txq->read_idx - txq->write_idx - 1; | ||
| 137 | } | ||
| 138 | |||
| 139 | static bool alx_clean_tx_irq(struct alx_priv *alx) | ||
| 140 | { | ||
| 141 | struct alx_tx_queue *txq = &alx->txq; | ||
| 142 | u16 hw_read_idx, sw_read_idx; | ||
| 143 | unsigned int total_bytes = 0, total_packets = 0; | ||
| 144 | int budget = ALX_DEFAULT_TX_WORK; | ||
| 145 | |||
| 146 | sw_read_idx = txq->read_idx; | ||
| 147 | hw_read_idx = alx_read_mem16(&alx->hw, ALX_TPD_PRI0_CIDX); | ||
| 148 | |||
| 149 | if (sw_read_idx != hw_read_idx) { | ||
| 150 | while (sw_read_idx != hw_read_idx && budget > 0) { | ||
| 151 | struct sk_buff *skb; | ||
| 152 | |||
| 153 | skb = txq->bufs[sw_read_idx].skb; | ||
| 154 | if (skb) { | ||
| 155 | total_bytes += skb->len; | ||
| 156 | total_packets++; | ||
| 157 | budget--; | ||
| 158 | } | ||
| 159 | |||
| 160 | alx_free_txbuf(alx, sw_read_idx); | ||
| 161 | |||
| 162 | if (++sw_read_idx == alx->tx_ringsz) | ||
| 163 | sw_read_idx = 0; | ||
| 164 | } | ||
| 165 | txq->read_idx = sw_read_idx; | ||
| 166 | |||
| 167 | netdev_completed_queue(alx->dev, total_packets, total_bytes); | ||
| 168 | } | ||
| 169 | |||
| 170 | if (netif_queue_stopped(alx->dev) && netif_carrier_ok(alx->dev) && | ||
| 171 | alx_tpd_avail(alx) > alx->tx_ringsz/4) | ||
| 172 | netif_wake_queue(alx->dev); | ||
| 173 | |||
| 174 | return sw_read_idx == hw_read_idx; | ||
| 175 | } | ||
| 176 | |||
| 177 | static void alx_schedule_link_check(struct alx_priv *alx) | ||
| 178 | { | ||
| 179 | schedule_work(&alx->link_check_wk); | ||
| 180 | } | ||
| 181 | |||
| 182 | static void alx_schedule_reset(struct alx_priv *alx) | ||
| 183 | { | ||
| 184 | schedule_work(&alx->reset_wk); | ||
| 185 | } | ||
| 186 | |||
| 187 | static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) | ||
| 188 | { | ||
| 189 | struct alx_rx_queue *rxq = &alx->rxq; | ||
| 190 | struct alx_rrd *rrd; | ||
| 191 | struct alx_buffer *rxb; | ||
| 192 | struct sk_buff *skb; | ||
| 193 | u16 length, rfd_cleaned = 0; | ||
| 194 | |||
| 195 | while (budget > 0) { | ||
| 196 | rrd = &rxq->rrd[rxq->rrd_read_idx]; | ||
| 197 | if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT))) | ||
| 198 | break; | ||
| 199 | rrd->word3 &= ~cpu_to_le32(1 << RRD_UPDATED_SHIFT); | ||
| 200 | |||
| 201 | if (ALX_GET_FIELD(le32_to_cpu(rrd->word0), | ||
| 202 | RRD_SI) != rxq->read_idx || | ||
| 203 | ALX_GET_FIELD(le32_to_cpu(rrd->word0), | ||
| 204 | RRD_NOR) != 1) { | ||
| 205 | alx_schedule_reset(alx); | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | rxb = &rxq->bufs[rxq->read_idx]; | ||
| 210 | dma_unmap_single(&alx->hw.pdev->dev, | ||
| 211 | dma_unmap_addr(rxb, dma), | ||
| 212 | dma_unmap_len(rxb, size), | ||
| 213 | DMA_FROM_DEVICE); | ||
| 214 | dma_unmap_len_set(rxb, size, 0); | ||
| 215 | skb = rxb->skb; | ||
| 216 | rxb->skb = NULL; | ||
| 217 | |||
| 218 | if (rrd->word3 & cpu_to_le32(1 << RRD_ERR_RES_SHIFT) || | ||
| 219 | rrd->word3 & cpu_to_le32(1 << RRD_ERR_LEN_SHIFT)) { | ||
| 220 | rrd->word3 = 0; | ||
| 221 | dev_kfree_skb_any(skb); | ||
| 222 | goto next_pkt; | ||
| 223 | } | ||
| 224 | |||
| 225 | length = ALX_GET_FIELD(le32_to_cpu(rrd->word3), | ||
| 226 | RRD_PKTLEN) - ETH_FCS_LEN; | ||
| 227 | skb_put(skb, length); | ||
| 228 | skb->protocol = eth_type_trans(skb, alx->dev); | ||
| 229 | |||
| 230 | skb_checksum_none_assert(skb); | ||
| 231 | if (alx->dev->features & NETIF_F_RXCSUM && | ||
| 232 | !(rrd->word3 & (cpu_to_le32(1 << RRD_ERR_L4_SHIFT) | | ||
| 233 | cpu_to_le32(1 << RRD_ERR_IPV4_SHIFT)))) { | ||
| 234 | switch (ALX_GET_FIELD(le32_to_cpu(rrd->word2), | ||
| 235 | RRD_PID)) { | ||
| 236 | case RRD_PID_IPV6UDP: | ||
| 237 | case RRD_PID_IPV4UDP: | ||
| 238 | case RRD_PID_IPV4TCP: | ||
| 239 | case RRD_PID_IPV6TCP: | ||
| 240 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 245 | napi_gro_receive(&alx->napi, skb); | ||
| 246 | budget--; | ||
| 247 | |||
| 248 | next_pkt: | ||
| 249 | if (++rxq->read_idx == alx->rx_ringsz) | ||
| 250 | rxq->read_idx = 0; | ||
| 251 | if (++rxq->rrd_read_idx == alx->rx_ringsz) | ||
| 252 | rxq->rrd_read_idx = 0; | ||
| 253 | |||
| 254 | if (++rfd_cleaned > ALX_RX_ALLOC_THRESH) | ||
| 255 | rfd_cleaned -= alx_refill_rx_ring(alx, GFP_ATOMIC); | ||
| 256 | } | ||
| 257 | |||
| 258 | if (rfd_cleaned) | ||
| 259 | alx_refill_rx_ring(alx, GFP_ATOMIC); | ||
| 260 | |||
| 261 | return budget > 0; | ||
| 262 | } | ||
| 263 | |||
| 264 | static int alx_poll(struct napi_struct *napi, int budget) | ||
| 265 | { | ||
| 266 | struct alx_priv *alx = container_of(napi, struct alx_priv, napi); | ||
| 267 | struct alx_hw *hw = &alx->hw; | ||
| 268 | bool complete = true; | ||
| 269 | unsigned long flags; | ||
| 270 | |||
| 271 | complete = alx_clean_tx_irq(alx) && | ||
| 272 | alx_clean_rx_irq(alx, budget); | ||
| 273 | |||
| 274 | if (!complete) | ||
| 275 | return 1; | ||
| 276 | |||
| 277 | napi_complete(&alx->napi); | ||
| 278 | |||
| 279 | /* enable interrupt */ | ||
| 280 | spin_lock_irqsave(&alx->irq_lock, flags); | ||
| 281 | alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0; | ||
| 282 | alx_write_mem32(hw, ALX_IMR, alx->int_mask); | ||
| 283 | spin_unlock_irqrestore(&alx->irq_lock, flags); | ||
| 284 | |||
| 285 | alx_post_write(hw); | ||
| 286 | |||
| 287 | return 0; | ||
| 288 | } | ||
| 289 | |||
| 290 | static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr) | ||
| 291 | { | ||
| 292 | struct alx_hw *hw = &alx->hw; | ||
| 293 | bool write_int_mask = false; | ||
| 294 | |||
| 295 | spin_lock(&alx->irq_lock); | ||
| 296 | |||
| 297 | /* ACK interrupt */ | ||
| 298 | alx_write_mem32(hw, ALX_ISR, intr | ALX_ISR_DIS); | ||
| 299 | intr &= alx->int_mask; | ||
| 300 | |||
| 301 | if (intr & ALX_ISR_FATAL) { | ||
| 302 | netif_warn(alx, hw, alx->dev, | ||
| 303 | "fatal interrupt 0x%x, resetting\n", intr); | ||
| 304 | alx_schedule_reset(alx); | ||
| 305 | goto out; | ||
| 306 | } | ||
| 307 | |||
| 308 | if (intr & ALX_ISR_ALERT) | ||
| 309 | netdev_warn(alx->dev, "alert interrupt: 0x%x\n", intr); | ||
| 310 | |||
| 311 | if (intr & ALX_ISR_PHY) { | ||
| 312 | /* suppress PHY interrupt, because the source | ||
| 313 | * is from PHY internal. only the internal status | ||
| 314 | * is cleared, the interrupt status could be cleared. | ||
| 315 | */ | ||
| 316 | alx->int_mask &= ~ALX_ISR_PHY; | ||
| 317 | write_int_mask = true; | ||
| 318 | alx_schedule_link_check(alx); | ||
| 319 | } | ||
| 320 | |||
| 321 | if (intr & (ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0)) { | ||
| 322 | napi_schedule(&alx->napi); | ||
| 323 | /* mask rx/tx interrupt, enable them when napi complete */ | ||
| 324 | alx->int_mask &= ~ALX_ISR_ALL_QUEUES; | ||
| 325 | write_int_mask = true; | ||
| 326 | } | ||
| 327 | |||
| 328 | if (write_int_mask) | ||
| 329 | alx_write_mem32(hw, ALX_IMR, alx->int_mask); | ||
| 330 | |||
| 331 | alx_write_mem32(hw, ALX_ISR, 0); | ||
| 332 | |||
| 333 | out: | ||
| 334 | spin_unlock(&alx->irq_lock); | ||
| 335 | return IRQ_HANDLED; | ||
| 336 | } | ||
| 337 | |||
| 338 | static irqreturn_t alx_intr_msi(int irq, void *data) | ||
| 339 | { | ||
| 340 | struct alx_priv *alx = data; | ||
| 341 | |||
| 342 | return alx_intr_handle(alx, alx_read_mem32(&alx->hw, ALX_ISR)); | ||
| 343 | } | ||
| 344 | |||
| 345 | static irqreturn_t alx_intr_legacy(int irq, void *data) | ||
| 346 | { | ||
| 347 | struct alx_priv *alx = data; | ||
| 348 | struct alx_hw *hw = &alx->hw; | ||
| 349 | u32 intr; | ||
| 350 | |||
| 351 | intr = alx_read_mem32(hw, ALX_ISR); | ||
| 352 | |||
| 353 | if (intr & ALX_ISR_DIS || !(intr & alx->int_mask)) | ||
| 354 | return IRQ_NONE; | ||
| 355 | |||
| 356 | return alx_intr_handle(alx, intr); | ||
| 357 | } | ||
| 358 | |||
| 359 | static void alx_init_ring_ptrs(struct alx_priv *alx) | ||
| 360 | { | ||
| 361 | struct alx_hw *hw = &alx->hw; | ||
| 362 | u32 addr_hi = ((u64)alx->descmem.dma) >> 32; | ||
| 363 | |||
| 364 | alx->rxq.read_idx = 0; | ||
| 365 | alx->rxq.write_idx = 0; | ||
| 366 | alx->rxq.rrd_read_idx = 0; | ||
| 367 | alx_write_mem32(hw, ALX_RX_BASE_ADDR_HI, addr_hi); | ||
| 368 | alx_write_mem32(hw, ALX_RRD_ADDR_LO, alx->rxq.rrd_dma); | ||
| 369 | alx_write_mem32(hw, ALX_RRD_RING_SZ, alx->rx_ringsz); | ||
| 370 | alx_write_mem32(hw, ALX_RFD_ADDR_LO, alx->rxq.rfd_dma); | ||
| 371 | alx_write_mem32(hw, ALX_RFD_RING_SZ, alx->rx_ringsz); | ||
| 372 | alx_write_mem32(hw, ALX_RFD_BUF_SZ, alx->rxbuf_size); | ||
| 373 | |||
| 374 | alx->txq.read_idx = 0; | ||
| 375 | alx->txq.write_idx = 0; | ||
| 376 | alx_write_mem32(hw, ALX_TX_BASE_ADDR_HI, addr_hi); | ||
| 377 | alx_write_mem32(hw, ALX_TPD_PRI0_ADDR_LO, alx->txq.tpd_dma); | ||
| 378 | alx_write_mem32(hw, ALX_TPD_RING_SZ, alx->tx_ringsz); | ||
| 379 | |||
| 380 | /* load these pointers into the chip */ | ||
| 381 | alx_write_mem32(hw, ALX_SRAM9, ALX_SRAM_LOAD_PTR); | ||
| 382 | } | ||
| 383 | |||
| 384 | static void alx_free_txring_buf(struct alx_priv *alx) | ||
| 385 | { | ||
| 386 | struct alx_tx_queue *txq = &alx->txq; | ||
| 387 | int i; | ||
| 388 | |||
| 389 | if (!txq->bufs) | ||
| 390 | return; | ||
| 391 | |||
| 392 | for (i = 0; i < alx->tx_ringsz; i++) | ||
| 393 | alx_free_txbuf(alx, i); | ||
| 394 | |||
| 395 | memset(txq->bufs, 0, alx->tx_ringsz * sizeof(struct alx_buffer)); | ||
| 396 | memset(txq->tpd, 0, alx->tx_ringsz * sizeof(struct alx_txd)); | ||
| 397 | txq->write_idx = 0; | ||
| 398 | txq->read_idx = 0; | ||
| 399 | |||
| 400 | netdev_reset_queue(alx->dev); | ||
| 401 | } | ||
| 402 | |||
| 403 | static void alx_free_rxring_buf(struct alx_priv *alx) | ||
| 404 | { | ||
| 405 | struct alx_rx_queue *rxq = &alx->rxq; | ||
| 406 | struct alx_buffer *cur_buf; | ||
| 407 | u16 i; | ||
| 408 | |||
| 409 | if (rxq == NULL) | ||
| 410 | return; | ||
| 411 | |||
| 412 | for (i = 0; i < alx->rx_ringsz; i++) { | ||
| 413 | cur_buf = rxq->bufs + i; | ||
| 414 | if (cur_buf->skb) { | ||
| 415 | dma_unmap_single(&alx->hw.pdev->dev, | ||
| 416 | dma_unmap_addr(cur_buf, dma), | ||
| 417 | dma_unmap_len(cur_buf, size), | ||
| 418 | DMA_FROM_DEVICE); | ||
| 419 | dev_kfree_skb(cur_buf->skb); | ||
| 420 | cur_buf->skb = NULL; | ||
| 421 | dma_unmap_len_set(cur_buf, size, 0); | ||
| 422 | dma_unmap_addr_set(cur_buf, dma, 0); | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | rxq->write_idx = 0; | ||
| 427 | rxq->read_idx = 0; | ||
| 428 | rxq->rrd_read_idx = 0; | ||
| 429 | } | ||
| 430 | |||
| 431 | static void alx_free_buffers(struct alx_priv *alx) | ||
| 432 | { | ||
| 433 | alx_free_txring_buf(alx); | ||
| 434 | alx_free_rxring_buf(alx); | ||
| 435 | } | ||
| 436 | |||
| 437 | static int alx_reinit_rings(struct alx_priv *alx) | ||
| 438 | { | ||
| 439 | alx_free_buffers(alx); | ||
| 440 | |||
| 441 | alx_init_ring_ptrs(alx); | ||
| 442 | |||
| 443 | if (!alx_refill_rx_ring(alx, GFP_KERNEL)) | ||
| 444 | return -ENOMEM; | ||
| 445 | |||
| 446 | return 0; | ||
| 447 | } | ||
| 448 | |||
| 449 | static void alx_add_mc_addr(struct alx_hw *hw, const u8 *addr, u32 *mc_hash) | ||
| 450 | { | ||
| 451 | u32 crc32, bit, reg; | ||
| 452 | |||
| 453 | crc32 = ether_crc(ETH_ALEN, addr); | ||
| 454 | reg = (crc32 >> 31) & 0x1; | ||
| 455 | bit = (crc32 >> 26) & 0x1F; | ||
| 456 | |||
| 457 | mc_hash[reg] |= BIT(bit); | ||
| 458 | } | ||
| 459 | |||
| 460 | static void __alx_set_rx_mode(struct net_device *netdev) | ||
| 461 | { | ||
| 462 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 463 | struct alx_hw *hw = &alx->hw; | ||
| 464 | struct netdev_hw_addr *ha; | ||
| 465 | u32 mc_hash[2] = {}; | ||
| 466 | |||
| 467 | if (!(netdev->flags & IFF_ALLMULTI)) { | ||
| 468 | netdev_for_each_mc_addr(ha, netdev) | ||
| 469 | alx_add_mc_addr(hw, ha->addr, mc_hash); | ||
| 470 | |||
| 471 | alx_write_mem32(hw, ALX_HASH_TBL0, mc_hash[0]); | ||
| 472 | alx_write_mem32(hw, ALX_HASH_TBL1, mc_hash[1]); | ||
| 473 | } | ||
| 474 | |||
| 475 | hw->rx_ctrl &= ~(ALX_MAC_CTRL_MULTIALL_EN | ALX_MAC_CTRL_PROMISC_EN); | ||
| 476 | if (netdev->flags & IFF_PROMISC) | ||
| 477 | hw->rx_ctrl |= ALX_MAC_CTRL_PROMISC_EN; | ||
| 478 | if (netdev->flags & IFF_ALLMULTI) | ||
| 479 | hw->rx_ctrl |= ALX_MAC_CTRL_MULTIALL_EN; | ||
| 480 | |||
| 481 | alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl); | ||
| 482 | } | ||
| 483 | |||
| 484 | static void alx_set_rx_mode(struct net_device *netdev) | ||
| 485 | { | ||
| 486 | __alx_set_rx_mode(netdev); | ||
| 487 | } | ||
| 488 | |||
| 489 | static int alx_set_mac_address(struct net_device *netdev, void *data) | ||
| 490 | { | ||
| 491 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 492 | struct alx_hw *hw = &alx->hw; | ||
| 493 | struct sockaddr *addr = data; | ||
| 494 | |||
| 495 | if (!is_valid_ether_addr(addr->sa_data)) | ||
| 496 | return -EADDRNOTAVAIL; | ||
| 497 | |||
| 498 | if (netdev->addr_assign_type & NET_ADDR_RANDOM) | ||
| 499 | netdev->addr_assign_type ^= NET_ADDR_RANDOM; | ||
| 500 | |||
| 501 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
| 502 | memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len); | ||
| 503 | alx_set_macaddr(hw, hw->mac_addr); | ||
| 504 | |||
| 505 | return 0; | ||
| 506 | } | ||
| 507 | |||
| 508 | static int alx_alloc_descriptors(struct alx_priv *alx) | ||
| 509 | { | ||
| 510 | alx->txq.bufs = kcalloc(alx->tx_ringsz, | ||
| 511 | sizeof(struct alx_buffer), | ||
| 512 | GFP_KERNEL); | ||
| 513 | if (!alx->txq.bufs) | ||
| 514 | return -ENOMEM; | ||
| 515 | |||
| 516 | alx->rxq.bufs = kcalloc(alx->rx_ringsz, | ||
| 517 | sizeof(struct alx_buffer), | ||
| 518 | GFP_KERNEL); | ||
| 519 | if (!alx->rxq.bufs) | ||
| 520 | goto out_free; | ||
| 521 | |||
| 522 | /* physical tx/rx ring descriptors | ||
| 523 | * | ||
| 524 | * Allocate them as a single chunk because they must not cross a | ||
| 525 | * 4G boundary (hardware has a single register for high 32 bits | ||
| 526 | * of addresses only) | ||
| 527 | */ | ||
| 528 | alx->descmem.size = sizeof(struct alx_txd) * alx->tx_ringsz + | ||
| 529 | sizeof(struct alx_rrd) * alx->rx_ringsz + | ||
| 530 | sizeof(struct alx_rfd) * alx->rx_ringsz; | ||
| 531 | alx->descmem.virt = dma_zalloc_coherent(&alx->hw.pdev->dev, | ||
| 532 | alx->descmem.size, | ||
| 533 | &alx->descmem.dma, | ||
| 534 | GFP_KERNEL); | ||
| 535 | if (!alx->descmem.virt) | ||
| 536 | goto out_free; | ||
| 537 | |||
| 538 | alx->txq.tpd = (void *)alx->descmem.virt; | ||
| 539 | alx->txq.tpd_dma = alx->descmem.dma; | ||
| 540 | |||
| 541 | /* alignment requirement for next block */ | ||
| 542 | BUILD_BUG_ON(sizeof(struct alx_txd) % 8); | ||
| 543 | |||
| 544 | alx->rxq.rrd = | ||
| 545 | (void *)((u8 *)alx->descmem.virt + | ||
| 546 | sizeof(struct alx_txd) * alx->tx_ringsz); | ||
| 547 | alx->rxq.rrd_dma = alx->descmem.dma + | ||
| 548 | sizeof(struct alx_txd) * alx->tx_ringsz; | ||
| 549 | |||
| 550 | /* alignment requirement for next block */ | ||
| 551 | BUILD_BUG_ON(sizeof(struct alx_rrd) % 8); | ||
| 552 | |||
| 553 | alx->rxq.rfd = | ||
| 554 | (void *)((u8 *)alx->descmem.virt + | ||
| 555 | sizeof(struct alx_txd) * alx->tx_ringsz + | ||
| 556 | sizeof(struct alx_rrd) * alx->rx_ringsz); | ||
| 557 | alx->rxq.rfd_dma = alx->descmem.dma + | ||
| 558 | sizeof(struct alx_txd) * alx->tx_ringsz + | ||
| 559 | sizeof(struct alx_rrd) * alx->rx_ringsz; | ||
| 560 | |||
| 561 | return 0; | ||
| 562 | out_free: | ||
| 563 | kfree(alx->txq.bufs); | ||
| 564 | kfree(alx->rxq.bufs); | ||
| 565 | return -ENOMEM; | ||
| 566 | } | ||
| 567 | |||
| 568 | static int alx_alloc_rings(struct alx_priv *alx) | ||
| 569 | { | ||
| 570 | int err; | ||
| 571 | |||
| 572 | err = alx_alloc_descriptors(alx); | ||
| 573 | if (err) | ||
| 574 | return err; | ||
| 575 | |||
| 576 | alx->int_mask &= ~ALX_ISR_ALL_QUEUES; | ||
| 577 | alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0; | ||
| 578 | alx->tx_ringsz = alx->tx_ringsz; | ||
| 579 | |||
| 580 | netif_napi_add(alx->dev, &alx->napi, alx_poll, 64); | ||
| 581 | |||
| 582 | alx_reinit_rings(alx); | ||
| 583 | return 0; | ||
| 584 | } | ||
| 585 | |||
| 586 | static void alx_free_rings(struct alx_priv *alx) | ||
| 587 | { | ||
| 588 | netif_napi_del(&alx->napi); | ||
| 589 | alx_free_buffers(alx); | ||
| 590 | |||
| 591 | kfree(alx->txq.bufs); | ||
| 592 | kfree(alx->rxq.bufs); | ||
| 593 | |||
| 594 | dma_free_coherent(&alx->hw.pdev->dev, | ||
| 595 | alx->descmem.size, | ||
| 596 | alx->descmem.virt, | ||
| 597 | alx->descmem.dma); | ||
| 598 | } | ||
| 599 | |||
| 600 | static void alx_config_vector_mapping(struct alx_priv *alx) | ||
| 601 | { | ||
| 602 | struct alx_hw *hw = &alx->hw; | ||
| 603 | |||
| 604 | alx_write_mem32(hw, ALX_MSI_MAP_TBL1, 0); | ||
| 605 | alx_write_mem32(hw, ALX_MSI_MAP_TBL2, 0); | ||
| 606 | alx_write_mem32(hw, ALX_MSI_ID_MAP, 0); | ||
| 607 | } | ||
| 608 | |||
| 609 | static void alx_irq_enable(struct alx_priv *alx) | ||
| 610 | { | ||
| 611 | struct alx_hw *hw = &alx->hw; | ||
| 612 | |||
| 613 | /* level-1 interrupt switch */ | ||
| 614 | alx_write_mem32(hw, ALX_ISR, 0); | ||
| 615 | alx_write_mem32(hw, ALX_IMR, alx->int_mask); | ||
| 616 | alx_post_write(hw); | ||
| 617 | } | ||
| 618 | |||
| 619 | static void alx_irq_disable(struct alx_priv *alx) | ||
| 620 | { | ||
| 621 | struct alx_hw *hw = &alx->hw; | ||
| 622 | |||
| 623 | alx_write_mem32(hw, ALX_ISR, ALX_ISR_DIS); | ||
| 624 | alx_write_mem32(hw, ALX_IMR, 0); | ||
| 625 | alx_post_write(hw); | ||
| 626 | |||
| 627 | synchronize_irq(alx->hw.pdev->irq); | ||
| 628 | } | ||
| 629 | |||
| 630 | static int alx_request_irq(struct alx_priv *alx) | ||
| 631 | { | ||
| 632 | struct pci_dev *pdev = alx->hw.pdev; | ||
| 633 | struct alx_hw *hw = &alx->hw; | ||
| 634 | int err; | ||
| 635 | u32 msi_ctrl; | ||
| 636 | |||
| 637 | msi_ctrl = (hw->imt >> 1) << ALX_MSI_RETRANS_TM_SHIFT; | ||
| 638 | |||
| 639 | if (!pci_enable_msi(alx->hw.pdev)) { | ||
| 640 | alx->msi = true; | ||
| 641 | |||
| 642 | alx_write_mem32(hw, ALX_MSI_RETRANS_TIMER, | ||
| 643 | msi_ctrl | ALX_MSI_MASK_SEL_LINE); | ||
| 644 | err = request_irq(pdev->irq, alx_intr_msi, 0, | ||
| 645 | alx->dev->name, alx); | ||
| 646 | if (!err) | ||
| 647 | goto out; | ||
| 648 | /* fall back to legacy interrupt */ | ||
| 649 | pci_disable_msi(alx->hw.pdev); | ||
| 650 | } | ||
| 651 | |||
| 652 | alx_write_mem32(hw, ALX_MSI_RETRANS_TIMER, 0); | ||
| 653 | err = request_irq(pdev->irq, alx_intr_legacy, IRQF_SHARED, | ||
| 654 | alx->dev->name, alx); | ||
| 655 | out: | ||
| 656 | if (!err) | ||
| 657 | alx_config_vector_mapping(alx); | ||
| 658 | return err; | ||
| 659 | } | ||
| 660 | |||
| 661 | static void alx_free_irq(struct alx_priv *alx) | ||
| 662 | { | ||
| 663 | struct pci_dev *pdev = alx->hw.pdev; | ||
| 664 | |||
| 665 | free_irq(pdev->irq, alx); | ||
| 666 | |||
| 667 | if (alx->msi) { | ||
| 668 | pci_disable_msi(alx->hw.pdev); | ||
| 669 | alx->msi = false; | ||
| 670 | } | ||
| 671 | } | ||
| 672 | |||
| 673 | static int alx_identify_hw(struct alx_priv *alx) | ||
| 674 | { | ||
| 675 | struct alx_hw *hw = &alx->hw; | ||
| 676 | int rev = alx_hw_revision(hw); | ||
| 677 | |||
| 678 | if (rev > ALX_REV_C0) | ||
| 679 | return -EINVAL; | ||
| 680 | |||
| 681 | hw->max_dma_chnl = rev >= ALX_REV_B0 ? 4 : 2; | ||
| 682 | |||
| 683 | return 0; | ||
| 684 | } | ||
| 685 | |||
| 686 | static int alx_init_sw(struct alx_priv *alx) | ||
| 687 | { | ||
| 688 | struct pci_dev *pdev = alx->hw.pdev; | ||
| 689 | struct alx_hw *hw = &alx->hw; | ||
| 690 | int err; | ||
| 691 | |||
| 692 | err = alx_identify_hw(alx); | ||
| 693 | if (err) { | ||
| 694 | dev_err(&pdev->dev, "unrecognized chip, aborting\n"); | ||
| 695 | return err; | ||
| 696 | } | ||
| 697 | |||
| 698 | alx->hw.lnk_patch = | ||
| 699 | pdev->device == ALX_DEV_ID_AR8161 && | ||
| 700 | pdev->subsystem_vendor == PCI_VENDOR_ID_ATTANSIC && | ||
| 701 | pdev->subsystem_device == 0x0091 && | ||
| 702 | pdev->revision == 0; | ||
| 703 | |||
| 704 | hw->smb_timer = 400; | ||
| 705 | hw->mtu = alx->dev->mtu; | ||
| 706 | alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8); | ||
| 707 | alx->tx_ringsz = 256; | ||
| 708 | alx->rx_ringsz = 512; | ||
| 709 | hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY; | ||
| 710 | hw->imt = 200; | ||
| 711 | alx->int_mask = ALX_ISR_MISC; | ||
| 712 | hw->dma_chnl = hw->max_dma_chnl; | ||
| 713 | hw->ith_tpd = alx->tx_ringsz / 3; | ||
| 714 | hw->link_speed = SPEED_UNKNOWN; | ||
| 715 | hw->adv_cfg = ADVERTISED_Autoneg | | ||
| 716 | ADVERTISED_10baseT_Half | | ||
| 717 | ADVERTISED_10baseT_Full | | ||
| 718 | ADVERTISED_100baseT_Full | | ||
| 719 | ADVERTISED_100baseT_Half | | ||
| 720 | ADVERTISED_1000baseT_Full; | ||
| 721 | hw->flowctrl = ALX_FC_ANEG | ALX_FC_RX | ALX_FC_TX; | ||
| 722 | |||
| 723 | hw->rx_ctrl = ALX_MAC_CTRL_WOLSPED_SWEN | | ||
| 724 | ALX_MAC_CTRL_MHASH_ALG_HI5B | | ||
| 725 | ALX_MAC_CTRL_BRD_EN | | ||
| 726 | ALX_MAC_CTRL_PCRCE | | ||
| 727 | ALX_MAC_CTRL_CRCE | | ||
| 728 | ALX_MAC_CTRL_RXFC_EN | | ||
| 729 | ALX_MAC_CTRL_TXFC_EN | | ||
| 730 | 7 << ALX_MAC_CTRL_PRMBLEN_SHIFT; | ||
| 731 | |||
| 732 | return err; | ||
| 733 | } | ||
| 734 | |||
| 735 | |||
| 736 | static netdev_features_t alx_fix_features(struct net_device *netdev, | ||
| 737 | netdev_features_t features) | ||
| 738 | { | ||
| 739 | if (netdev->mtu > ALX_MAX_TSO_PKT_SIZE) | ||
| 740 | features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
| 741 | |||
| 742 | return features; | ||
| 743 | } | ||
| 744 | |||
| 745 | static void alx_netif_stop(struct alx_priv *alx) | ||
| 746 | { | ||
| 747 | alx->dev->trans_start = jiffies; | ||
| 748 | if (netif_carrier_ok(alx->dev)) { | ||
| 749 | netif_carrier_off(alx->dev); | ||
| 750 | netif_tx_disable(alx->dev); | ||
| 751 | napi_disable(&alx->napi); | ||
| 752 | } | ||
| 753 | } | ||
| 754 | |||
| 755 | static void alx_halt(struct alx_priv *alx) | ||
| 756 | { | ||
| 757 | struct alx_hw *hw = &alx->hw; | ||
| 758 | |||
| 759 | alx_netif_stop(alx); | ||
| 760 | hw->link_speed = SPEED_UNKNOWN; | ||
| 761 | |||
| 762 | alx_reset_mac(hw); | ||
| 763 | |||
| 764 | /* disable l0s/l1 */ | ||
| 765 | alx_enable_aspm(hw, false, false); | ||
| 766 | alx_irq_disable(alx); | ||
| 767 | alx_free_buffers(alx); | ||
| 768 | } | ||
| 769 | |||
| 770 | static void alx_configure(struct alx_priv *alx) | ||
| 771 | { | ||
| 772 | struct alx_hw *hw = &alx->hw; | ||
| 773 | |||
| 774 | alx_configure_basic(hw); | ||
| 775 | alx_disable_rss(hw); | ||
| 776 | __alx_set_rx_mode(alx->dev); | ||
| 777 | |||
| 778 | alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl); | ||
| 779 | } | ||
| 780 | |||
| 781 | static void alx_activate(struct alx_priv *alx) | ||
| 782 | { | ||
| 783 | /* hardware setting lost, restore it */ | ||
| 784 | alx_reinit_rings(alx); | ||
| 785 | alx_configure(alx); | ||
| 786 | |||
| 787 | /* clear old interrupts */ | ||
| 788 | alx_write_mem32(&alx->hw, ALX_ISR, ~(u32)ALX_ISR_DIS); | ||
| 789 | |||
| 790 | alx_irq_enable(alx); | ||
| 791 | |||
| 792 | alx_schedule_link_check(alx); | ||
| 793 | } | ||
| 794 | |||
| 795 | static void alx_reinit(struct alx_priv *alx) | ||
| 796 | { | ||
| 797 | ASSERT_RTNL(); | ||
| 798 | |||
| 799 | alx_halt(alx); | ||
| 800 | alx_activate(alx); | ||
| 801 | } | ||
| 802 | |||
| 803 | static int alx_change_mtu(struct net_device *netdev, int mtu) | ||
| 804 | { | ||
| 805 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 806 | int max_frame = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; | ||
| 807 | |||
| 808 | if ((max_frame < ALX_MIN_FRAME_SIZE) || | ||
| 809 | (max_frame > ALX_MAX_FRAME_SIZE)) | ||
| 810 | return -EINVAL; | ||
| 811 | |||
| 812 | if (netdev->mtu == mtu) | ||
| 813 | return 0; | ||
| 814 | |||
| 815 | netdev->mtu = mtu; | ||
| 816 | alx->hw.mtu = mtu; | ||
| 817 | alx->rxbuf_size = mtu > ALX_DEF_RXBUF_SIZE ? | ||
| 818 | ALIGN(max_frame, 8) : ALX_DEF_RXBUF_SIZE; | ||
| 819 | netdev_update_features(netdev); | ||
| 820 | if (netif_running(netdev)) | ||
| 821 | alx_reinit(alx); | ||
| 822 | return 0; | ||
| 823 | } | ||
| 824 | |||
| 825 | static void alx_netif_start(struct alx_priv *alx) | ||
| 826 | { | ||
| 827 | netif_tx_wake_all_queues(alx->dev); | ||
| 828 | napi_enable(&alx->napi); | ||
| 829 | netif_carrier_on(alx->dev); | ||
| 830 | } | ||
| 831 | |||
| 832 | static int __alx_open(struct alx_priv *alx, bool resume) | ||
| 833 | { | ||
| 834 | int err; | ||
| 835 | |||
| 836 | if (!resume) | ||
| 837 | netif_carrier_off(alx->dev); | ||
| 838 | |||
| 839 | err = alx_alloc_rings(alx); | ||
| 840 | if (err) | ||
| 841 | return err; | ||
| 842 | |||
| 843 | alx_configure(alx); | ||
| 844 | |||
| 845 | err = alx_request_irq(alx); | ||
| 846 | if (err) | ||
| 847 | goto out_free_rings; | ||
| 848 | |||
| 849 | /* clear old interrupts */ | ||
| 850 | alx_write_mem32(&alx->hw, ALX_ISR, ~(u32)ALX_ISR_DIS); | ||
| 851 | |||
| 852 | alx_irq_enable(alx); | ||
| 853 | |||
| 854 | if (!resume) | ||
| 855 | netif_tx_start_all_queues(alx->dev); | ||
| 856 | |||
| 857 | alx_schedule_link_check(alx); | ||
| 858 | return 0; | ||
| 859 | |||
| 860 | out_free_rings: | ||
| 861 | alx_free_rings(alx); | ||
| 862 | return err; | ||
| 863 | } | ||
| 864 | |||
| 865 | static void __alx_stop(struct alx_priv *alx) | ||
| 866 | { | ||
| 867 | alx_halt(alx); | ||
| 868 | alx_free_irq(alx); | ||
| 869 | alx_free_rings(alx); | ||
| 870 | } | ||
| 871 | |||
| 872 | static const char *alx_speed_desc(u16 speed) | ||
| 873 | { | ||
| 874 | switch (speed) { | ||
| 875 | case SPEED_1000 + DUPLEX_FULL: | ||
| 876 | return "1 Gbps Full"; | ||
| 877 | case SPEED_100 + DUPLEX_FULL: | ||
| 878 | return "100 Mbps Full"; | ||
| 879 | case SPEED_100 + DUPLEX_HALF: | ||
| 880 | return "100 Mbps Half"; | ||
| 881 | case SPEED_10 + DUPLEX_FULL: | ||
| 882 | return "10 Mbps Full"; | ||
| 883 | case SPEED_10 + DUPLEX_HALF: | ||
| 884 | return "10 Mbps Half"; | ||
| 885 | default: | ||
| 886 | return "Unknown speed"; | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 890 | static void alx_check_link(struct alx_priv *alx) | ||
| 891 | { | ||
| 892 | struct alx_hw *hw = &alx->hw; | ||
| 893 | unsigned long flags; | ||
| 894 | int speed, old_speed; | ||
| 895 | int err; | ||
| 896 | |||
| 897 | /* clear PHY internal interrupt status, otherwise the main | ||
| 898 | * interrupt status will be asserted forever | ||
| 899 | */ | ||
| 900 | alx_clear_phy_intr(hw); | ||
| 901 | |||
| 902 | err = alx_get_phy_link(hw, &speed); | ||
| 903 | if (err < 0) | ||
| 904 | goto reset; | ||
| 905 | |||
| 906 | spin_lock_irqsave(&alx->irq_lock, flags); | ||
| 907 | alx->int_mask |= ALX_ISR_PHY; | ||
| 908 | alx_write_mem32(hw, ALX_IMR, alx->int_mask); | ||
| 909 | spin_unlock_irqrestore(&alx->irq_lock, flags); | ||
| 910 | |||
| 911 | old_speed = hw->link_speed; | ||
| 912 | |||
| 913 | if (old_speed == speed) | ||
| 914 | return; | ||
| 915 | hw->link_speed = speed; | ||
| 916 | |||
| 917 | if (speed != SPEED_UNKNOWN) { | ||
| 918 | netif_info(alx, link, alx->dev, | ||
| 919 | "NIC Up: %s\n", alx_speed_desc(speed)); | ||
| 920 | alx_post_phy_link(hw); | ||
| 921 | alx_enable_aspm(hw, true, true); | ||
| 922 | alx_start_mac(hw); | ||
| 923 | |||
| 924 | if (old_speed == SPEED_UNKNOWN) | ||
| 925 | alx_netif_start(alx); | ||
| 926 | } else { | ||
| 927 | /* link is now down */ | ||
| 928 | alx_netif_stop(alx); | ||
| 929 | netif_info(alx, link, alx->dev, "Link Down\n"); | ||
| 930 | err = alx_reset_mac(hw); | ||
| 931 | if (err) | ||
| 932 | goto reset; | ||
| 933 | alx_irq_disable(alx); | ||
| 934 | |||
| 935 | /* MAC reset causes all HW settings to be lost, restore all */ | ||
| 936 | err = alx_reinit_rings(alx); | ||
| 937 | if (err) | ||
| 938 | goto reset; | ||
| 939 | alx_configure(alx); | ||
| 940 | alx_enable_aspm(hw, false, true); | ||
| 941 | alx_post_phy_link(hw); | ||
| 942 | alx_irq_enable(alx); | ||
| 943 | } | ||
| 944 | |||
| 945 | return; | ||
| 946 | |||
| 947 | reset: | ||
| 948 | alx_schedule_reset(alx); | ||
| 949 | } | ||
| 950 | |||
| 951 | static int alx_open(struct net_device *netdev) | ||
| 952 | { | ||
| 953 | return __alx_open(netdev_priv(netdev), false); | ||
| 954 | } | ||
| 955 | |||
| 956 | static int alx_stop(struct net_device *netdev) | ||
| 957 | { | ||
| 958 | __alx_stop(netdev_priv(netdev)); | ||
| 959 | return 0; | ||
| 960 | } | ||
| 961 | |||
| 962 | static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en) | ||
| 963 | { | ||
| 964 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
| 965 | struct net_device *netdev = alx->dev; | ||
| 966 | struct alx_hw *hw = &alx->hw; | ||
| 967 | int err, speed; | ||
| 968 | |||
| 969 | netif_device_detach(netdev); | ||
| 970 | |||
| 971 | if (netif_running(netdev)) | ||
| 972 | __alx_stop(alx); | ||
| 973 | |||
| 974 | #ifdef CONFIG_PM_SLEEP | ||
| 975 | err = pci_save_state(pdev); | ||
| 976 | if (err) | ||
| 977 | return err; | ||
| 978 | #endif | ||
| 979 | |||
| 980 | err = alx_select_powersaving_speed(hw, &speed); | ||
| 981 | if (err) | ||
| 982 | return err; | ||
| 983 | err = alx_clear_phy_intr(hw); | ||
| 984 | if (err) | ||
| 985 | return err; | ||
| 986 | err = alx_pre_suspend(hw, speed); | ||
| 987 | if (err) | ||
| 988 | return err; | ||
| 989 | err = alx_config_wol(hw); | ||
| 990 | if (err) | ||
| 991 | return err; | ||
| 992 | |||
| 993 | *wol_en = false; | ||
| 994 | if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) { | ||
| 995 | netif_info(alx, wol, netdev, | ||
| 996 | "wol: ctrl=%X, speed=%X\n", | ||
| 997 | hw->sleep_ctrl, speed); | ||
| 998 | device_set_wakeup_enable(&pdev->dev, true); | ||
| 999 | *wol_en = true; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | pci_disable_device(pdev); | ||
| 1003 | |||
| 1004 | return 0; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | static void alx_shutdown(struct pci_dev *pdev) | ||
| 1008 | { | ||
| 1009 | int err; | ||
| 1010 | bool wol_en; | ||
| 1011 | |||
| 1012 | err = __alx_shutdown(pdev, &wol_en); | ||
| 1013 | if (!err) { | ||
| 1014 | pci_wake_from_d3(pdev, wol_en); | ||
| 1015 | pci_set_power_state(pdev, PCI_D3hot); | ||
| 1016 | } else { | ||
| 1017 | dev_err(&pdev->dev, "shutdown fail %d\n", err); | ||
| 1018 | } | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | static void alx_link_check(struct work_struct *work) | ||
| 1022 | { | ||
| 1023 | struct alx_priv *alx; | ||
| 1024 | |||
| 1025 | alx = container_of(work, struct alx_priv, link_check_wk); | ||
| 1026 | |||
| 1027 | rtnl_lock(); | ||
| 1028 | alx_check_link(alx); | ||
| 1029 | rtnl_unlock(); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static void alx_reset(struct work_struct *work) | ||
| 1033 | { | ||
| 1034 | struct alx_priv *alx = container_of(work, struct alx_priv, reset_wk); | ||
| 1035 | |||
| 1036 | rtnl_lock(); | ||
| 1037 | alx_reinit(alx); | ||
| 1038 | rtnl_unlock(); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | static int alx_tx_csum(struct sk_buff *skb, struct alx_txd *first) | ||
| 1042 | { | ||
| 1043 | u8 cso, css; | ||
| 1044 | |||
| 1045 | if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
| 1046 | return 0; | ||
| 1047 | |||
| 1048 | cso = skb_checksum_start_offset(skb); | ||
| 1049 | if (cso & 1) | ||
| 1050 | return -EINVAL; | ||
| 1051 | |||
| 1052 | css = cso + skb->csum_offset; | ||
| 1053 | first->word1 |= cpu_to_le32((cso >> 1) << TPD_CXSUMSTART_SHIFT); | ||
| 1054 | first->word1 |= cpu_to_le32((css >> 1) << TPD_CXSUMOFFSET_SHIFT); | ||
| 1055 | first->word1 |= cpu_to_le32(1 << TPD_CXSUM_EN_SHIFT); | ||
| 1056 | |||
| 1057 | return 0; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | static int alx_map_tx_skb(struct alx_priv *alx, struct sk_buff *skb) | ||
| 1061 | { | ||
| 1062 | struct alx_tx_queue *txq = &alx->txq; | ||
| 1063 | struct alx_txd *tpd, *first_tpd; | ||
| 1064 | dma_addr_t dma; | ||
| 1065 | int maplen, f, first_idx = txq->write_idx; | ||
| 1066 | |||
| 1067 | first_tpd = &txq->tpd[txq->write_idx]; | ||
| 1068 | tpd = first_tpd; | ||
| 1069 | |||
| 1070 | maplen = skb_headlen(skb); | ||
| 1071 | dma = dma_map_single(&alx->hw.pdev->dev, skb->data, maplen, | ||
| 1072 | DMA_TO_DEVICE); | ||
| 1073 | if (dma_mapping_error(&alx->hw.pdev->dev, dma)) | ||
| 1074 | goto err_dma; | ||
| 1075 | |||
| 1076 | dma_unmap_len_set(&txq->bufs[txq->write_idx], size, maplen); | ||
| 1077 | dma_unmap_addr_set(&txq->bufs[txq->write_idx], dma, dma); | ||
| 1078 | |||
| 1079 | tpd->adrl.addr = cpu_to_le64(dma); | ||
| 1080 | tpd->len = cpu_to_le16(maplen); | ||
| 1081 | |||
| 1082 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { | ||
| 1083 | struct skb_frag_struct *frag; | ||
| 1084 | |||
| 1085 | frag = &skb_shinfo(skb)->frags[f]; | ||
| 1086 | |||
| 1087 | if (++txq->write_idx == alx->tx_ringsz) | ||
| 1088 | txq->write_idx = 0; | ||
| 1089 | tpd = &txq->tpd[txq->write_idx]; | ||
| 1090 | |||
| 1091 | tpd->word1 = first_tpd->word1; | ||
| 1092 | |||
| 1093 | maplen = skb_frag_size(frag); | ||
| 1094 | dma = skb_frag_dma_map(&alx->hw.pdev->dev, frag, 0, | ||
| 1095 | maplen, DMA_TO_DEVICE); | ||
| 1096 | if (dma_mapping_error(&alx->hw.pdev->dev, dma)) | ||
| 1097 | goto err_dma; | ||
| 1098 | dma_unmap_len_set(&txq->bufs[txq->write_idx], size, maplen); | ||
| 1099 | dma_unmap_addr_set(&txq->bufs[txq->write_idx], dma, dma); | ||
| 1100 | |||
| 1101 | tpd->adrl.addr = cpu_to_le64(dma); | ||
| 1102 | tpd->len = cpu_to_le16(maplen); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | /* last TPD, set EOP flag and store skb */ | ||
| 1106 | tpd->word1 |= cpu_to_le32(1 << TPD_EOP_SHIFT); | ||
| 1107 | txq->bufs[txq->write_idx].skb = skb; | ||
| 1108 | |||
| 1109 | if (++txq->write_idx == alx->tx_ringsz) | ||
| 1110 | txq->write_idx = 0; | ||
| 1111 | |||
| 1112 | return 0; | ||
| 1113 | |||
| 1114 | err_dma: | ||
| 1115 | f = first_idx; | ||
| 1116 | while (f != txq->write_idx) { | ||
| 1117 | alx_free_txbuf(alx, f); | ||
| 1118 | if (++f == alx->tx_ringsz) | ||
| 1119 | f = 0; | ||
| 1120 | } | ||
| 1121 | return -ENOMEM; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | static netdev_tx_t alx_start_xmit(struct sk_buff *skb, | ||
| 1125 | struct net_device *netdev) | ||
| 1126 | { | ||
| 1127 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 1128 | struct alx_tx_queue *txq = &alx->txq; | ||
| 1129 | struct alx_txd *first; | ||
| 1130 | int tpdreq = skb_shinfo(skb)->nr_frags + 1; | ||
| 1131 | |||
| 1132 | if (alx_tpd_avail(alx) < tpdreq) { | ||
| 1133 | netif_stop_queue(alx->dev); | ||
| 1134 | goto drop; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | first = &txq->tpd[txq->write_idx]; | ||
| 1138 | memset(first, 0, sizeof(*first)); | ||
| 1139 | |||
| 1140 | if (alx_tx_csum(skb, first)) | ||
| 1141 | goto drop; | ||
| 1142 | |||
| 1143 | if (alx_map_tx_skb(alx, skb) < 0) | ||
| 1144 | goto drop; | ||
| 1145 | |||
| 1146 | netdev_sent_queue(alx->dev, skb->len); | ||
| 1147 | |||
| 1148 | /* flush updates before updating hardware */ | ||
| 1149 | wmb(); | ||
| 1150 | alx_write_mem16(&alx->hw, ALX_TPD_PRI0_PIDX, txq->write_idx); | ||
| 1151 | |||
| 1152 | if (alx_tpd_avail(alx) < alx->tx_ringsz/8) | ||
| 1153 | netif_stop_queue(alx->dev); | ||
| 1154 | |||
| 1155 | return NETDEV_TX_OK; | ||
| 1156 | |||
| 1157 | drop: | ||
| 1158 | dev_kfree_skb(skb); | ||
| 1159 | return NETDEV_TX_OK; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | static void alx_tx_timeout(struct net_device *dev) | ||
| 1163 | { | ||
| 1164 | struct alx_priv *alx = netdev_priv(dev); | ||
| 1165 | |||
| 1166 | alx_schedule_reset(alx); | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | static int alx_mdio_read(struct net_device *netdev, | ||
| 1170 | int prtad, int devad, u16 addr) | ||
| 1171 | { | ||
| 1172 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 1173 | struct alx_hw *hw = &alx->hw; | ||
| 1174 | u16 val; | ||
| 1175 | int err; | ||
| 1176 | |||
| 1177 | if (prtad != hw->mdio.prtad) | ||
| 1178 | return -EINVAL; | ||
| 1179 | |||
| 1180 | if (devad == MDIO_DEVAD_NONE) | ||
| 1181 | err = alx_read_phy_reg(hw, addr, &val); | ||
| 1182 | else | ||
| 1183 | err = alx_read_phy_ext(hw, devad, addr, &val); | ||
| 1184 | |||
| 1185 | if (err) | ||
| 1186 | return err; | ||
| 1187 | return val; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | static int alx_mdio_write(struct net_device *netdev, | ||
| 1191 | int prtad, int devad, u16 addr, u16 val) | ||
| 1192 | { | ||
| 1193 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 1194 | struct alx_hw *hw = &alx->hw; | ||
| 1195 | |||
| 1196 | if (prtad != hw->mdio.prtad) | ||
| 1197 | return -EINVAL; | ||
| 1198 | |||
| 1199 | if (devad == MDIO_DEVAD_NONE) | ||
| 1200 | return alx_write_phy_reg(hw, addr, val); | ||
| 1201 | |||
| 1202 | return alx_write_phy_ext(hw, devad, addr, val); | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | static int alx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | ||
| 1206 | { | ||
| 1207 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 1208 | |||
| 1209 | if (!netif_running(netdev)) | ||
| 1210 | return -EAGAIN; | ||
| 1211 | |||
| 1212 | return mdio_mii_ioctl(&alx->hw.mdio, if_mii(ifr), cmd); | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 1216 | static void alx_poll_controller(struct net_device *netdev) | ||
| 1217 | { | ||
| 1218 | struct alx_priv *alx = netdev_priv(netdev); | ||
| 1219 | |||
| 1220 | if (alx->msi) | ||
| 1221 | alx_intr_msi(0, alx); | ||
| 1222 | else | ||
| 1223 | alx_intr_legacy(0, alx); | ||
| 1224 | } | ||
| 1225 | #endif | ||
| 1226 | |||
| 1227 | static const struct net_device_ops alx_netdev_ops = { | ||
| 1228 | .ndo_open = alx_open, | ||
| 1229 | .ndo_stop = alx_stop, | ||
| 1230 | .ndo_start_xmit = alx_start_xmit, | ||
| 1231 | .ndo_set_rx_mode = alx_set_rx_mode, | ||
| 1232 | .ndo_validate_addr = eth_validate_addr, | ||
| 1233 | .ndo_set_mac_address = alx_set_mac_address, | ||
| 1234 | .ndo_change_mtu = alx_change_mtu, | ||
| 1235 | .ndo_do_ioctl = alx_ioctl, | ||
| 1236 | .ndo_tx_timeout = alx_tx_timeout, | ||
| 1237 | .ndo_fix_features = alx_fix_features, | ||
| 1238 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 1239 | .ndo_poll_controller = alx_poll_controller, | ||
| 1240 | #endif | ||
| 1241 | }; | ||
| 1242 | |||
| 1243 | static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
| 1244 | { | ||
| 1245 | struct net_device *netdev; | ||
| 1246 | struct alx_priv *alx; | ||
| 1247 | struct alx_hw *hw; | ||
| 1248 | bool phy_configured; | ||
| 1249 | int bars, pm_cap, err; | ||
| 1250 | |||
| 1251 | err = pci_enable_device_mem(pdev); | ||
| 1252 | if (err) | ||
| 1253 | return err; | ||
| 1254 | |||
| 1255 | /* The alx chip can DMA to 64-bit addresses, but it uses a single | ||
| 1256 | * shared register for the high 32 bits, so only a single, aligned, | ||
| 1257 | * 4 GB physical address range can be used for descriptors. | ||
| 1258 | */ | ||
| 1259 | if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && | ||
| 1260 | !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { | ||
| 1261 | dev_dbg(&pdev->dev, "DMA to 64-BIT addresses\n"); | ||
| 1262 | } else { | ||
| 1263 | err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); | ||
| 1264 | if (err) { | ||
| 1265 | err = dma_set_coherent_mask(&pdev->dev, | ||
| 1266 | DMA_BIT_MASK(32)); | ||
| 1267 | if (err) { | ||
| 1268 | dev_err(&pdev->dev, | ||
| 1269 | "No usable DMA config, aborting\n"); | ||
| 1270 | goto out_pci_disable; | ||
| 1271 | } | ||
| 1272 | } | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
| 1276 | err = pci_request_selected_regions(pdev, bars, alx_drv_name); | ||
| 1277 | if (err) { | ||
| 1278 | dev_err(&pdev->dev, | ||
| 1279 | "pci_request_selected_regions failed(bars:%d)\n", bars); | ||
| 1280 | goto out_pci_disable; | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | pci_enable_pcie_error_reporting(pdev); | ||
| 1284 | pci_set_master(pdev); | ||
| 1285 | |||
| 1286 | pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
| 1287 | if (pm_cap == 0) { | ||
| 1288 | dev_err(&pdev->dev, | ||
| 1289 | "Can't find power management capability, aborting\n"); | ||
| 1290 | err = -EIO; | ||
| 1291 | goto out_pci_release; | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | err = pci_set_power_state(pdev, PCI_D0); | ||
| 1295 | if (err) | ||
| 1296 | goto out_pci_release; | ||
| 1297 | |||
| 1298 | netdev = alloc_etherdev(sizeof(*alx)); | ||
| 1299 | if (!netdev) { | ||
| 1300 | err = -ENOMEM; | ||
| 1301 | goto out_pci_release; | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
| 1305 | alx = netdev_priv(netdev); | ||
| 1306 | alx->dev = netdev; | ||
| 1307 | alx->hw.pdev = pdev; | ||
| 1308 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | | ||
| 1309 | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR | NETIF_MSG_WOL; | ||
| 1310 | hw = &alx->hw; | ||
| 1311 | pci_set_drvdata(pdev, alx); | ||
| 1312 | |||
| 1313 | hw->hw_addr = pci_ioremap_bar(pdev, 0); | ||
| 1314 | if (!hw->hw_addr) { | ||
| 1315 | dev_err(&pdev->dev, "cannot map device registers\n"); | ||
| 1316 | err = -EIO; | ||
| 1317 | goto out_free_netdev; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | netdev->netdev_ops = &alx_netdev_ops; | ||
| 1321 | SET_ETHTOOL_OPS(netdev, &alx_ethtool_ops); | ||
| 1322 | netdev->irq = pdev->irq; | ||
| 1323 | netdev->watchdog_timeo = ALX_WATCHDOG_TIME; | ||
| 1324 | |||
| 1325 | if (ent->driver_data & ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG) | ||
| 1326 | pdev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | ||
| 1327 | |||
| 1328 | err = alx_init_sw(alx); | ||
| 1329 | if (err) { | ||
| 1330 | dev_err(&pdev->dev, "net device private data init failed\n"); | ||
| 1331 | goto out_unmap; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | alx_reset_pcie(hw); | ||
| 1335 | |||
| 1336 | phy_configured = alx_phy_configured(hw); | ||
| 1337 | |||
| 1338 | if (!phy_configured) | ||
| 1339 | alx_reset_phy(hw); | ||
| 1340 | |||
| 1341 | err = alx_reset_mac(hw); | ||
| 1342 | if (err) { | ||
| 1343 | dev_err(&pdev->dev, "MAC Reset failed, error = %d\n", err); | ||
| 1344 | goto out_unmap; | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | /* setup link to put it in a known good starting state */ | ||
| 1348 | if (!phy_configured) { | ||
| 1349 | err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl); | ||
| 1350 | if (err) { | ||
| 1351 | dev_err(&pdev->dev, | ||
| 1352 | "failed to configure PHY speed/duplex (err=%d)\n", | ||
| 1353 | err); | ||
| 1354 | goto out_unmap; | ||
| 1355 | } | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM; | ||
| 1359 | |||
| 1360 | if (alx_get_perm_macaddr(hw, hw->perm_addr)) { | ||
| 1361 | dev_warn(&pdev->dev, | ||
| 1362 | "Invalid permanent address programmed, using random one\n"); | ||
| 1363 | eth_hw_addr_random(netdev); | ||
| 1364 | memcpy(hw->perm_addr, netdev->dev_addr, netdev->addr_len); | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | memcpy(hw->mac_addr, hw->perm_addr, ETH_ALEN); | ||
| 1368 | memcpy(netdev->dev_addr, hw->mac_addr, ETH_ALEN); | ||
| 1369 | memcpy(netdev->perm_addr, hw->perm_addr, ETH_ALEN); | ||
| 1370 | |||
| 1371 | hw->mdio.prtad = 0; | ||
| 1372 | hw->mdio.mmds = 0; | ||
| 1373 | hw->mdio.dev = netdev; | ||
| 1374 | hw->mdio.mode_support = MDIO_SUPPORTS_C45 | | ||
| 1375 | MDIO_SUPPORTS_C22 | | ||
| 1376 | MDIO_EMULATE_C22; | ||
| 1377 | hw->mdio.mdio_read = alx_mdio_read; | ||
| 1378 | hw->mdio.mdio_write = alx_mdio_write; | ||
| 1379 | |||
| 1380 | if (!alx_get_phy_info(hw)) { | ||
| 1381 | dev_err(&pdev->dev, "failed to identify PHY\n"); | ||
| 1382 | err = -EIO; | ||
| 1383 | goto out_unmap; | ||
| 1384 | } | ||
| 1385 | |||
| 1386 | INIT_WORK(&alx->link_check_wk, alx_link_check); | ||
| 1387 | INIT_WORK(&alx->reset_wk, alx_reset); | ||
| 1388 | spin_lock_init(&alx->hw.mdio_lock); | ||
| 1389 | spin_lock_init(&alx->irq_lock); | ||
| 1390 | |||
| 1391 | netif_carrier_off(netdev); | ||
| 1392 | |||
| 1393 | err = register_netdev(netdev); | ||
| 1394 | if (err) { | ||
| 1395 | dev_err(&pdev->dev, "register netdevice failed\n"); | ||
| 1396 | goto out_unmap; | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl); | ||
| 1400 | |||
| 1401 | netdev_info(netdev, | ||
| 1402 | "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n", | ||
| 1403 | netdev->dev_addr); | ||
| 1404 | |||
| 1405 | return 0; | ||
| 1406 | |||
| 1407 | out_unmap: | ||
| 1408 | iounmap(hw->hw_addr); | ||
| 1409 | out_free_netdev: | ||
| 1410 | free_netdev(netdev); | ||
| 1411 | out_pci_release: | ||
| 1412 | pci_release_selected_regions(pdev, bars); | ||
| 1413 | out_pci_disable: | ||
| 1414 | pci_disable_device(pdev); | ||
| 1415 | return err; | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | static void alx_remove(struct pci_dev *pdev) | ||
| 1419 | { | ||
| 1420 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
| 1421 | struct alx_hw *hw = &alx->hw; | ||
| 1422 | |||
| 1423 | cancel_work_sync(&alx->link_check_wk); | ||
| 1424 | cancel_work_sync(&alx->reset_wk); | ||
| 1425 | |||
| 1426 | /* restore permanent mac address */ | ||
| 1427 | alx_set_macaddr(hw, hw->perm_addr); | ||
| 1428 | |||
| 1429 | unregister_netdev(alx->dev); | ||
| 1430 | iounmap(hw->hw_addr); | ||
| 1431 | pci_release_selected_regions(pdev, | ||
| 1432 | pci_select_bars(pdev, IORESOURCE_MEM)); | ||
| 1433 | |||
| 1434 | pci_disable_pcie_error_reporting(pdev); | ||
| 1435 | pci_disable_device(pdev); | ||
| 1436 | pci_set_drvdata(pdev, NULL); | ||
| 1437 | |||
| 1438 | free_netdev(alx->dev); | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | #ifdef CONFIG_PM_SLEEP | ||
| 1442 | static int alx_suspend(struct device *dev) | ||
| 1443 | { | ||
| 1444 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 1445 | int err; | ||
| 1446 | bool wol_en; | ||
| 1447 | |||
| 1448 | err = __alx_shutdown(pdev, &wol_en); | ||
| 1449 | if (err) { | ||
| 1450 | dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err); | ||
| 1451 | return err; | ||
| 1452 | } | ||
| 1453 | |||
| 1454 | if (wol_en) { | ||
| 1455 | pci_prepare_to_sleep(pdev); | ||
| 1456 | } else { | ||
| 1457 | pci_wake_from_d3(pdev, false); | ||
| 1458 | pci_set_power_state(pdev, PCI_D3hot); | ||
| 1459 | } | ||
| 1460 | |||
| 1461 | return 0; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | static int alx_resume(struct device *dev) | ||
| 1465 | { | ||
| 1466 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 1467 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
| 1468 | struct net_device *netdev = alx->dev; | ||
| 1469 | struct alx_hw *hw = &alx->hw; | ||
| 1470 | int err; | ||
| 1471 | |||
| 1472 | pci_set_power_state(pdev, PCI_D0); | ||
| 1473 | pci_restore_state(pdev); | ||
| 1474 | pci_save_state(pdev); | ||
| 1475 | |||
| 1476 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
| 1477 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
| 1478 | |||
| 1479 | hw->link_speed = SPEED_UNKNOWN; | ||
| 1480 | alx->int_mask = ALX_ISR_MISC; | ||
| 1481 | |||
| 1482 | alx_reset_pcie(hw); | ||
| 1483 | alx_reset_phy(hw); | ||
| 1484 | |||
| 1485 | err = alx_reset_mac(hw); | ||
| 1486 | if (err) { | ||
| 1487 | netif_err(alx, hw, alx->dev, | ||
| 1488 | "resume:reset_mac fail %d\n", err); | ||
| 1489 | return -EIO; | ||
| 1490 | } | ||
| 1491 | |||
| 1492 | err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl); | ||
| 1493 | if (err) { | ||
| 1494 | netif_err(alx, hw, alx->dev, | ||
| 1495 | "resume:setup_speed_duplex fail %d\n", err); | ||
| 1496 | return -EIO; | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | if (netif_running(netdev)) { | ||
| 1500 | err = __alx_open(alx, true); | ||
| 1501 | if (err) | ||
| 1502 | return err; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | netif_device_attach(netdev); | ||
| 1506 | |||
| 1507 | return err; | ||
| 1508 | } | ||
| 1509 | #endif | ||
| 1510 | |||
| 1511 | static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev, | ||
| 1512 | pci_channel_state_t state) | ||
| 1513 | { | ||
| 1514 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
| 1515 | struct net_device *netdev = alx->dev; | ||
| 1516 | pci_ers_result_t rc = PCI_ERS_RESULT_NEED_RESET; | ||
| 1517 | |||
| 1518 | dev_info(&pdev->dev, "pci error detected\n"); | ||
| 1519 | |||
| 1520 | rtnl_lock(); | ||
| 1521 | |||
| 1522 | if (netif_running(netdev)) { | ||
| 1523 | netif_device_detach(netdev); | ||
| 1524 | alx_halt(alx); | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | if (state == pci_channel_io_perm_failure) | ||
| 1528 | rc = PCI_ERS_RESULT_DISCONNECT; | ||
| 1529 | else | ||
| 1530 | pci_disable_device(pdev); | ||
| 1531 | |||
| 1532 | rtnl_unlock(); | ||
| 1533 | |||
| 1534 | return rc; | ||
| 1535 | } | ||
| 1536 | |||
| 1537 | static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev) | ||
| 1538 | { | ||
| 1539 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
| 1540 | struct alx_hw *hw = &alx->hw; | ||
| 1541 | pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT; | ||
| 1542 | |||
| 1543 | dev_info(&pdev->dev, "pci error slot reset\n"); | ||
| 1544 | |||
| 1545 | rtnl_lock(); | ||
| 1546 | |||
| 1547 | if (pci_enable_device(pdev)) { | ||
| 1548 | dev_err(&pdev->dev, "Failed to re-enable PCI device after reset\n"); | ||
| 1549 | goto out; | ||
| 1550 | } | ||
| 1551 | |||
| 1552 | pci_set_master(pdev); | ||
| 1553 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
| 1554 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
| 1555 | |||
| 1556 | alx_reset_pcie(hw); | ||
| 1557 | if (!alx_reset_mac(hw)) | ||
| 1558 | rc = PCI_ERS_RESULT_RECOVERED; | ||
| 1559 | out: | ||
| 1560 | pci_cleanup_aer_uncorrect_error_status(pdev); | ||
| 1561 | |||
| 1562 | rtnl_unlock(); | ||
| 1563 | |||
| 1564 | return rc; | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | static void alx_pci_error_resume(struct pci_dev *pdev) | ||
| 1568 | { | ||
| 1569 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
| 1570 | struct net_device *netdev = alx->dev; | ||
| 1571 | |||
| 1572 | dev_info(&pdev->dev, "pci error resume\n"); | ||
| 1573 | |||
| 1574 | rtnl_lock(); | ||
| 1575 | |||
| 1576 | if (netif_running(netdev)) { | ||
| 1577 | alx_activate(alx); | ||
| 1578 | netif_device_attach(netdev); | ||
| 1579 | } | ||
| 1580 | |||
| 1581 | rtnl_unlock(); | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | static const struct pci_error_handlers alx_err_handlers = { | ||
| 1585 | .error_detected = alx_pci_error_detected, | ||
| 1586 | .slot_reset = alx_pci_error_slot_reset, | ||
| 1587 | .resume = alx_pci_error_resume, | ||
| 1588 | }; | ||
| 1589 | |||
| 1590 | #ifdef CONFIG_PM_SLEEP | ||
| 1591 | static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume); | ||
| 1592 | #define ALX_PM_OPS (&alx_pm_ops) | ||
| 1593 | #else | ||
| 1594 | #define ALX_PM_OPS NULL | ||
| 1595 | #endif | ||
| 1596 | |||
| 1597 | static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = { | ||
| 1598 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161), | ||
| 1599 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | ||
| 1600 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2200), | ||
| 1601 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | ||
| 1602 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162), | ||
| 1603 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | ||
| 1604 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) }, | ||
| 1605 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8172) }, | ||
| 1606 | {} | ||
| 1607 | }; | ||
| 1608 | |||
| 1609 | static struct pci_driver alx_driver = { | ||
| 1610 | .name = alx_drv_name, | ||
| 1611 | .id_table = alx_pci_tbl, | ||
| 1612 | .probe = alx_probe, | ||
| 1613 | .remove = alx_remove, | ||
| 1614 | .shutdown = alx_shutdown, | ||
| 1615 | .err_handler = &alx_err_handlers, | ||
| 1616 | .driver.pm = ALX_PM_OPS, | ||
| 1617 | }; | ||
| 1618 | |||
| 1619 | module_pci_driver(alx_driver); | ||
| 1620 | MODULE_DEVICE_TABLE(pci, alx_pci_tbl); | ||
| 1621 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); | ||
| 1622 | MODULE_AUTHOR("Qualcomm Corporation, <nic-devel@qualcomm.com>"); | ||
| 1623 | MODULE_DESCRIPTION( | ||
| 1624 | "Qualcomm Atheros(R) AR816x/AR817x PCI-E Ethernet Network Driver"); | ||
| 1625 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/atheros/alx/reg.h b/drivers/net/ethernet/atheros/alx/reg.h new file mode 100644 index 000000000000..e4358c98bc4e --- /dev/null +++ b/drivers/net/ethernet/atheros/alx/reg.h | |||
| @@ -0,0 +1,810 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net> | ||
| 3 | * | ||
| 4 | * This file is free software: you may copy, redistribute and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation, either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | * | ||
| 9 | * This file is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | * | ||
| 17 | * This file incorporates work covered by the following copyright and | ||
| 18 | * permission notice: | ||
| 19 | * | ||
| 20 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
| 21 | * | ||
| 22 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 23 | * purpose with or without fee is hereby granted, provided that the above | ||
| 24 | * copyright notice and this permission notice appear in all copies. | ||
| 25 | * | ||
| 26 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 27 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 28 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 29 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 30 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 31 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 32 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #ifndef ALX_REG_H | ||
| 36 | #define ALX_REG_H | ||
| 37 | |||
| 38 | #define ALX_DEV_ID_AR8161 0x1091 | ||
| 39 | #define ALX_DEV_ID_E2200 0xe091 | ||
| 40 | #define ALX_DEV_ID_AR8162 0x1090 | ||
| 41 | #define ALX_DEV_ID_AR8171 0x10A1 | ||
| 42 | #define ALX_DEV_ID_AR8172 0x10A0 | ||
| 43 | |||
| 44 | /* rev definition, | ||
| 45 | * bit(0): with xD support | ||
| 46 | * bit(1): with Card Reader function | ||
| 47 | * bit(7:2): real revision | ||
| 48 | */ | ||
| 49 | #define ALX_PCI_REVID_SHIFT 3 | ||
| 50 | #define ALX_REV_A0 0 | ||
| 51 | #define ALX_REV_A1 1 | ||
| 52 | #define ALX_REV_B0 2 | ||
| 53 | #define ALX_REV_C0 3 | ||
| 54 | |||
| 55 | #define ALX_DEV_CTRL 0x0060 | ||
| 56 | #define ALX_DEV_CTRL_MAXRRS_MIN 2 | ||
| 57 | |||
| 58 | #define ALX_MSIX_MASK 0x0090 | ||
| 59 | |||
| 60 | #define ALX_UE_SVRT 0x010C | ||
| 61 | #define ALX_UE_SVRT_FCPROTERR BIT(13) | ||
| 62 | #define ALX_UE_SVRT_DLPROTERR BIT(4) | ||
| 63 | |||
| 64 | /* eeprom & flash load register */ | ||
| 65 | #define ALX_EFLD 0x0204 | ||
| 66 | #define ALX_EFLD_F_EXIST BIT(10) | ||
| 67 | #define ALX_EFLD_E_EXIST BIT(9) | ||
| 68 | #define ALX_EFLD_STAT BIT(5) | ||
| 69 | #define ALX_EFLD_START BIT(0) | ||
| 70 | |||
| 71 | /* eFuse load register */ | ||
| 72 | #define ALX_SLD 0x0218 | ||
| 73 | #define ALX_SLD_STAT BIT(12) | ||
| 74 | #define ALX_SLD_START BIT(11) | ||
| 75 | #define ALX_SLD_MAX_TO 100 | ||
| 76 | |||
| 77 | #define ALX_PDLL_TRNS1 0x1104 | ||
| 78 | #define ALX_PDLL_TRNS1_D3PLLOFF_EN BIT(11) | ||
| 79 | |||
| 80 | #define ALX_PMCTRL 0x12F8 | ||
| 81 | #define ALX_PMCTRL_HOTRST_WTEN BIT(31) | ||
| 82 | /* bit30: L0s/L1 controlled by MAC based on throughput(setting in 15A0) */ | ||
| 83 | #define ALX_PMCTRL_ASPM_FCEN BIT(30) | ||
| 84 | #define ALX_PMCTRL_SADLY_EN BIT(29) | ||
| 85 | #define ALX_PMCTRL_LCKDET_TIMER_MASK 0xF | ||
| 86 | #define ALX_PMCTRL_LCKDET_TIMER_SHIFT 24 | ||
| 87 | #define ALX_PMCTRL_LCKDET_TIMER_DEF 0xC | ||
| 88 | /* bit[23:20] if pm_request_l1 time > @, then enter L0s not L1 */ | ||
| 89 | #define ALX_PMCTRL_L1REQ_TO_MASK 0xF | ||
| 90 | #define ALX_PMCTRL_L1REQ_TO_SHIFT 20 | ||
| 91 | #define ALX_PMCTRL_L1REG_TO_DEF 0xF | ||
| 92 | #define ALX_PMCTRL_TXL1_AFTER_L0S BIT(19) | ||
| 93 | #define ALX_PMCTRL_L1_TIMER_MASK 0x7 | ||
| 94 | #define ALX_PMCTRL_L1_TIMER_SHIFT 16 | ||
| 95 | #define ALX_PMCTRL_L1_TIMER_16US 4 | ||
| 96 | #define ALX_PMCTRL_RCVR_WT_1US BIT(15) | ||
| 97 | /* bit13: enable pcie clk switch in L1 state */ | ||
| 98 | #define ALX_PMCTRL_L1_CLKSW_EN BIT(13) | ||
| 99 | #define ALX_PMCTRL_L0S_EN BIT(12) | ||
| 100 | #define ALX_PMCTRL_RXL1_AFTER_L0S BIT(11) | ||
| 101 | #define ALX_PMCTRL_L1_BUFSRX_EN BIT(7) | ||
| 102 | /* bit6: power down serdes RX */ | ||
| 103 | #define ALX_PMCTRL_L1_SRDSRX_PWD BIT(6) | ||
| 104 | #define ALX_PMCTRL_L1_SRDSPLL_EN BIT(5) | ||
| 105 | #define ALX_PMCTRL_L1_SRDS_EN BIT(4) | ||
| 106 | #define ALX_PMCTRL_L1_EN BIT(3) | ||
| 107 | |||
| 108 | /*******************************************************/ | ||
| 109 | /* following registers are mapped only to memory space */ | ||
| 110 | /*******************************************************/ | ||
| 111 | |||
| 112 | #define ALX_MASTER 0x1400 | ||
| 113 | /* bit12: 1:alwys select pclk from serdes, not sw to 25M */ | ||
| 114 | #define ALX_MASTER_PCLKSEL_SRDS BIT(12) | ||
| 115 | /* bit11: irq moduration for rx */ | ||
| 116 | #define ALX_MASTER_IRQMOD2_EN BIT(11) | ||
| 117 | /* bit10: irq moduration for tx/rx */ | ||
| 118 | #define ALX_MASTER_IRQMOD1_EN BIT(10) | ||
| 119 | #define ALX_MASTER_SYSALVTIMER_EN BIT(7) | ||
| 120 | #define ALX_MASTER_OOB_DIS BIT(6) | ||
| 121 | /* bit5: wakeup without pcie clk */ | ||
| 122 | #define ALX_MASTER_WAKEN_25M BIT(5) | ||
| 123 | /* bit0: MAC & DMA reset */ | ||
| 124 | #define ALX_MASTER_DMA_MAC_RST BIT(0) | ||
| 125 | #define ALX_DMA_MAC_RST_TO 50 | ||
| 126 | |||
| 127 | #define ALX_IRQ_MODU_TIMER 0x1408 | ||
| 128 | #define ALX_IRQ_MODU_TIMER1_MASK 0xFFFF | ||
| 129 | #define ALX_IRQ_MODU_TIMER1_SHIFT 0 | ||
| 130 | |||
| 131 | #define ALX_PHY_CTRL 0x140C | ||
| 132 | #define ALX_PHY_CTRL_100AB_EN BIT(17) | ||
| 133 | /* bit14: affect MAC & PHY, go to low power sts */ | ||
| 134 | #define ALX_PHY_CTRL_POWER_DOWN BIT(14) | ||
| 135 | /* bit13: 1:pll always ON, 0:can switch in lpw */ | ||
| 136 | #define ALX_PHY_CTRL_PLL_ON BIT(13) | ||
| 137 | #define ALX_PHY_CTRL_RST_ANALOG BIT(12) | ||
| 138 | #define ALX_PHY_CTRL_HIB_PULSE BIT(11) | ||
| 139 | #define ALX_PHY_CTRL_HIB_EN BIT(10) | ||
| 140 | #define ALX_PHY_CTRL_IDDQ BIT(7) | ||
| 141 | #define ALX_PHY_CTRL_GATE_25M BIT(5) | ||
| 142 | #define ALX_PHY_CTRL_LED_MODE BIT(2) | ||
| 143 | /* bit0: out of dsp RST state */ | ||
| 144 | #define ALX_PHY_CTRL_DSPRST_OUT BIT(0) | ||
| 145 | #define ALX_PHY_CTRL_DSPRST_TO 80 | ||
| 146 | #define ALX_PHY_CTRL_CLS (ALX_PHY_CTRL_LED_MODE | \ | ||
| 147 | ALX_PHY_CTRL_100AB_EN | \ | ||
| 148 | ALX_PHY_CTRL_PLL_ON) | ||
| 149 | |||
| 150 | #define ALX_MAC_STS 0x1410 | ||
| 151 | #define ALX_MAC_STS_TXQ_BUSY BIT(3) | ||
| 152 | #define ALX_MAC_STS_RXQ_BUSY BIT(2) | ||
| 153 | #define ALX_MAC_STS_TXMAC_BUSY BIT(1) | ||
| 154 | #define ALX_MAC_STS_RXMAC_BUSY BIT(0) | ||
| 155 | #define ALX_MAC_STS_IDLE (ALX_MAC_STS_TXQ_BUSY | \ | ||
| 156 | ALX_MAC_STS_RXQ_BUSY | \ | ||
| 157 | ALX_MAC_STS_TXMAC_BUSY | \ | ||
| 158 | ALX_MAC_STS_RXMAC_BUSY) | ||
| 159 | |||
| 160 | #define ALX_MDIO 0x1414 | ||
| 161 | #define ALX_MDIO_MODE_EXT BIT(30) | ||
| 162 | #define ALX_MDIO_BUSY BIT(27) | ||
| 163 | #define ALX_MDIO_CLK_SEL_MASK 0x7 | ||
| 164 | #define ALX_MDIO_CLK_SEL_SHIFT 24 | ||
| 165 | #define ALX_MDIO_CLK_SEL_25MD4 0 | ||
| 166 | #define ALX_MDIO_CLK_SEL_25MD128 7 | ||
| 167 | #define ALX_MDIO_START BIT(23) | ||
| 168 | #define ALX_MDIO_SPRES_PRMBL BIT(22) | ||
| 169 | /* bit21: 1:read,0:write */ | ||
| 170 | #define ALX_MDIO_OP_READ BIT(21) | ||
| 171 | #define ALX_MDIO_REG_MASK 0x1F | ||
| 172 | #define ALX_MDIO_REG_SHIFT 16 | ||
| 173 | #define ALX_MDIO_DATA_MASK 0xFFFF | ||
| 174 | #define ALX_MDIO_DATA_SHIFT 0 | ||
| 175 | #define ALX_MDIO_MAX_AC_TO 120 | ||
| 176 | |||
| 177 | #define ALX_MDIO_EXTN 0x1448 | ||
| 178 | #define ALX_MDIO_EXTN_DEVAD_MASK 0x1F | ||
| 179 | #define ALX_MDIO_EXTN_DEVAD_SHIFT 16 | ||
| 180 | #define ALX_MDIO_EXTN_REG_MASK 0xFFFF | ||
| 181 | #define ALX_MDIO_EXTN_REG_SHIFT 0 | ||
| 182 | |||
| 183 | #define ALX_SERDES 0x1424 | ||
| 184 | #define ALX_SERDES_PHYCLK_SLWDWN BIT(18) | ||
| 185 | #define ALX_SERDES_MACCLK_SLWDWN BIT(17) | ||
| 186 | |||
| 187 | #define ALX_LPI_CTRL 0x1440 | ||
| 188 | #define ALX_LPI_CTRL_EN BIT(0) | ||
| 189 | |||
| 190 | /* for B0+, bit[13..] for C0+ */ | ||
| 191 | #define ALX_HRTBT_EXT_CTRL 0x1AD0 | ||
| 192 | #define L1F_HRTBT_EXT_CTRL_PERIOD_HIGH_MASK 0x3F | ||
| 193 | #define L1F_HRTBT_EXT_CTRL_PERIOD_HIGH_SHIFT 24 | ||
| 194 | #define L1F_HRTBT_EXT_CTRL_SWOI_STARTUP_PKT_EN BIT(23) | ||
| 195 | #define L1F_HRTBT_EXT_CTRL_IOAC_2_FRAGMENTED BIT(22) | ||
| 196 | #define L1F_HRTBT_EXT_CTRL_IOAC_1_FRAGMENTED BIT(21) | ||
| 197 | #define L1F_HRTBT_EXT_CTRL_IOAC_1_KEEPALIVE_EN BIT(20) | ||
| 198 | #define L1F_HRTBT_EXT_CTRL_IOAC_1_HAS_VLAN BIT(19) | ||
| 199 | #define L1F_HRTBT_EXT_CTRL_IOAC_1_IS_8023 BIT(18) | ||
| 200 | #define L1F_HRTBT_EXT_CTRL_IOAC_1_IS_IPV6 BIT(17) | ||
| 201 | #define L1F_HRTBT_EXT_CTRL_IOAC_2_KEEPALIVE_EN BIT(16) | ||
| 202 | #define L1F_HRTBT_EXT_CTRL_IOAC_2_HAS_VLAN BIT(15) | ||
| 203 | #define L1F_HRTBT_EXT_CTRL_IOAC_2_IS_8023 BIT(14) | ||
| 204 | #define L1F_HRTBT_EXT_CTRL_IOAC_2_IS_IPV6 BIT(13) | ||
| 205 | #define ALX_HRTBT_EXT_CTRL_NS_EN BIT(12) | ||
| 206 | #define ALX_HRTBT_EXT_CTRL_FRAG_LEN_MASK 0xFF | ||
| 207 | #define ALX_HRTBT_EXT_CTRL_FRAG_LEN_SHIFT 4 | ||
| 208 | #define ALX_HRTBT_EXT_CTRL_IS_8023 BIT(3) | ||
| 209 | #define ALX_HRTBT_EXT_CTRL_IS_IPV6 BIT(2) | ||
| 210 | #define ALX_HRTBT_EXT_CTRL_WAKEUP_EN BIT(1) | ||
| 211 | #define ALX_HRTBT_EXT_CTRL_ARP_EN BIT(0) | ||
| 212 | |||
| 213 | #define ALX_HRTBT_REM_IPV4_ADDR 0x1AD4 | ||
| 214 | #define ALX_HRTBT_HOST_IPV4_ADDR 0x1478 | ||
| 215 | #define ALX_HRTBT_REM_IPV6_ADDR3 0x1AD8 | ||
| 216 | #define ALX_HRTBT_REM_IPV6_ADDR2 0x1ADC | ||
| 217 | #define ALX_HRTBT_REM_IPV6_ADDR1 0x1AE0 | ||
| 218 | #define ALX_HRTBT_REM_IPV6_ADDR0 0x1AE4 | ||
| 219 | |||
| 220 | /* 1B8C ~ 1B94 for C0+ */ | ||
| 221 | #define ALX_SWOI_ACER_CTRL 0x1B8C | ||
| 222 | #define ALX_SWOI_ORIG_ACK_NAK_EN BIT(20) | ||
| 223 | #define ALX_SWOI_ORIG_ACK_NAK_PKT_LEN_MASK 0XFF | ||
| 224 | #define ALX_SWOI_ORIG_ACK_NAK_PKT_LEN_SHIFT 12 | ||
| 225 | #define ALX_SWOI_ORIG_ACK_ADDR_MASK 0XFFF | ||
| 226 | #define ALX_SWOI_ORIG_ACK_ADDR_SHIFT 0 | ||
| 227 | |||
| 228 | #define ALX_SWOI_IOAC_CTRL_2 0x1B90 | ||
| 229 | #define ALX_SWOI_IOAC_CTRL_2_SWOI_1_FRAG_LEN_MASK 0xFF | ||
| 230 | #define ALX_SWOI_IOAC_CTRL_2_SWOI_1_FRAG_LEN_SHIFT 24 | ||
| 231 | #define ALX_SWOI_IOAC_CTRL_2_SWOI_1_PKT_LEN_MASK 0xFFF | ||
| 232 | #define ALX_SWOI_IOAC_CTRL_2_SWOI_1_PKT_LEN_SHIFT 12 | ||
| 233 | #define ALX_SWOI_IOAC_CTRL_2_SWOI_1_HDR_ADDR_MASK 0xFFF | ||
| 234 | #define ALX_SWOI_IOAC_CTRL_2_SWOI_1_HDR_ADDR_SHIFT 0 | ||
| 235 | |||
| 236 | #define ALX_SWOI_IOAC_CTRL_3 0x1B94 | ||
| 237 | #define ALX_SWOI_IOAC_CTRL_3_SWOI_2_FRAG_LEN_MASK 0xFF | ||
| 238 | #define ALX_SWOI_IOAC_CTRL_3_SWOI_2_FRAG_LEN_SHIFT 24 | ||
| 239 | #define ALX_SWOI_IOAC_CTRL_3_SWOI_2_PKT_LEN_MASK 0xFFF | ||
| 240 | #define ALX_SWOI_IOAC_CTRL_3_SWOI_2_PKT_LEN_SHIFT 12 | ||
| 241 | #define ALX_SWOI_IOAC_CTRL_3_SWOI_2_HDR_ADDR_MASK 0xFFF | ||
| 242 | #define ALX_SWOI_IOAC_CTRL_3_SWOI_2_HDR_ADDR_SHIFT 0 | ||
| 243 | |||
| 244 | /* for B0 */ | ||
| 245 | #define ALX_IDLE_DECISN_TIMER 0x1474 | ||
| 246 | /* 1ms */ | ||
| 247 | #define ALX_IDLE_DECISN_TIMER_DEF 0x400 | ||
| 248 | |||
| 249 | #define ALX_MAC_CTRL 0x1480 | ||
| 250 | #define ALX_MAC_CTRL_FAST_PAUSE BIT(31) | ||
| 251 | #define ALX_MAC_CTRL_WOLSPED_SWEN BIT(30) | ||
| 252 | /* bit29: 1:legacy(hi5b), 0:marvl(lo5b)*/ | ||
| 253 | #define ALX_MAC_CTRL_MHASH_ALG_HI5B BIT(29) | ||
| 254 | #define ALX_MAC_CTRL_BRD_EN BIT(26) | ||
| 255 | #define ALX_MAC_CTRL_MULTIALL_EN BIT(25) | ||
| 256 | #define ALX_MAC_CTRL_SPEED_MASK 0x3 | ||
| 257 | #define ALX_MAC_CTRL_SPEED_SHIFT 20 | ||
| 258 | #define ALX_MAC_CTRL_SPEED_10_100 1 | ||
| 259 | #define ALX_MAC_CTRL_SPEED_1000 2 | ||
| 260 | #define ALX_MAC_CTRL_PROMISC_EN BIT(15) | ||
| 261 | #define ALX_MAC_CTRL_VLANSTRIP BIT(14) | ||
| 262 | #define ALX_MAC_CTRL_PRMBLEN_MASK 0xF | ||
| 263 | #define ALX_MAC_CTRL_PRMBLEN_SHIFT 10 | ||
| 264 | #define ALX_MAC_CTRL_PCRCE BIT(7) | ||
| 265 | #define ALX_MAC_CTRL_CRCE BIT(6) | ||
| 266 | #define ALX_MAC_CTRL_FULLD BIT(5) | ||
| 267 | #define ALX_MAC_CTRL_RXFC_EN BIT(3) | ||
| 268 | #define ALX_MAC_CTRL_TXFC_EN BIT(2) | ||
| 269 | #define ALX_MAC_CTRL_RX_EN BIT(1) | ||
| 270 | #define ALX_MAC_CTRL_TX_EN BIT(0) | ||
| 271 | |||
| 272 | #define ALX_STAD0 0x1488 | ||
| 273 | #define ALX_STAD1 0x148C | ||
| 274 | |||
| 275 | #define ALX_HASH_TBL0 0x1490 | ||
| 276 | #define ALX_HASH_TBL1 0x1494 | ||
| 277 | |||
| 278 | #define ALX_MTU 0x149C | ||
| 279 | #define ALX_MTU_JUMBO_TH 1514 | ||
| 280 | #define ALX_MTU_STD_ALGN 1536 | ||
| 281 | |||
| 282 | #define ALX_SRAM5 0x1524 | ||
| 283 | #define ALX_SRAM_RXF_LEN_MASK 0xFFF | ||
| 284 | #define ALX_SRAM_RXF_LEN_SHIFT 0 | ||
| 285 | #define ALX_SRAM_RXF_LEN_8K (8*1024) | ||
| 286 | |||
| 287 | #define ALX_SRAM9 0x1534 | ||
| 288 | #define ALX_SRAM_LOAD_PTR BIT(0) | ||
| 289 | |||
| 290 | #define ALX_RX_BASE_ADDR_HI 0x1540 | ||
| 291 | |||
| 292 | #define ALX_TX_BASE_ADDR_HI 0x1544 | ||
| 293 | |||
| 294 | #define ALX_RFD_ADDR_LO 0x1550 | ||
| 295 | #define ALX_RFD_RING_SZ 0x1560 | ||
| 296 | #define ALX_RFD_BUF_SZ 0x1564 | ||
| 297 | |||
| 298 | #define ALX_RRD_ADDR_LO 0x1568 | ||
| 299 | #define ALX_RRD_RING_SZ 0x1578 | ||
| 300 | |||
| 301 | /* pri3: highest, pri0: lowest */ | ||
| 302 | #define ALX_TPD_PRI3_ADDR_LO 0x14E4 | ||
| 303 | #define ALX_TPD_PRI2_ADDR_LO 0x14E0 | ||
| 304 | #define ALX_TPD_PRI1_ADDR_LO 0x157C | ||
| 305 | #define ALX_TPD_PRI0_ADDR_LO 0x1580 | ||
| 306 | |||
| 307 | /* producer index is 16bit */ | ||
| 308 | #define ALX_TPD_PRI3_PIDX 0x1618 | ||
| 309 | #define ALX_TPD_PRI2_PIDX 0x161A | ||
| 310 | #define ALX_TPD_PRI1_PIDX 0x15F0 | ||
| 311 | #define ALX_TPD_PRI0_PIDX 0x15F2 | ||
| 312 | |||
| 313 | /* consumer index is 16bit */ | ||
| 314 | #define ALX_TPD_PRI3_CIDX 0x161C | ||
| 315 | #define ALX_TPD_PRI2_CIDX 0x161E | ||
| 316 | #define ALX_TPD_PRI1_CIDX 0x15F4 | ||
| 317 | #define ALX_TPD_PRI0_CIDX 0x15F6 | ||
| 318 | |||
| 319 | #define ALX_TPD_RING_SZ 0x1584 | ||
| 320 | |||
| 321 | #define ALX_TXQ0 0x1590 | ||
| 322 | #define ALX_TXQ0_TXF_BURST_PREF_MASK 0xFFFF | ||
| 323 | #define ALX_TXQ0_TXF_BURST_PREF_SHIFT 16 | ||
| 324 | #define ALX_TXQ_TXF_BURST_PREF_DEF 0x200 | ||
| 325 | #define ALX_TXQ0_LSO_8023_EN BIT(7) | ||
| 326 | #define ALX_TXQ0_MODE_ENHANCE BIT(6) | ||
| 327 | #define ALX_TXQ0_EN BIT(5) | ||
| 328 | #define ALX_TXQ0_SUPT_IPOPT BIT(4) | ||
| 329 | #define ALX_TXQ0_TPD_BURSTPREF_MASK 0xF | ||
| 330 | #define ALX_TXQ0_TPD_BURSTPREF_SHIFT 0 | ||
| 331 | #define ALX_TXQ_TPD_BURSTPREF_DEF 5 | ||
| 332 | |||
| 333 | #define ALX_TXQ1 0x1594 | ||
| 334 | /* bit11: drop large packet, len > (rfd buf) */ | ||
| 335 | #define ALX_TXQ1_ERRLGPKT_DROP_EN BIT(11) | ||
| 336 | #define ALX_TXQ1_JUMBO_TSO_TH (7*1024) | ||
| 337 | |||
| 338 | #define ALX_RXQ0 0x15A0 | ||
| 339 | #define ALX_RXQ0_EN BIT(31) | ||
| 340 | #define ALX_RXQ0_RSS_HASH_EN BIT(29) | ||
| 341 | #define ALX_RXQ0_RSS_MODE_MASK 0x3 | ||
| 342 | #define ALX_RXQ0_RSS_MODE_SHIFT 26 | ||
| 343 | #define ALX_RXQ0_RSS_MODE_DIS 0 | ||
| 344 | #define ALX_RXQ0_RSS_MODE_MQMI 3 | ||
| 345 | #define ALX_RXQ0_NUM_RFD_PREF_MASK 0x3F | ||
| 346 | #define ALX_RXQ0_NUM_RFD_PREF_SHIFT 20 | ||
| 347 | #define ALX_RXQ0_NUM_RFD_PREF_DEF 8 | ||
| 348 | #define ALX_RXQ0_IDT_TBL_SIZE_MASK 0x1FF | ||
| 349 | #define ALX_RXQ0_IDT_TBL_SIZE_SHIFT 8 | ||
| 350 | #define ALX_RXQ0_IDT_TBL_SIZE_DEF 0x100 | ||
| 351 | #define ALX_RXQ0_IDT_TBL_SIZE_NORMAL 128 | ||
| 352 | #define ALX_RXQ0_IPV6_PARSE_EN BIT(7) | ||
| 353 | #define ALX_RXQ0_RSS_HSTYP_MASK 0xF | ||
| 354 | #define ALX_RXQ0_RSS_HSTYP_SHIFT 2 | ||
| 355 | #define ALX_RXQ0_RSS_HSTYP_IPV6_TCP_EN BIT(5) | ||
| 356 | #define ALX_RXQ0_RSS_HSTYP_IPV6_EN BIT(4) | ||
| 357 | #define ALX_RXQ0_RSS_HSTYP_IPV4_TCP_EN BIT(3) | ||
| 358 | #define ALX_RXQ0_RSS_HSTYP_IPV4_EN BIT(2) | ||
| 359 | #define ALX_RXQ0_RSS_HSTYP_ALL (ALX_RXQ0_RSS_HSTYP_IPV6_TCP_EN | \ | ||
| 360 | ALX_RXQ0_RSS_HSTYP_IPV4_TCP_EN | \ | ||
| 361 | ALX_RXQ0_RSS_HSTYP_IPV6_EN | \ | ||
| 362 | ALX_RXQ0_RSS_HSTYP_IPV4_EN) | ||
| 363 | #define ALX_RXQ0_ASPM_THRESH_MASK 0x3 | ||
| 364 | #define ALX_RXQ0_ASPM_THRESH_SHIFT 0 | ||
| 365 | #define ALX_RXQ0_ASPM_THRESH_100M 3 | ||
| 366 | |||
| 367 | #define ALX_RXQ2 0x15A8 | ||
| 368 | #define ALX_RXQ2_RXF_XOFF_THRESH_MASK 0xFFF | ||
| 369 | #define ALX_RXQ2_RXF_XOFF_THRESH_SHIFT 16 | ||
| 370 | #define ALX_RXQ2_RXF_XON_THRESH_MASK 0xFFF | ||
| 371 | #define ALX_RXQ2_RXF_XON_THRESH_SHIFT 0 | ||
| 372 | /* Size = tx-packet(1522) + IPG(12) + SOF(8) + 64(Pause) + IPG(12) + SOF(8) + | ||
| 373 | * rx-packet(1522) + delay-of-link(64) | ||
| 374 | * = 3212. | ||
| 375 | */ | ||
| 376 | #define ALX_RXQ2_RXF_FLOW_CTRL_RSVD 3212 | ||
| 377 | |||
| 378 | #define ALX_DMA 0x15C0 | ||
| 379 | #define ALX_DMA_RCHNL_SEL_MASK 0x3 | ||
| 380 | #define ALX_DMA_RCHNL_SEL_SHIFT 26 | ||
| 381 | #define ALX_DMA_WDLY_CNT_MASK 0xF | ||
| 382 | #define ALX_DMA_WDLY_CNT_SHIFT 16 | ||
| 383 | #define ALX_DMA_WDLY_CNT_DEF 4 | ||
| 384 | #define ALX_DMA_RDLY_CNT_MASK 0x1F | ||
| 385 | #define ALX_DMA_RDLY_CNT_SHIFT 11 | ||
| 386 | #define ALX_DMA_RDLY_CNT_DEF 15 | ||
| 387 | /* bit10: 0:tpd with pri, 1: data */ | ||
| 388 | #define ALX_DMA_RREQ_PRI_DATA BIT(10) | ||
| 389 | #define ALX_DMA_RREQ_BLEN_MASK 0x7 | ||
| 390 | #define ALX_DMA_RREQ_BLEN_SHIFT 4 | ||
| 391 | #define ALX_DMA_RORDER_MODE_MASK 0x7 | ||
| 392 | #define ALX_DMA_RORDER_MODE_SHIFT 0 | ||
| 393 | #define ALX_DMA_RORDER_MODE_OUT 4 | ||
| 394 | |||
| 395 | #define ALX_WOL0 0x14A0 | ||
| 396 | #define ALX_WOL0_PME_LINK BIT(5) | ||
| 397 | #define ALX_WOL0_LINK_EN BIT(4) | ||
| 398 | #define ALX_WOL0_PME_MAGIC_EN BIT(3) | ||
| 399 | #define ALX_WOL0_MAGIC_EN BIT(2) | ||
| 400 | |||
| 401 | #define ALX_RFD_PIDX 0x15E0 | ||
| 402 | |||
| 403 | #define ALX_RFD_CIDX 0x15F8 | ||
| 404 | |||
| 405 | /* MIB */ | ||
| 406 | #define ALX_MIB_BASE 0x1700 | ||
| 407 | #define ALX_MIB_RX_OK (ALX_MIB_BASE + 0) | ||
| 408 | #define ALX_MIB_RX_ERRADDR (ALX_MIB_BASE + 92) | ||
| 409 | #define ALX_MIB_TX_OK (ALX_MIB_BASE + 96) | ||
| 410 | #define ALX_MIB_TX_MCCNT (ALX_MIB_BASE + 192) | ||
| 411 | |||
| 412 | #define ALX_RX_STATS_BIN ALX_MIB_RX_OK | ||
| 413 | #define ALX_RX_STATS_END ALX_MIB_RX_ERRADDR | ||
| 414 | #define ALX_TX_STATS_BIN ALX_MIB_TX_OK | ||
| 415 | #define ALX_TX_STATS_END ALX_MIB_TX_MCCNT | ||
| 416 | |||
| 417 | #define ALX_ISR 0x1600 | ||
| 418 | #define ALX_ISR_DIS BIT(31) | ||
| 419 | #define ALX_ISR_RX_Q7 BIT(30) | ||
| 420 | #define ALX_ISR_RX_Q6 BIT(29) | ||
| 421 | #define ALX_ISR_RX_Q5 BIT(28) | ||
| 422 | #define ALX_ISR_RX_Q4 BIT(27) | ||
| 423 | #define ALX_ISR_PCIE_LNKDOWN BIT(26) | ||
| 424 | #define ALX_ISR_RX_Q3 BIT(19) | ||
| 425 | #define ALX_ISR_RX_Q2 BIT(18) | ||
| 426 | #define ALX_ISR_RX_Q1 BIT(17) | ||
| 427 | #define ALX_ISR_RX_Q0 BIT(16) | ||
| 428 | #define ALX_ISR_TX_Q0 BIT(15) | ||
| 429 | #define ALX_ISR_PHY BIT(12) | ||
| 430 | #define ALX_ISR_DMAW BIT(10) | ||
| 431 | #define ALX_ISR_DMAR BIT(9) | ||
| 432 | #define ALX_ISR_TXF_UR BIT(8) | ||
| 433 | #define ALX_ISR_TX_Q3 BIT(7) | ||
| 434 | #define ALX_ISR_TX_Q2 BIT(6) | ||
| 435 | #define ALX_ISR_TX_Q1 BIT(5) | ||
| 436 | #define ALX_ISR_RFD_UR BIT(4) | ||
| 437 | #define ALX_ISR_RXF_OV BIT(3) | ||
| 438 | #define ALX_ISR_MANU BIT(2) | ||
| 439 | #define ALX_ISR_TIMER BIT(1) | ||
| 440 | #define ALX_ISR_SMB BIT(0) | ||
| 441 | |||
| 442 | #define ALX_IMR 0x1604 | ||
| 443 | |||
| 444 | /* re-send assert msg if SW no response */ | ||
| 445 | #define ALX_INT_RETRIG 0x1608 | ||
| 446 | /* 40ms */ | ||
| 447 | #define ALX_INT_RETRIG_TO 20000 | ||
| 448 | |||
| 449 | #define ALX_SMB_TIMER 0x15C4 | ||
| 450 | |||
| 451 | #define ALX_TINT_TPD_THRSHLD 0x15C8 | ||
| 452 | |||
| 453 | #define ALX_TINT_TIMER 0x15CC | ||
| 454 | |||
| 455 | #define ALX_CLK_GATE 0x1814 | ||
| 456 | #define ALX_CLK_GATE_RXMAC BIT(5) | ||
| 457 | #define ALX_CLK_GATE_TXMAC BIT(4) | ||
| 458 | #define ALX_CLK_GATE_RXQ BIT(3) | ||
| 459 | #define ALX_CLK_GATE_TXQ BIT(2) | ||
| 460 | #define ALX_CLK_GATE_DMAR BIT(1) | ||
| 461 | #define ALX_CLK_GATE_DMAW BIT(0) | ||
| 462 | #define ALX_CLK_GATE_ALL (ALX_CLK_GATE_RXMAC | \ | ||
| 463 | ALX_CLK_GATE_TXMAC | \ | ||
| 464 | ALX_CLK_GATE_RXQ | \ | ||
| 465 | ALX_CLK_GATE_TXQ | \ | ||
| 466 | ALX_CLK_GATE_DMAR | \ | ||
| 467 | ALX_CLK_GATE_DMAW) | ||
| 468 | |||
| 469 | /* interop between drivers */ | ||
| 470 | #define ALX_DRV 0x1804 | ||
| 471 | #define ALX_DRV_PHY_AUTO BIT(28) | ||
| 472 | #define ALX_DRV_PHY_1000 BIT(27) | ||
| 473 | #define ALX_DRV_PHY_100 BIT(26) | ||
| 474 | #define ALX_DRV_PHY_10 BIT(25) | ||
| 475 | #define ALX_DRV_PHY_DUPLEX BIT(24) | ||
| 476 | /* bit23: adv Pause */ | ||
| 477 | #define ALX_DRV_PHY_PAUSE BIT(23) | ||
| 478 | /* bit22: adv Asym Pause */ | ||
| 479 | #define ALX_DRV_PHY_MASK 0xFF | ||
| 480 | #define ALX_DRV_PHY_SHIFT 21 | ||
| 481 | #define ALX_DRV_PHY_UNKNOWN 0 | ||
| 482 | |||
| 483 | /* flag of phy inited */ | ||
| 484 | #define ALX_PHY_INITED 0x003F | ||
| 485 | |||
| 486 | /* reg 1830 ~ 186C for C0+, 16 bit map patterns and wake packet detection */ | ||
| 487 | #define ALX_WOL_CTRL2 0x1830 | ||
| 488 | #define ALX_WOL_CTRL2_DATA_STORE BIT(3) | ||
| 489 | #define ALX_WOL_CTRL2_PTRN_EVT BIT(2) | ||
| 490 | #define ALX_WOL_CTRL2_PME_PTRN_EN BIT(1) | ||
| 491 | #define ALX_WOL_CTRL2_PTRN_EN BIT(0) | ||
| 492 | |||
| 493 | #define ALX_WOL_CTRL3 0x1834 | ||
| 494 | #define ALX_WOL_CTRL3_PTRN_ADDR_MASK 0xFFFFF | ||
| 495 | #define ALX_WOL_CTRL3_PTRN_ADDR_SHIFT 0 | ||
| 496 | |||
| 497 | #define ALX_WOL_CTRL4 0x1838 | ||
| 498 | #define ALX_WOL_CTRL4_PT15_MATCH BIT(31) | ||
| 499 | #define ALX_WOL_CTRL4_PT14_MATCH BIT(30) | ||
| 500 | #define ALX_WOL_CTRL4_PT13_MATCH BIT(29) | ||
| 501 | #define ALX_WOL_CTRL4_PT12_MATCH BIT(28) | ||
| 502 | #define ALX_WOL_CTRL4_PT11_MATCH BIT(27) | ||
| 503 | #define ALX_WOL_CTRL4_PT10_MATCH BIT(26) | ||
| 504 | #define ALX_WOL_CTRL4_PT9_MATCH BIT(25) | ||
| 505 | #define ALX_WOL_CTRL4_PT8_MATCH BIT(24) | ||
| 506 | #define ALX_WOL_CTRL4_PT7_MATCH BIT(23) | ||
| 507 | #define ALX_WOL_CTRL4_PT6_MATCH BIT(22) | ||
| 508 | #define ALX_WOL_CTRL4_PT5_MATCH BIT(21) | ||
| 509 | #define ALX_WOL_CTRL4_PT4_MATCH BIT(20) | ||
| 510 | #define ALX_WOL_CTRL4_PT3_MATCH BIT(19) | ||
| 511 | #define ALX_WOL_CTRL4_PT2_MATCH BIT(18) | ||
| 512 | #define ALX_WOL_CTRL4_PT1_MATCH BIT(17) | ||
| 513 | #define ALX_WOL_CTRL4_PT0_MATCH BIT(16) | ||
| 514 | #define ALX_WOL_CTRL4_PT15_EN BIT(15) | ||
| 515 | #define ALX_WOL_CTRL4_PT14_EN BIT(14) | ||
| 516 | #define ALX_WOL_CTRL4_PT13_EN BIT(13) | ||
| 517 | #define ALX_WOL_CTRL4_PT12_EN BIT(12) | ||
| 518 | #define ALX_WOL_CTRL4_PT11_EN BIT(11) | ||
| 519 | #define ALX_WOL_CTRL4_PT10_EN BIT(10) | ||
| 520 | #define ALX_WOL_CTRL4_PT9_EN BIT(9) | ||
| 521 | #define ALX_WOL_CTRL4_PT8_EN BIT(8) | ||
| 522 | #define ALX_WOL_CTRL4_PT7_EN BIT(7) | ||
| 523 | #define ALX_WOL_CTRL4_PT6_EN BIT(6) | ||
| 524 | #define ALX_WOL_CTRL4_PT5_EN BIT(5) | ||
| 525 | #define ALX_WOL_CTRL4_PT4_EN BIT(4) | ||
| 526 | #define ALX_WOL_CTRL4_PT3_EN BIT(3) | ||
| 527 | #define ALX_WOL_CTRL4_PT2_EN BIT(2) | ||
| 528 | #define ALX_WOL_CTRL4_PT1_EN BIT(1) | ||
| 529 | #define ALX_WOL_CTRL4_PT0_EN BIT(0) | ||
| 530 | |||
| 531 | #define ALX_WOL_CTRL5 0x183C | ||
| 532 | #define ALX_WOL_CTRL5_PT3_LEN_MASK 0xFF | ||
| 533 | #define ALX_WOL_CTRL5_PT3_LEN_SHIFT 24 | ||
| 534 | #define ALX_WOL_CTRL5_PT2_LEN_MASK 0xFF | ||
| 535 | #define ALX_WOL_CTRL5_PT2_LEN_SHIFT 16 | ||
| 536 | #define ALX_WOL_CTRL5_PT1_LEN_MASK 0xFF | ||
| 537 | #define ALX_WOL_CTRL5_PT1_LEN_SHIFT 8 | ||
| 538 | #define ALX_WOL_CTRL5_PT0_LEN_MASK 0xFF | ||
| 539 | #define ALX_WOL_CTRL5_PT0_LEN_SHIFT 0 | ||
| 540 | |||
| 541 | #define ALX_WOL_CTRL6 0x1840 | ||
| 542 | #define ALX_WOL_CTRL5_PT7_LEN_MASK 0xFF | ||
| 543 | #define ALX_WOL_CTRL5_PT7_LEN_SHIFT 24 | ||
| 544 | #define ALX_WOL_CTRL5_PT6_LEN_MASK 0xFF | ||
| 545 | #define ALX_WOL_CTRL5_PT6_LEN_SHIFT 16 | ||
| 546 | #define ALX_WOL_CTRL5_PT5_LEN_MASK 0xFF | ||
| 547 | #define ALX_WOL_CTRL5_PT5_LEN_SHIFT 8 | ||
| 548 | #define ALX_WOL_CTRL5_PT4_LEN_MASK 0xFF | ||
| 549 | #define ALX_WOL_CTRL5_PT4_LEN_SHIFT 0 | ||
| 550 | |||
| 551 | #define ALX_WOL_CTRL7 0x1844 | ||
| 552 | #define ALX_WOL_CTRL5_PT11_LEN_MASK 0xFF | ||
| 553 | #define ALX_WOL_CTRL5_PT11_LEN_SHIFT 24 | ||
| 554 | #define ALX_WOL_CTRL5_PT10_LEN_MASK 0xFF | ||
| 555 | #define ALX_WOL_CTRL5_PT10_LEN_SHIFT 16 | ||
| 556 | #define ALX_WOL_CTRL5_PT9_LEN_MASK 0xFF | ||
| 557 | #define ALX_WOL_CTRL5_PT9_LEN_SHIFT 8 | ||
| 558 | #define ALX_WOL_CTRL5_PT8_LEN_MASK 0xFF | ||
| 559 | #define ALX_WOL_CTRL5_PT8_LEN_SHIFT 0 | ||
| 560 | |||
| 561 | #define ALX_WOL_CTRL8 0x1848 | ||
| 562 | #define ALX_WOL_CTRL5_PT15_LEN_MASK 0xFF | ||
| 563 | #define ALX_WOL_CTRL5_PT15_LEN_SHIFT 24 | ||
| 564 | #define ALX_WOL_CTRL5_PT14_LEN_MASK 0xFF | ||
| 565 | #define ALX_WOL_CTRL5_PT14_LEN_SHIFT 16 | ||
| 566 | #define ALX_WOL_CTRL5_PT13_LEN_MASK 0xFF | ||
| 567 | #define ALX_WOL_CTRL5_PT13_LEN_SHIFT 8 | ||
| 568 | #define ALX_WOL_CTRL5_PT12_LEN_MASK 0xFF | ||
| 569 | #define ALX_WOL_CTRL5_PT12_LEN_SHIFT 0 | ||
| 570 | |||
| 571 | #define ALX_ACER_FIXED_PTN0 0x1850 | ||
| 572 | #define ALX_ACER_FIXED_PTN0_MASK 0xFFFFFFFF | ||
| 573 | #define ALX_ACER_FIXED_PTN0_SHIFT 0 | ||
| 574 | |||
| 575 | #define ALX_ACER_FIXED_PTN1 0x1854 | ||
| 576 | #define ALX_ACER_FIXED_PTN1_MASK 0xFFFF | ||
| 577 | #define ALX_ACER_FIXED_PTN1_SHIFT 0 | ||
| 578 | |||
| 579 | #define ALX_ACER_RANDOM_NUM0 0x1858 | ||
| 580 | #define ALX_ACER_RANDOM_NUM0_MASK 0xFFFFFFFF | ||
| 581 | #define ALX_ACER_RANDOM_NUM0_SHIFT 0 | ||
| 582 | |||
| 583 | #define ALX_ACER_RANDOM_NUM1 0x185C | ||
| 584 | #define ALX_ACER_RANDOM_NUM1_MASK 0xFFFFFFFF | ||
| 585 | #define ALX_ACER_RANDOM_NUM1_SHIFT 0 | ||
| 586 | |||
| 587 | #define ALX_ACER_RANDOM_NUM2 0x1860 | ||
| 588 | #define ALX_ACER_RANDOM_NUM2_MASK 0xFFFFFFFF | ||
| 589 | #define ALX_ACER_RANDOM_NUM2_SHIFT 0 | ||
| 590 | |||
| 591 | #define ALX_ACER_RANDOM_NUM3 0x1864 | ||
| 592 | #define ALX_ACER_RANDOM_NUM3_MASK 0xFFFFFFFF | ||
| 593 | #define ALX_ACER_RANDOM_NUM3_SHIFT 0 | ||
| 594 | |||
| 595 | #define ALX_ACER_MAGIC 0x1868 | ||
| 596 | #define ALX_ACER_MAGIC_EN BIT(31) | ||
| 597 | #define ALX_ACER_MAGIC_PME_EN BIT(30) | ||
| 598 | #define ALX_ACER_MAGIC_MATCH BIT(29) | ||
| 599 | #define ALX_ACER_MAGIC_FF_CHECK BIT(10) | ||
| 600 | #define ALX_ACER_MAGIC_RAN_LEN_MASK 0x1F | ||
| 601 | #define ALX_ACER_MAGIC_RAN_LEN_SHIFT 5 | ||
| 602 | #define ALX_ACER_MAGIC_FIX_LEN_MASK 0x1F | ||
| 603 | #define ALX_ACER_MAGIC_FIX_LEN_SHIFT 0 | ||
| 604 | |||
| 605 | #define ALX_ACER_TIMER 0x186C | ||
| 606 | #define ALX_ACER_TIMER_EN BIT(31) | ||
| 607 | #define ALX_ACER_TIMER_PME_EN BIT(30) | ||
| 608 | #define ALX_ACER_TIMER_MATCH BIT(29) | ||
| 609 | #define ALX_ACER_TIMER_THRES_MASK 0x1FFFF | ||
| 610 | #define ALX_ACER_TIMER_THRES_SHIFT 0 | ||
| 611 | #define ALX_ACER_TIMER_THRES_DEF 1 | ||
| 612 | |||
| 613 | /* RSS definitions */ | ||
| 614 | #define ALX_RSS_KEY0 0x14B0 | ||
| 615 | #define ALX_RSS_KEY1 0x14B4 | ||
| 616 | #define ALX_RSS_KEY2 0x14B8 | ||
| 617 | #define ALX_RSS_KEY3 0x14BC | ||
| 618 | #define ALX_RSS_KEY4 0x14C0 | ||
| 619 | #define ALX_RSS_KEY5 0x14C4 | ||
| 620 | #define ALX_RSS_KEY6 0x14C8 | ||
| 621 | #define ALX_RSS_KEY7 0x14CC | ||
| 622 | #define ALX_RSS_KEY8 0x14D0 | ||
| 623 | #define ALX_RSS_KEY9 0x14D4 | ||
| 624 | |||
| 625 | #define ALX_RSS_IDT_TBL0 0x1B00 | ||
| 626 | |||
| 627 | #define ALX_MSI_MAP_TBL1 0x15D0 | ||
| 628 | #define ALX_MSI_MAP_TBL1_TXQ1_SHIFT 20 | ||
| 629 | #define ALX_MSI_MAP_TBL1_TXQ0_SHIFT 16 | ||
| 630 | #define ALX_MSI_MAP_TBL1_RXQ3_SHIFT 12 | ||
| 631 | #define ALX_MSI_MAP_TBL1_RXQ2_SHIFT 8 | ||
| 632 | #define ALX_MSI_MAP_TBL1_RXQ1_SHIFT 4 | ||
| 633 | #define ALX_MSI_MAP_TBL1_RXQ0_SHIFT 0 | ||
| 634 | |||
| 635 | #define ALX_MSI_MAP_TBL2 0x15D8 | ||
| 636 | #define ALX_MSI_MAP_TBL2_TXQ3_SHIFT 20 | ||
| 637 | #define ALX_MSI_MAP_TBL2_TXQ2_SHIFT 16 | ||
| 638 | #define ALX_MSI_MAP_TBL2_RXQ7_SHIFT 12 | ||
| 639 | #define ALX_MSI_MAP_TBL2_RXQ6_SHIFT 8 | ||
| 640 | #define ALX_MSI_MAP_TBL2_RXQ5_SHIFT 4 | ||
| 641 | #define ALX_MSI_MAP_TBL2_RXQ4_SHIFT 0 | ||
| 642 | |||
| 643 | #define ALX_MSI_ID_MAP 0x15D4 | ||
| 644 | |||
| 645 | #define ALX_MSI_RETRANS_TIMER 0x1920 | ||
| 646 | /* bit16: 1:line,0:standard */ | ||
| 647 | #define ALX_MSI_MASK_SEL_LINE BIT(16) | ||
| 648 | #define ALX_MSI_RETRANS_TM_MASK 0xFFFF | ||
| 649 | #define ALX_MSI_RETRANS_TM_SHIFT 0 | ||
| 650 | |||
| 651 | /* CR DMA ctrl */ | ||
| 652 | |||
| 653 | /* TX QoS */ | ||
| 654 | #define ALX_WRR 0x1938 | ||
| 655 | #define ALX_WRR_PRI_MASK 0x3 | ||
| 656 | #define ALX_WRR_PRI_SHIFT 29 | ||
| 657 | #define ALX_WRR_PRI_RESTRICT_NONE 3 | ||
| 658 | #define ALX_WRR_PRI3_MASK 0x1F | ||
| 659 | #define ALX_WRR_PRI3_SHIFT 24 | ||
| 660 | #define ALX_WRR_PRI2_MASK 0x1F | ||
| 661 | #define ALX_WRR_PRI2_SHIFT 16 | ||
| 662 | #define ALX_WRR_PRI1_MASK 0x1F | ||
| 663 | #define ALX_WRR_PRI1_SHIFT 8 | ||
| 664 | #define ALX_WRR_PRI0_MASK 0x1F | ||
| 665 | #define ALX_WRR_PRI0_SHIFT 0 | ||
| 666 | |||
| 667 | #define ALX_HQTPD 0x193C | ||
| 668 | #define ALX_HQTPD_BURST_EN BIT(31) | ||
| 669 | #define ALX_HQTPD_Q3_NUMPREF_MASK 0xF | ||
| 670 | #define ALX_HQTPD_Q3_NUMPREF_SHIFT 8 | ||
| 671 | #define ALX_HQTPD_Q2_NUMPREF_MASK 0xF | ||
| 672 | #define ALX_HQTPD_Q2_NUMPREF_SHIFT 4 | ||
| 673 | #define ALX_HQTPD_Q1_NUMPREF_MASK 0xF | ||
| 674 | #define ALX_HQTPD_Q1_NUMPREF_SHIFT 0 | ||
| 675 | |||
| 676 | #define ALX_MISC 0x19C0 | ||
| 677 | #define ALX_MISC_PSW_OCP_MASK 0x7 | ||
| 678 | #define ALX_MISC_PSW_OCP_SHIFT 21 | ||
| 679 | #define ALX_MISC_PSW_OCP_DEF 0x7 | ||
| 680 | #define ALX_MISC_ISO_EN BIT(12) | ||
| 681 | #define ALX_MISC_INTNLOSC_OPEN BIT(3) | ||
| 682 | |||
| 683 | #define ALX_MSIC2 0x19C8 | ||
| 684 | #define ALX_MSIC2_CALB_START BIT(0) | ||
| 685 | |||
| 686 | #define ALX_MISC3 0x19CC | ||
| 687 | /* bit1: 1:Software control 25M */ | ||
| 688 | #define ALX_MISC3_25M_BY_SW BIT(1) | ||
| 689 | /* bit0: 25M switch to intnl OSC */ | ||
| 690 | #define ALX_MISC3_25M_NOTO_INTNL BIT(0) | ||
| 691 | |||
| 692 | /* MSIX tbl in memory space */ | ||
| 693 | #define ALX_MSIX_ENTRY_BASE 0x2000 | ||
| 694 | |||
| 695 | /********************* PHY regs definition ***************************/ | ||
| 696 | |||
| 697 | /* PHY Specific Status Register */ | ||
| 698 | #define ALX_MII_GIGA_PSSR 0x11 | ||
| 699 | #define ALX_GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800 | ||
| 700 | #define ALX_GIGA_PSSR_DPLX 0x2000 | ||
| 701 | #define ALX_GIGA_PSSR_SPEED 0xC000 | ||
| 702 | #define ALX_GIGA_PSSR_10MBS 0x0000 | ||
| 703 | #define ALX_GIGA_PSSR_100MBS 0x4000 | ||
| 704 | #define ALX_GIGA_PSSR_1000MBS 0x8000 | ||
| 705 | |||
| 706 | /* PHY Interrupt Enable Register */ | ||
| 707 | #define ALX_MII_IER 0x12 | ||
| 708 | #define ALX_IER_LINK_UP 0x0400 | ||
| 709 | #define ALX_IER_LINK_DOWN 0x0800 | ||
| 710 | |||
| 711 | /* PHY Interrupt Status Register */ | ||
| 712 | #define ALX_MII_ISR 0x13 | ||
| 713 | |||
| 714 | #define ALX_MII_DBG_ADDR 0x1D | ||
| 715 | #define ALX_MII_DBG_DATA 0x1E | ||
| 716 | |||
| 717 | /***************************** debug port *************************************/ | ||
| 718 | |||
| 719 | #define ALX_MIIDBG_ANACTRL 0x00 | ||
| 720 | #define ALX_ANACTRL_DEF 0x02EF | ||
| 721 | |||
| 722 | #define ALX_MIIDBG_SYSMODCTRL 0x04 | ||
| 723 | /* en half bias */ | ||
| 724 | #define ALX_SYSMODCTRL_IECHOADJ_DEF 0xBB8B | ||
| 725 | |||
| 726 | #define ALX_MIIDBG_SRDSYSMOD 0x05 | ||
| 727 | #define ALX_SRDSYSMOD_DEEMP_EN 0x0040 | ||
| 728 | #define ALX_SRDSYSMOD_DEF 0x2C46 | ||
| 729 | |||
| 730 | #define ALX_MIIDBG_HIBNEG 0x0B | ||
| 731 | #define ALX_HIBNEG_PSHIB_EN 0x8000 | ||
| 732 | #define ALX_HIBNEG_HIB_PSE 0x1000 | ||
| 733 | #define ALX_HIBNEG_DEF 0xBC40 | ||
| 734 | #define ALX_HIBNEG_NOHIB (ALX_HIBNEG_DEF & \ | ||
| 735 | ~(ALX_HIBNEG_PSHIB_EN | ALX_HIBNEG_HIB_PSE)) | ||
| 736 | |||
| 737 | #define ALX_MIIDBG_TST10BTCFG 0x12 | ||
| 738 | #define ALX_TST10BTCFG_DEF 0x4C04 | ||
| 739 | |||
| 740 | #define ALX_MIIDBG_AZ_ANADECT 0x15 | ||
| 741 | #define ALX_AZ_ANADECT_DEF 0x3220 | ||
| 742 | #define ALX_AZ_ANADECT_LONG 0x3210 | ||
| 743 | |||
| 744 | #define ALX_MIIDBG_MSE16DB 0x18 | ||
| 745 | #define ALX_MSE16DB_UP 0x05EA | ||
| 746 | #define ALX_MSE16DB_DOWN 0x02EA | ||
| 747 | |||
| 748 | #define ALX_MIIDBG_MSE20DB 0x1C | ||
| 749 | #define ALX_MSE20DB_TH_MASK 0x7F | ||
| 750 | #define ALX_MSE20DB_TH_SHIFT 2 | ||
| 751 | #define ALX_MSE20DB_TH_DEF 0x2E | ||
| 752 | #define ALX_MSE20DB_TH_HI 0x54 | ||
| 753 | |||
| 754 | #define ALX_MIIDBG_AGC 0x23 | ||
| 755 | #define ALX_AGC_2_VGA_MASK 0x3FU | ||
| 756 | #define ALX_AGC_2_VGA_SHIFT 8 | ||
| 757 | #define ALX_AGC_LONG1G_LIMT 40 | ||
| 758 | #define ALX_AGC_LONG100M_LIMT 44 | ||
| 759 | |||
| 760 | #define ALX_MIIDBG_LEGCYPS 0x29 | ||
| 761 | #define ALX_LEGCYPS_EN 0x8000 | ||
| 762 | #define ALX_LEGCYPS_DEF 0x129D | ||
| 763 | |||
| 764 | #define ALX_MIIDBG_TST100BTCFG 0x36 | ||
| 765 | #define ALX_TST100BTCFG_DEF 0xE12C | ||
| 766 | |||
| 767 | #define ALX_MIIDBG_GREENCFG 0x3B | ||
| 768 | #define ALX_GREENCFG_DEF 0x7078 | ||
| 769 | |||
| 770 | #define ALX_MIIDBG_GREENCFG2 0x3D | ||
| 771 | #define ALX_GREENCFG2_BP_GREEN 0x8000 | ||
| 772 | #define ALX_GREENCFG2_GATE_DFSE_EN 0x0080 | ||
| 773 | |||
| 774 | /******* dev 3 *********/ | ||
| 775 | #define ALX_MIIEXT_PCS 3 | ||
| 776 | |||
| 777 | #define ALX_MIIEXT_CLDCTRL3 0x8003 | ||
| 778 | #define ALX_CLDCTRL3_BP_CABLE1TH_DET_GT 0x8000 | ||
| 779 | |||
| 780 | #define ALX_MIIEXT_CLDCTRL5 0x8005 | ||
| 781 | #define ALX_CLDCTRL5_BP_VD_HLFBIAS 0x4000 | ||
| 782 | |||
| 783 | #define ALX_MIIEXT_CLDCTRL6 0x8006 | ||
| 784 | #define ALX_CLDCTRL6_CAB_LEN_MASK 0xFF | ||
| 785 | #define ALX_CLDCTRL6_CAB_LEN_SHIFT 0 | ||
| 786 | #define ALX_CLDCTRL6_CAB_LEN_SHORT1G 116 | ||
| 787 | #define ALX_CLDCTRL6_CAB_LEN_SHORT100M 152 | ||
| 788 | |||
| 789 | #define ALX_MIIEXT_VDRVBIAS 0x8062 | ||
| 790 | #define ALX_VDRVBIAS_DEF 0x3 | ||
| 791 | |||
| 792 | /********* dev 7 **********/ | ||
| 793 | #define ALX_MIIEXT_ANEG 7 | ||
| 794 | |||
| 795 | #define ALX_MIIEXT_LOCAL_EEEADV 0x3C | ||
| 796 | #define ALX_LOCAL_EEEADV_1000BT 0x0004 | ||
| 797 | #define ALX_LOCAL_EEEADV_100BT 0x0002 | ||
| 798 | |||
| 799 | #define ALX_MIIEXT_AFE 0x801A | ||
| 800 | #define ALX_AFE_10BT_100M_TH 0x0040 | ||
| 801 | |||
| 802 | #define ALX_MIIEXT_S3DIG10 0x8023 | ||
| 803 | /* bit0: 1:bypass 10BT rx fifo, 0:original 10BT rx */ | ||
| 804 | #define ALX_MIIEXT_S3DIG10_SL 0x0001 | ||
| 805 | #define ALX_MIIEXT_S3DIG10_DEF 0 | ||
| 806 | |||
| 807 | #define ALX_MIIEXT_NLP78 0x8027 | ||
| 808 | #define ALX_MIIEXT_NLP78_120M_DEF 0x8A05 | ||
| 809 | |||
| 810 | #endif | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index c777b9013164..a13463e8a2c3 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -744,6 +744,9 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) | |||
| 744 | status = tg3_ape_read32(tp, gnt + off); | 744 | status = tg3_ape_read32(tp, gnt + off); |
| 745 | if (status == bit) | 745 | if (status == bit) |
| 746 | break; | 746 | break; |
| 747 | if (pci_channel_offline(tp->pdev)) | ||
| 748 | break; | ||
| 749 | |||
| 747 | udelay(10); | 750 | udelay(10); |
| 748 | } | 751 | } |
| 749 | 752 | ||
| @@ -1635,6 +1638,9 @@ static void tg3_wait_for_event_ack(struct tg3 *tp) | |||
| 1635 | for (i = 0; i < delay_cnt; i++) { | 1638 | for (i = 0; i < delay_cnt; i++) { |
| 1636 | if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) | 1639 | if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) |
| 1637 | break; | 1640 | break; |
| 1641 | if (pci_channel_offline(tp->pdev)) | ||
| 1642 | break; | ||
| 1643 | |||
| 1638 | udelay(8); | 1644 | udelay(8); |
| 1639 | } | 1645 | } |
| 1640 | } | 1646 | } |
| @@ -1813,6 +1819,9 @@ static int tg3_poll_fw(struct tg3 *tp) | |||
| 1813 | for (i = 0; i < 200; i++) { | 1819 | for (i = 0; i < 200; i++) { |
| 1814 | if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) | 1820 | if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) |
| 1815 | return 0; | 1821 | return 0; |
| 1822 | if (pci_channel_offline(tp->pdev)) | ||
| 1823 | return -ENODEV; | ||
| 1824 | |||
| 1816 | udelay(100); | 1825 | udelay(100); |
| 1817 | } | 1826 | } |
| 1818 | return -ENODEV; | 1827 | return -ENODEV; |
| @@ -1823,6 +1832,15 @@ static int tg3_poll_fw(struct tg3 *tp) | |||
| 1823 | tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); | 1832 | tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); |
| 1824 | if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) | 1833 | if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) |
| 1825 | break; | 1834 | break; |
| 1835 | if (pci_channel_offline(tp->pdev)) { | ||
| 1836 | if (!tg3_flag(tp, NO_FWARE_REPORTED)) { | ||
| 1837 | tg3_flag_set(tp, NO_FWARE_REPORTED); | ||
| 1838 | netdev_info(tp->dev, "No firmware running\n"); | ||
| 1839 | } | ||
| 1840 | |||
| 1841 | break; | ||
| 1842 | } | ||
| 1843 | |||
| 1826 | udelay(10); | 1844 | udelay(10); |
| 1827 | } | 1845 | } |
| 1828 | 1846 | ||
| @@ -3520,6 +3538,8 @@ static int tg3_pause_cpu(struct tg3 *tp, u32 cpu_base) | |||
| 3520 | tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); | 3538 | tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); |
| 3521 | if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT) | 3539 | if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT) |
| 3522 | break; | 3540 | break; |
| 3541 | if (pci_channel_offline(tp->pdev)) | ||
| 3542 | return -EBUSY; | ||
| 3523 | } | 3543 | } |
| 3524 | 3544 | ||
| 3525 | return (i == iters) ? -EBUSY : 0; | 3545 | return (i == iters) ? -EBUSY : 0; |
| @@ -8589,6 +8609,14 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, boo | |||
| 8589 | tw32_f(ofs, val); | 8609 | tw32_f(ofs, val); |
| 8590 | 8610 | ||
| 8591 | for (i = 0; i < MAX_WAIT_CNT; i++) { | 8611 | for (i = 0; i < MAX_WAIT_CNT; i++) { |
| 8612 | if (pci_channel_offline(tp->pdev)) { | ||
| 8613 | dev_err(&tp->pdev->dev, | ||
| 8614 | "tg3_stop_block device offline, " | ||
| 8615 | "ofs=%lx enable_bit=%x\n", | ||
| 8616 | ofs, enable_bit); | ||
| 8617 | return -ENODEV; | ||
| 8618 | } | ||
| 8619 | |||
| 8592 | udelay(100); | 8620 | udelay(100); |
| 8593 | val = tr32(ofs); | 8621 | val = tr32(ofs); |
| 8594 | if ((val & enable_bit) == 0) | 8622 | if ((val & enable_bit) == 0) |
| @@ -8612,6 +8640,13 @@ static int tg3_abort_hw(struct tg3 *tp, bool silent) | |||
| 8612 | 8640 | ||
| 8613 | tg3_disable_ints(tp); | 8641 | tg3_disable_ints(tp); |
| 8614 | 8642 | ||
| 8643 | if (pci_channel_offline(tp->pdev)) { | ||
| 8644 | tp->rx_mode &= ~(RX_MODE_ENABLE | TX_MODE_ENABLE); | ||
| 8645 | tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; | ||
| 8646 | err = -ENODEV; | ||
| 8647 | goto err_no_dev; | ||
| 8648 | } | ||
| 8649 | |||
| 8615 | tp->rx_mode &= ~RX_MODE_ENABLE; | 8650 | tp->rx_mode &= ~RX_MODE_ENABLE; |
| 8616 | tw32_f(MAC_RX_MODE, tp->rx_mode); | 8651 | tw32_f(MAC_RX_MODE, tp->rx_mode); |
| 8617 | udelay(10); | 8652 | udelay(10); |
| @@ -8660,6 +8695,7 @@ static int tg3_abort_hw(struct tg3 *tp, bool silent) | |||
| 8660 | err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); | 8695 | err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); |
| 8661 | err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); | 8696 | err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); |
| 8662 | 8697 | ||
| 8698 | err_no_dev: | ||
| 8663 | for (i = 0; i < tp->irq_cnt; i++) { | 8699 | for (i = 0; i < tp->irq_cnt; i++) { |
| 8664 | struct tg3_napi *tnapi = &tp->napi[i]; | 8700 | struct tg3_napi *tnapi = &tp->napi[i]; |
| 8665 | if (tnapi->hw_status) | 8701 | if (tnapi->hw_status) |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index a667015be22a..d48099f03b7f 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -516,6 +516,7 @@ fec_restart(struct net_device *ndev, int duplex) | |||
| 516 | /* Set MII speed */ | 516 | /* Set MII speed */ |
| 517 | writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); | 517 | writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); |
| 518 | 518 | ||
| 519 | #if !defined(CONFIG_M5272) | ||
| 519 | /* set RX checksum */ | 520 | /* set RX checksum */ |
| 520 | val = readl(fep->hwp + FEC_RACC); | 521 | val = readl(fep->hwp + FEC_RACC); |
| 521 | if (fep->csum_flags & FLAG_RX_CSUM_ENABLED) | 522 | if (fep->csum_flags & FLAG_RX_CSUM_ENABLED) |
| @@ -523,6 +524,7 @@ fec_restart(struct net_device *ndev, int duplex) | |||
| 523 | else | 524 | else |
| 524 | val &= ~FEC_RACC_OPTIONS; | 525 | val &= ~FEC_RACC_OPTIONS; |
| 525 | writel(val, fep->hwp + FEC_RACC); | 526 | writel(val, fep->hwp + FEC_RACC); |
| 527 | #endif | ||
| 526 | 528 | ||
| 527 | /* | 529 | /* |
| 528 | * The phy interface and speed need to get configured | 530 | * The phy interface and speed need to get configured |
| @@ -575,6 +577,7 @@ fec_restart(struct net_device *ndev, int duplex) | |||
| 575 | #endif | 577 | #endif |
| 576 | } | 578 | } |
| 577 | 579 | ||
| 580 | #if !defined(CONFIG_M5272) | ||
| 578 | /* enable pause frame*/ | 581 | /* enable pause frame*/ |
| 579 | if ((fep->pause_flag & FEC_PAUSE_FLAG_ENABLE) || | 582 | if ((fep->pause_flag & FEC_PAUSE_FLAG_ENABLE) || |
| 580 | ((fep->pause_flag & FEC_PAUSE_FLAG_AUTONEG) && | 583 | ((fep->pause_flag & FEC_PAUSE_FLAG_AUTONEG) && |
| @@ -592,6 +595,7 @@ fec_restart(struct net_device *ndev, int duplex) | |||
| 592 | } else { | 595 | } else { |
| 593 | rcntl &= ~FEC_ENET_FCE; | 596 | rcntl &= ~FEC_ENET_FCE; |
| 594 | } | 597 | } |
| 598 | #endif /* !defined(CONFIG_M5272) */ | ||
| 595 | 599 | ||
| 596 | writel(rcntl, fep->hwp + FEC_R_CNTRL); | 600 | writel(rcntl, fep->hwp + FEC_R_CNTRL); |
| 597 | 601 | ||
| @@ -1205,7 +1209,9 @@ static int fec_enet_mii_probe(struct net_device *ndev) | |||
| 1205 | /* mask with MAC supported features */ | 1209 | /* mask with MAC supported features */ |
| 1206 | if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) { | 1210 | if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) { |
| 1207 | phy_dev->supported &= PHY_GBIT_FEATURES; | 1211 | phy_dev->supported &= PHY_GBIT_FEATURES; |
| 1212 | #if !defined(CONFIG_M5272) | ||
| 1208 | phy_dev->supported |= SUPPORTED_Pause; | 1213 | phy_dev->supported |= SUPPORTED_Pause; |
| 1214 | #endif | ||
| 1209 | } | 1215 | } |
| 1210 | else | 1216 | else |
| 1211 | phy_dev->supported &= PHY_BASIC_FEATURES; | 1217 | phy_dev->supported &= PHY_BASIC_FEATURES; |
| @@ -1390,6 +1396,8 @@ static int fec_enet_get_ts_info(struct net_device *ndev, | |||
| 1390 | } | 1396 | } |
| 1391 | } | 1397 | } |
| 1392 | 1398 | ||
| 1399 | #if !defined(CONFIG_M5272) | ||
| 1400 | |||
| 1393 | static void fec_enet_get_pauseparam(struct net_device *ndev, | 1401 | static void fec_enet_get_pauseparam(struct net_device *ndev, |
| 1394 | struct ethtool_pauseparam *pause) | 1402 | struct ethtool_pauseparam *pause) |
| 1395 | { | 1403 | { |
| @@ -1436,9 +1444,13 @@ static int fec_enet_set_pauseparam(struct net_device *ndev, | |||
| 1436 | return 0; | 1444 | return 0; |
| 1437 | } | 1445 | } |
| 1438 | 1446 | ||
| 1447 | #endif /* !defined(CONFIG_M5272) */ | ||
| 1448 | |||
| 1439 | static const struct ethtool_ops fec_enet_ethtool_ops = { | 1449 | static const struct ethtool_ops fec_enet_ethtool_ops = { |
| 1450 | #if !defined(CONFIG_M5272) | ||
| 1440 | .get_pauseparam = fec_enet_get_pauseparam, | 1451 | .get_pauseparam = fec_enet_get_pauseparam, |
| 1441 | .set_pauseparam = fec_enet_set_pauseparam, | 1452 | .set_pauseparam = fec_enet_set_pauseparam, |
| 1453 | #endif | ||
| 1442 | .get_settings = fec_enet_get_settings, | 1454 | .get_settings = fec_enet_get_settings, |
| 1443 | .set_settings = fec_enet_set_settings, | 1455 | .set_settings = fec_enet_set_settings, |
| 1444 | .get_drvinfo = fec_enet_get_drvinfo, | 1456 | .get_drvinfo = fec_enet_get_drvinfo, |
| @@ -1874,10 +1886,12 @@ fec_probe(struct platform_device *pdev) | |||
| 1874 | /* setup board info structure */ | 1886 | /* setup board info structure */ |
| 1875 | fep = netdev_priv(ndev); | 1887 | fep = netdev_priv(ndev); |
| 1876 | 1888 | ||
| 1889 | #if !defined(CONFIG_M5272) | ||
| 1877 | /* default enable pause frame auto negotiation */ | 1890 | /* default enable pause frame auto negotiation */ |
| 1878 | if (pdev->id_entry && | 1891 | if (pdev->id_entry && |
| 1879 | (pdev->id_entry->driver_data & FEC_QUIRK_HAS_GBIT)) | 1892 | (pdev->id_entry->driver_data & FEC_QUIRK_HAS_GBIT)) |
| 1880 | fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG; | 1893 | fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG; |
| 1894 | #endif | ||
| 1881 | 1895 | ||
| 1882 | fep->hwp = devm_request_and_ioremap(&pdev->dev, r); | 1896 | fep->hwp = devm_request_and_ioremap(&pdev->dev, r); |
| 1883 | fep->pdev = pdev; | 1897 | fep->pdev = pdev; |
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 2ad1494efbb3..d1cbfb12c1ca 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
| @@ -1757,7 +1757,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) | |||
| 1757 | memset(rxq->rx_desc_area, 0, size); | 1757 | memset(rxq->rx_desc_area, 0, size); |
| 1758 | 1758 | ||
| 1759 | rxq->rx_desc_area_size = size; | 1759 | rxq->rx_desc_area_size = size; |
| 1760 | rxq->rx_skb = kmalloc_array(rxq->rx_ring_size, sizeof(*rxq->rx_skb), | 1760 | rxq->rx_skb = kcalloc(rxq->rx_ring_size, sizeof(*rxq->rx_skb), |
| 1761 | GFP_KERNEL); | 1761 | GFP_KERNEL); |
| 1762 | if (rxq->rx_skb == NULL) | 1762 | if (rxq->rx_skb == NULL) |
| 1763 | goto out_free; | 1763 | goto out_free; |
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 339bb323cb0c..1c8af8ba08d9 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c | |||
| @@ -1015,7 +1015,7 @@ static int rxq_init(struct net_device *dev) | |||
| 1015 | int rx_desc_num = pep->rx_ring_size; | 1015 | int rx_desc_num = pep->rx_ring_size; |
| 1016 | 1016 | ||
| 1017 | /* Allocate RX skb rings */ | 1017 | /* Allocate RX skb rings */ |
| 1018 | pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size, | 1018 | pep->rx_skb = kzalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size, |
| 1019 | GFP_KERNEL); | 1019 | GFP_KERNEL); |
| 1020 | if (!pep->rx_skb) | 1020 | if (!pep->rx_skb) |
| 1021 | return -ENOMEM; | 1021 | return -ENOMEM; |
| @@ -1076,7 +1076,7 @@ static int txq_init(struct net_device *dev) | |||
| 1076 | int size = 0, i = 0; | 1076 | int size = 0, i = 0; |
| 1077 | int tx_desc_num = pep->tx_ring_size; | 1077 | int tx_desc_num = pep->tx_ring_size; |
| 1078 | 1078 | ||
| 1079 | pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size, | 1079 | pep->tx_skb = kzalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size, |
| 1080 | GFP_KERNEL); | 1080 | GFP_KERNEL); |
| 1081 | if (!pep->tx_skb) | 1081 | if (!pep->tx_skb) |
| 1082 | return -ENOMEM; | 1082 | return -ENOMEM; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 2f4a26039e80..8a434997a0df 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -632,6 +632,9 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
| 632 | dev->caps.cqe_size = 32; | 632 | dev->caps.cqe_size = 32; |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS; | ||
| 636 | mlx4_warn(dev, "Timestamping is not supported in slave mode.\n"); | ||
| 637 | |||
| 635 | slave_adjust_steering_mode(dev, &dev_cap, &hca_param); | 638 | slave_adjust_steering_mode(dev, &dev_cap, &hca_param); |
| 636 | 639 | ||
| 637 | return 0; | 640 | return 0; |
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c index 921729f9c85c..91a8a5d28037 100644 --- a/drivers/net/ethernet/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/octeon/octeon_mgmt.c | |||
| @@ -46,17 +46,25 @@ | |||
| 46 | union mgmt_port_ring_entry { | 46 | union mgmt_port_ring_entry { |
| 47 | u64 d64; | 47 | u64 d64; |
| 48 | struct { | 48 | struct { |
| 49 | u64 reserved_62_63:2; | 49 | #define RING_ENTRY_CODE_DONE 0xf |
| 50 | #define RING_ENTRY_CODE_MORE 0x10 | ||
| 51 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 52 | u64 reserved_62_63:2; | ||
| 50 | /* Length of the buffer/packet in bytes */ | 53 | /* Length of the buffer/packet in bytes */ |
| 51 | u64 len:14; | 54 | u64 len:14; |
| 52 | /* For TX, signals that the packet should be timestamped */ | 55 | /* For TX, signals that the packet should be timestamped */ |
| 53 | u64 tstamp:1; | 56 | u64 tstamp:1; |
| 54 | /* The RX error code */ | 57 | /* The RX error code */ |
| 55 | u64 code:7; | 58 | u64 code:7; |
| 56 | #define RING_ENTRY_CODE_DONE 0xf | ||
| 57 | #define RING_ENTRY_CODE_MORE 0x10 | ||
| 58 | /* Physical address of the buffer */ | 59 | /* Physical address of the buffer */ |
| 59 | u64 addr:40; | 60 | u64 addr:40; |
| 61 | #else | ||
| 62 | u64 addr:40; | ||
| 63 | u64 code:7; | ||
| 64 | u64 tstamp:1; | ||
| 65 | u64 len:14; | ||
| 66 | u64 reserved_62_63:2; | ||
| 67 | #endif | ||
| 60 | } s; | 68 | } s; |
| 61 | }; | 69 | }; |
| 62 | 70 | ||
| @@ -1141,10 +1149,13 @@ static int octeon_mgmt_open(struct net_device *netdev) | |||
| 1141 | /* For compensation state to lock. */ | 1149 | /* For compensation state to lock. */ |
| 1142 | ndelay(1040 * NS_PER_PHY_CLK); | 1150 | ndelay(1040 * NS_PER_PHY_CLK); |
| 1143 | 1151 | ||
| 1144 | /* Some Ethernet switches cannot handle standard | 1152 | /* Default Interframe Gaps are too small. Recommended |
| 1145 | * Interframe Gap, increase to 16 bytes. | 1153 | * workaround is. |
| 1154 | * | ||
| 1155 | * AGL_GMX_TX_IFG[IFG1]=14 | ||
| 1156 | * AGL_GMX_TX_IFG[IFG2]=10 | ||
| 1146 | */ | 1157 | */ |
| 1147 | cvmx_write_csr(CVMX_AGL_GMX_TX_IFG, 0x88); | 1158 | cvmx_write_csr(CVMX_AGL_GMX_TX_IFG, 0xae); |
| 1148 | } | 1159 | } |
| 1149 | 1160 | ||
| 1150 | octeon_mgmt_rx_fill_ring(netdev); | 1161 | octeon_mgmt_rx_fill_ring(netdev); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 43562c256379..6acf82b9f018 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |||
| @@ -642,7 +642,7 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter) | |||
| 642 | qlcnic_83xx_config_intrpt(adapter, 0); | 642 | qlcnic_83xx_config_intrpt(adapter, 0); |
| 643 | } | 643 | } |
| 644 | /* Allow dma queues to drain after context reset */ | 644 | /* Allow dma queues to drain after context reset */ |
| 645 | msleep(20); | 645 | mdelay(20); |
| 646 | } | 646 | } |
| 647 | } | 647 | } |
| 648 | 648 | ||
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 5e3982fc5398..e29fe8dbd226 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
| @@ -380,8 +380,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
| 380 | .eesipr_value = 0x01ff009f, | 380 | .eesipr_value = 0x01ff009f, |
| 381 | 381 | ||
| 382 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, | 382 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, |
| 383 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE | | 383 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | |
| 384 | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, | 384 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | |
| 385 | EESR_ECI, | ||
| 385 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, | 386 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, |
| 386 | 387 | ||
| 387 | .apr = 1, | 388 | .apr = 1, |
| @@ -427,8 +428,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
| 427 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f, | 428 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f, |
| 428 | 429 | ||
| 429 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, | 430 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, |
| 430 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE | | 431 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | |
| 431 | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, | 432 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | |
| 433 | EESR_ECI, | ||
| 432 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, | 434 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, |
| 433 | 435 | ||
| 434 | .apr = 1, | 436 | .apr = 1, |
| @@ -478,8 +480,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
| 478 | .rmcr_value = 0x00000001, | 480 | .rmcr_value = 0x00000001, |
| 479 | 481 | ||
| 480 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, | 482 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, |
| 481 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE | | 483 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | |
| 482 | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, | 484 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | |
| 485 | EESR_ECI, | ||
| 483 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, | 486 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, |
| 484 | 487 | ||
| 485 | .apr = 1, | 488 | .apr = 1, |
| @@ -592,9 +595,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = { | |||
| 592 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, | 595 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, |
| 593 | 596 | ||
| 594 | .tx_check = EESR_TC1 | EESR_FTC, | 597 | .tx_check = EESR_TC1 | EESR_FTC, |
| 595 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ | 598 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | |
| 596 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ | 599 | EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | |
| 597 | EESR_ECI, | 600 | EESR_TDE | EESR_ECI, |
| 598 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ | 601 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ |
| 599 | EESR_TFE, | 602 | EESR_TFE, |
| 600 | .fdr_value = 0x0000072f, | 603 | .fdr_value = 0x0000072f, |
| @@ -674,9 +677,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
| 674 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, | 677 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, |
| 675 | 678 | ||
| 676 | .tx_check = EESR_TC1 | EESR_FTC, | 679 | .tx_check = EESR_TC1 | EESR_FTC, |
| 677 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ | 680 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | |
| 678 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ | 681 | EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | |
| 679 | EESR_ECI, | 682 | EESR_TDE | EESR_ECI, |
| 680 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ | 683 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ |
| 681 | EESR_TFE, | 684 | EESR_TFE, |
| 682 | 685 | ||
| @@ -811,9 +814,9 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
| 811 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, | 814 | .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, |
| 812 | 815 | ||
| 813 | .tx_check = EESR_TC1 | EESR_FTC, | 816 | .tx_check = EESR_TC1 | EESR_FTC, |
| 814 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ | 817 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | |
| 815 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ | 818 | EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | |
| 816 | EESR_ECI, | 819 | EESR_TDE | EESR_ECI, |
| 817 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ | 820 | .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ |
| 818 | EESR_TFE, | 821 | EESR_TFE, |
| 819 | 822 | ||
| @@ -1549,11 +1552,12 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) | |||
| 1549 | 1552 | ||
| 1550 | ignore_link: | 1553 | ignore_link: |
| 1551 | if (intr_status & EESR_TWB) { | 1554 | if (intr_status & EESR_TWB) { |
| 1552 | /* Write buck end. unused write back interrupt */ | 1555 | /* Unused write back interrupt */ |
| 1553 | if (intr_status & EESR_TABT) /* Transmit Abort int */ | 1556 | if (intr_status & EESR_TABT) { /* Transmit Abort int */ |
| 1554 | ndev->stats.tx_aborted_errors++; | 1557 | ndev->stats.tx_aborted_errors++; |
| 1555 | if (netif_msg_tx_err(mdp)) | 1558 | if (netif_msg_tx_err(mdp)) |
| 1556 | dev_err(&ndev->dev, "Transmit Abort\n"); | 1559 | dev_err(&ndev->dev, "Transmit Abort\n"); |
| 1560 | } | ||
| 1557 | } | 1561 | } |
| 1558 | 1562 | ||
| 1559 | if (intr_status & EESR_RABT) { | 1563 | if (intr_status & EESR_RABT) { |
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 1ddc9f235bcb..62689a5823be 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h | |||
| @@ -253,7 +253,7 @@ enum EESR_BIT { | |||
| 253 | 253 | ||
| 254 | #define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \ | 254 | #define DEFAULT_TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \ |
| 255 | EESR_RTO) | 255 | EESR_RTO) |
| 256 | #define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \ | 256 | #define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \ |
| 257 | EESR_RDE | EESR_RFRMER | EESR_ADE | \ | 257 | EESR_RDE | EESR_RFRMER | EESR_ADE | \ |
| 258 | EESR_TFE | EESR_TDE | EESR_ECI) | 258 | EESR_TFE | EESR_TDE | EESR_ECI) |
| 259 | #define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \ | 259 | #define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \ |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 39e4cb39de29..4a14a940c65e 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
| @@ -2139,7 +2139,7 @@ show_phy_type(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 2139 | struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); | 2139 | struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); |
| 2140 | return sprintf(buf, "%d\n", efx->phy_type); | 2140 | return sprintf(buf, "%d\n", efx->phy_type); |
| 2141 | } | 2141 | } |
| 2142 | static DEVICE_ATTR(phy_type, 0644, show_phy_type, NULL); | 2142 | static DEVICE_ATTR(phy_type, 0444, show_phy_type, NULL); |
| 2143 | 2143 | ||
| 2144 | static int efx_register_netdev(struct efx_nic *efx) | 2144 | static int efx_register_netdev(struct efx_nic *efx) |
| 2145 | { | 2145 | { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 7788fbe44f0a..95176979b2d2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
| @@ -297,8 +297,8 @@ struct dma_features { | |||
| 297 | #define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */ | 297 | #define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */ |
| 298 | 298 | ||
| 299 | /* Default LPI timers */ | 299 | /* Default LPI timers */ |
| 300 | #define STMMAC_DEFAULT_LIT_LS_TIMER 0x3E8 | 300 | #define STMMAC_DEFAULT_LIT_LS 0x3E8 |
| 301 | #define STMMAC_DEFAULT_TWT_LS_TIMER 0x0 | 301 | #define STMMAC_DEFAULT_TWT_LS 0x0 |
| 302 | 302 | ||
| 303 | #define STMMAC_CHAIN_MODE 0x1 | 303 | #define STMMAC_CHAIN_MODE 0x1 |
| 304 | #define STMMAC_RING_MODE 0x2 | 304 | #define STMMAC_RING_MODE 0x2 |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index ee919ca8b8a0..e9eab29db7be 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -130,7 +130,7 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | | |||
| 130 | static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; | 130 | static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; |
| 131 | module_param(eee_timer, int, S_IRUGO | S_IWUSR); | 131 | module_param(eee_timer, int, S_IRUGO | S_IWUSR); |
| 132 | MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); | 132 | MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); |
| 133 | #define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x)) | 133 | #define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x)) |
| 134 | 134 | ||
| 135 | /* By default the driver will use the ring mode to manage tx and rx descriptors | 135 | /* By default the driver will use the ring mode to manage tx and rx descriptors |
| 136 | * but passing this value so user can force to use the chain instead of the ring | 136 | * but passing this value so user can force to use the chain instead of the ring |
| @@ -288,7 +288,7 @@ static void stmmac_eee_ctrl_timer(unsigned long arg) | |||
| 288 | struct stmmac_priv *priv = (struct stmmac_priv *)arg; | 288 | struct stmmac_priv *priv = (struct stmmac_priv *)arg; |
| 289 | 289 | ||
| 290 | stmmac_enable_eee_mode(priv); | 290 | stmmac_enable_eee_mode(priv); |
| 291 | mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); | 291 | mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | /** | 294 | /** |
| @@ -304,22 +304,34 @@ bool stmmac_eee_init(struct stmmac_priv *priv) | |||
| 304 | { | 304 | { |
| 305 | bool ret = false; | 305 | bool ret = false; |
| 306 | 306 | ||
| 307 | /* Using PCS we cannot dial with the phy registers at this stage | ||
| 308 | * so we do not support extra feature like EEE. | ||
| 309 | */ | ||
| 310 | if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) || | ||
| 311 | (priv->pcs == STMMAC_PCS_RTBI)) | ||
| 312 | goto out; | ||
| 313 | |||
| 307 | /* MAC core supports the EEE feature. */ | 314 | /* MAC core supports the EEE feature. */ |
| 308 | if (priv->dma_cap.eee) { | 315 | if (priv->dma_cap.eee) { |
| 309 | /* Check if the PHY supports EEE */ | 316 | /* Check if the PHY supports EEE */ |
| 310 | if (phy_init_eee(priv->phydev, 1)) | 317 | if (phy_init_eee(priv->phydev, 1)) |
| 311 | goto out; | 318 | goto out; |
| 312 | 319 | ||
| 313 | priv->eee_active = 1; | 320 | if (!priv->eee_active) { |
| 314 | init_timer(&priv->eee_ctrl_timer); | 321 | priv->eee_active = 1; |
| 315 | priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; | 322 | init_timer(&priv->eee_ctrl_timer); |
| 316 | priv->eee_ctrl_timer.data = (unsigned long)priv; | 323 | priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; |
| 317 | priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer); | 324 | priv->eee_ctrl_timer.data = (unsigned long)priv; |
| 318 | add_timer(&priv->eee_ctrl_timer); | 325 | priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer); |
| 319 | 326 | add_timer(&priv->eee_ctrl_timer); | |
| 320 | priv->hw->mac->set_eee_timer(priv->ioaddr, | 327 | |
| 321 | STMMAC_DEFAULT_LIT_LS_TIMER, | 328 | priv->hw->mac->set_eee_timer(priv->ioaddr, |
| 322 | priv->tx_lpi_timer); | 329 | STMMAC_DEFAULT_LIT_LS, |
| 330 | priv->tx_lpi_timer); | ||
| 331 | } else | ||
| 332 | /* Set HW EEE according to the speed */ | ||
| 333 | priv->hw->mac->set_eee_pls(priv->ioaddr, | ||
| 334 | priv->phydev->link); | ||
| 323 | 335 | ||
| 324 | pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); | 336 | pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); |
| 325 | 337 | ||
| @@ -329,20 +341,6 @@ out: | |||
| 329 | return ret; | 341 | return ret; |
| 330 | } | 342 | } |
| 331 | 343 | ||
| 332 | /** | ||
| 333 | * stmmac_eee_adjust: adjust HW EEE according to the speed | ||
| 334 | * @priv: driver private structure | ||
| 335 | * Description: | ||
| 336 | * When the EEE has been already initialised we have to | ||
| 337 | * modify the PLS bit in the LPI ctrl & status reg according | ||
| 338 | * to the PHY link status. For this reason. | ||
| 339 | */ | ||
| 340 | static void stmmac_eee_adjust(struct stmmac_priv *priv) | ||
| 341 | { | ||
| 342 | if (priv->eee_enabled) | ||
| 343 | priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link); | ||
| 344 | } | ||
| 345 | |||
| 346 | /* stmmac_get_tx_hwtstamp: get HW TX timestamps | 344 | /* stmmac_get_tx_hwtstamp: get HW TX timestamps |
| 347 | * @priv: driver private structure | 345 | * @priv: driver private structure |
| 348 | * @entry : descriptor index to be used. | 346 | * @entry : descriptor index to be used. |
| @@ -769,7 +767,10 @@ static void stmmac_adjust_link(struct net_device *dev) | |||
| 769 | if (new_state && netif_msg_link(priv)) | 767 | if (new_state && netif_msg_link(priv)) |
| 770 | phy_print_status(phydev); | 768 | phy_print_status(phydev); |
| 771 | 769 | ||
| 772 | stmmac_eee_adjust(priv); | 770 | /* At this stage, it could be needed to setup the EEE or adjust some |
| 771 | * MAC related HW registers. | ||
| 772 | */ | ||
| 773 | priv->eee_enabled = stmmac_eee_init(priv); | ||
| 773 | 774 | ||
| 774 | spin_unlock_irqrestore(&priv->lock, flags); | 775 | spin_unlock_irqrestore(&priv->lock, flags); |
| 775 | 776 | ||
| @@ -1277,7 +1278,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) | |||
| 1277 | 1278 | ||
| 1278 | if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { | 1279 | if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { |
| 1279 | stmmac_enable_eee_mode(priv); | 1280 | stmmac_enable_eee_mode(priv); |
| 1280 | mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); | 1281 | mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); |
| 1281 | } | 1282 | } |
| 1282 | spin_unlock(&priv->tx_lock); | 1283 | spin_unlock(&priv->tx_lock); |
| 1283 | } | 1284 | } |
| @@ -1671,14 +1672,9 @@ static int stmmac_open(struct net_device *dev) | |||
| 1671 | if (priv->phydev) | 1672 | if (priv->phydev) |
| 1672 | phy_start(priv->phydev); | 1673 | phy_start(priv->phydev); |
| 1673 | 1674 | ||
| 1674 | priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER; | 1675 | priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; |
| 1675 | 1676 | ||
| 1676 | /* Using PCS we cannot dial with the phy registers at this stage | 1677 | priv->eee_enabled = stmmac_eee_init(priv); |
| 1677 | * so we do not support extra feature like EEE. | ||
| 1678 | */ | ||
| 1679 | if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && | ||
| 1680 | priv->pcs != STMMAC_PCS_RTBI) | ||
| 1681 | priv->eee_enabled = stmmac_eee_init(priv); | ||
| 1682 | 1678 | ||
| 1683 | stmmac_init_tx_coalesce(priv); | 1679 | stmmac_init_tx_coalesce(priv); |
| 1684 | 1680 | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 21a5b291b4b3..d1a769f35f9d 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -1679,7 +1679,7 @@ static int cpsw_probe(struct platform_device *pdev) | |||
| 1679 | priv->rx_packet_max = max(rx_packet_max, 128); | 1679 | priv->rx_packet_max = max(rx_packet_max, 128); |
| 1680 | priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL); | 1680 | priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL); |
| 1681 | priv->irq_enabled = true; | 1681 | priv->irq_enabled = true; |
| 1682 | if (!ndev) { | 1682 | if (!priv->cpts) { |
| 1683 | pr_err("error allocating cpts\n"); | 1683 | pr_err("error allocating cpts\n"); |
| 1684 | goto clean_ndev_ret; | 1684 | goto clean_ndev_ret; |
| 1685 | } | 1685 | } |
| @@ -1973,9 +1973,12 @@ static int cpsw_suspend(struct device *dev) | |||
| 1973 | { | 1973 | { |
| 1974 | struct platform_device *pdev = to_platform_device(dev); | 1974 | struct platform_device *pdev = to_platform_device(dev); |
| 1975 | struct net_device *ndev = platform_get_drvdata(pdev); | 1975 | struct net_device *ndev = platform_get_drvdata(pdev); |
| 1976 | struct cpsw_priv *priv = netdev_priv(ndev); | ||
| 1976 | 1977 | ||
| 1977 | if (netif_running(ndev)) | 1978 | if (netif_running(ndev)) |
| 1978 | cpsw_ndo_stop(ndev); | 1979 | cpsw_ndo_stop(ndev); |
| 1980 | soft_reset("sliver 0", &priv->slaves[0].sliver->soft_reset); | ||
| 1981 | soft_reset("sliver 1", &priv->slaves[1].sliver->soft_reset); | ||
| 1979 | pm_runtime_put_sync(&pdev->dev); | 1982 | pm_runtime_put_sync(&pdev->dev); |
| 1980 | 1983 | ||
| 1981 | return 0; | 1984 | return 0; |
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index 49dfd592ac1e..053c84fd0853 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c | |||
| @@ -705,6 +705,13 @@ int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data, | |||
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | buffer = dma_map_single(ctlr->dev, data, len, chan->dir); | 707 | buffer = dma_map_single(ctlr->dev, data, len, chan->dir); |
| 708 | ret = dma_mapping_error(ctlr->dev, buffer); | ||
| 709 | if (ret) { | ||
| 710 | cpdma_desc_free(ctlr->pool, desc, 1); | ||
| 711 | ret = -EINVAL; | ||
| 712 | goto unlock_ret; | ||
| 713 | } | ||
| 714 | |||
| 708 | mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP; | 715 | mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP; |
| 709 | cpdma_desc_to_port(chan, mode, directed); | 716 | cpdma_desc_to_port(chan, mode, directed); |
| 710 | 717 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index ab2307b5d9a7..4dccead586be 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -285,7 +285,9 @@ int netvsc_recv_callback(struct hv_device *device_obj, | |||
| 285 | 285 | ||
| 286 | skb->protocol = eth_type_trans(skb, net); | 286 | skb->protocol = eth_type_trans(skb, net); |
| 287 | skb->ip_summed = CHECKSUM_NONE; | 287 | skb->ip_summed = CHECKSUM_NONE; |
| 288 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), packet->vlan_tci); | 288 | if (packet->vlan_tci & VLAN_TAG_PRESENT) |
| 289 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | ||
| 290 | packet->vlan_tci); | ||
| 289 | 291 | ||
| 290 | net->stats.rx_packets++; | 292 | net->stats.rx_packets++; |
| 291 | net->stats.rx_bytes += packet->total_data_buflen; | 293 | net->stats.rx_bytes += packet->total_data_buflen; |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 59e9605de316..b6dd6a75919a 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
| @@ -524,8 +524,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
| 524 | return -EMSGSIZE; | 524 | return -EMSGSIZE; |
| 525 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); | 525 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); |
| 526 | if (num_pages != size) { | 526 | if (num_pages != size) { |
| 527 | for (i = 0; i < num_pages; i++) | 527 | int j; |
| 528 | put_page(page[i]); | 528 | |
| 529 | for (j = 0; j < num_pages; j++) | ||
| 530 | put_page(page[i + j]); | ||
| 529 | return -EFAULT; | 531 | return -EFAULT; |
| 530 | } | 532 | } |
| 531 | truesize = size * PAGE_SIZE; | 533 | truesize = size * PAGE_SIZE; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index bfa9bb48e42d..9c61f8734a40 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -1010,8 +1010,10 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
| 1010 | return -EMSGSIZE; | 1010 | return -EMSGSIZE; |
| 1011 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); | 1011 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); |
| 1012 | if (num_pages != size) { | 1012 | if (num_pages != size) { |
| 1013 | for (i = 0; i < num_pages; i++) | 1013 | int j; |
| 1014 | put_page(page[i]); | 1014 | |
| 1015 | for (j = 0; j < num_pages; j++) | ||
| 1016 | put_page(page[i + j]); | ||
| 1015 | return -EFAULT; | 1017 | return -EFAULT; |
| 1016 | } | 1018 | } |
| 1017 | truesize = size * PAGE_SIZE; | 1019 | truesize = size * PAGE_SIZE; |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index d095d0d3056b..56459215a22b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -590,7 +590,13 @@ static const struct usb_device_id products[] = { | |||
| 590 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 590 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
| 591 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | 591 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ |
| 592 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | 592 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ |
| 593 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | 593 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel/Verizon USB-1000 */ |
| 594 | {QMI_GOBI1K_DEVICE(0x1410, 0xa002)}, /* Novatel Gobi Modem device */ | ||
| 595 | {QMI_GOBI1K_DEVICE(0x1410, 0xa003)}, /* Novatel Gobi Modem device */ | ||
| 596 | {QMI_GOBI1K_DEVICE(0x1410, 0xa004)}, /* Novatel Gobi Modem device */ | ||
| 597 | {QMI_GOBI1K_DEVICE(0x1410, 0xa005)}, /* Novatel Gobi Modem device */ | ||
| 598 | {QMI_GOBI1K_DEVICE(0x1410, 0xa006)}, /* Novatel Gobi Modem device */ | ||
| 599 | {QMI_GOBI1K_DEVICE(0x1410, 0xa007)}, /* Novatel Gobi Modem device */ | ||
| 594 | {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ | 600 | {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ |
| 595 | {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ | 601 | {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ |
| 596 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ | 602 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 3b1d2ee7156b..57325f356d4f 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -565,18 +565,22 @@ skip: | |||
| 565 | 565 | ||
| 566 | /* Watch incoming packets to learn mapping between Ethernet address | 566 | /* Watch incoming packets to learn mapping between Ethernet address |
| 567 | * and Tunnel endpoint. | 567 | * and Tunnel endpoint. |
| 568 | * Return true if packet is bogus and should be droppped. | ||
| 568 | */ | 569 | */ |
| 569 | static void vxlan_snoop(struct net_device *dev, | 570 | static bool vxlan_snoop(struct net_device *dev, |
| 570 | __be32 src_ip, const u8 *src_mac) | 571 | __be32 src_ip, const u8 *src_mac) |
| 571 | { | 572 | { |
| 572 | struct vxlan_dev *vxlan = netdev_priv(dev); | 573 | struct vxlan_dev *vxlan = netdev_priv(dev); |
| 573 | struct vxlan_fdb *f; | 574 | struct vxlan_fdb *f; |
| 574 | int err; | ||
| 575 | 575 | ||
| 576 | f = vxlan_find_mac(vxlan, src_mac); | 576 | f = vxlan_find_mac(vxlan, src_mac); |
| 577 | if (likely(f)) { | 577 | if (likely(f)) { |
| 578 | if (likely(f->remote.remote_ip == src_ip)) | 578 | if (likely(f->remote.remote_ip == src_ip)) |
| 579 | return; | 579 | return false; |
| 580 | |||
| 581 | /* Don't migrate static entries, drop packets */ | ||
| 582 | if (f->state & NUD_NOARP) | ||
| 583 | return true; | ||
| 580 | 584 | ||
| 581 | if (net_ratelimit()) | 585 | if (net_ratelimit()) |
| 582 | netdev_info(dev, | 586 | netdev_info(dev, |
| @@ -588,14 +592,19 @@ static void vxlan_snoop(struct net_device *dev, | |||
| 588 | } else { | 592 | } else { |
| 589 | /* learned new entry */ | 593 | /* learned new entry */ |
| 590 | spin_lock(&vxlan->hash_lock); | 594 | spin_lock(&vxlan->hash_lock); |
| 591 | err = vxlan_fdb_create(vxlan, src_mac, src_ip, | 595 | |
| 592 | NUD_REACHABLE, | 596 | /* close off race between vxlan_flush and incoming packets */ |
| 593 | NLM_F_EXCL|NLM_F_CREATE, | 597 | if (netif_running(dev)) |
| 594 | vxlan->dst_port, | 598 | vxlan_fdb_create(vxlan, src_mac, src_ip, |
| 595 | vxlan->default_dst.remote_vni, | 599 | NUD_REACHABLE, |
| 596 | 0, NTF_SELF); | 600 | NLM_F_EXCL|NLM_F_CREATE, |
| 601 | vxlan->dst_port, | ||
| 602 | vxlan->default_dst.remote_vni, | ||
| 603 | 0, NTF_SELF); | ||
| 597 | spin_unlock(&vxlan->hash_lock); | 604 | spin_unlock(&vxlan->hash_lock); |
| 598 | } | 605 | } |
| 606 | |||
| 607 | return false; | ||
| 599 | } | 608 | } |
| 600 | 609 | ||
| 601 | 610 | ||
| @@ -727,8 +736,9 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
| 727 | vxlan->dev->dev_addr) == 0) | 736 | vxlan->dev->dev_addr) == 0) |
| 728 | goto drop; | 737 | goto drop; |
| 729 | 738 | ||
| 730 | if (vxlan->flags & VXLAN_F_LEARN) | 739 | if ((vxlan->flags & VXLAN_F_LEARN) && |
| 731 | vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source); | 740 | vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source)) |
| 741 | goto drop; | ||
| 732 | 742 | ||
| 733 | __skb_tunnel_rx(skb, vxlan->dev); | 743 | __skb_tunnel_rx(skb, vxlan->dev); |
| 734 | skb_reset_network_header(skb); | 744 | skb_reset_network_header(skb); |
| @@ -1151,9 +1161,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1151 | struct sk_buff *skb1; | 1161 | struct sk_buff *skb1; |
| 1152 | 1162 | ||
| 1153 | skb1 = skb_clone(skb, GFP_ATOMIC); | 1163 | skb1 = skb_clone(skb, GFP_ATOMIC); |
| 1154 | rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc); | 1164 | if (skb1) { |
| 1155 | if (rc == NETDEV_TX_OK) | 1165 | rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc); |
| 1156 | rc = rc1; | 1166 | if (rc == NETDEV_TX_OK) |
| 1167 | rc = rc1; | ||
| 1168 | } | ||
| 1157 | } | 1169 | } |
| 1158 | 1170 | ||
| 1159 | rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc); | 1171 | rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc); |
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 147614ed86aa..6a8a382c5f4c 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c | |||
| @@ -384,21 +384,37 @@ static int dlci_del(struct dlci_add *dlci) | |||
| 384 | struct frad_local *flp; | 384 | struct frad_local *flp; |
| 385 | struct net_device *master, *slave; | 385 | struct net_device *master, *slave; |
| 386 | int err; | 386 | int err; |
| 387 | bool found = false; | ||
| 388 | |||
| 389 | rtnl_lock(); | ||
| 387 | 390 | ||
| 388 | /* validate slave device */ | 391 | /* validate slave device */ |
| 389 | master = __dev_get_by_name(&init_net, dlci->devname); | 392 | master = __dev_get_by_name(&init_net, dlci->devname); |
| 390 | if (!master) | 393 | if (!master) { |
| 391 | return -ENODEV; | 394 | err = -ENODEV; |
| 395 | goto out; | ||
| 396 | } | ||
| 397 | |||
| 398 | list_for_each_entry(dlp, &dlci_devs, list) { | ||
| 399 | if (dlp->master == master) { | ||
| 400 | found = true; | ||
| 401 | break; | ||
| 402 | } | ||
| 403 | } | ||
| 404 | if (!found) { | ||
| 405 | err = -ENODEV; | ||
| 406 | goto out; | ||
| 407 | } | ||
| 392 | 408 | ||
| 393 | if (netif_running(master)) { | 409 | if (netif_running(master)) { |
| 394 | return -EBUSY; | 410 | err = -EBUSY; |
| 411 | goto out; | ||
| 395 | } | 412 | } |
| 396 | 413 | ||
| 397 | dlp = netdev_priv(master); | 414 | dlp = netdev_priv(master); |
| 398 | slave = dlp->slave; | 415 | slave = dlp->slave; |
| 399 | flp = netdev_priv(slave); | 416 | flp = netdev_priv(slave); |
| 400 | 417 | ||
| 401 | rtnl_lock(); | ||
| 402 | err = (*flp->deassoc)(slave, master); | 418 | err = (*flp->deassoc)(slave, master); |
| 403 | if (!err) { | 419 | if (!err) { |
| 404 | list_del(&dlp->list); | 420 | list_del(&dlp->list); |
| @@ -407,8 +423,8 @@ static int dlci_del(struct dlci_add *dlci) | |||
| 407 | 423 | ||
| 408 | dev_put(slave); | 424 | dev_put(slave); |
| 409 | } | 425 | } |
| 426 | out: | ||
| 410 | rtnl_unlock(); | 427 | rtnl_unlock(); |
| 411 | |||
| 412 | return err; | 428 | return err; |
| 413 | } | 429 | } |
| 414 | 430 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 0743a47cef8f..62f1b7636c92 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -1174,7 +1174,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1174 | mutex_lock(&priv->htc_pm_lock); | 1174 | mutex_lock(&priv->htc_pm_lock); |
| 1175 | 1175 | ||
| 1176 | priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); | 1176 | priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
| 1177 | if (priv->ps_idle) | 1177 | if (!priv->ps_idle) |
| 1178 | chip_reset = true; | 1178 | chip_reset = true; |
| 1179 | 1179 | ||
| 1180 | mutex_unlock(&priv->htc_pm_lock); | 1180 | mutex_unlock(&priv->htc_pm_lock); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 1c9b1bac8b0d..83ab6be3fe6d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1570,6 +1570,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
| 1570 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) | 1570 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) |
| 1571 | return; | 1571 | return; |
| 1572 | 1572 | ||
| 1573 | rcu_read_lock(); | ||
| 1574 | |||
| 1573 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); | 1575 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); |
| 1574 | last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); | 1576 | last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); |
| 1575 | 1577 | ||
| @@ -1608,8 +1610,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
| 1608 | 1610 | ||
| 1609 | if (ac == last_ac || | 1611 | if (ac == last_ac || |
| 1610 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) | 1612 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) |
| 1611 | return; | 1613 | break; |
| 1612 | } | 1614 | } |
| 1615 | |||
| 1616 | rcu_read_unlock(); | ||
| 1613 | } | 1617 | } |
| 1614 | 1618 | ||
| 1615 | /***********/ | 1619 | /***********/ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index b98f2235978e..2c593570497c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
| @@ -930,6 +930,10 @@ fail: | |||
| 930 | brcmf_fws_del_interface(ifp); | 930 | brcmf_fws_del_interface(ifp); |
| 931 | brcmf_fws_deinit(drvr); | 931 | brcmf_fws_deinit(drvr); |
| 932 | } | 932 | } |
| 933 | if (drvr->iflist[0]) { | ||
| 934 | free_netdev(ifp->ndev); | ||
| 935 | drvr->iflist[0] = NULL; | ||
| 936 | } | ||
| 933 | if (p2p_ifp) { | 937 | if (p2p_ifp) { |
| 934 | free_netdev(p2p_ifp->ndev); | 938 | free_netdev(p2p_ifp->ndev); |
| 935 | drvr->iflist[1] = NULL; | 939 | drvr->iflist[1] = NULL; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 28e7aeedd184..9fd6f2fef11b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
| @@ -3074,21 +3074,8 @@ static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail) | |||
| 3074 | */ | 3074 | */ |
| 3075 | static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) | 3075 | static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) |
| 3076 | { | 3076 | { |
| 3077 | /* disallow PS when one of the following global conditions meets */ | 3077 | /* not supporting PS so always return false for now */ |
| 3078 | if (!wlc->pub->associated) | 3078 | return false; |
| 3079 | return false; | ||
| 3080 | |||
| 3081 | /* disallow PS when one of these meets when not scanning */ | ||
| 3082 | if (wlc->filter_flags & FIF_PROMISC_IN_BSS) | ||
| 3083 | return false; | ||
| 3084 | |||
| 3085 | if (wlc->bsscfg->type == BRCMS_TYPE_AP) | ||
| 3086 | return false; | ||
| 3087 | |||
| 3088 | if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC) | ||
| 3089 | return false; | ||
| 3090 | |||
| 3091 | return true; | ||
| 3092 | } | 3079 | } |
| 3093 | 3080 | ||
| 3094 | static void brcms_c_statsupd(struct brcms_c_info *wlc) | 3081 | static void brcms_c_statsupd(struct brcms_c_info *wlc) |
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index c9f197d9ca1e..fe31590a51b2 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c | |||
| @@ -816,6 +816,7 @@ out: | |||
| 816 | rs_sta->last_txrate_idx = idx; | 816 | rs_sta->last_txrate_idx = idx; |
| 817 | info->control.rates[0].idx = rs_sta->last_txrate_idx; | 817 | info->control.rates[0].idx = rs_sta->last_txrate_idx; |
| 818 | } | 818 | } |
| 819 | info->control.rates[0].count = 1; | ||
| 819 | 820 | ||
| 820 | D_RATE("leave: %d\n", idx); | 821 | D_RATE("leave: %d\n", idx); |
| 821 | } | 822 | } |
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 1fc0b227e120..ed3c42a63a43 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c | |||
| @@ -2268,7 +2268,7 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, | |||
| 2268 | info->control.rates[0].flags = 0; | 2268 | info->control.rates[0].flags = 0; |
| 2269 | } | 2269 | } |
| 2270 | info->control.rates[0].idx = rate_idx; | 2270 | info->control.rates[0].idx = rate_idx; |
| 2271 | 2271 | info->control.rates[0].count = 1; | |
| 2272 | } | 2272 | } |
| 2273 | 2273 | ||
| 2274 | static void * | 2274 | static void * |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 907bd6e50aad..10fbb176cc8e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
| @@ -2799,7 +2799,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, | |||
| 2799 | info->control.rates[0].flags = 0; | 2799 | info->control.rates[0].flags = 0; |
| 2800 | } | 2800 | } |
| 2801 | info->control.rates[0].idx = rate_idx; | 2801 | info->control.rates[0].idx = rate_idx; |
| 2802 | 2802 | info->control.rates[0].count = 1; | |
| 2803 | } | 2803 | } |
| 2804 | 2804 | ||
| 2805 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, | 2805 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 707446fa00bd..cd1ad0019185 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
| @@ -1378,7 +1378,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | |||
| 1378 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 1378 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
| 1379 | int ret; | 1379 | int ret; |
| 1380 | 1380 | ||
| 1381 | if (!(priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)) | 1381 | if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED) |
| 1382 | return; | 1382 | return; |
| 1383 | 1383 | ||
| 1384 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && | 1384 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 39aad9893e0b..40fed1f511e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
| @@ -1000,10 +1000,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
| 1000 | */ | 1000 | */ |
| 1001 | if (load_module) { | 1001 | if (load_module) { |
| 1002 | err = request_module("%s", op->name); | 1002 | err = request_module("%s", op->name); |
| 1003 | #ifdef CONFIG_IWLWIFI_OPMODE_MODULAR | ||
| 1003 | if (err) | 1004 | if (err) |
| 1004 | IWL_ERR(drv, | 1005 | IWL_ERR(drv, |
| 1005 | "failed to load module %s (error %d), is dynamic loading enabled?\n", | 1006 | "failed to load module %s (error %d), is dynamic loading enabled?\n", |
| 1006 | op->name, err); | 1007 | op->name, err); |
| 1008 | #endif | ||
| 1007 | } | 1009 | } |
| 1008 | return; | 1010 | return; |
| 1009 | 1011 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 55334d542e26..b99fe3163866 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
| @@ -2546,6 +2546,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, | |||
| 2546 | info->control.rates[0].flags = 0; | 2546 | info->control.rates[0].flags = 0; |
| 2547 | } | 2547 | } |
| 2548 | info->control.rates[0].idx = rate_idx; | 2548 | info->control.rates[0].idx = rate_idx; |
| 2549 | info->control.rates[0].count = 1; | ||
| 2549 | } | 2550 | } |
| 2550 | 2551 | ||
| 2551 | static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, | 2552 | static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index f212f16502ff..48c1891e3df6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
| @@ -180,7 +180,8 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, | |||
| 180 | tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); | 180 | tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); |
| 181 | return; | 181 | return; |
| 182 | } else if (ieee80211_is_back_req(fc)) { | 182 | } else if (ieee80211_is_back_req(fc)) { |
| 183 | tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); | 183 | tx_cmd->tx_flags |= |
| 184 | cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR); | ||
| 184 | } | 185 | } |
| 185 | 186 | ||
| 186 | /* HT rate doesn't make sense for a non data frame */ | 187 | /* HT rate doesn't make sense for a non data frame */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b52d70c75e1a..72f32e5caa4d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -3027,19 +3027,26 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
| 3027 | * TODO: we do not use +6 dBm option to do not increase power beyond | 3027 | * TODO: we do not use +6 dBm option to do not increase power beyond |
| 3028 | * regulatory limit, however this could be utilized for devices with | 3028 | * regulatory limit, however this could be utilized for devices with |
| 3029 | * CAPABILITY_POWER_LIMIT. | 3029 | * CAPABILITY_POWER_LIMIT. |
| 3030 | * | ||
| 3031 | * TODO: add different temperature compensation code for RT3290 & RT5390 | ||
| 3032 | * to allow to use BBP_R1 for those chips. | ||
| 3030 | */ | 3033 | */ |
| 3031 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 3034 | if (!rt2x00_rt(rt2x00dev, RT3290) && |
| 3032 | if (delta <= -12) { | 3035 | !rt2x00_rt(rt2x00dev, RT5390)) { |
| 3033 | power_ctrl = 2; | 3036 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
| 3034 | delta += 12; | 3037 | if (delta <= -12) { |
| 3035 | } else if (delta <= -6) { | 3038 | power_ctrl = 2; |
| 3036 | power_ctrl = 1; | 3039 | delta += 12; |
| 3037 | delta += 6; | 3040 | } else if (delta <= -6) { |
| 3038 | } else { | 3041 | power_ctrl = 1; |
| 3039 | power_ctrl = 0; | 3042 | delta += 6; |
| 3043 | } else { | ||
| 3044 | power_ctrl = 0; | ||
| 3045 | } | ||
| 3046 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl); | ||
| 3047 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
| 3040 | } | 3048 | } |
| 3041 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl); | 3049 | |
| 3042 | rt2800_bbp_write(rt2x00dev, 1, r1); | ||
| 3043 | offset = TX_PWR_CFG_0; | 3050 | offset = TX_PWR_CFG_0; |
| 3044 | 3051 | ||
| 3045 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { | 3052 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 9544cdc0d1af..e79e006eb9ab 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
| @@ -811,6 +811,70 @@ int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev) | |||
| 811 | return pcidev->irq; | 811 | return pcidev->irq; |
| 812 | } | 812 | } |
| 813 | 813 | ||
| 814 | static struct iosapic_info *first_isi = NULL; | ||
| 815 | |||
| 816 | #ifdef CONFIG_64BIT | ||
| 817 | int iosapic_serial_irq(int num) | ||
| 818 | { | ||
| 819 | struct iosapic_info *isi = first_isi; | ||
| 820 | struct irt_entry *irte = NULL; /* only used if PAT PDC */ | ||
| 821 | struct vector_info *vi; | ||
| 822 | int isi_line; /* line used by device */ | ||
| 823 | |||
| 824 | /* lookup IRT entry for isi/slot/pin set */ | ||
| 825 | irte = &irt_cell[num]; | ||
| 826 | |||
| 827 | DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n", | ||
| 828 | irte, | ||
| 829 | irte->entry_type, | ||
| 830 | irte->entry_length, | ||
| 831 | irte->polarity_trigger, | ||
| 832 | irte->src_bus_irq_devno, | ||
| 833 | irte->src_bus_id, | ||
| 834 | irte->src_seg_id, | ||
| 835 | irte->dest_iosapic_intin, | ||
| 836 | (u32) irte->dest_iosapic_addr); | ||
| 837 | isi_line = irte->dest_iosapic_intin; | ||
| 838 | |||
| 839 | /* get vector info for this input line */ | ||
| 840 | vi = isi->isi_vector + isi_line; | ||
| 841 | DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi); | ||
| 842 | |||
| 843 | /* If this IRQ line has already been setup, skip it */ | ||
| 844 | if (vi->irte) | ||
| 845 | goto out; | ||
| 846 | |||
| 847 | vi->irte = irte; | ||
| 848 | |||
| 849 | /* | ||
| 850 | * Allocate processor IRQ | ||
| 851 | * | ||
| 852 | * XXX/FIXME The txn_alloc_irq() code and related code should be | ||
| 853 | * moved to enable_irq(). That way we only allocate processor IRQ | ||
| 854 | * bits for devices that actually have drivers claiming them. | ||
| 855 | * Right now we assign an IRQ to every PCI device present, | ||
| 856 | * regardless of whether it's used or not. | ||
| 857 | */ | ||
| 858 | vi->txn_irq = txn_alloc_irq(8); | ||
| 859 | |||
| 860 | if (vi->txn_irq < 0) | ||
| 861 | panic("I/O sapic: couldn't get TXN IRQ\n"); | ||
| 862 | |||
| 863 | /* enable_irq() will use txn_* to program IRdT */ | ||
| 864 | vi->txn_addr = txn_alloc_addr(vi->txn_irq); | ||
| 865 | vi->txn_data = txn_alloc_data(vi->txn_irq); | ||
| 866 | |||
| 867 | vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI; | ||
| 868 | vi->eoi_data = cpu_to_le32(vi->txn_data); | ||
| 869 | |||
| 870 | cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi); | ||
| 871 | |||
| 872 | out: | ||
| 873 | |||
| 874 | return vi->txn_irq; | ||
| 875 | } | ||
| 876 | #endif | ||
| 877 | |||
| 814 | 878 | ||
| 815 | /* | 879 | /* |
| 816 | ** squirrel away the I/O Sapic Version | 880 | ** squirrel away the I/O Sapic Version |
| @@ -877,6 +941,8 @@ void *iosapic_register(unsigned long hpa) | |||
| 877 | vip->irqline = (unsigned char) cnt; | 941 | vip->irqline = (unsigned char) cnt; |
| 878 | vip->iosapic = isi; | 942 | vip->iosapic = isi; |
| 879 | } | 943 | } |
| 944 | if (!first_isi) | ||
| 945 | first_isi = isi; | ||
| 880 | return isi; | 946 | return isi; |
| 881 | } | 947 | } |
| 882 | 948 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 716aa93fff76..59df8575a48c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
| @@ -61,6 +61,7 @@ static DEFINE_MUTEX(bridge_mutex); | |||
| 61 | static void handle_hotplug_event_bridge (acpi_handle, u32, void *); | 61 | static void handle_hotplug_event_bridge (acpi_handle, u32, void *); |
| 62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
| 63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | 63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); |
| 64 | static void hotplug_event_func(acpi_handle handle, u32 type, void *context); | ||
| 64 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | 65 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); |
| 65 | static void free_bridge(struct kref *kref); | 66 | static void free_bridge(struct kref *kref); |
| 66 | 67 | ||
| @@ -147,7 +148,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | |||
| 147 | 148 | ||
| 148 | 149 | ||
| 149 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 150 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
| 150 | .handler = handle_hotplug_event_func, | 151 | .handler = hotplug_event_func, |
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 153 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | 154 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ |
| @@ -179,6 +180,20 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) | |||
| 179 | return true; | 180 | return true; |
| 180 | } | 181 | } |
| 181 | 182 | ||
| 183 | static void acpiphp_dock_init(void *data) | ||
| 184 | { | ||
| 185 | struct acpiphp_func *func = data; | ||
| 186 | |||
| 187 | get_bridge(func->slot->bridge); | ||
| 188 | } | ||
| 189 | |||
| 190 | static void acpiphp_dock_release(void *data) | ||
| 191 | { | ||
| 192 | struct acpiphp_func *func = data; | ||
| 193 | |||
| 194 | put_bridge(func->slot->bridge); | ||
| 195 | } | ||
| 196 | |||
| 182 | /* callback routine to register each ACPI PCI slot object */ | 197 | /* callback routine to register each ACPI PCI slot object */ |
| 183 | static acpi_status | 198 | static acpi_status |
| 184 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | 199 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) |
| @@ -298,7 +313,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 298 | */ | 313 | */ |
| 299 | newfunc->flags &= ~FUNC_HAS_EJ0; | 314 | newfunc->flags &= ~FUNC_HAS_EJ0; |
| 300 | if (register_hotplug_dock_device(handle, | 315 | if (register_hotplug_dock_device(handle, |
| 301 | &acpiphp_dock_ops, newfunc)) | 316 | &acpiphp_dock_ops, newfunc, |
| 317 | acpiphp_dock_init, acpiphp_dock_release)) | ||
| 302 | dbg("failed to register dock device\n"); | 318 | dbg("failed to register dock device\n"); |
| 303 | 319 | ||
| 304 | /* we need to be notified when dock events happen | 320 | /* we need to be notified when dock events happen |
| @@ -670,6 +686,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
| 670 | struct pci_bus *bus = slot->bridge->pci_bus; | 686 | struct pci_bus *bus = slot->bridge->pci_bus; |
| 671 | struct acpiphp_func *func; | 687 | struct acpiphp_func *func; |
| 672 | int num, max, pass; | 688 | int num, max, pass; |
| 689 | LIST_HEAD(add_list); | ||
| 673 | 690 | ||
| 674 | if (slot->flags & SLOT_ENABLED) | 691 | if (slot->flags & SLOT_ENABLED) |
| 675 | goto err_exit; | 692 | goto err_exit; |
| @@ -694,13 +711,15 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
| 694 | max = pci_scan_bridge(bus, dev, max, pass); | 711 | max = pci_scan_bridge(bus, dev, max, pass); |
| 695 | if (pass && dev->subordinate) { | 712 | if (pass && dev->subordinate) { |
| 696 | check_hotplug_bridge(slot, dev); | 713 | check_hotplug_bridge(slot, dev); |
| 697 | pci_bus_size_bridges(dev->subordinate); | 714 | pcibios_resource_survey_bus(dev->subordinate); |
| 715 | __pci_bus_size_bridges(dev->subordinate, | ||
| 716 | &add_list); | ||
| 698 | } | 717 | } |
| 699 | } | 718 | } |
| 700 | } | 719 | } |
| 701 | } | 720 | } |
| 702 | 721 | ||
| 703 | pci_bus_assign_resources(bus); | 722 | __pci_bus_assign_resources(bus, &add_list, NULL); |
| 704 | acpiphp_sanitize_bus(bus); | 723 | acpiphp_sanitize_bus(bus); |
| 705 | acpiphp_set_hpp_values(bus); | 724 | acpiphp_set_hpp_values(bus); |
| 706 | acpiphp_set_acpi_region(slot); | 725 | acpiphp_set_acpi_region(slot); |
| @@ -1065,22 +1084,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
| 1065 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); | 1084 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
| 1066 | } | 1085 | } |
| 1067 | 1086 | ||
| 1068 | static void _handle_hotplug_event_func(struct work_struct *work) | 1087 | static void hotplug_event_func(acpi_handle handle, u32 type, void *context) |
| 1069 | { | 1088 | { |
| 1070 | struct acpiphp_func *func; | 1089 | struct acpiphp_func *func = context; |
| 1071 | char objname[64]; | 1090 | char objname[64]; |
| 1072 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1091 | struct acpi_buffer buffer = { .length = sizeof(objname), |
| 1073 | .pointer = objname }; | 1092 | .pointer = objname }; |
| 1074 | struct acpi_hp_work *hp_work; | ||
| 1075 | acpi_handle handle; | ||
| 1076 | u32 type; | ||
| 1077 | |||
| 1078 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
| 1079 | handle = hp_work->handle; | ||
| 1080 | type = hp_work->type; | ||
| 1081 | func = (struct acpiphp_func *)hp_work->context; | ||
| 1082 | |||
| 1083 | acpi_scan_lock_acquire(); | ||
| 1084 | 1093 | ||
| 1085 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1094 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
| 1086 | 1095 | ||
| @@ -1113,6 +1122,18 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
| 1113 | warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); | 1122 | warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); |
| 1114 | break; | 1123 | break; |
| 1115 | } | 1124 | } |
| 1125 | } | ||
| 1126 | |||
| 1127 | static void _handle_hotplug_event_func(struct work_struct *work) | ||
| 1128 | { | ||
| 1129 | struct acpi_hp_work *hp_work; | ||
| 1130 | struct acpiphp_func *func; | ||
| 1131 | |||
| 1132 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
| 1133 | func = hp_work->context; | ||
| 1134 | acpi_scan_lock_acquire(); | ||
| 1135 | |||
| 1136 | hotplug_event_func(hp_work->handle, hp_work->type, func); | ||
| 1116 | 1137 | ||
| 1117 | acpi_scan_lock_release(); | 1138 | acpi_scan_lock_release(); |
| 1118 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ | 1139 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 68678ed76b0d..d1182c4a754e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -202,6 +202,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 202 | struct resource *res, unsigned int reg); | 202 | struct resource *res, unsigned int reg); |
| 203 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); | 203 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); |
| 204 | void pci_configure_ari(struct pci_dev *dev); | 204 | void pci_configure_ari(struct pci_dev *dev); |
| 205 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | ||
| 206 | struct list_head *realloc_head); | ||
| 207 | void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | ||
| 208 | struct list_head *realloc_head, | ||
| 209 | struct list_head *fail_head); | ||
| 205 | 210 | ||
| 206 | /** | 211 | /** |
| 207 | * pci_ari_enabled - query ARI forwarding status | 212 | * pci_ari_enabled - query ARI forwarding status |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 16abaaa1f83c..d254e2379533 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -1044,7 +1044,7 @@ handle_done: | |||
| 1044 | ; | 1044 | ; |
| 1045 | } | 1045 | } |
| 1046 | 1046 | ||
| 1047 | static void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 1047 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
| 1048 | struct list_head *realloc_head) | 1048 | struct list_head *realloc_head) |
| 1049 | { | 1049 | { |
| 1050 | struct pci_dev *dev; | 1050 | struct pci_dev *dev; |
| @@ -1115,9 +1115,9 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
| 1115 | } | 1115 | } |
| 1116 | EXPORT_SYMBOL(pci_bus_size_bridges); | 1116 | EXPORT_SYMBOL(pci_bus_size_bridges); |
| 1117 | 1117 | ||
| 1118 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | 1118 | void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
| 1119 | struct list_head *realloc_head, | 1119 | struct list_head *realloc_head, |
| 1120 | struct list_head *fail_head) | 1120 | struct list_head *fail_head) |
| 1121 | { | 1121 | { |
| 1122 | struct pci_bus *b; | 1122 | struct pci_bus *b; |
| 1123 | struct pci_dev *dev; | 1123 | struct pci_dev *dev; |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index d8fa37d5c734..2c9155b66f09 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
| @@ -439,7 +439,7 @@ static int tps6586x_regulator_remove(struct platform_device *pdev) | |||
| 439 | 439 | ||
| 440 | static struct platform_driver tps6586x_regulator_driver = { | 440 | static struct platform_driver tps6586x_regulator_driver = { |
| 441 | .driver = { | 441 | .driver = { |
| 442 | .name = "tps6586x-pmic", | 442 | .name = "tps6586x-regulator", |
| 443 | .owner = THIS_MODULE, | 443 | .owner = THIS_MODULE, |
| 444 | }, | 444 | }, |
| 445 | .probe = tps6586x_regulator_probe, | 445 | .probe = tps6586x_regulator_probe, |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 292b24f9bf93..32ae6c67ea3a 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
| @@ -1656,9 +1656,12 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
| 1656 | 1656 | ||
| 1657 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && | 1657 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && |
| 1658 | fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) { | 1658 | fcoe->realdev->features & NETIF_F_HW_VLAN_CTAG_TX) { |
| 1659 | skb->vlan_tci = VLAN_TAG_PRESENT | | 1659 | /* must set skb->dev before calling vlan_put_tag */ |
| 1660 | vlan_dev_vlan_id(fcoe->netdev); | ||
| 1661 | skb->dev = fcoe->realdev; | 1660 | skb->dev = fcoe->realdev; |
| 1661 | skb = __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | ||
| 1662 | vlan_dev_vlan_id(fcoe->netdev)); | ||
| 1663 | if (!skb) | ||
| 1664 | return -ENOMEM; | ||
| 1662 | } else | 1665 | } else |
| 1663 | skb->dev = fcoe->netdev; | 1666 | skb->dev = fcoe->netdev; |
| 1664 | 1667 | ||
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 7a3870f385f6..66b0b26a1381 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
| @@ -688,8 +688,12 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) | |||
| 688 | * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen | 688 | * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen |
| 689 | * for qla_tgt_xmit_response LLD code | 689 | * for qla_tgt_xmit_response LLD code |
| 690 | */ | 690 | */ |
| 691 | if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
| 692 | se_cmd->se_cmd_flags &= ~SCF_OVERFLOW_BIT; | ||
| 693 | se_cmd->residual_count = 0; | ||
| 694 | } | ||
| 691 | se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; | 695 | se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; |
| 692 | se_cmd->residual_count = se_cmd->data_length; | 696 | se_cmd->residual_count += se_cmd->data_length; |
| 693 | 697 | ||
| 694 | cmd->bufflen = 0; | 698 | cmd->bufflen = 0; |
| 695 | } | 699 | } |
diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c index c735c5a008a2..6427600b5bbe 100644 --- a/drivers/spi/spi-pxa2xx-dma.c +++ b/drivers/spi/spi-pxa2xx-dma.c | |||
| @@ -59,7 +59,7 @@ static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data, | |||
| 59 | int ret; | 59 | int ret; |
| 60 | 60 | ||
| 61 | sg_free_table(sgt); | 61 | sg_free_table(sgt); |
| 62 | ret = sg_alloc_table(sgt, nents, GFP_KERNEL); | 62 | ret = sg_alloc_table(sgt, nents, GFP_ATOMIC); |
| 63 | if (ret) | 63 | if (ret) |
| 64 | return ret; | 64 | return ret; |
| 65 | } | 65 | } |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index f5d84d6f8222..48b396fced0a 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
| @@ -1075,7 +1075,7 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) | |||
| 1075 | acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) | 1075 | acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) |
| 1076 | return NULL; | 1076 | return NULL; |
| 1077 | 1077 | ||
| 1078 | pdata = devm_kzalloc(&pdev->dev, sizeof(*ssp), GFP_KERNEL); | 1078 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
| 1079 | if (!pdata) { | 1079 | if (!pdata) { |
| 1080 | dev_err(&pdev->dev, | 1080 | dev_err(&pdev->dev, |
| 1081 | "failed to allocate memory for platform data\n"); | 1081 | "failed to allocate memory for platform data\n"); |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 5000586cb98d..71cc3e6ef47c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
| @@ -444,7 +444,7 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) | |||
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | ret = pm_runtime_get_sync(&sdd->pdev->dev); | 446 | ret = pm_runtime_get_sync(&sdd->pdev->dev); |
| 447 | if (ret != 0) { | 447 | if (ret < 0) { |
| 448 | dev_err(dev, "Failed to enable device: %d\n", ret); | 448 | dev_err(dev, "Failed to enable device: %d\n", ret); |
| 449 | goto out_tx; | 449 | goto out_tx; |
| 450 | } | 450 | } |
diff --git a/drivers/staging/media/davinci_vpfe/Kconfig b/drivers/staging/media/davinci_vpfe/Kconfig index 2e4a28b018e8..12f321dd2399 100644 --- a/drivers/staging/media/davinci_vpfe/Kconfig +++ b/drivers/staging/media/davinci_vpfe/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config VIDEO_DM365_VPFE | 1 | config VIDEO_DM365_VPFE |
| 2 | tristate "DM365 VPFE Media Controller Capture Driver" | 2 | tristate "DM365 VPFE Media Controller Capture Driver" |
| 3 | depends on VIDEO_V4L2 && ARCH_DAVINCI_DM365 && !VIDEO_VPFE_CAPTURE | 3 | depends on VIDEO_V4L2 && ARCH_DAVINCI_DM365 && !VIDEO_DM365_ISIF |
| 4 | select VIDEOBUF2_DMA_CONTIG | 4 | select VIDEOBUF2_DMA_CONTIG |
| 5 | help | 5 | help |
| 6 | Support for DM365 VPFE based Media Controller Capture driver. | 6 | Support for DM365 VPFE based Media Controller Capture driver. |
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index b88e1ddce229..d8ce20d2fbda 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c | |||
| @@ -639,7 +639,8 @@ static int vpfe_probe(struct platform_device *pdev) | |||
| 639 | if (ret) | 639 | if (ret) |
| 640 | goto probe_free_dev_mem; | 640 | goto probe_free_dev_mem; |
| 641 | 641 | ||
| 642 | if (vpfe_initialize_modules(vpfe_dev, pdev)) | 642 | ret = vpfe_initialize_modules(vpfe_dev, pdev); |
| 643 | if (ret) | ||
| 643 | goto probe_disable_clock; | 644 | goto probe_disable_clock; |
| 644 | 645 | ||
| 645 | vpfe_dev->media_dev.dev = vpfe_dev->pdev; | 646 | vpfe_dev->media_dev.dev = vpfe_dev->pdev; |
| @@ -663,7 +664,8 @@ static int vpfe_probe(struct platform_device *pdev) | |||
| 663 | /* set the driver data in platform device */ | 664 | /* set the driver data in platform device */ |
| 664 | platform_set_drvdata(pdev, vpfe_dev); | 665 | platform_set_drvdata(pdev, vpfe_dev); |
| 665 | /* register subdevs/entities */ | 666 | /* register subdevs/entities */ |
| 666 | if (vpfe_register_entities(vpfe_dev)) | 667 | ret = vpfe_register_entities(vpfe_dev); |
| 668 | if (ret) | ||
| 667 | goto probe_out_v4l2_unregister; | 669 | goto probe_out_v4l2_unregister; |
| 668 | 670 | ||
| 669 | ret = vpfe_attach_irq(vpfe_dev); | 671 | ret = vpfe_attach_irq(vpfe_dev); |
diff --git a/drivers/staging/media/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig index df6569b997b8..34f3b6d02d2a 100644 --- a/drivers/staging/media/solo6x10/Kconfig +++ b/drivers/staging/media/solo6x10/Kconfig | |||
| @@ -5,6 +5,7 @@ config SOLO6X10 | |||
| 5 | select VIDEOBUF2_DMA_SG | 5 | select VIDEOBUF2_DMA_SG |
| 6 | select VIDEOBUF2_DMA_CONTIG | 6 | select VIDEOBUF2_DMA_CONTIG |
| 7 | select SND_PCM | 7 | select SND_PCM |
| 8 | select FONT_8x16 | ||
| 8 | ---help--- | 9 | ---help--- |
| 9 | This driver supports the Softlogic based MPEG-4 and h.264 codec | 10 | This driver supports the Softlogic based MPEG-4 and h.264 codec |
| 10 | cards. | 11 | cards. |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 13e9e715ad2e..8d8b3ff68490 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
| @@ -155,7 +155,7 @@ static ssize_t lio_target_np_store_iser( | |||
| 155 | struct iscsi_tpg_np *tpg_np_iser = NULL; | 155 | struct iscsi_tpg_np *tpg_np_iser = NULL; |
| 156 | char *endptr; | 156 | char *endptr; |
| 157 | u32 op; | 157 | u32 op; |
| 158 | int rc; | 158 | int rc = 0; |
| 159 | 159 | ||
| 160 | op = simple_strtoul(page, &endptr, 0); | 160 | op = simple_strtoul(page, &endptr, 0); |
| 161 | if ((op != 1) && (op != 0)) { | 161 | if ((op != 1) && (op != 0)) { |
| @@ -174,31 +174,32 @@ static ssize_t lio_target_np_store_iser( | |||
| 174 | return -EINVAL; | 174 | return -EINVAL; |
| 175 | 175 | ||
| 176 | if (op) { | 176 | if (op) { |
| 177 | int rc = request_module("ib_isert"); | 177 | rc = request_module("ib_isert"); |
| 178 | if (rc != 0) | 178 | if (rc != 0) { |
| 179 | pr_warn("Unable to request_module for ib_isert\n"); | 179 | pr_warn("Unable to request_module for ib_isert\n"); |
| 180 | rc = 0; | ||
| 181 | } | ||
| 180 | 182 | ||
| 181 | tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, | 183 | tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, |
| 182 | np->np_ip, tpg_np, ISCSI_INFINIBAND); | 184 | np->np_ip, tpg_np, ISCSI_INFINIBAND); |
| 183 | if (!tpg_np_iser || IS_ERR(tpg_np_iser)) | 185 | if (IS_ERR(tpg_np_iser)) { |
| 186 | rc = PTR_ERR(tpg_np_iser); | ||
| 184 | goto out; | 187 | goto out; |
| 188 | } | ||
| 185 | } else { | 189 | } else { |
| 186 | tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND); | 190 | tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND); |
| 187 | if (!tpg_np_iser) | 191 | if (tpg_np_iser) { |
| 188 | goto out; | 192 | rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser); |
| 189 | 193 | if (rc < 0) | |
| 190 | rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser); | 194 | goto out; |
| 191 | if (rc < 0) | 195 | } |
| 192 | goto out; | ||
| 193 | } | 196 | } |
| 194 | 197 | ||
| 195 | printk("lio_target_np_store_iser() done, op: %d\n", op); | ||
| 196 | |||
| 197 | iscsit_put_tpg(tpg); | 198 | iscsit_put_tpg(tpg); |
| 198 | return count; | 199 | return count; |
| 199 | out: | 200 | out: |
| 200 | iscsit_put_tpg(tpg); | 201 | iscsit_put_tpg(tpg); |
| 201 | return -EINVAL; | 202 | return rc; |
| 202 | } | 203 | } |
| 203 | 204 | ||
| 204 | TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR); | 205 | TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR); |
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index 8e6298cc8839..dcb199da06b9 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c | |||
| @@ -842,11 +842,11 @@ int iscsit_stop_time2retain_timer(struct iscsi_session *sess) | |||
| 842 | return 0; | 842 | return 0; |
| 843 | 843 | ||
| 844 | sess->time2retain_timer_flags |= ISCSI_TF_STOP; | 844 | sess->time2retain_timer_flags |= ISCSI_TF_STOP; |
| 845 | spin_unlock_bh(&se_tpg->session_lock); | 845 | spin_unlock(&se_tpg->session_lock); |
| 846 | 846 | ||
| 847 | del_timer_sync(&sess->time2retain_timer); | 847 | del_timer_sync(&sess->time2retain_timer); |
| 848 | 848 | ||
| 849 | spin_lock_bh(&se_tpg->session_lock); | 849 | spin_lock(&se_tpg->session_lock); |
| 850 | sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING; | 850 | sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING; |
| 851 | pr_debug("Stopped Time2Retain Timer for SID: %u\n", | 851 | pr_debug("Stopped Time2Retain Timer for SID: %u\n", |
| 852 | sess->sid); | 852 | sess->sid); |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index bb5d5c5bce65..3402241be87c 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
| @@ -984,8 +984,6 @@ int iscsi_target_setup_login_socket( | |||
| 984 | } | 984 | } |
| 985 | 985 | ||
| 986 | np->np_transport = t; | 986 | np->np_transport = t; |
| 987 | printk("Set np->np_transport to %p -> %s\n", np->np_transport, | ||
| 988 | np->np_transport->name); | ||
| 989 | return 0; | 987 | return 0; |
| 990 | } | 988 | } |
| 991 | 989 | ||
| @@ -1002,7 +1000,6 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) | |||
| 1002 | 1000 | ||
| 1003 | conn->sock = new_sock; | 1001 | conn->sock = new_sock; |
| 1004 | conn->login_family = np->np_sockaddr.ss_family; | 1002 | conn->login_family = np->np_sockaddr.ss_family; |
| 1005 | printk("iSCSI/TCP: Setup conn->sock from new_sock: %p\n", new_sock); | ||
| 1006 | 1003 | ||
| 1007 | if (np->np_sockaddr.ss_family == AF_INET6) { | 1004 | if (np->np_sockaddr.ss_family == AF_INET6) { |
| 1008 | memset(&sock_in6, 0, sizeof(struct sockaddr_in6)); | 1005 | memset(&sock_in6, 0, sizeof(struct sockaddr_in6)); |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 7ad912060e21..cd5018ff9cd7 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
| @@ -721,9 +721,6 @@ int iscsi_target_locate_portal( | |||
| 721 | 721 | ||
| 722 | start += strlen(key) + strlen(value) + 2; | 722 | start += strlen(key) + strlen(value) + 2; |
| 723 | } | 723 | } |
| 724 | |||
| 725 | printk("i_buf: %s, s_buf: %s, t_buf: %s\n", i_buf, s_buf, t_buf); | ||
| 726 | |||
| 727 | /* | 724 | /* |
| 728 | * See 5.3. Login Phase. | 725 | * See 5.3. Login Phase. |
| 729 | */ | 726 | */ |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 59bfaecc4e14..abfd99089781 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
| @@ -244,14 +244,9 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
| 244 | 244 | ||
| 245 | static int pty_open(struct tty_struct *tty, struct file *filp) | 245 | static int pty_open(struct tty_struct *tty, struct file *filp) |
| 246 | { | 246 | { |
| 247 | int retval = -ENODEV; | ||
| 248 | |||
| 249 | if (!tty || !tty->link) | 247 | if (!tty || !tty->link) |
| 250 | goto out; | 248 | return -ENODEV; |
| 251 | |||
| 252 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
| 253 | 249 | ||
| 254 | retval = -EIO; | ||
| 255 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | 250 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) |
| 256 | goto out; | 251 | goto out; |
| 257 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) | 252 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) |
| @@ -262,9 +257,11 @@ static int pty_open(struct tty_struct *tty, struct file *filp) | |||
| 262 | clear_bit(TTY_IO_ERROR, &tty->flags); | 257 | clear_bit(TTY_IO_ERROR, &tty->flags); |
| 263 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 258 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
| 264 | set_bit(TTY_THROTTLED, &tty->flags); | 259 | set_bit(TTY_THROTTLED, &tty->flags); |
| 265 | retval = 0; | 260 | return 0; |
| 261 | |||
| 266 | out: | 262 | out: |
| 267 | return retval; | 263 | set_bit(TTY_IO_ERROR, &tty->flags); |
| 264 | return -EIO; | ||
| 268 | } | 265 | } |
| 269 | 266 | ||
| 270 | static void pty_set_termios(struct tty_struct *tty, | 267 | static void pty_set_termios(struct tty_struct *tty, |
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index 097dff9c08ad..bb91b4713ebd 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c | |||
| @@ -30,6 +30,12 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
| 30 | unsigned long address; | 30 | unsigned long address; |
| 31 | int err; | 31 | int err; |
| 32 | 32 | ||
| 33 | #ifdef CONFIG_64BIT | ||
| 34 | extern int iosapic_serial_irq(int cellnum); | ||
| 35 | if (!dev->irq && (dev->id.sversion == 0xad)) | ||
| 36 | dev->irq = iosapic_serial_irq(dev->mod_index-1); | ||
| 37 | #endif | ||
| 38 | |||
| 33 | if (!dev->irq) { | 39 | if (!dev->irq) { |
| 34 | /* We find some unattached serial ports by walking native | 40 | /* We find some unattached serial ports by walking native |
| 35 | * busses. These should be silently ignored. Otherwise, | 41 | * busses. These should be silently ignored. Otherwise, |
| @@ -51,7 +57,8 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
| 51 | memset(&uart, 0, sizeof(uart)); | 57 | memset(&uart, 0, sizeof(uart)); |
| 52 | uart.port.iotype = UPIO_MEM; | 58 | uart.port.iotype = UPIO_MEM; |
| 53 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ | 59 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ |
| 54 | uart.port.uartclk = 7272727; | 60 | uart.port.uartclk = (dev->id.sversion != 0xad) ? |
| 61 | 7272727 : 1843200; | ||
| 55 | uart.port.mapbase = address; | 62 | uart.port.mapbase = address; |
| 56 | uart.port.membase = ioremap_nocache(address, 16); | 63 | uart.port.membase = ioremap_nocache(address, 16); |
| 57 | uart.port.irq = dev->irq; | 64 | uart.port.irq = dev->irq; |
| @@ -73,6 +80,7 @@ static struct parisc_device_id serial_tbl[] = { | |||
| 73 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, | 80 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, |
| 74 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, | 81 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, |
| 75 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, | 82 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, |
| 83 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad }, | ||
| 76 | { 0 } | 84 | { 0 } |
| 77 | }; | 85 | }; |
| 78 | 86 | ||
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index fc2c06c66e89..2bd78e2ac8ec 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
| @@ -289,13 +289,10 @@ static int vt_disallocate(unsigned int vc_num) | |||
| 289 | struct vc_data *vc = NULL; | 289 | struct vc_data *vc = NULL; |
| 290 | int ret = 0; | 290 | int ret = 0; |
| 291 | 291 | ||
| 292 | if (!vc_num) | ||
| 293 | return 0; | ||
| 294 | |||
| 295 | console_lock(); | 292 | console_lock(); |
| 296 | if (VT_BUSY(vc_num)) | 293 | if (VT_BUSY(vc_num)) |
| 297 | ret = -EBUSY; | 294 | ret = -EBUSY; |
| 298 | else | 295 | else if (vc_num) |
| 299 | vc = vc_deallocate(vc_num); | 296 | vc = vc_deallocate(vc_num); |
| 300 | console_unlock(); | 297 | console_unlock(); |
| 301 | 298 | ||
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 7ef3eb8617a6..2311b1e4e43c 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig | |||
| @@ -4,11 +4,17 @@ | |||
| 4 | menuconfig USB_PHY | 4 | menuconfig USB_PHY |
| 5 | bool "USB Physical Layer drivers" | 5 | bool "USB Physical Layer drivers" |
| 6 | help | 6 | help |
| 7 | USB controllers (those which are host, device or DRD) need a | 7 | Most USB controllers have the physical layer signalling part |
| 8 | device to handle the physical layer signalling, commonly called | 8 | (commonly called a PHY) built in. However, dual-role devices |
| 9 | a PHY. | 9 | (a.k.a. USB on-the-go) which support being USB master or slave |
| 10 | with the same connector often use an external PHY. | ||
| 10 | 11 | ||
| 11 | The following drivers add support for such PHY devices. | 12 | The drivers in this submenu add support for such PHY devices. |
| 13 | They are not needed for standard master-only (or the vast | ||
| 14 | majority of slave-only) USB interfaces. | ||
| 15 | |||
| 16 | If you're not sure if this applies to you, it probably doesn't; | ||
| 17 | say N here. | ||
| 12 | 18 | ||
| 13 | if USB_PHY | 19 | if USB_PHY |
| 14 | 20 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index c92c5ed4e580..e581c2549a57 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -172,7 +172,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { | |||
| 172 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | 172 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, |
| 173 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, | 173 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, |
| 174 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, | 174 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, |
| 175 | { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, | 175 | { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, |
| 176 | { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, | ||
| 176 | { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, | 177 | { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, |
| 177 | }; | 178 | }; |
| 178 | 179 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h index b353e7e3d480..4a2423e84d55 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.h +++ b/drivers/usb/serial/ti_usb_3410_5052.h | |||
| @@ -52,7 +52,9 @@ | |||
| 52 | 52 | ||
| 53 | /* Abbott Diabetics vendor and product ids */ | 53 | /* Abbott Diabetics vendor and product ids */ |
| 54 | #define ABBOTT_VENDOR_ID 0x1a61 | 54 | #define ABBOTT_VENDOR_ID 0x1a61 |
| 55 | #define ABBOTT_PRODUCT_ID 0x3410 | 55 | #define ABBOTT_STEREO_PLUG_ID 0x3410 |
| 56 | #define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID | ||
| 57 | #define ABBOTT_STRIP_PORT_ID 0x3420 | ||
| 56 | 58 | ||
| 57 | /* Commands */ | 59 | /* Commands */ |
| 58 | #define TI_GET_VERSION 0x01 | 60 | #define TI_GET_VERSION 0x01 |
| @@ -1135,13 +1135,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
| 1135 | set_dumpable(current->mm, suid_dumpable); | 1135 | set_dumpable(current->mm, suid_dumpable); |
| 1136 | } | 1136 | } |
| 1137 | 1137 | ||
| 1138 | /* | ||
| 1139 | * Flush performance counters when crossing a | ||
| 1140 | * security domain: | ||
| 1141 | */ | ||
| 1142 | if (!get_dumpable(current->mm)) | ||
| 1143 | perf_event_exit_task(current); | ||
| 1144 | |||
| 1145 | /* An exec changes our domain. We are no longer part of the thread | 1138 | /* An exec changes our domain. We are no longer part of the thread |
| 1146 | group */ | 1139 | group */ |
| 1147 | 1140 | ||
| @@ -1205,6 +1198,15 @@ void install_exec_creds(struct linux_binprm *bprm) | |||
| 1205 | 1198 | ||
| 1206 | commit_creds(bprm->cred); | 1199 | commit_creds(bprm->cred); |
| 1207 | bprm->cred = NULL; | 1200 | bprm->cred = NULL; |
| 1201 | |||
| 1202 | /* | ||
| 1203 | * Disable monitoring for regular users | ||
| 1204 | * when executing setuid binaries. Must | ||
| 1205 | * wait until new credentials are committed | ||
| 1206 | * by commit_creds() above | ||
| 1207 | */ | ||
| 1208 | if (get_dumpable(current->mm) != SUID_DUMP_USER) | ||
| 1209 | perf_event_exit_task(current); | ||
| 1208 | /* | 1210 | /* |
| 1209 | * cred_guard_mutex must be held at least to this point to prevent | 1211 | * cred_guard_mutex must be held at least to this point to prevent |
| 1210 | * ptrace_attach() from altering our determination of the task's | 1212 | * ptrace_attach() from altering our determination of the task's |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e570081f9f76..35f281033142 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -2470,13 +2470,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2470 | .mode = mode | 2470 | .mode = mode |
| 2471 | }; | 2471 | }; |
| 2472 | int err; | 2472 | int err; |
| 2473 | bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || | ||
| 2474 | (mode & FALLOC_FL_PUNCH_HOLE); | ||
| 2473 | 2475 | ||
| 2474 | if (fc->no_fallocate) | 2476 | if (fc->no_fallocate) |
| 2475 | return -EOPNOTSUPP; | 2477 | return -EOPNOTSUPP; |
| 2476 | 2478 | ||
| 2477 | if (mode & FALLOC_FL_PUNCH_HOLE) { | 2479 | if (lock_inode) { |
| 2478 | mutex_lock(&inode->i_mutex); | 2480 | mutex_lock(&inode->i_mutex); |
| 2479 | fuse_set_nowrite(inode); | 2481 | if (mode & FALLOC_FL_PUNCH_HOLE) |
| 2482 | fuse_set_nowrite(inode); | ||
| 2480 | } | 2483 | } |
| 2481 | 2484 | ||
| 2482 | req = fuse_get_req_nopages(fc); | 2485 | req = fuse_get_req_nopages(fc); |
| @@ -2511,8 +2514,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2511 | fuse_invalidate_attr(inode); | 2514 | fuse_invalidate_attr(inode); |
| 2512 | 2515 | ||
| 2513 | out: | 2516 | out: |
| 2514 | if (mode & FALLOC_FL_PUNCH_HOLE) { | 2517 | if (lock_inode) { |
| 2515 | fuse_release_nowrite(inode); | 2518 | if (mode & FALLOC_FL_PUNCH_HOLE) |
| 2519 | fuse_release_nowrite(inode); | ||
| 2516 | mutex_unlock(&inode->i_mutex); | 2520 | mutex_unlock(&inode->i_mutex); |
| 2517 | } | 2521 | } |
| 2518 | 2522 | ||
diff --git a/fs/splice.c b/fs/splice.c index 9eca476227d5..d37431dd60a1 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -1283,6 +1283,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, | |||
| 1283 | * @in: file to splice from | 1283 | * @in: file to splice from |
| 1284 | * @ppos: input file offset | 1284 | * @ppos: input file offset |
| 1285 | * @out: file to splice to | 1285 | * @out: file to splice to |
| 1286 | * @opos: output file offset | ||
| 1286 | * @len: number of bytes to splice | 1287 | * @len: number of bytes to splice |
| 1287 | * @flags: splice modifier flags | 1288 | * @flags: splice modifier flags |
| 1288 | * | 1289 | * |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 636c59f2003a..c13c919ab99e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -382,6 +382,7 @@ const char *acpi_power_state_string(int state); | |||
| 382 | int acpi_device_get_power(struct acpi_device *device, int *state); | 382 | int acpi_device_get_power(struct acpi_device *device, int *state); |
| 383 | int acpi_device_set_power(struct acpi_device *device, int state); | 383 | int acpi_device_set_power(struct acpi_device *device, int state); |
| 384 | int acpi_bus_init_power(struct acpi_device *device); | 384 | int acpi_bus_init_power(struct acpi_device *device); |
| 385 | int acpi_device_fix_up_power(struct acpi_device *device); | ||
| 385 | int acpi_bus_update_power(acpi_handle handle, int *state_p); | 386 | int acpi_bus_update_power(acpi_handle handle, int *state_p); |
| 386 | bool acpi_bus_power_manageable(acpi_handle handle); | 387 | bool acpi_bus_power_manageable(acpi_handle handle); |
| 387 | 388 | ||
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index e6168a24b9f0..b420939f5eb5 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
| @@ -123,7 +123,9 @@ extern int register_dock_notifier(struct notifier_block *nb); | |||
| 123 | extern void unregister_dock_notifier(struct notifier_block *nb); | 123 | extern void unregister_dock_notifier(struct notifier_block *nb); |
| 124 | extern int register_hotplug_dock_device(acpi_handle handle, | 124 | extern int register_hotplug_dock_device(acpi_handle handle, |
| 125 | const struct acpi_dock_ops *ops, | 125 | const struct acpi_dock_ops *ops, |
| 126 | void *context); | 126 | void *context, |
| 127 | void (*init)(void *), | ||
| 128 | void (*release)(void *)); | ||
| 127 | extern void unregister_hotplug_dock_device(acpi_handle handle); | 129 | extern void unregister_hotplug_dock_device(acpi_handle handle); |
| 128 | #else | 130 | #else |
| 129 | static inline int is_dock_device(acpi_handle handle) | 131 | static inline int is_dock_device(acpi_handle handle) |
| @@ -139,7 +141,9 @@ static inline void unregister_dock_notifier(struct notifier_block *nb) | |||
| 139 | } | 141 | } |
| 140 | static inline int register_hotplug_dock_device(acpi_handle handle, | 142 | static inline int register_hotplug_dock_device(acpi_handle handle, |
| 141 | const struct acpi_dock_ops *ops, | 143 | const struct acpi_dock_ops *ops, |
| 142 | void *context) | 144 | void *context, |
| 145 | void (*init)(void *), | ||
| 146 | void (*release)(void *)) | ||
| 143 | { | 147 | { |
| 144 | return -ENODEV; | 148 | return -ENODEV; |
| 145 | } | 149 | } |
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index 365f4a61bf04..fc09d7b0dacf 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
| 5 | #include <linux/percpu.h> | 5 | #include <linux/percpu.h> |
| 6 | #include <linux/vtime.h> | ||
| 6 | #include <asm/ptrace.h> | 7 | #include <asm/ptrace.h> |
| 7 | 8 | ||
| 8 | struct context_tracking { | 9 | struct context_tracking { |
| @@ -19,6 +20,26 @@ struct context_tracking { | |||
| 19 | } state; | 20 | } state; |
| 20 | }; | 21 | }; |
| 21 | 22 | ||
| 23 | static inline void __guest_enter(void) | ||
| 24 | { | ||
| 25 | /* | ||
| 26 | * This is running in ioctl context so we can avoid | ||
| 27 | * the call to vtime_account() with its unnecessary idle check. | ||
| 28 | */ | ||
| 29 | vtime_account_system(current); | ||
| 30 | current->flags |= PF_VCPU; | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline void __guest_exit(void) | ||
| 34 | { | ||
| 35 | /* | ||
| 36 | * This is running in ioctl context so we can avoid | ||
| 37 | * the call to vtime_account() with its unnecessary idle check. | ||
| 38 | */ | ||
| 39 | vtime_account_system(current); | ||
| 40 | current->flags &= ~PF_VCPU; | ||
| 41 | } | ||
| 42 | |||
| 22 | #ifdef CONFIG_CONTEXT_TRACKING | 43 | #ifdef CONFIG_CONTEXT_TRACKING |
| 23 | DECLARE_PER_CPU(struct context_tracking, context_tracking); | 44 | DECLARE_PER_CPU(struct context_tracking, context_tracking); |
| 24 | 45 | ||
| @@ -35,6 +56,9 @@ static inline bool context_tracking_active(void) | |||
| 35 | extern void user_enter(void); | 56 | extern void user_enter(void); |
| 36 | extern void user_exit(void); | 57 | extern void user_exit(void); |
| 37 | 58 | ||
| 59 | extern void guest_enter(void); | ||
| 60 | extern void guest_exit(void); | ||
| 61 | |||
| 38 | static inline enum ctx_state exception_enter(void) | 62 | static inline enum ctx_state exception_enter(void) |
| 39 | { | 63 | { |
| 40 | enum ctx_state prev_ctx; | 64 | enum ctx_state prev_ctx; |
| @@ -57,6 +81,17 @@ extern void context_tracking_task_switch(struct task_struct *prev, | |||
| 57 | static inline bool context_tracking_in_user(void) { return false; } | 81 | static inline bool context_tracking_in_user(void) { return false; } |
| 58 | static inline void user_enter(void) { } | 82 | static inline void user_enter(void) { } |
| 59 | static inline void user_exit(void) { } | 83 | static inline void user_exit(void) { } |
| 84 | |||
| 85 | static inline void guest_enter(void) | ||
| 86 | { | ||
| 87 | __guest_enter(); | ||
| 88 | } | ||
| 89 | |||
| 90 | static inline void guest_exit(void) | ||
| 91 | { | ||
| 92 | __guest_exit(); | ||
| 93 | } | ||
| 94 | |||
| 60 | static inline enum ctx_state exception_enter(void) { return 0; } | 95 | static inline enum ctx_state exception_enter(void) { return 0; } |
| 61 | static inline void exception_exit(enum ctx_state prev_ctx) { } | 96 | static inline void exception_exit(enum ctx_state prev_ctx) { } |
| 62 | static inline void context_tracking_task_switch(struct task_struct *prev, | 97 | static inline void context_tracking_task_switch(struct task_struct *prev, |
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 52bd03b38962..637fa71de0c7 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
| @@ -44,7 +44,7 @@ struct vlan_hdr { | |||
| 44 | * struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr) | 44 | * struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr) |
| 45 | * @h_dest: destination ethernet address | 45 | * @h_dest: destination ethernet address |
| 46 | * @h_source: source ethernet address | 46 | * @h_source: source ethernet address |
| 47 | * @h_vlan_proto: ethernet protocol (always 0x8100) | 47 | * @h_vlan_proto: ethernet protocol |
| 48 | * @h_vlan_TCI: priority and VLAN ID | 48 | * @h_vlan_TCI: priority and VLAN ID |
| 49 | * @h_vlan_encapsulated_proto: packet type ID or len | 49 | * @h_vlan_encapsulated_proto: packet type ID or len |
| 50 | */ | 50 | */ |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f0eea07d2c2b..8db53cfaccdb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/ratelimit.h> | 23 | #include <linux/ratelimit.h> |
| 24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
| 25 | #include <linux/irqflags.h> | 25 | #include <linux/irqflags.h> |
| 26 | #include <linux/context_tracking.h> | ||
| 26 | #include <asm/signal.h> | 27 | #include <asm/signal.h> |
| 27 | 28 | ||
| 28 | #include <linux/kvm.h> | 29 | #include <linux/kvm.h> |
| @@ -760,42 +761,6 @@ static inline int kvm_iommu_unmap_guest(struct kvm *kvm) | |||
| 760 | } | 761 | } |
| 761 | #endif | 762 | #endif |
| 762 | 763 | ||
| 763 | static inline void __guest_enter(void) | ||
| 764 | { | ||
| 765 | /* | ||
| 766 | * This is running in ioctl context so we can avoid | ||
| 767 | * the call to vtime_account() with its unnecessary idle check. | ||
| 768 | */ | ||
| 769 | vtime_account_system(current); | ||
| 770 | current->flags |= PF_VCPU; | ||
| 771 | } | ||
| 772 | |||
| 773 | static inline void __guest_exit(void) | ||
| 774 | { | ||
| 775 | /* | ||
| 776 | * This is running in ioctl context so we can avoid | ||
| 777 | * the call to vtime_account() with its unnecessary idle check. | ||
| 778 | */ | ||
| 779 | vtime_account_system(current); | ||
| 780 | current->flags &= ~PF_VCPU; | ||
| 781 | } | ||
| 782 | |||
| 783 | #ifdef CONFIG_CONTEXT_TRACKING | ||
| 784 | extern void guest_enter(void); | ||
| 785 | extern void guest_exit(void); | ||
| 786 | |||
| 787 | #else /* !CONFIG_CONTEXT_TRACKING */ | ||
| 788 | static inline void guest_enter(void) | ||
| 789 | { | ||
| 790 | __guest_enter(); | ||
| 791 | } | ||
| 792 | |||
| 793 | static inline void guest_exit(void) | ||
| 794 | { | ||
| 795 | __guest_exit(); | ||
| 796 | } | ||
| 797 | #endif /* !CONFIG_CONTEXT_TRACKING */ | ||
| 798 | |||
| 799 | static inline void kvm_guest_enter(void) | 764 | static inline void kvm_guest_enter(void) |
| 800 | { | 765 | { |
| 801 | unsigned long flags; | 766 | unsigned long flags; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 60584b185a0c..96e4c21e15e0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1695,6 +1695,7 @@ extern int init_dummy_netdev(struct net_device *dev); | |||
| 1695 | extern struct net_device *dev_get_by_index(struct net *net, int ifindex); | 1695 | extern struct net_device *dev_get_by_index(struct net *net, int ifindex); |
| 1696 | extern struct net_device *__dev_get_by_index(struct net *net, int ifindex); | 1696 | extern struct net_device *__dev_get_by_index(struct net *net, int ifindex); |
| 1697 | extern struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); | 1697 | extern struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); |
| 1698 | extern int netdev_get_name(struct net *net, char *name, int ifindex); | ||
| 1698 | extern int dev_restart(struct net_device *dev); | 1699 | extern int dev_restart(struct net_device *dev); |
| 1699 | #ifdef CONFIG_NETPOLL_TRAP | 1700 | #ifdef CONFIG_NETPOLL_TRAP |
| 1700 | extern int netpoll_trap(void); | 1701 | extern int netpoll_trap(void); |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index f463a46424e2..c5b6dbf9c2fc 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -389,8 +389,7 @@ struct perf_event { | |||
| 389 | /* mmap bits */ | 389 | /* mmap bits */ |
| 390 | struct mutex mmap_mutex; | 390 | struct mutex mmap_mutex; |
| 391 | atomic_t mmap_count; | 391 | atomic_t mmap_count; |
| 392 | int mmap_locked; | 392 | |
| 393 | struct user_struct *mmap_user; | ||
| 394 | struct ring_buffer *rb; | 393 | struct ring_buffer *rb; |
| 395 | struct list_head rb_entry; | 394 | struct list_head rb_entry; |
| 396 | 395 | ||
diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 87a03c746f17..f5d4723cdb3d 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h | |||
| @@ -33,9 +33,25 @@ do { \ | |||
| 33 | preempt_schedule(); \ | 33 | preempt_schedule(); \ |
| 34 | } while (0) | 34 | } while (0) |
| 35 | 35 | ||
| 36 | #ifdef CONFIG_CONTEXT_TRACKING | ||
| 37 | |||
| 38 | void preempt_schedule_context(void); | ||
| 39 | |||
| 40 | #define preempt_check_resched_context() \ | ||
| 41 | do { \ | ||
| 42 | if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ | ||
| 43 | preempt_schedule_context(); \ | ||
| 44 | } while (0) | ||
| 45 | #else | ||
| 46 | |||
| 47 | #define preempt_check_resched_context() preempt_check_resched() | ||
| 48 | |||
| 49 | #endif /* CONFIG_CONTEXT_TRACKING */ | ||
| 50 | |||
| 36 | #else /* !CONFIG_PREEMPT */ | 51 | #else /* !CONFIG_PREEMPT */ |
| 37 | 52 | ||
| 38 | #define preempt_check_resched() do { } while (0) | 53 | #define preempt_check_resched() do { } while (0) |
| 54 | #define preempt_check_resched_context() do { } while (0) | ||
| 39 | 55 | ||
| 40 | #endif /* CONFIG_PREEMPT */ | 56 | #endif /* CONFIG_PREEMPT */ |
| 41 | 57 | ||
| @@ -88,7 +104,7 @@ do { \ | |||
| 88 | do { \ | 104 | do { \ |
| 89 | preempt_enable_no_resched_notrace(); \ | 105 | preempt_enable_no_resched_notrace(); \ |
| 90 | barrier(); \ | 106 | barrier(); \ |
| 91 | preempt_check_resched(); \ | 107 | preempt_check_resched_context(); \ |
| 92 | } while (0) | 108 | } while (0) |
| 93 | 109 | ||
| 94 | #else /* !CONFIG_PREEMPT_COUNT */ | 110 | #else /* !CONFIG_PREEMPT_COUNT */ |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 9c676eae3968..dec1748cd002 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -627,6 +627,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb) | |||
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | extern void kfree_skb(struct sk_buff *skb); | 629 | extern void kfree_skb(struct sk_buff *skb); |
| 630 | extern void kfree_skb_list(struct sk_buff *segs); | ||
| 630 | extern void skb_tx_error(struct sk_buff *skb); | 631 | extern void skb_tx_error(struct sk_buff *skb); |
| 631 | extern void consume_skb(struct sk_buff *skb); | 632 | extern void consume_skb(struct sk_buff *skb); |
| 632 | extern void __kfree_skb(struct sk_buff *skb); | 633 | extern void __kfree_skb(struct sk_buff *skb); |
diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 71a5782d8c59..b1dd2db80076 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h | |||
| @@ -34,7 +34,7 @@ static inline void vtime_user_exit(struct task_struct *tsk) | |||
| 34 | } | 34 | } |
| 35 | extern void vtime_guest_enter(struct task_struct *tsk); | 35 | extern void vtime_guest_enter(struct task_struct *tsk); |
| 36 | extern void vtime_guest_exit(struct task_struct *tsk); | 36 | extern void vtime_guest_exit(struct task_struct *tsk); |
| 37 | extern void vtime_init_idle(struct task_struct *tsk); | 37 | extern void vtime_init_idle(struct task_struct *tsk, int cpu); |
| 38 | #else | 38 | #else |
| 39 | static inline void vtime_account_irq_exit(struct task_struct *tsk) | 39 | static inline void vtime_account_irq_exit(struct task_struct *tsk) |
| 40 | { | 40 | { |
| @@ -45,7 +45,7 @@ static inline void vtime_user_enter(struct task_struct *tsk) { } | |||
| 45 | static inline void vtime_user_exit(struct task_struct *tsk) { } | 45 | static inline void vtime_user_exit(struct task_struct *tsk) { } |
| 46 | static inline void vtime_guest_enter(struct task_struct *tsk) { } | 46 | static inline void vtime_guest_enter(struct task_struct *tsk) { } |
| 47 | static inline void vtime_guest_exit(struct task_struct *tsk) { } | 47 | static inline void vtime_guest_exit(struct task_struct *tsk) { } |
| 48 | static inline void vtime_init_idle(struct task_struct *tsk) { } | 48 | static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | 51 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING |
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index d3eef01da648..0f4555b2a31b 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h | |||
| @@ -110,6 +110,8 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | |||
| 110 | struct v4l2_buffer *buf); | 110 | struct v4l2_buffer *buf); |
| 111 | int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | 111 | int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, |
| 112 | struct v4l2_buffer *buf); | 112 | struct v4l2_buffer *buf); |
| 113 | int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | ||
| 114 | struct v4l2_create_buffers *create); | ||
| 113 | 115 | ||
| 114 | int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | 116 | int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, |
| 115 | struct v4l2_exportbuffer *eb); | 117 | struct v4l2_exportbuffer *eb); |
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index ab5d4992e568..bdc6e87ff3eb 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild | |||
| @@ -261,6 +261,7 @@ header-y += net_dropmon.h | |||
| 261 | header-y += net_tstamp.h | 261 | header-y += net_tstamp.h |
| 262 | header-y += netconf.h | 262 | header-y += netconf.h |
| 263 | header-y += netdevice.h | 263 | header-y += netdevice.h |
| 264 | header-y += netlink_diag.h | ||
| 264 | header-y += netfilter.h | 265 | header-y += netfilter.h |
| 265 | header-y += netfilter_arp.h | 266 | header-y += netfilter_arp.h |
| 266 | header-y += netfilter_bridge.h | 267 | header-y += netfilter_bridge.h |
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 65349f07b878..383f8231e436 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/context_tracking.h> | 17 | #include <linux/context_tracking.h> |
| 18 | #include <linux/kvm_host.h> | ||
| 19 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
| 20 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
| 21 | #include <linux/hardirq.h> | 20 | #include <linux/hardirq.h> |
| @@ -71,6 +70,46 @@ void user_enter(void) | |||
| 71 | local_irq_restore(flags); | 70 | local_irq_restore(flags); |
| 72 | } | 71 | } |
| 73 | 72 | ||
| 73 | #ifdef CONFIG_PREEMPT | ||
| 74 | /** | ||
| 75 | * preempt_schedule_context - preempt_schedule called by tracing | ||
| 76 | * | ||
| 77 | * The tracing infrastructure uses preempt_enable_notrace to prevent | ||
| 78 | * recursion and tracing preempt enabling caused by the tracing | ||
| 79 | * infrastructure itself. But as tracing can happen in areas coming | ||
| 80 | * from userspace or just about to enter userspace, a preempt enable | ||
| 81 | * can occur before user_exit() is called. This will cause the scheduler | ||
| 82 | * to be called when the system is still in usermode. | ||
| 83 | * | ||
| 84 | * To prevent this, the preempt_enable_notrace will use this function | ||
| 85 | * instead of preempt_schedule() to exit user context if needed before | ||
| 86 | * calling the scheduler. | ||
| 87 | */ | ||
| 88 | void __sched notrace preempt_schedule_context(void) | ||
| 89 | { | ||
| 90 | struct thread_info *ti = current_thread_info(); | ||
| 91 | enum ctx_state prev_ctx; | ||
| 92 | |||
| 93 | if (likely(ti->preempt_count || irqs_disabled())) | ||
| 94 | return; | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Need to disable preemption in case user_exit() is traced | ||
| 98 | * and the tracer calls preempt_enable_notrace() causing | ||
| 99 | * an infinite recursion. | ||
| 100 | */ | ||
| 101 | preempt_disable_notrace(); | ||
| 102 | prev_ctx = exception_enter(); | ||
| 103 | preempt_enable_no_resched_notrace(); | ||
| 104 | |||
| 105 | preempt_schedule(); | ||
| 106 | |||
| 107 | preempt_disable_notrace(); | ||
| 108 | exception_exit(prev_ctx); | ||
| 109 | preempt_enable_notrace(); | ||
| 110 | } | ||
| 111 | EXPORT_SYMBOL_GPL(preempt_schedule_context); | ||
| 112 | #endif /* CONFIG_PREEMPT */ | ||
| 74 | 113 | ||
| 75 | /** | 114 | /** |
| 76 | * user_exit - Inform the context tracking that the CPU is | 115 | * user_exit - Inform the context tracking that the CPU is |
diff --git a/kernel/cpu/idle.c b/kernel/cpu/idle.c index d5585f5e038e..e695c0a0bcb5 100644 --- a/kernel/cpu/idle.c +++ b/kernel/cpu/idle.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/cpu.h> | 5 | #include <linux/cpu.h> |
| 6 | #include <linux/tick.h> | 6 | #include <linux/tick.h> |
| 7 | #include <linux/mm.h> | 7 | #include <linux/mm.h> |
| 8 | #include <linux/stackprotector.h> | ||
| 8 | 9 | ||
| 9 | #include <asm/tlb.h> | 10 | #include <asm/tlb.h> |
| 10 | 11 | ||
| @@ -58,6 +59,7 @@ void __weak arch_cpu_idle_dead(void) { } | |||
| 58 | void __weak arch_cpu_idle(void) | 59 | void __weak arch_cpu_idle(void) |
| 59 | { | 60 | { |
| 60 | cpu_idle_force_poll = 1; | 61 | cpu_idle_force_poll = 1; |
| 62 | local_irq_enable(); | ||
| 61 | } | 63 | } |
| 62 | 64 | ||
| 63 | /* | 65 | /* |
| @@ -112,6 +114,21 @@ static void cpu_idle_loop(void) | |||
| 112 | 114 | ||
| 113 | void cpu_startup_entry(enum cpuhp_state state) | 115 | void cpu_startup_entry(enum cpuhp_state state) |
| 114 | { | 116 | { |
| 117 | /* | ||
| 118 | * This #ifdef needs to die, but it's too late in the cycle to | ||
| 119 | * make this generic (arm and sh have never invoked the canary | ||
| 120 | * init for the non boot cpus!). Will be fixed in 3.11 | ||
| 121 | */ | ||
| 122 | #ifdef CONFIG_X86 | ||
| 123 | /* | ||
| 124 | * If we're the non-boot CPU, nothing set the stack canary up | ||
| 125 | * for us. The boot CPU already has it initialized but no harm | ||
| 126 | * in doing it again. This is a good place for updating it, as | ||
| 127 | * we wont ever return from this function (so the invalid | ||
| 128 | * canaries already on the stack wont ever trigger). | ||
| 129 | */ | ||
| 130 | boot_init_stack_canary(); | ||
| 131 | #endif | ||
| 115 | current_set_polling(); | 132 | current_set_polling(); |
| 116 | arch_cpu_idle_prepare(); | 133 | arch_cpu_idle_prepare(); |
| 117 | cpu_idle_loop(); | 134 | cpu_idle_loop(); |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 9dc297faf7c0..b391907d5352 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -196,9 +196,6 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, | |||
| 196 | static void update_context_time(struct perf_event_context *ctx); | 196 | static void update_context_time(struct perf_event_context *ctx); |
| 197 | static u64 perf_event_time(struct perf_event *event); | 197 | static u64 perf_event_time(struct perf_event *event); |
| 198 | 198 | ||
| 199 | static void ring_buffer_attach(struct perf_event *event, | ||
| 200 | struct ring_buffer *rb); | ||
| 201 | |||
| 202 | void __weak perf_event_print_debug(void) { } | 199 | void __weak perf_event_print_debug(void) { } |
| 203 | 200 | ||
| 204 | extern __weak const char *perf_pmu_name(void) | 201 | extern __weak const char *perf_pmu_name(void) |
| @@ -2918,6 +2915,7 @@ static void free_event_rcu(struct rcu_head *head) | |||
| 2918 | } | 2915 | } |
| 2919 | 2916 | ||
| 2920 | static void ring_buffer_put(struct ring_buffer *rb); | 2917 | static void ring_buffer_put(struct ring_buffer *rb); |
| 2918 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb); | ||
| 2921 | 2919 | ||
| 2922 | static void free_event(struct perf_event *event) | 2920 | static void free_event(struct perf_event *event) |
| 2923 | { | 2921 | { |
| @@ -2942,15 +2940,30 @@ static void free_event(struct perf_event *event) | |||
| 2942 | if (has_branch_stack(event)) { | 2940 | if (has_branch_stack(event)) { |
| 2943 | static_key_slow_dec_deferred(&perf_sched_events); | 2941 | static_key_slow_dec_deferred(&perf_sched_events); |
| 2944 | /* is system-wide event */ | 2942 | /* is system-wide event */ |
| 2945 | if (!(event->attach_state & PERF_ATTACH_TASK)) | 2943 | if (!(event->attach_state & PERF_ATTACH_TASK)) { |
| 2946 | atomic_dec(&per_cpu(perf_branch_stack_events, | 2944 | atomic_dec(&per_cpu(perf_branch_stack_events, |
| 2947 | event->cpu)); | 2945 | event->cpu)); |
| 2946 | } | ||
| 2948 | } | 2947 | } |
| 2949 | } | 2948 | } |
| 2950 | 2949 | ||
| 2951 | if (event->rb) { | 2950 | if (event->rb) { |
| 2952 | ring_buffer_put(event->rb); | 2951 | struct ring_buffer *rb; |
| 2953 | event->rb = NULL; | 2952 | |
| 2953 | /* | ||
| 2954 | * Can happen when we close an event with re-directed output. | ||
| 2955 | * | ||
| 2956 | * Since we have a 0 refcount, perf_mmap_close() will skip | ||
| 2957 | * over us; possibly making our ring_buffer_put() the last. | ||
| 2958 | */ | ||
| 2959 | mutex_lock(&event->mmap_mutex); | ||
| 2960 | rb = event->rb; | ||
| 2961 | if (rb) { | ||
| 2962 | rcu_assign_pointer(event->rb, NULL); | ||
| 2963 | ring_buffer_detach(event, rb); | ||
| 2964 | ring_buffer_put(rb); /* could be last */ | ||
| 2965 | } | ||
| 2966 | mutex_unlock(&event->mmap_mutex); | ||
| 2954 | } | 2967 | } |
| 2955 | 2968 | ||
| 2956 | if (is_cgroup_event(event)) | 2969 | if (is_cgroup_event(event)) |
| @@ -3188,30 +3201,13 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) | |||
| 3188 | unsigned int events = POLL_HUP; | 3201 | unsigned int events = POLL_HUP; |
| 3189 | 3202 | ||
| 3190 | /* | 3203 | /* |
| 3191 | * Race between perf_event_set_output() and perf_poll(): perf_poll() | 3204 | * Pin the event->rb by taking event->mmap_mutex; otherwise |
| 3192 | * grabs the rb reference but perf_event_set_output() overrides it. | 3205 | * perf_event_set_output() can swizzle our rb and make us miss wakeups. |
| 3193 | * Here is the timeline for two threads T1, T2: | ||
| 3194 | * t0: T1, rb = rcu_dereference(event->rb) | ||
| 3195 | * t1: T2, old_rb = event->rb | ||
| 3196 | * t2: T2, event->rb = new rb | ||
| 3197 | * t3: T2, ring_buffer_detach(old_rb) | ||
| 3198 | * t4: T1, ring_buffer_attach(rb1) | ||
| 3199 | * t5: T1, poll_wait(event->waitq) | ||
| 3200 | * | ||
| 3201 | * To avoid this problem, we grab mmap_mutex in perf_poll() | ||
| 3202 | * thereby ensuring that the assignment of the new ring buffer | ||
| 3203 | * and the detachment of the old buffer appear atomic to perf_poll() | ||
| 3204 | */ | 3206 | */ |
| 3205 | mutex_lock(&event->mmap_mutex); | 3207 | mutex_lock(&event->mmap_mutex); |
| 3206 | 3208 | rb = event->rb; | |
| 3207 | rcu_read_lock(); | 3209 | if (rb) |
| 3208 | rb = rcu_dereference(event->rb); | ||
| 3209 | if (rb) { | ||
| 3210 | ring_buffer_attach(event, rb); | ||
| 3211 | events = atomic_xchg(&rb->poll, 0); | 3210 | events = atomic_xchg(&rb->poll, 0); |
| 3212 | } | ||
| 3213 | rcu_read_unlock(); | ||
| 3214 | |||
| 3215 | mutex_unlock(&event->mmap_mutex); | 3211 | mutex_unlock(&event->mmap_mutex); |
| 3216 | 3212 | ||
| 3217 | poll_wait(file, &event->waitq, wait); | 3213 | poll_wait(file, &event->waitq, wait); |
| @@ -3521,16 +3517,12 @@ static void ring_buffer_attach(struct perf_event *event, | |||
| 3521 | return; | 3517 | return; |
| 3522 | 3518 | ||
| 3523 | spin_lock_irqsave(&rb->event_lock, flags); | 3519 | spin_lock_irqsave(&rb->event_lock, flags); |
| 3524 | if (!list_empty(&event->rb_entry)) | 3520 | if (list_empty(&event->rb_entry)) |
| 3525 | goto unlock; | 3521 | list_add(&event->rb_entry, &rb->event_list); |
| 3526 | |||
| 3527 | list_add(&event->rb_entry, &rb->event_list); | ||
| 3528 | unlock: | ||
| 3529 | spin_unlock_irqrestore(&rb->event_lock, flags); | 3522 | spin_unlock_irqrestore(&rb->event_lock, flags); |
| 3530 | } | 3523 | } |
| 3531 | 3524 | ||
| 3532 | static void ring_buffer_detach(struct perf_event *event, | 3525 | static void ring_buffer_detach(struct perf_event *event, struct ring_buffer *rb) |
| 3533 | struct ring_buffer *rb) | ||
| 3534 | { | 3526 | { |
| 3535 | unsigned long flags; | 3527 | unsigned long flags; |
| 3536 | 3528 | ||
| @@ -3549,13 +3541,10 @@ static void ring_buffer_wakeup(struct perf_event *event) | |||
| 3549 | 3541 | ||
| 3550 | rcu_read_lock(); | 3542 | rcu_read_lock(); |
| 3551 | rb = rcu_dereference(event->rb); | 3543 | rb = rcu_dereference(event->rb); |
| 3552 | if (!rb) | 3544 | if (rb) { |
| 3553 | goto unlock; | 3545 | list_for_each_entry_rcu(event, &rb->event_list, rb_entry) |
| 3554 | 3546 | wake_up_all(&event->waitq); | |
| 3555 | list_for_each_entry_rcu(event, &rb->event_list, rb_entry) | 3547 | } |
| 3556 | wake_up_all(&event->waitq); | ||
| 3557 | |||
| 3558 | unlock: | ||
| 3559 | rcu_read_unlock(); | 3548 | rcu_read_unlock(); |
| 3560 | } | 3549 | } |
| 3561 | 3550 | ||
| @@ -3584,18 +3573,10 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) | |||
| 3584 | 3573 | ||
| 3585 | static void ring_buffer_put(struct ring_buffer *rb) | 3574 | static void ring_buffer_put(struct ring_buffer *rb) |
| 3586 | { | 3575 | { |
| 3587 | struct perf_event *event, *n; | ||
| 3588 | unsigned long flags; | ||
| 3589 | |||
| 3590 | if (!atomic_dec_and_test(&rb->refcount)) | 3576 | if (!atomic_dec_and_test(&rb->refcount)) |
| 3591 | return; | 3577 | return; |
| 3592 | 3578 | ||
| 3593 | spin_lock_irqsave(&rb->event_lock, flags); | 3579 | WARN_ON_ONCE(!list_empty(&rb->event_list)); |
| 3594 | list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { | ||
| 3595 | list_del_init(&event->rb_entry); | ||
| 3596 | wake_up_all(&event->waitq); | ||
| 3597 | } | ||
| 3598 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
| 3599 | 3580 | ||
| 3600 | call_rcu(&rb->rcu_head, rb_free_rcu); | 3581 | call_rcu(&rb->rcu_head, rb_free_rcu); |
| 3601 | } | 3582 | } |
| @@ -3605,26 +3586,100 @@ static void perf_mmap_open(struct vm_area_struct *vma) | |||
| 3605 | struct perf_event *event = vma->vm_file->private_data; | 3586 | struct perf_event *event = vma->vm_file->private_data; |
| 3606 | 3587 | ||
| 3607 | atomic_inc(&event->mmap_count); | 3588 | atomic_inc(&event->mmap_count); |
| 3589 | atomic_inc(&event->rb->mmap_count); | ||
| 3608 | } | 3590 | } |
| 3609 | 3591 | ||
| 3592 | /* | ||
| 3593 | * A buffer can be mmap()ed multiple times; either directly through the same | ||
| 3594 | * event, or through other events by use of perf_event_set_output(). | ||
| 3595 | * | ||
| 3596 | * In order to undo the VM accounting done by perf_mmap() we need to destroy | ||
| 3597 | * the buffer here, where we still have a VM context. This means we need | ||
| 3598 | * to detach all events redirecting to us. | ||
| 3599 | */ | ||
| 3610 | static void perf_mmap_close(struct vm_area_struct *vma) | 3600 | static void perf_mmap_close(struct vm_area_struct *vma) |
| 3611 | { | 3601 | { |
| 3612 | struct perf_event *event = vma->vm_file->private_data; | 3602 | struct perf_event *event = vma->vm_file->private_data; |
| 3613 | 3603 | ||
| 3614 | if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { | 3604 | struct ring_buffer *rb = event->rb; |
| 3615 | unsigned long size = perf_data_size(event->rb); | 3605 | struct user_struct *mmap_user = rb->mmap_user; |
| 3616 | struct user_struct *user = event->mmap_user; | 3606 | int mmap_locked = rb->mmap_locked; |
| 3617 | struct ring_buffer *rb = event->rb; | 3607 | unsigned long size = perf_data_size(rb); |
| 3608 | |||
| 3609 | atomic_dec(&rb->mmap_count); | ||
| 3610 | |||
| 3611 | if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) | ||
| 3612 | return; | ||
| 3618 | 3613 | ||
| 3619 | atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); | 3614 | /* Detach current event from the buffer. */ |
| 3620 | vma->vm_mm->pinned_vm -= event->mmap_locked; | 3615 | rcu_assign_pointer(event->rb, NULL); |
| 3621 | rcu_assign_pointer(event->rb, NULL); | 3616 | ring_buffer_detach(event, rb); |
| 3622 | ring_buffer_detach(event, rb); | 3617 | mutex_unlock(&event->mmap_mutex); |
| 3618 | |||
| 3619 | /* If there's still other mmap()s of this buffer, we're done. */ | ||
| 3620 | if (atomic_read(&rb->mmap_count)) { | ||
| 3621 | ring_buffer_put(rb); /* can't be last */ | ||
| 3622 | return; | ||
| 3623 | } | ||
| 3624 | |||
| 3625 | /* | ||
| 3626 | * No other mmap()s, detach from all other events that might redirect | ||
| 3627 | * into the now unreachable buffer. Somewhat complicated by the | ||
| 3628 | * fact that rb::event_lock otherwise nests inside mmap_mutex. | ||
| 3629 | */ | ||
| 3630 | again: | ||
| 3631 | rcu_read_lock(); | ||
| 3632 | list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { | ||
| 3633 | if (!atomic_long_inc_not_zero(&event->refcount)) { | ||
| 3634 | /* | ||
| 3635 | * This event is en-route to free_event() which will | ||
| 3636 | * detach it and remove it from the list. | ||
| 3637 | */ | ||
| 3638 | continue; | ||
| 3639 | } | ||
| 3640 | rcu_read_unlock(); | ||
| 3641 | |||
| 3642 | mutex_lock(&event->mmap_mutex); | ||
| 3643 | /* | ||
| 3644 | * Check we didn't race with perf_event_set_output() which can | ||
| 3645 | * swizzle the rb from under us while we were waiting to | ||
| 3646 | * acquire mmap_mutex. | ||
| 3647 | * | ||
| 3648 | * If we find a different rb; ignore this event, a next | ||
| 3649 | * iteration will no longer find it on the list. We have to | ||
| 3650 | * still restart the iteration to make sure we're not now | ||
| 3651 | * iterating the wrong list. | ||
| 3652 | */ | ||
| 3653 | if (event->rb == rb) { | ||
| 3654 | rcu_assign_pointer(event->rb, NULL); | ||
| 3655 | ring_buffer_detach(event, rb); | ||
| 3656 | ring_buffer_put(rb); /* can't be last, we still have one */ | ||
| 3657 | } | ||
| 3623 | mutex_unlock(&event->mmap_mutex); | 3658 | mutex_unlock(&event->mmap_mutex); |
| 3659 | put_event(event); | ||
| 3624 | 3660 | ||
| 3625 | ring_buffer_put(rb); | 3661 | /* |
| 3626 | free_uid(user); | 3662 | * Restart the iteration; either we're on the wrong list or |
| 3663 | * destroyed its integrity by doing a deletion. | ||
| 3664 | */ | ||
| 3665 | goto again; | ||
| 3627 | } | 3666 | } |
| 3667 | rcu_read_unlock(); | ||
| 3668 | |||
| 3669 | /* | ||
| 3670 | * It could be there's still a few 0-ref events on the list; they'll | ||
| 3671 | * get cleaned up by free_event() -- they'll also still have their | ||
| 3672 | * ref on the rb and will free it whenever they are done with it. | ||
| 3673 | * | ||
| 3674 | * Aside from that, this buffer is 'fully' detached and unmapped, | ||
| 3675 | * undo the VM accounting. | ||
| 3676 | */ | ||
| 3677 | |||
| 3678 | atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm); | ||
| 3679 | vma->vm_mm->pinned_vm -= mmap_locked; | ||
| 3680 | free_uid(mmap_user); | ||
| 3681 | |||
| 3682 | ring_buffer_put(rb); /* could be last */ | ||
| 3628 | } | 3683 | } |
| 3629 | 3684 | ||
| 3630 | static const struct vm_operations_struct perf_mmap_vmops = { | 3685 | static const struct vm_operations_struct perf_mmap_vmops = { |
| @@ -3674,12 +3729,24 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3674 | return -EINVAL; | 3729 | return -EINVAL; |
| 3675 | 3730 | ||
| 3676 | WARN_ON_ONCE(event->ctx->parent_ctx); | 3731 | WARN_ON_ONCE(event->ctx->parent_ctx); |
| 3732 | again: | ||
| 3677 | mutex_lock(&event->mmap_mutex); | 3733 | mutex_lock(&event->mmap_mutex); |
| 3678 | if (event->rb) { | 3734 | if (event->rb) { |
| 3679 | if (event->rb->nr_pages == nr_pages) | 3735 | if (event->rb->nr_pages != nr_pages) { |
| 3680 | atomic_inc(&event->rb->refcount); | ||
| 3681 | else | ||
| 3682 | ret = -EINVAL; | 3736 | ret = -EINVAL; |
| 3737 | goto unlock; | ||
| 3738 | } | ||
| 3739 | |||
| 3740 | if (!atomic_inc_not_zero(&event->rb->mmap_count)) { | ||
| 3741 | /* | ||
| 3742 | * Raced against perf_mmap_close() through | ||
| 3743 | * perf_event_set_output(). Try again, hope for better | ||
| 3744 | * luck. | ||
| 3745 | */ | ||
| 3746 | mutex_unlock(&event->mmap_mutex); | ||
| 3747 | goto again; | ||
| 3748 | } | ||
| 3749 | |||
| 3683 | goto unlock; | 3750 | goto unlock; |
| 3684 | } | 3751 | } |
| 3685 | 3752 | ||
| @@ -3720,12 +3787,16 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 3720 | ret = -ENOMEM; | 3787 | ret = -ENOMEM; |
| 3721 | goto unlock; | 3788 | goto unlock; |
| 3722 | } | 3789 | } |
| 3723 | rcu_assign_pointer(event->rb, rb); | 3790 | |
| 3791 | atomic_set(&rb->mmap_count, 1); | ||
| 3792 | rb->mmap_locked = extra; | ||
| 3793 | rb->mmap_user = get_current_user(); | ||
| 3724 | 3794 | ||
| 3725 | atomic_long_add(user_extra, &user->locked_vm); | 3795 | atomic_long_add(user_extra, &user->locked_vm); |
| 3726 | event->mmap_locked = extra; | 3796 | vma->vm_mm->pinned_vm += extra; |
| 3727 | event->mmap_user = get_current_user(); | 3797 | |
| 3728 | vma->vm_mm->pinned_vm += event->mmap_locked; | 3798 | ring_buffer_attach(event, rb); |
| 3799 | rcu_assign_pointer(event->rb, rb); | ||
| 3729 | 3800 | ||
| 3730 | perf_event_update_userpage(event); | 3801 | perf_event_update_userpage(event); |
| 3731 | 3802 | ||
| @@ -3734,7 +3805,11 @@ unlock: | |||
| 3734 | atomic_inc(&event->mmap_count); | 3805 | atomic_inc(&event->mmap_count); |
| 3735 | mutex_unlock(&event->mmap_mutex); | 3806 | mutex_unlock(&event->mmap_mutex); |
| 3736 | 3807 | ||
| 3737 | vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; | 3808 | /* |
| 3809 | * Since pinned accounting is per vm we cannot allow fork() to copy our | ||
| 3810 | * vma. | ||
| 3811 | */ | ||
| 3812 | vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP; | ||
| 3738 | vma->vm_ops = &perf_mmap_vmops; | 3813 | vma->vm_ops = &perf_mmap_vmops; |
| 3739 | 3814 | ||
| 3740 | return ret; | 3815 | return ret; |
| @@ -6412,6 +6487,8 @@ set: | |||
| 6412 | if (atomic_read(&event->mmap_count)) | 6487 | if (atomic_read(&event->mmap_count)) |
| 6413 | goto unlock; | 6488 | goto unlock; |
| 6414 | 6489 | ||
| 6490 | old_rb = event->rb; | ||
| 6491 | |||
| 6415 | if (output_event) { | 6492 | if (output_event) { |
| 6416 | /* get the rb we want to redirect to */ | 6493 | /* get the rb we want to redirect to */ |
| 6417 | rb = ring_buffer_get(output_event); | 6494 | rb = ring_buffer_get(output_event); |
| @@ -6419,16 +6496,28 @@ set: | |||
| 6419 | goto unlock; | 6496 | goto unlock; |
| 6420 | } | 6497 | } |
| 6421 | 6498 | ||
| 6422 | old_rb = event->rb; | ||
| 6423 | rcu_assign_pointer(event->rb, rb); | ||
| 6424 | if (old_rb) | 6499 | if (old_rb) |
| 6425 | ring_buffer_detach(event, old_rb); | 6500 | ring_buffer_detach(event, old_rb); |
| 6501 | |||
| 6502 | if (rb) | ||
| 6503 | ring_buffer_attach(event, rb); | ||
| 6504 | |||
| 6505 | rcu_assign_pointer(event->rb, rb); | ||
| 6506 | |||
| 6507 | if (old_rb) { | ||
| 6508 | ring_buffer_put(old_rb); | ||
| 6509 | /* | ||
| 6510 | * Since we detached before setting the new rb, so that we | ||
| 6511 | * could attach the new rb, we could have missed a wakeup. | ||
| 6512 | * Provide it now. | ||
| 6513 | */ | ||
| 6514 | wake_up_all(&event->waitq); | ||
| 6515 | } | ||
| 6516 | |||
| 6426 | ret = 0; | 6517 | ret = 0; |
| 6427 | unlock: | 6518 | unlock: |
| 6428 | mutex_unlock(&event->mmap_mutex); | 6519 | mutex_unlock(&event->mmap_mutex); |
| 6429 | 6520 | ||
| 6430 | if (old_rb) | ||
| 6431 | ring_buffer_put(old_rb); | ||
| 6432 | out: | 6521 | out: |
| 6433 | return ret; | 6522 | return ret; |
| 6434 | } | 6523 | } |
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index a64f8aeb5c1f..20185ea64aa6 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c | |||
| @@ -120,7 +120,7 @@ static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) | |||
| 120 | list_for_each_entry(iter, &bp_task_head, hw.bp_list) { | 120 | list_for_each_entry(iter, &bp_task_head, hw.bp_list) { |
| 121 | if (iter->hw.bp_target == tsk && | 121 | if (iter->hw.bp_target == tsk && |
| 122 | find_slot_idx(iter) == type && | 122 | find_slot_idx(iter) == type && |
| 123 | cpu == iter->cpu) | 123 | (iter->cpu < 0 || cpu == iter->cpu)) |
| 124 | count += hw_breakpoint_weight(iter); | 124 | count += hw_breakpoint_weight(iter); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| @@ -149,7 +149,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, | |||
| 149 | return; | 149 | return; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | for_each_online_cpu(cpu) { | 152 | for_each_possible_cpu(cpu) { |
| 153 | unsigned int nr; | 153 | unsigned int nr; |
| 154 | 154 | ||
| 155 | nr = per_cpu(nr_cpu_bp_pinned[type], cpu); | 155 | nr = per_cpu(nr_cpu_bp_pinned[type], cpu); |
| @@ -235,7 +235,7 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type, | |||
| 235 | if (cpu >= 0) { | 235 | if (cpu >= 0) { |
| 236 | toggle_bp_task_slot(bp, cpu, enable, type, weight); | 236 | toggle_bp_task_slot(bp, cpu, enable, type, weight); |
| 237 | } else { | 237 | } else { |
| 238 | for_each_online_cpu(cpu) | 238 | for_each_possible_cpu(cpu) |
| 239 | toggle_bp_task_slot(bp, cpu, enable, type, weight); | 239 | toggle_bp_task_slot(bp, cpu, enable, type, weight); |
| 240 | } | 240 | } |
| 241 | 241 | ||
diff --git a/kernel/events/internal.h b/kernel/events/internal.h index eb675c4d59df..ca6599723be5 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h | |||
| @@ -31,6 +31,10 @@ struct ring_buffer { | |||
| 31 | spinlock_t event_lock; | 31 | spinlock_t event_lock; |
| 32 | struct list_head event_list; | 32 | struct list_head event_list; |
| 33 | 33 | ||
| 34 | atomic_t mmap_count; | ||
| 35 | unsigned long mmap_locked; | ||
| 36 | struct user_struct *mmap_user; | ||
| 37 | |||
| 34 | struct perf_event_mmap_page *user_page; | 38 | struct perf_event_mmap_page *user_page; |
| 35 | void *data_pages[0]; | 39 | void *data_pages[0]; |
| 36 | }; | 40 | }; |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3fed7f0cbcdf..bddf3b201a48 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -467,6 +467,7 @@ static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr) | |||
| 467 | /* Optimization staging list, protected by kprobe_mutex */ | 467 | /* Optimization staging list, protected by kprobe_mutex */ |
| 468 | static LIST_HEAD(optimizing_list); | 468 | static LIST_HEAD(optimizing_list); |
| 469 | static LIST_HEAD(unoptimizing_list); | 469 | static LIST_HEAD(unoptimizing_list); |
| 470 | static LIST_HEAD(freeing_list); | ||
| 470 | 471 | ||
| 471 | static void kprobe_optimizer(struct work_struct *work); | 472 | static void kprobe_optimizer(struct work_struct *work); |
| 472 | static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); | 473 | static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); |
| @@ -504,7 +505,7 @@ static __kprobes void do_optimize_kprobes(void) | |||
| 504 | * Unoptimize (replace a jump with a breakpoint and remove the breakpoint | 505 | * Unoptimize (replace a jump with a breakpoint and remove the breakpoint |
| 505 | * if need) kprobes listed on unoptimizing_list. | 506 | * if need) kprobes listed on unoptimizing_list. |
| 506 | */ | 507 | */ |
| 507 | static __kprobes void do_unoptimize_kprobes(struct list_head *free_list) | 508 | static __kprobes void do_unoptimize_kprobes(void) |
| 508 | { | 509 | { |
| 509 | struct optimized_kprobe *op, *tmp; | 510 | struct optimized_kprobe *op, *tmp; |
| 510 | 511 | ||
| @@ -515,9 +516,9 @@ static __kprobes void do_unoptimize_kprobes(struct list_head *free_list) | |||
| 515 | /* Ditto to do_optimize_kprobes */ | 516 | /* Ditto to do_optimize_kprobes */ |
| 516 | get_online_cpus(); | 517 | get_online_cpus(); |
| 517 | mutex_lock(&text_mutex); | 518 | mutex_lock(&text_mutex); |
| 518 | arch_unoptimize_kprobes(&unoptimizing_list, free_list); | 519 | arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); |
| 519 | /* Loop free_list for disarming */ | 520 | /* Loop free_list for disarming */ |
| 520 | list_for_each_entry_safe(op, tmp, free_list, list) { | 521 | list_for_each_entry_safe(op, tmp, &freeing_list, list) { |
| 521 | /* Disarm probes if marked disabled */ | 522 | /* Disarm probes if marked disabled */ |
| 522 | if (kprobe_disabled(&op->kp)) | 523 | if (kprobe_disabled(&op->kp)) |
| 523 | arch_disarm_kprobe(&op->kp); | 524 | arch_disarm_kprobe(&op->kp); |
| @@ -536,11 +537,11 @@ static __kprobes void do_unoptimize_kprobes(struct list_head *free_list) | |||
| 536 | } | 537 | } |
| 537 | 538 | ||
| 538 | /* Reclaim all kprobes on the free_list */ | 539 | /* Reclaim all kprobes on the free_list */ |
| 539 | static __kprobes void do_free_cleaned_kprobes(struct list_head *free_list) | 540 | static __kprobes void do_free_cleaned_kprobes(void) |
| 540 | { | 541 | { |
| 541 | struct optimized_kprobe *op, *tmp; | 542 | struct optimized_kprobe *op, *tmp; |
| 542 | 543 | ||
| 543 | list_for_each_entry_safe(op, tmp, free_list, list) { | 544 | list_for_each_entry_safe(op, tmp, &freeing_list, list) { |
| 544 | BUG_ON(!kprobe_unused(&op->kp)); | 545 | BUG_ON(!kprobe_unused(&op->kp)); |
| 545 | list_del_init(&op->list); | 546 | list_del_init(&op->list); |
| 546 | free_aggr_kprobe(&op->kp); | 547 | free_aggr_kprobe(&op->kp); |
| @@ -556,8 +557,6 @@ static __kprobes void kick_kprobe_optimizer(void) | |||
| 556 | /* Kprobe jump optimizer */ | 557 | /* Kprobe jump optimizer */ |
| 557 | static __kprobes void kprobe_optimizer(struct work_struct *work) | 558 | static __kprobes void kprobe_optimizer(struct work_struct *work) |
| 558 | { | 559 | { |
| 559 | LIST_HEAD(free_list); | ||
| 560 | |||
| 561 | mutex_lock(&kprobe_mutex); | 560 | mutex_lock(&kprobe_mutex); |
| 562 | /* Lock modules while optimizing kprobes */ | 561 | /* Lock modules while optimizing kprobes */ |
| 563 | mutex_lock(&module_mutex); | 562 | mutex_lock(&module_mutex); |
| @@ -566,7 +565,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work) | |||
| 566 | * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed) | 565 | * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed) |
| 567 | * kprobes before waiting for quiesence period. | 566 | * kprobes before waiting for quiesence period. |
| 568 | */ | 567 | */ |
| 569 | do_unoptimize_kprobes(&free_list); | 568 | do_unoptimize_kprobes(); |
| 570 | 569 | ||
| 571 | /* | 570 | /* |
| 572 | * Step 2: Wait for quiesence period to ensure all running interrupts | 571 | * Step 2: Wait for quiesence period to ensure all running interrupts |
| @@ -581,7 +580,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work) | |||
| 581 | do_optimize_kprobes(); | 580 | do_optimize_kprobes(); |
| 582 | 581 | ||
| 583 | /* Step 4: Free cleaned kprobes after quiesence period */ | 582 | /* Step 4: Free cleaned kprobes after quiesence period */ |
| 584 | do_free_cleaned_kprobes(&free_list); | 583 | do_free_cleaned_kprobes(); |
| 585 | 584 | ||
| 586 | mutex_unlock(&module_mutex); | 585 | mutex_unlock(&module_mutex); |
| 587 | mutex_unlock(&kprobe_mutex); | 586 | mutex_unlock(&kprobe_mutex); |
| @@ -723,8 +722,19 @@ static void __kprobes kill_optimized_kprobe(struct kprobe *p) | |||
| 723 | if (!list_empty(&op->list)) | 722 | if (!list_empty(&op->list)) |
| 724 | /* Dequeue from the (un)optimization queue */ | 723 | /* Dequeue from the (un)optimization queue */ |
| 725 | list_del_init(&op->list); | 724 | list_del_init(&op->list); |
| 726 | |||
| 727 | op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; | 725 | op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; |
| 726 | |||
| 727 | if (kprobe_unused(p)) { | ||
| 728 | /* Enqueue if it is unused */ | ||
| 729 | list_add(&op->list, &freeing_list); | ||
| 730 | /* | ||
| 731 | * Remove unused probes from the hash list. After waiting | ||
| 732 | * for synchronization, this probe is reclaimed. | ||
| 733 | * (reclaiming is done by do_free_cleaned_kprobes().) | ||
| 734 | */ | ||
| 735 | hlist_del_rcu(&op->kp.hlist); | ||
| 736 | } | ||
| 737 | |||
| 728 | /* Don't touch the code, because it is already freed. */ | 738 | /* Don't touch the code, because it is already freed. */ |
| 729 | arch_remove_optimized_kprobe(op); | 739 | arch_remove_optimized_kprobe(op); |
| 730 | } | 740 | } |
diff --git a/kernel/range.c b/kernel/range.c index eb911dbce267..322ea8e93e4b 100644 --- a/kernel/range.c +++ b/kernel/range.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
| 5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| 6 | #include <linux/sort.h> | 6 | #include <linux/sort.h> |
| 7 | 7 | #include <linux/string.h> | |
| 8 | #include <linux/range.h> | 8 | #include <linux/range.h> |
| 9 | 9 | ||
| 10 | int add_range(struct range *range, int az, int nr_range, u64 start, u64 end) | 10 | int add_range(struct range *range, int az, int nr_range, u64 start, u64 end) |
| @@ -32,9 +32,8 @@ int add_range_with_merge(struct range *range, int az, int nr_range, | |||
| 32 | if (start >= end) | 32 | if (start >= end) |
| 33 | return nr_range; | 33 | return nr_range; |
| 34 | 34 | ||
| 35 | /* Try to merge it with old one: */ | 35 | /* get new start/end: */ |
| 36 | for (i = 0; i < nr_range; i++) { | 36 | for (i = 0; i < nr_range; i++) { |
| 37 | u64 final_start, final_end; | ||
| 38 | u64 common_start, common_end; | 37 | u64 common_start, common_end; |
| 39 | 38 | ||
| 40 | if (!range[i].end) | 39 | if (!range[i].end) |
| @@ -45,14 +44,16 @@ int add_range_with_merge(struct range *range, int az, int nr_range, | |||
| 45 | if (common_start > common_end) | 44 | if (common_start > common_end) |
| 46 | continue; | 45 | continue; |
| 47 | 46 | ||
| 48 | final_start = min(range[i].start, start); | 47 | /* new start/end, will add it back at last */ |
| 49 | final_end = max(range[i].end, end); | 48 | start = min(range[i].start, start); |
| 49 | end = max(range[i].end, end); | ||
| 50 | 50 | ||
| 51 | /* clear it and add it back for further merge */ | 51 | memmove(&range[i], &range[i + 1], |
| 52 | range[i].start = 0; | 52 | (nr_range - (i + 1)) * sizeof(range[i])); |
| 53 | range[i].end = 0; | 53 | range[nr_range - 1].start = 0; |
| 54 | return add_range_with_merge(range, az, nr_range, | 54 | range[nr_range - 1].end = 0; |
| 55 | final_start, final_end); | 55 | nr_range--; |
| 56 | i--; | ||
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | /* Need to add it: */ | 59 | /* Need to add it: */ |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 58453b8272fd..e8b335016c52 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -633,7 +633,19 @@ void wake_up_nohz_cpu(int cpu) | |||
| 633 | static inline bool got_nohz_idle_kick(void) | 633 | static inline bool got_nohz_idle_kick(void) |
| 634 | { | 634 | { |
| 635 | int cpu = smp_processor_id(); | 635 | int cpu = smp_processor_id(); |
| 636 | return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)); | 636 | |
| 637 | if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu))) | ||
| 638 | return false; | ||
| 639 | |||
| 640 | if (idle_cpu(cpu) && !need_resched()) | ||
| 641 | return true; | ||
| 642 | |||
| 643 | /* | ||
| 644 | * We can't run Idle Load Balance on this CPU for this time so we | ||
| 645 | * cancel it and clear NOHZ_BALANCE_KICK | ||
| 646 | */ | ||
| 647 | clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)); | ||
| 648 | return false; | ||
| 637 | } | 649 | } |
| 638 | 650 | ||
| 639 | #else /* CONFIG_NO_HZ_COMMON */ | 651 | #else /* CONFIG_NO_HZ_COMMON */ |
| @@ -1393,8 +1405,9 @@ static void sched_ttwu_pending(void) | |||
| 1393 | 1405 | ||
| 1394 | void scheduler_ipi(void) | 1406 | void scheduler_ipi(void) |
| 1395 | { | 1407 | { |
| 1396 | if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick() | 1408 | if (llist_empty(&this_rq()->wake_list) |
| 1397 | && !tick_nohz_full_cpu(smp_processor_id())) | 1409 | && !tick_nohz_full_cpu(smp_processor_id()) |
| 1410 | && !got_nohz_idle_kick()) | ||
| 1398 | return; | 1411 | return; |
| 1399 | 1412 | ||
| 1400 | /* | 1413 | /* |
| @@ -1417,7 +1430,7 @@ void scheduler_ipi(void) | |||
| 1417 | /* | 1430 | /* |
| 1418 | * Check if someone kicked us for doing the nohz idle load balance. | 1431 | * Check if someone kicked us for doing the nohz idle load balance. |
| 1419 | */ | 1432 | */ |
| 1420 | if (unlikely(got_nohz_idle_kick() && !need_resched())) { | 1433 | if (unlikely(got_nohz_idle_kick())) { |
| 1421 | this_rq()->idle_balance = 1; | 1434 | this_rq()->idle_balance = 1; |
| 1422 | raise_softirq_irqoff(SCHED_SOFTIRQ); | 1435 | raise_softirq_irqoff(SCHED_SOFTIRQ); |
| 1423 | } | 1436 | } |
| @@ -4745,7 +4758,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) | |||
| 4745 | */ | 4758 | */ |
| 4746 | idle->sched_class = &idle_sched_class; | 4759 | idle->sched_class = &idle_sched_class; |
| 4747 | ftrace_graph_init_idle_task(idle, cpu); | 4760 | ftrace_graph_init_idle_task(idle, cpu); |
| 4748 | vtime_init_idle(idle); | 4761 | vtime_init_idle(idle, cpu); |
| 4749 | #if defined(CONFIG_SMP) | 4762 | #if defined(CONFIG_SMP) |
| 4750 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); | 4763 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); |
| 4751 | #endif | 4764 | #endif |
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index cc2dc3eea8a3..b5ccba22603b 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c | |||
| @@ -747,17 +747,17 @@ void arch_vtime_task_switch(struct task_struct *prev) | |||
| 747 | 747 | ||
| 748 | write_seqlock(¤t->vtime_seqlock); | 748 | write_seqlock(¤t->vtime_seqlock); |
| 749 | current->vtime_snap_whence = VTIME_SYS; | 749 | current->vtime_snap_whence = VTIME_SYS; |
| 750 | current->vtime_snap = sched_clock(); | 750 | current->vtime_snap = sched_clock_cpu(smp_processor_id()); |
| 751 | write_sequnlock(¤t->vtime_seqlock); | 751 | write_sequnlock(¤t->vtime_seqlock); |
| 752 | } | 752 | } |
| 753 | 753 | ||
| 754 | void vtime_init_idle(struct task_struct *t) | 754 | void vtime_init_idle(struct task_struct *t, int cpu) |
| 755 | { | 755 | { |
| 756 | unsigned long flags; | 756 | unsigned long flags; |
| 757 | 757 | ||
| 758 | write_seqlock_irqsave(&t->vtime_seqlock, flags); | 758 | write_seqlock_irqsave(&t->vtime_seqlock, flags); |
| 759 | t->vtime_snap_whence = VTIME_SYS; | 759 | t->vtime_snap_whence = VTIME_SYS; |
| 760 | t->vtime_snap = sched_clock(); | 760 | t->vtime_snap = sched_clock_cpu(cpu); |
| 761 | write_sequnlock_irqrestore(&t->vtime_seqlock, flags); | 761 | write_sequnlock_irqrestore(&t->vtime_seqlock, flags); |
| 762 | } | 762 | } |
| 763 | 763 | ||
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 0c739423b0f9..20d6fba70652 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -599,8 +599,6 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 599 | } else { | 599 | } else { |
| 600 | if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) { | 600 | if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) { |
| 601 | clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); | 601 | clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); |
| 602 | if (dev->next_event.tv64 == KTIME_MAX) | ||
| 603 | goto out; | ||
| 604 | /* | 602 | /* |
| 605 | * The cpu which was handling the broadcast | 603 | * The cpu which was handling the broadcast |
| 606 | * timer marked this cpu in the broadcast | 604 | * timer marked this cpu in the broadcast |
| @@ -615,6 +613,11 @@ void tick_broadcast_oneshot_control(unsigned long reason) | |||
| 615 | goto out; | 613 | goto out; |
| 616 | 614 | ||
| 617 | /* | 615 | /* |
| 616 | * Bail out if there is no next event. | ||
| 617 | */ | ||
| 618 | if (dev->next_event.tv64 == KTIME_MAX) | ||
| 619 | goto out; | ||
| 620 | /* | ||
| 618 | * If the pending bit is not set, then we are | 621 | * If the pending bit is not set, then we are |
| 619 | * either the CPU handling the broadcast | 622 | * either the CPU handling the broadcast |
| 620 | * interrupt or we got woken by something else. | 623 | * interrupt or we got woken by something else. |
| @@ -698,10 +701,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) | |||
| 698 | 701 | ||
| 699 | bc->event_handler = tick_handle_oneshot_broadcast; | 702 | bc->event_handler = tick_handle_oneshot_broadcast; |
| 700 | 703 | ||
| 701 | /* Take the do_timer update */ | ||
| 702 | if (!tick_nohz_full_cpu(cpu)) | ||
| 703 | tick_do_timer_cpu = cpu; | ||
| 704 | |||
| 705 | /* | 704 | /* |
| 706 | * We must be careful here. There might be other CPUs | 705 | * We must be careful here. There might be other CPUs |
| 707 | * waiting for periodic broadcast. We need to set the | 706 | * waiting for periodic broadcast. We need to set the |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f4208138fbf4..0cf1c1453181 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -306,7 +306,7 @@ static int __cpuinit tick_nohz_cpu_down_callback(struct notifier_block *nfb, | |||
| 306 | * we can't safely shutdown that CPU. | 306 | * we can't safely shutdown that CPU. |
| 307 | */ | 307 | */ |
| 308 | if (have_nohz_full_mask && tick_do_timer_cpu == cpu) | 308 | if (have_nohz_full_mask && tick_do_timer_cpu == cpu) |
| 309 | return -EINVAL; | 309 | return NOTIFY_BAD; |
| 310 | break; | 310 | break; |
| 311 | } | 311 | } |
| 312 | return NOTIFY_OK; | 312 | return NOTIFY_OK; |
diff --git a/mm/slab_common.c b/mm/slab_common.c index ff3218a0f5e1..2d414508e9ec 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
| @@ -373,8 +373,10 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) | |||
| 373 | { | 373 | { |
| 374 | int index; | 374 | int index; |
| 375 | 375 | ||
| 376 | if (WARN_ON_ONCE(size > KMALLOC_MAX_SIZE)) | 376 | if (size > KMALLOC_MAX_SIZE) { |
| 377 | WARN_ON_ONCE(!(flags & __GFP_NOWARN)); | ||
| 377 | return NULL; | 378 | return NULL; |
| 379 | } | ||
| 378 | 380 | ||
| 379 | if (size <= 192) { | 381 | if (size <= 192) { |
| 380 | if (!size) | 382 | if (!size) |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d817c932d634..ace5e55fe5a3 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -341,7 +341,6 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt) | |||
| 341 | 341 | ||
| 342 | static void bredr_setup(struct hci_request *req) | 342 | static void bredr_setup(struct hci_request *req) |
| 343 | { | 343 | { |
| 344 | struct hci_cp_delete_stored_link_key cp; | ||
| 345 | __le16 param; | 344 | __le16 param; |
| 346 | __u8 flt_type; | 345 | __u8 flt_type; |
| 347 | 346 | ||
| @@ -365,10 +364,6 @@ static void bredr_setup(struct hci_request *req) | |||
| 365 | param = __constant_cpu_to_le16(0x7d00); | 364 | param = __constant_cpu_to_le16(0x7d00); |
| 366 | hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); | 365 | hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); |
| 367 | 366 | ||
| 368 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
| 369 | cp.delete_all = 0x01; | ||
| 370 | hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | ||
| 371 | |||
| 372 | /* Read page scan parameters */ | 367 | /* Read page scan parameters */ |
| 373 | if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { | 368 | if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) { |
| 374 | hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); | 369 | hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL); |
| @@ -602,6 +597,16 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
| 602 | struct hci_dev *hdev = req->hdev; | 597 | struct hci_dev *hdev = req->hdev; |
| 603 | u8 p; | 598 | u8 p; |
| 604 | 599 | ||
| 600 | /* Only send HCI_Delete_Stored_Link_Key if it is supported */ | ||
| 601 | if (hdev->commands[6] & 0x80) { | ||
| 602 | struct hci_cp_delete_stored_link_key cp; | ||
| 603 | |||
| 604 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
| 605 | cp.delete_all = 0x01; | ||
| 606 | hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY, | ||
| 607 | sizeof(cp), &cp); | ||
| 608 | } | ||
| 609 | |||
| 605 | if (hdev->commands[5] & 0x10) | 610 | if (hdev->commands[5] & 0x10) |
| 606 | hci_setup_link_policy(req); | 611 | hci_setup_link_policy(req); |
| 607 | 612 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 24bee07ee4ce..68843a28a7af 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -2852,6 +2852,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, | |||
| 2852 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", | 2852 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", |
| 2853 | conn, code, ident, dlen); | 2853 | conn, code, ident, dlen); |
| 2854 | 2854 | ||
| 2855 | if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE) | ||
| 2856 | return NULL; | ||
| 2857 | |||
| 2855 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; | 2858 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; |
| 2856 | count = min_t(unsigned int, conn->mtu, len); | 2859 | count = min_t(unsigned int, conn->mtu, len); |
| 2857 | 2860 | ||
| @@ -4330,7 +4333,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, | |||
| 4330 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; | 4333 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
| 4331 | u16 type, result; | 4334 | u16 type, result; |
| 4332 | 4335 | ||
| 4333 | if (cmd_len != sizeof(*rsp)) | 4336 | if (cmd_len < sizeof(*rsp)) |
| 4334 | return -EPROTO; | 4337 | return -EPROTO; |
| 4335 | 4338 | ||
| 4336 | type = __le16_to_cpu(rsp->type); | 4339 | type = __le16_to_cpu(rsp->type); |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 81f2389f78eb..d6448e35e027 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -465,8 +465,9 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | |||
| 465 | skb_set_transport_header(skb, skb->len); | 465 | skb_set_transport_header(skb, skb->len); |
| 466 | mldq = (struct mld_msg *) icmp6_hdr(skb); | 466 | mldq = (struct mld_msg *) icmp6_hdr(skb); |
| 467 | 467 | ||
| 468 | interval = ipv6_addr_any(group) ? br->multicast_last_member_interval : | 468 | interval = ipv6_addr_any(group) ? |
| 469 | br->multicast_query_response_interval; | 469 | br->multicast_query_response_interval : |
| 470 | br->multicast_last_member_interval; | ||
| 470 | 471 | ||
| 471 | mldq->mld_type = ICMPV6_MGM_QUERY; | 472 | mldq->mld_type = ICMPV6_MGM_QUERY; |
| 472 | mldq->mld_code = 0; | 473 | mldq->mld_code = 0; |
diff --git a/net/core/dev.c b/net/core/dev.c index fc1e289397f5..faebb398fb46 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -792,6 +792,40 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex) | |||
| 792 | EXPORT_SYMBOL(dev_get_by_index); | 792 | EXPORT_SYMBOL(dev_get_by_index); |
| 793 | 793 | ||
| 794 | /** | 794 | /** |
| 795 | * netdev_get_name - get a netdevice name, knowing its ifindex. | ||
| 796 | * @net: network namespace | ||
| 797 | * @name: a pointer to the buffer where the name will be stored. | ||
| 798 | * @ifindex: the ifindex of the interface to get the name from. | ||
| 799 | * | ||
| 800 | * The use of raw_seqcount_begin() and cond_resched() before | ||
| 801 | * retrying is required as we want to give the writers a chance | ||
| 802 | * to complete when CONFIG_PREEMPT is not set. | ||
| 803 | */ | ||
| 804 | int netdev_get_name(struct net *net, char *name, int ifindex) | ||
| 805 | { | ||
| 806 | struct net_device *dev; | ||
| 807 | unsigned int seq; | ||
| 808 | |||
| 809 | retry: | ||
| 810 | seq = raw_seqcount_begin(&devnet_rename_seq); | ||
| 811 | rcu_read_lock(); | ||
| 812 | dev = dev_get_by_index_rcu(net, ifindex); | ||
| 813 | if (!dev) { | ||
| 814 | rcu_read_unlock(); | ||
| 815 | return -ENODEV; | ||
| 816 | } | ||
| 817 | |||
| 818 | strcpy(name, dev->name); | ||
| 819 | rcu_read_unlock(); | ||
| 820 | if (read_seqcount_retry(&devnet_rename_seq, seq)) { | ||
| 821 | cond_resched(); | ||
| 822 | goto retry; | ||
| 823 | } | ||
| 824 | |||
| 825 | return 0; | ||
| 826 | } | ||
| 827 | |||
| 828 | /** | ||
| 795 | * dev_getbyhwaddr_rcu - find a device by its hardware address | 829 | * dev_getbyhwaddr_rcu - find a device by its hardware address |
| 796 | * @net: the applicable net namespace | 830 | * @net: the applicable net namespace |
| 797 | * @type: media type of device | 831 | * @type: media type of device |
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 6cc0481faade..5b7d0e1d0664 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c | |||
| @@ -19,9 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | static int dev_ifname(struct net *net, struct ifreq __user *arg) | 20 | static int dev_ifname(struct net *net, struct ifreq __user *arg) |
| 21 | { | 21 | { |
| 22 | struct net_device *dev; | ||
| 23 | struct ifreq ifr; | 22 | struct ifreq ifr; |
| 24 | unsigned seq; | 23 | int error; |
| 25 | 24 | ||
| 26 | /* | 25 | /* |
| 27 | * Fetch the caller's info block. | 26 | * Fetch the caller's info block. |
| @@ -30,19 +29,9 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg) | |||
| 30 | if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) | 29 | if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) |
| 31 | return -EFAULT; | 30 | return -EFAULT; |
| 32 | 31 | ||
| 33 | retry: | 32 | error = netdev_get_name(net, ifr.ifr_name, ifr.ifr_ifindex); |
| 34 | seq = read_seqcount_begin(&devnet_rename_seq); | 33 | if (error) |
| 35 | rcu_read_lock(); | 34 | return error; |
| 36 | dev = dev_get_by_index_rcu(net, ifr.ifr_ifindex); | ||
| 37 | if (!dev) { | ||
| 38 | rcu_read_unlock(); | ||
| 39 | return -ENODEV; | ||
| 40 | } | ||
| 41 | |||
| 42 | strcpy(ifr.ifr_name, dev->name); | ||
| 43 | rcu_read_unlock(); | ||
| 44 | if (read_seqcount_retry(&devnet_rename_seq, seq)) | ||
| 45 | goto retry; | ||
| 46 | 35 | ||
| 47 | if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) | 36 | if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) |
| 48 | return -EFAULT; | 37 | return -EFAULT; |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 22efdaa76ebf..ce91766eeca9 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -60,10 +60,10 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] | |||
| 60 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", | 60 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", |
| 61 | [NETIF_F_HIGHDMA_BIT] = "highdma", | 61 | [NETIF_F_HIGHDMA_BIT] = "highdma", |
| 62 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", | 62 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", |
| 63 | [NETIF_F_HW_VLAN_CTAG_TX_BIT] = "tx-vlan-ctag-hw-insert", | 63 | [NETIF_F_HW_VLAN_CTAG_TX_BIT] = "tx-vlan-hw-insert", |
| 64 | 64 | ||
| 65 | [NETIF_F_HW_VLAN_CTAG_RX_BIT] = "rx-vlan-ctag-hw-parse", | 65 | [NETIF_F_HW_VLAN_CTAG_RX_BIT] = "rx-vlan-hw-parse", |
| 66 | [NETIF_F_HW_VLAN_CTAG_FILTER_BIT] = "rx-vlan-ctag-filter", | 66 | [NETIF_F_HW_VLAN_CTAG_FILTER_BIT] = "rx-vlan-filter", |
| 67 | [NETIF_F_HW_VLAN_STAG_TX_BIT] = "tx-vlan-stag-hw-insert", | 67 | [NETIF_F_HW_VLAN_STAG_TX_BIT] = "tx-vlan-stag-hw-insert", |
| 68 | [NETIF_F_HW_VLAN_STAG_RX_BIT] = "rx-vlan-stag-hw-parse", | 68 | [NETIF_F_HW_VLAN_STAG_RX_BIT] = "rx-vlan-stag-hw-parse", |
| 69 | [NETIF_F_HW_VLAN_STAG_FILTER_BIT] = "rx-vlan-stag-filter", | 69 | [NETIF_F_HW_VLAN_STAG_FILTER_BIT] = "rx-vlan-stag-filter", |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index cfd777bd6bd0..1c1738cc4538 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -483,15 +483,8 @@ EXPORT_SYMBOL(skb_add_rx_frag); | |||
| 483 | 483 | ||
| 484 | static void skb_drop_list(struct sk_buff **listp) | 484 | static void skb_drop_list(struct sk_buff **listp) |
| 485 | { | 485 | { |
| 486 | struct sk_buff *list = *listp; | 486 | kfree_skb_list(*listp); |
| 487 | |||
| 488 | *listp = NULL; | 487 | *listp = NULL; |
| 489 | |||
| 490 | do { | ||
| 491 | struct sk_buff *this = list; | ||
| 492 | list = list->next; | ||
| 493 | kfree_skb(this); | ||
| 494 | } while (list); | ||
| 495 | } | 488 | } |
| 496 | 489 | ||
| 497 | static inline void skb_drop_fraglist(struct sk_buff *skb) | 490 | static inline void skb_drop_fraglist(struct sk_buff *skb) |
| @@ -651,6 +644,17 @@ void kfree_skb(struct sk_buff *skb) | |||
| 651 | } | 644 | } |
| 652 | EXPORT_SYMBOL(kfree_skb); | 645 | EXPORT_SYMBOL(kfree_skb); |
| 653 | 646 | ||
| 647 | void kfree_skb_list(struct sk_buff *segs) | ||
| 648 | { | ||
| 649 | while (segs) { | ||
| 650 | struct sk_buff *next = segs->next; | ||
| 651 | |||
| 652 | kfree_skb(segs); | ||
| 653 | segs = next; | ||
| 654 | } | ||
| 655 | } | ||
| 656 | EXPORT_SYMBOL(kfree_skb_list); | ||
| 657 | |||
| 654 | /** | 658 | /** |
| 655 | * skb_tx_error - report an sk_buff xmit error | 659 | * skb_tx_error - report an sk_buff xmit error |
| 656 | * @skb: buffer that triggered an error | 660 | * @skb: buffer that triggered an error |
diff --git a/net/core/sock.c b/net/core/sock.c index 88868a9d21da..d6d024cfaaaf 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -571,9 +571,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval, | |||
| 571 | int ret = -ENOPROTOOPT; | 571 | int ret = -ENOPROTOOPT; |
| 572 | #ifdef CONFIG_NETDEVICES | 572 | #ifdef CONFIG_NETDEVICES |
| 573 | struct net *net = sock_net(sk); | 573 | struct net *net = sock_net(sk); |
| 574 | struct net_device *dev; | ||
| 575 | char devname[IFNAMSIZ]; | 574 | char devname[IFNAMSIZ]; |
| 576 | unsigned seq; | ||
| 577 | 575 | ||
| 578 | if (sk->sk_bound_dev_if == 0) { | 576 | if (sk->sk_bound_dev_if == 0) { |
| 579 | len = 0; | 577 | len = 0; |
| @@ -584,20 +582,9 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval, | |||
| 584 | if (len < IFNAMSIZ) | 582 | if (len < IFNAMSIZ) |
| 585 | goto out; | 583 | goto out; |
| 586 | 584 | ||
| 587 | retry: | 585 | ret = netdev_get_name(net, devname, sk->sk_bound_dev_if); |
| 588 | seq = read_seqcount_begin(&devnet_rename_seq); | 586 | if (ret) |
| 589 | rcu_read_lock(); | ||
| 590 | dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); | ||
| 591 | ret = -ENODEV; | ||
| 592 | if (!dev) { | ||
| 593 | rcu_read_unlock(); | ||
| 594 | goto out; | 587 | goto out; |
| 595 | } | ||
| 596 | |||
| 597 | strcpy(devname, dev->name); | ||
| 598 | rcu_read_unlock(); | ||
| 599 | if (read_seqcount_retry(&devnet_rename_seq, seq)) | ||
| 600 | goto retry; | ||
| 601 | 588 | ||
| 602 | len = strlen(devname) + 1; | 589 | len = strlen(devname) + 1; |
| 603 | 590 | ||
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index b2e805af9b87..7856d1651d05 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c | |||
| @@ -178,7 +178,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
| 178 | 178 | ||
| 179 | err = __skb_linearize(skb); | 179 | err = __skb_linearize(skb); |
| 180 | if (err) { | 180 | if (err) { |
| 181 | kfree_skb(segs); | 181 | kfree_skb_list(segs); |
| 182 | segs = ERR_PTR(err); | 182 | segs = ERR_PTR(err); |
| 183 | goto out; | 183 | goto out; |
| 184 | } | 184 | } |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index ff4b781b1056..32b0e978c8e0 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
| @@ -125,15 +125,16 @@ static void ulog_send(struct ulog_net *ulog, unsigned int nlgroupnum) | |||
| 125 | /* timer function to flush queue in flushtimeout time */ | 125 | /* timer function to flush queue in flushtimeout time */ |
| 126 | static void ulog_timer(unsigned long data) | 126 | static void ulog_timer(unsigned long data) |
| 127 | { | 127 | { |
| 128 | unsigned int groupnum = *((unsigned int *)data); | ||
| 128 | struct ulog_net *ulog = container_of((void *)data, | 129 | struct ulog_net *ulog = container_of((void *)data, |
| 129 | struct ulog_net, | 130 | struct ulog_net, |
| 130 | nlgroup[*(unsigned int *)data]); | 131 | nlgroup[groupnum]); |
| 131 | pr_debug("timer function called, calling ulog_send\n"); | 132 | pr_debug("timer function called, calling ulog_send\n"); |
| 132 | 133 | ||
| 133 | /* lock to protect against somebody modifying our structure | 134 | /* lock to protect against somebody modifying our structure |
| 134 | * from ipt_ulog_target at the same time */ | 135 | * from ipt_ulog_target at the same time */ |
| 135 | spin_lock_bh(&ulog->lock); | 136 | spin_lock_bh(&ulog->lock); |
| 136 | ulog_send(ulog, data); | 137 | ulog_send(ulog, groupnum); |
| 137 | spin_unlock_bh(&ulog->lock); | 138 | spin_unlock_bh(&ulog->lock); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| @@ -407,8 +408,11 @@ static int __net_init ulog_tg_net_init(struct net *net) | |||
| 407 | 408 | ||
| 408 | spin_lock_init(&ulog->lock); | 409 | spin_lock_init(&ulog->lock); |
| 409 | /* initialize ulog_buffers */ | 410 | /* initialize ulog_buffers */ |
| 410 | for (i = 0; i < ULOG_MAXNLGROUPS; i++) | 411 | for (i = 0; i < ULOG_MAXNLGROUPS; i++) { |
| 411 | setup_timer(&ulog->ulog_buffers[i].timer, ulog_timer, i); | 412 | ulog->nlgroup[i] = i; |
| 413 | setup_timer(&ulog->ulog_buffers[i].timer, ulog_timer, | ||
| 414 | (unsigned long)&ulog->nlgroup[i]); | ||
| 415 | } | ||
| 412 | 416 | ||
| 413 | ulog->nflognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg); | 417 | ulog->nflognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg); |
| 414 | if (!ulog->nflognl) | 418 | if (!ulog->nflognl) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 719652305a29..7999fc55c83b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1003,7 +1003,7 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, | |||
| 1003 | struct tcp_sock *tp = tcp_sk(sk); | 1003 | struct tcp_sock *tp = tcp_sk(sk); |
| 1004 | struct tcp_md5sig_info *md5sig; | 1004 | struct tcp_md5sig_info *md5sig; |
| 1005 | 1005 | ||
| 1006 | key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET); | 1006 | key = tcp_md5_do_lookup(sk, addr, family); |
| 1007 | if (key) { | 1007 | if (key) { |
| 1008 | /* Pre-existing entry - just update that one. */ | 1008 | /* Pre-existing entry - just update that one. */ |
| 1009 | memcpy(key->key, newkey, newkeylen); | 1009 | memcpy(key->key, newkey, newkeylen); |
| @@ -1048,7 +1048,7 @@ int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family) | |||
| 1048 | struct tcp_md5sig_key *key; | 1048 | struct tcp_md5sig_key *key; |
| 1049 | struct tcp_md5sig_info *md5sig; | 1049 | struct tcp_md5sig_info *md5sig; |
| 1050 | 1050 | ||
| 1051 | key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET); | 1051 | key = tcp_md5_do_lookup(sk, addr, family); |
| 1052 | if (!key) | 1052 | if (!key) |
| 1053 | return -ENOENT; | 1053 | return -ENOENT; |
| 1054 | hlist_del_rcu(&key->node); | 1054 | hlist_del_rcu(&key->node); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1bbf744c2cc3..4ab4c38958c6 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2655,6 +2655,9 @@ static void init_loopback(struct net_device *dev) | |||
| 2655 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) | 2655 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) |
| 2656 | continue; | 2656 | continue; |
| 2657 | 2657 | ||
| 2658 | if (sp_ifa->rt) | ||
| 2659 | continue; | ||
| 2660 | |||
| 2658 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | 2661 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); |
| 2659 | 2662 | ||
| 2660 | /* Failure cases are ignored */ | 2663 | /* Failure cases are ignored */ |
| @@ -4303,6 +4306,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
| 4303 | struct inet6_ifaddr *ifp; | 4306 | struct inet6_ifaddr *ifp; |
| 4304 | struct net_device *dev = idev->dev; | 4307 | struct net_device *dev = idev->dev; |
| 4305 | bool update_rs = false; | 4308 | bool update_rs = false; |
| 4309 | struct in6_addr ll_addr; | ||
| 4306 | 4310 | ||
| 4307 | if (token == NULL) | 4311 | if (token == NULL) |
| 4308 | return -EINVAL; | 4312 | return -EINVAL; |
| @@ -4322,11 +4326,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) | |||
| 4322 | 4326 | ||
| 4323 | write_unlock_bh(&idev->lock); | 4327 | write_unlock_bh(&idev->lock); |
| 4324 | 4328 | ||
| 4325 | if (!idev->dead && (idev->if_flags & IF_READY)) { | 4329 | if (!idev->dead && (idev->if_flags & IF_READY) && |
| 4326 | struct in6_addr ll_addr; | 4330 | !ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | |
| 4327 | 4331 | IFA_F_OPTIMISTIC)) { | |
| 4328 | ipv6_get_lladdr(dev, &ll_addr, IFA_F_TENTATIVE | | ||
| 4329 | IFA_F_OPTIMISTIC); | ||
| 4330 | 4332 | ||
| 4331 | /* If we're not ready, then normal ifup will take care | 4333 | /* If we're not ready, then normal ifup will take care |
| 4332 | * of this. Otherwise, we need to request our rs here. | 4334 | * of this. Otherwise, we need to request our rs here. |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index dae1949019d7..d5d20cde8d92 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -381,9 +381,8 @@ int ip6_forward(struct sk_buff *skb) | |||
| 381 | * cannot be fragmented, because there is no warranty | 381 | * cannot be fragmented, because there is no warranty |
| 382 | * that different fragments will go along one path. --ANK | 382 | * that different fragments will go along one path. --ANK |
| 383 | */ | 383 | */ |
| 384 | if (opt->ra) { | 384 | if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) { |
| 385 | u8 *ptr = skb_network_header(skb) + opt->ra; | 385 | if (ip6_call_ra_chain(skb, ntohs(opt->ra))) |
| 386 | if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3])) | ||
| 387 | return 0; | 386 | return 0; |
| 388 | } | 387 | } |
| 389 | 388 | ||
| @@ -822,11 +821,17 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, | |||
| 822 | const struct flowi6 *fl6) | 821 | const struct flowi6 *fl6) |
| 823 | { | 822 | { |
| 824 | struct ipv6_pinfo *np = inet6_sk(sk); | 823 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 825 | struct rt6_info *rt = (struct rt6_info *)dst; | 824 | struct rt6_info *rt; |
| 826 | 825 | ||
| 827 | if (!dst) | 826 | if (!dst) |
| 828 | goto out; | 827 | goto out; |
| 829 | 828 | ||
| 829 | if (dst->ops->family != AF_INET6) { | ||
| 830 | dst_release(dst); | ||
| 831 | return NULL; | ||
| 832 | } | ||
| 833 | |||
| 834 | rt = (struct rt6_info *)dst; | ||
| 830 | /* Yes, checking route validity in not connected | 835 | /* Yes, checking route validity in not connected |
| 831 | * case is not very simple. Take into account, | 836 | * case is not very simple. Take into account, |
| 832 | * that we do not support routing by source, TOS, | 837 | * that we do not support routing by source, TOS, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 2712ab22a174..ca4ffcc287f1 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1493,7 +1493,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
| 1493 | */ | 1493 | */ |
| 1494 | 1494 | ||
| 1495 | if (ha) | 1495 | if (ha) |
| 1496 | ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR, ha); | 1496 | ndisc_fill_addr_option(buff, ND_OPT_TARGET_LL_ADDR, ha); |
| 1497 | 1497 | ||
| 1498 | /* | 1498 | /* |
| 1499 | * build redirect option and copy skb over to the new packet. | 1499 | * build redirect option and copy skb over to the new packet. |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 97bcf2bae857..c9b6a6e6a1e8 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -204,7 +204,7 @@ static unsigned int __ipv6_conntrack_in(struct net *net, | |||
| 204 | if (ct != NULL && !nf_ct_is_untracked(ct)) { | 204 | if (ct != NULL && !nf_ct_is_untracked(ct)) { |
| 205 | help = nfct_help(ct); | 205 | help = nfct_help(ct); |
| 206 | if ((help && help->helper) || !nf_ct_is_confirmed(ct)) { | 206 | if ((help && help->helper) || !nf_ct_is_confirmed(ct)) { |
| 207 | nf_conntrack_get_reasm(skb); | 207 | nf_conntrack_get_reasm(reasm); |
| 208 | NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm, | 208 | NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm, |
| 209 | (struct net_device *)in, | 209 | (struct net_device *)in, |
| 210 | (struct net_device *)out, | 210 | (struct net_device *)out, |
diff --git a/net/key/af_key.c b/net/key/af_key.c index c5fbd7589681..9da862070dd8 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1710,6 +1710,7 @@ static int key_notify_sa_flush(const struct km_event *c) | |||
| 1710 | hdr->sadb_msg_version = PF_KEY_V2; | 1710 | hdr->sadb_msg_version = PF_KEY_V2; |
| 1711 | hdr->sadb_msg_errno = (uint8_t) 0; | 1711 | hdr->sadb_msg_errno = (uint8_t) 0; |
| 1712 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 1712 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
| 1713 | hdr->sadb_msg_reserved = 0; | ||
| 1713 | 1714 | ||
| 1714 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); | 1715 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
| 1715 | 1716 | ||
| @@ -2699,6 +2700,7 @@ static int key_notify_policy_flush(const struct km_event *c) | |||
| 2699 | hdr->sadb_msg_errno = (uint8_t) 0; | 2700 | hdr->sadb_msg_errno = (uint8_t) 0; |
| 2700 | hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; | 2701 | hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; |
| 2701 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); | 2702 | hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); |
| 2703 | hdr->sadb_msg_reserved = 0; | ||
| 2702 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); | 2704 | pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); |
| 2703 | return 0; | 2705 | return 0; |
| 2704 | 2706 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1a89c80e6407..4fdb306e42e0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1057,6 +1057,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
| 1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 1057 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
| 1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 1058 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
| 1059 | 1059 | ||
| 1060 | if (sdata->wdev.cac_started) { | ||
| 1061 | cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); | ||
| 1062 | cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, | ||
| 1063 | GFP_KERNEL); | ||
| 1064 | } | ||
| 1065 | |||
| 1060 | drv_stop_ap(sdata->local, sdata); | 1066 | drv_stop_ap(sdata->local, sdata); |
| 1061 | 1067 | ||
| 1062 | /* free all potentially still buffered bcast frames */ | 1068 | /* free all potentially still buffered bcast frames */ |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 44be28cfc6c4..9ca8e3278cc0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1497,10 +1497,11 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, | |||
| 1497 | ieee80211_tx_skb_tid(sdata, skb, 7); | 1497 | ieee80211_tx_skb_tid(sdata, skb, 7); |
| 1498 | } | 1498 | } |
| 1499 | 1499 | ||
| 1500 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 1500 | u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, |
| 1501 | struct ieee802_11_elems *elems, | 1501 | struct ieee802_11_elems *elems, |
| 1502 | u64 filter, u32 crc); | 1502 | u64 filter, u32 crc); |
| 1503 | static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, | 1503 | static inline void ieee802_11_parse_elems(const u8 *start, size_t len, |
| 1504 | bool action, | ||
| 1504 | struct ieee802_11_elems *elems) | 1505 | struct ieee802_11_elems *elems) |
| 1505 | { | 1506 | { |
| 1506 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); | 1507 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a8c2130c8ba4..741448b30825 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -2522,8 +2522,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2522 | u16 capab_info, aid; | 2522 | u16 capab_info, aid; |
| 2523 | struct ieee802_11_elems elems; | 2523 | struct ieee802_11_elems elems; |
| 2524 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 2524 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
| 2525 | const struct cfg80211_bss_ies *bss_ies = NULL; | ||
| 2526 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; | ||
| 2525 | u32 changed = 0; | 2527 | u32 changed = 0; |
| 2526 | int err; | 2528 | int err; |
| 2529 | bool ret; | ||
| 2527 | 2530 | ||
| 2528 | /* AssocResp and ReassocResp have identical structure */ | 2531 | /* AssocResp and ReassocResp have identical structure */ |
| 2529 | 2532 | ||
| @@ -2555,21 +2558,86 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2555 | ifmgd->aid = aid; | 2558 | ifmgd->aid = aid; |
| 2556 | 2559 | ||
| 2557 | /* | 2560 | /* |
| 2561 | * Some APs are erroneously not including some information in their | ||
| 2562 | * (re)association response frames. Try to recover by using the data | ||
| 2563 | * from the beacon or probe response. This seems to afflict mobile | ||
| 2564 | * 2G/3G/4G wifi routers, reported models include the "Onda PN51T", | ||
| 2565 | * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device. | ||
| 2566 | */ | ||
| 2567 | if ((assoc_data->wmm && !elems.wmm_param) || | ||
| 2568 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | ||
| 2569 | (!elems.ht_cap_elem || !elems.ht_operation)) || | ||
| 2570 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | ||
| 2571 | (!elems.vht_cap_elem || !elems.vht_operation))) { | ||
| 2572 | const struct cfg80211_bss_ies *ies; | ||
| 2573 | struct ieee802_11_elems bss_elems; | ||
| 2574 | |||
| 2575 | rcu_read_lock(); | ||
| 2576 | ies = rcu_dereference(cbss->ies); | ||
| 2577 | if (ies) | ||
| 2578 | bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, | ||
| 2579 | GFP_ATOMIC); | ||
| 2580 | rcu_read_unlock(); | ||
| 2581 | if (!bss_ies) | ||
| 2582 | return false; | ||
| 2583 | |||
| 2584 | ieee802_11_parse_elems(bss_ies->data, bss_ies->len, | ||
| 2585 | false, &bss_elems); | ||
| 2586 | if (assoc_data->wmm && | ||
| 2587 | !elems.wmm_param && bss_elems.wmm_param) { | ||
| 2588 | elems.wmm_param = bss_elems.wmm_param; | ||
| 2589 | sdata_info(sdata, | ||
| 2590 | "AP bug: WMM param missing from AssocResp\n"); | ||
| 2591 | } | ||
| 2592 | |||
| 2593 | /* | ||
| 2594 | * Also check if we requested HT/VHT, otherwise the AP doesn't | ||
| 2595 | * have to include the IEs in the (re)association response. | ||
| 2596 | */ | ||
| 2597 | if (!elems.ht_cap_elem && bss_elems.ht_cap_elem && | ||
| 2598 | !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
| 2599 | elems.ht_cap_elem = bss_elems.ht_cap_elem; | ||
| 2600 | sdata_info(sdata, | ||
| 2601 | "AP bug: HT capability missing from AssocResp\n"); | ||
| 2602 | } | ||
| 2603 | if (!elems.ht_operation && bss_elems.ht_operation && | ||
| 2604 | !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { | ||
| 2605 | elems.ht_operation = bss_elems.ht_operation; | ||
| 2606 | sdata_info(sdata, | ||
| 2607 | "AP bug: HT operation missing from AssocResp\n"); | ||
| 2608 | } | ||
| 2609 | if (!elems.vht_cap_elem && bss_elems.vht_cap_elem && | ||
| 2610 | !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { | ||
| 2611 | elems.vht_cap_elem = bss_elems.vht_cap_elem; | ||
| 2612 | sdata_info(sdata, | ||
| 2613 | "AP bug: VHT capa missing from AssocResp\n"); | ||
| 2614 | } | ||
| 2615 | if (!elems.vht_operation && bss_elems.vht_operation && | ||
| 2616 | !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { | ||
| 2617 | elems.vht_operation = bss_elems.vht_operation; | ||
| 2618 | sdata_info(sdata, | ||
| 2619 | "AP bug: VHT operation missing from AssocResp\n"); | ||
| 2620 | } | ||
| 2621 | } | ||
| 2622 | |||
| 2623 | /* | ||
| 2558 | * We previously checked these in the beacon/probe response, so | 2624 | * We previously checked these in the beacon/probe response, so |
| 2559 | * they should be present here. This is just a safety net. | 2625 | * they should be present here. This is just a safety net. |
| 2560 | */ | 2626 | */ |
| 2561 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && | 2627 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && |
| 2562 | (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { | 2628 | (!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) { |
| 2563 | sdata_info(sdata, | 2629 | sdata_info(sdata, |
| 2564 | "HT AP is missing WMM params or HT capability/operation in AssocResp\n"); | 2630 | "HT AP is missing WMM params or HT capability/operation\n"); |
| 2565 | return false; | 2631 | ret = false; |
| 2632 | goto out; | ||
| 2566 | } | 2633 | } |
| 2567 | 2634 | ||
| 2568 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && | 2635 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && |
| 2569 | (!elems.vht_cap_elem || !elems.vht_operation)) { | 2636 | (!elems.vht_cap_elem || !elems.vht_operation)) { |
| 2570 | sdata_info(sdata, | 2637 | sdata_info(sdata, |
| 2571 | "VHT AP is missing VHT capability/operation in AssocResp\n"); | 2638 | "VHT AP is missing VHT capability/operation\n"); |
| 2572 | return false; | 2639 | ret = false; |
| 2640 | goto out; | ||
| 2573 | } | 2641 | } |
| 2574 | 2642 | ||
| 2575 | mutex_lock(&sdata->local->sta_mtx); | 2643 | mutex_lock(&sdata->local->sta_mtx); |
| @@ -2580,7 +2648,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2580 | sta = sta_info_get(sdata, cbss->bssid); | 2648 | sta = sta_info_get(sdata, cbss->bssid); |
| 2581 | if (WARN_ON(!sta)) { | 2649 | if (WARN_ON(!sta)) { |
| 2582 | mutex_unlock(&sdata->local->sta_mtx); | 2650 | mutex_unlock(&sdata->local->sta_mtx); |
| 2583 | return false; | 2651 | ret = false; |
| 2652 | goto out; | ||
| 2584 | } | 2653 | } |
| 2585 | 2654 | ||
| 2586 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; | 2655 | sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; |
| @@ -2633,7 +2702,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2633 | sta->sta.addr); | 2702 | sta->sta.addr); |
| 2634 | WARN_ON(__sta_info_destroy(sta)); | 2703 | WARN_ON(__sta_info_destroy(sta)); |
| 2635 | mutex_unlock(&sdata->local->sta_mtx); | 2704 | mutex_unlock(&sdata->local->sta_mtx); |
| 2636 | return false; | 2705 | ret = false; |
| 2706 | goto out; | ||
| 2637 | } | 2707 | } |
| 2638 | 2708 | ||
| 2639 | mutex_unlock(&sdata->local->sta_mtx); | 2709 | mutex_unlock(&sdata->local->sta_mtx); |
| @@ -2673,7 +2743,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
| 2673 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 2743 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
| 2674 | ieee80211_sta_reset_beacon_monitor(sdata); | 2744 | ieee80211_sta_reset_beacon_monitor(sdata); |
| 2675 | 2745 | ||
| 2676 | return true; | 2746 | ret = true; |
| 2747 | out: | ||
| 2748 | kfree(bss_ies); | ||
| 2749 | return ret; | ||
| 2677 | } | 2750 | } |
| 2678 | 2751 | ||
| 2679 | static enum rx_mgmt_action __must_check | 2752 | static enum rx_mgmt_action __must_check |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index d3f414fe67e0..a02bef35b134 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
| @@ -615,7 +615,7 @@ static void rate_control_apply_mask(struct ieee80211_sub_if_data *sdata, | |||
| 615 | if (rates[i].idx < 0) | 615 | if (rates[i].idx < 0) |
| 616 | break; | 616 | break; |
| 617 | 617 | ||
| 618 | rate_idx_match_mask(&rates[i], sband, mask, chan_width, | 618 | rate_idx_match_mask(&rates[i], sband, chan_width, mask, |
| 619 | mcs_mask); | 619 | mcs_mask); |
| 620 | } | 620 | } |
| 621 | } | 621 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 27e07150eb46..72e6292955bb 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -661,12 +661,12 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
| 661 | } | 661 | } |
| 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | 662 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); |
| 663 | 663 | ||
| 664 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action, | 664 | u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, |
| 665 | struct ieee802_11_elems *elems, | 665 | struct ieee802_11_elems *elems, |
| 666 | u64 filter, u32 crc) | 666 | u64 filter, u32 crc) |
| 667 | { | 667 | { |
| 668 | size_t left = len; | 668 | size_t left = len; |
| 669 | u8 *pos = start; | 669 | const u8 *pos = start; |
| 670 | bool calc_crc = filter != 0; | 670 | bool calc_crc = filter != 0; |
| 671 | DECLARE_BITMAP(seen_elems, 256); | 671 | DECLARE_BITMAP(seen_elems, 256); |
| 672 | const u8 *ie; | 672 | const u8 *ie; |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 05565d2b3a61..23b8eb53a569 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -1442,7 +1442,8 @@ ignore_ipip: | |||
| 1442 | 1442 | ||
| 1443 | /* do the statistics and put it back */ | 1443 | /* do the statistics and put it back */ |
| 1444 | ip_vs_in_stats(cp, skb); | 1444 | ip_vs_in_stats(cp, skb); |
| 1445 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) | 1445 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol || |
| 1446 | IPPROTO_SCTP == cih->protocol) | ||
| 1446 | offset += 2 * sizeof(__u16); | 1447 | offset += 2 * sizeof(__u16); |
| 1447 | verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph); | 1448 | verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph); |
| 1448 | 1449 | ||
diff --git a/net/netfilter/nf_conntrack_labels.c b/net/netfilter/nf_conntrack_labels.c index 8fe2e99428b7..355d2ef08094 100644 --- a/net/netfilter/nf_conntrack_labels.c +++ b/net/netfilter/nf_conntrack_labels.c | |||
| @@ -45,7 +45,7 @@ int nf_connlabel_set(struct nf_conn *ct, u16 bit) | |||
| 45 | if (test_bit(bit, labels->bits)) | 45 | if (test_bit(bit, labels->bits)) |
| 46 | return 0; | 46 | return 0; |
| 47 | 47 | ||
| 48 | if (test_and_set_bit(bit, labels->bits)) | 48 | if (!test_and_set_bit(bit, labels->bits)) |
| 49 | nf_conntrack_event_cache(IPCT_LABEL, ct); | 49 | nf_conntrack_event_cache(IPCT_LABEL, ct); |
| 50 | 50 | ||
| 51 | return 0; | 51 | return 0; |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6d0f8a17c5b7..ecf065f94032 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -1825,6 +1825,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1825 | nf_conntrack_eventmask_report((1 << IPCT_REPLY) | | 1825 | nf_conntrack_eventmask_report((1 << IPCT_REPLY) | |
| 1826 | (1 << IPCT_ASSURED) | | 1826 | (1 << IPCT_ASSURED) | |
| 1827 | (1 << IPCT_HELPER) | | 1827 | (1 << IPCT_HELPER) | |
| 1828 | (1 << IPCT_LABEL) | | ||
| 1828 | (1 << IPCT_PROTOINFO) | | 1829 | (1 << IPCT_PROTOINFO) | |
| 1829 | (1 << IPCT_NATSEQADJ) | | 1830 | (1 << IPCT_NATSEQADJ) | |
| 1830 | (1 << IPCT_MARK), | 1831 | (1 << IPCT_MARK), |
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index 96ccdf78a29f..dac11f73868e 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c | |||
| @@ -230,9 +230,10 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, | |||
| 230 | &ct->tuplehash[!dir].tuple.src.u3, | 230 | &ct->tuplehash[!dir].tuple.src.u3, |
| 231 | false); | 231 | false); |
| 232 | if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, | 232 | if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, |
| 233 | poff, plen, buffer, buflen)) | 233 | poff, plen, buffer, buflen)) { |
| 234 | nf_ct_helper_log(skb, ct, "cannot mangle received"); | 234 | nf_ct_helper_log(skb, ct, "cannot mangle received"); |
| 235 | return NF_DROP; | 235 | return NF_DROP; |
| 236 | } | ||
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | /* The rport= parameter (RFC 3581) contains the port number | 239 | /* The rport= parameter (RFC 3581) contains the port number |
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index afaebc766933..7011c71646f0 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
| @@ -45,17 +45,22 @@ optlen(const u_int8_t *opt, unsigned int offset) | |||
| 45 | 45 | ||
| 46 | static int | 46 | static int |
| 47 | tcpmss_mangle_packet(struct sk_buff *skb, | 47 | tcpmss_mangle_packet(struct sk_buff *skb, |
| 48 | const struct xt_tcpmss_info *info, | 48 | const struct xt_action_param *par, |
| 49 | unsigned int in_mtu, | 49 | unsigned int in_mtu, |
| 50 | unsigned int tcphoff, | 50 | unsigned int tcphoff, |
| 51 | unsigned int minlen) | 51 | unsigned int minlen) |
| 52 | { | 52 | { |
| 53 | const struct xt_tcpmss_info *info = par->targinfo; | ||
| 53 | struct tcphdr *tcph; | 54 | struct tcphdr *tcph; |
| 54 | unsigned int tcplen, i; | 55 | unsigned int tcplen, i; |
| 55 | __be16 oldval; | 56 | __be16 oldval; |
| 56 | u16 newmss; | 57 | u16 newmss; |
| 57 | u8 *opt; | 58 | u8 *opt; |
| 58 | 59 | ||
| 60 | /* This is a fragment, no TCP header is available */ | ||
| 61 | if (par->fragoff != 0) | ||
| 62 | return XT_CONTINUE; | ||
| 63 | |||
| 59 | if (!skb_make_writable(skb, skb->len)) | 64 | if (!skb_make_writable(skb, skb->len)) |
| 60 | return -1; | 65 | return -1; |
| 61 | 66 | ||
| @@ -125,11 +130,17 @@ tcpmss_mangle_packet(struct sk_buff *skb, | |||
| 125 | 130 | ||
| 126 | skb_put(skb, TCPOLEN_MSS); | 131 | skb_put(skb, TCPOLEN_MSS); |
| 127 | 132 | ||
| 128 | /* RFC 879 states that the default MSS is 536 without specific | 133 | /* |
| 129 | * knowledge that the destination host is prepared to accept larger. | 134 | * IPv4: RFC 1122 states "If an MSS option is not received at |
| 130 | * Since no MSS was provided, we MUST NOT set a value > 536. | 135 | * connection setup, TCP MUST assume a default send MSS of 536". |
| 136 | * IPv6: RFC 2460 states IPv6 has a minimum MTU of 1280 and a minimum | ||
| 137 | * length IPv6 header of 60, ergo the default MSS value is 1220 | ||
| 138 | * Since no MSS was provided, we must use the default values | ||
| 131 | */ | 139 | */ |
| 132 | newmss = min(newmss, (u16)536); | 140 | if (par->family == NFPROTO_IPV4) |
| 141 | newmss = min(newmss, (u16)536); | ||
| 142 | else | ||
| 143 | newmss = min(newmss, (u16)1220); | ||
| 133 | 144 | ||
| 134 | opt = (u_int8_t *)tcph + sizeof(struct tcphdr); | 145 | opt = (u_int8_t *)tcph + sizeof(struct tcphdr); |
| 135 | memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); | 146 | memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); |
| @@ -188,7 +199,7 @@ tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 188 | __be16 newlen; | 199 | __be16 newlen; |
| 189 | int ret; | 200 | int ret; |
| 190 | 201 | ||
| 191 | ret = tcpmss_mangle_packet(skb, par->targinfo, | 202 | ret = tcpmss_mangle_packet(skb, par, |
| 192 | tcpmss_reverse_mtu(skb, PF_INET), | 203 | tcpmss_reverse_mtu(skb, PF_INET), |
| 193 | iph->ihl * 4, | 204 | iph->ihl * 4, |
| 194 | sizeof(*iph) + sizeof(struct tcphdr)); | 205 | sizeof(*iph) + sizeof(struct tcphdr)); |
| @@ -217,7 +228,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 217 | tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr, &frag_off); | 228 | tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr, &frag_off); |
| 218 | if (tcphoff < 0) | 229 | if (tcphoff < 0) |
| 219 | return NF_DROP; | 230 | return NF_DROP; |
| 220 | ret = tcpmss_mangle_packet(skb, par->targinfo, | 231 | ret = tcpmss_mangle_packet(skb, par, |
| 221 | tcpmss_reverse_mtu(skb, PF_INET6), | 232 | tcpmss_reverse_mtu(skb, PF_INET6), |
| 222 | tcphoff, | 233 | tcphoff, |
| 223 | sizeof(*ipv6h) + sizeof(struct tcphdr)); | 234 | sizeof(*ipv6h) + sizeof(struct tcphdr)); |
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c index 1eb1a44bfd3d..b68fa191710f 100644 --- a/net/netfilter/xt_TCPOPTSTRIP.c +++ b/net/netfilter/xt_TCPOPTSTRIP.c | |||
| @@ -48,11 +48,13 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb, | |||
| 48 | return NF_DROP; | 48 | return NF_DROP; |
| 49 | 49 | ||
| 50 | len = skb->len - tcphoff; | 50 | len = skb->len - tcphoff; |
| 51 | if (len < (int)sizeof(struct tcphdr) || | 51 | if (len < (int)sizeof(struct tcphdr)) |
| 52 | tcp_hdr(skb)->doff * 4 > len) | ||
| 53 | return NF_DROP; | 52 | return NF_DROP; |
| 54 | 53 | ||
| 55 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); | 54 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); |
| 55 | if (tcph->doff * 4 > len) | ||
| 56 | return NF_DROP; | ||
| 57 | |||
| 56 | opt = (u_int8_t *)tcph; | 58 | opt = (u_int8_t *)tcph; |
| 57 | 59 | ||
| 58 | /* | 60 | /* |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d5aed3bb3945..b14b7e3cb6e6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -1564,12 +1564,17 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1564 | struct cfg80211_registered_device *dev; | 1564 | struct cfg80211_registered_device *dev; |
| 1565 | s64 filter_wiphy = -1; | 1565 | s64 filter_wiphy = -1; |
| 1566 | bool split = false; | 1566 | bool split = false; |
| 1567 | struct nlattr **tb = nl80211_fam.attrbuf; | 1567 | struct nlattr **tb; |
| 1568 | int res; | 1568 | int res; |
| 1569 | 1569 | ||
| 1570 | /* will be zeroed in nlmsg_parse() */ | ||
| 1571 | tb = kmalloc(sizeof(*tb) * (NL80211_ATTR_MAX + 1), GFP_KERNEL); | ||
| 1572 | if (!tb) | ||
| 1573 | return -ENOMEM; | ||
| 1574 | |||
| 1570 | mutex_lock(&cfg80211_mutex); | 1575 | mutex_lock(&cfg80211_mutex); |
| 1571 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | 1576 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
| 1572 | tb, nl80211_fam.maxattr, nl80211_policy); | 1577 | tb, NL80211_ATTR_MAX, nl80211_policy); |
| 1573 | if (res == 0) { | 1578 | if (res == 0) { |
| 1574 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; | 1579 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; |
| 1575 | if (tb[NL80211_ATTR_WIPHY]) | 1580 | if (tb[NL80211_ATTR_WIPHY]) |
| @@ -1583,6 +1588,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1583 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); | 1588 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); |
| 1584 | if (!netdev) { | 1589 | if (!netdev) { |
| 1585 | mutex_unlock(&cfg80211_mutex); | 1590 | mutex_unlock(&cfg80211_mutex); |
| 1591 | kfree(tb); | ||
| 1586 | return -ENODEV; | 1592 | return -ENODEV; |
| 1587 | } | 1593 | } |
| 1588 | if (netdev->ieee80211_ptr) { | 1594 | if (netdev->ieee80211_ptr) { |
| @@ -1593,6 +1599,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1593 | dev_put(netdev); | 1599 | dev_put(netdev); |
| 1594 | } | 1600 | } |
| 1595 | } | 1601 | } |
| 1602 | kfree(tb); | ||
| 1596 | 1603 | ||
| 1597 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { | 1604 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { |
| 1598 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) | 1605 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index bd8d46cca2b3..cccaf9c7a7bb 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
| @@ -58,6 +58,7 @@ enum { | |||
| 58 | CS420X_GPIO_23, | 58 | CS420X_GPIO_23, |
| 59 | CS420X_MBP101, | 59 | CS420X_MBP101, |
| 60 | CS420X_MBP81, | 60 | CS420X_MBP81, |
| 61 | CS420X_MBA42, | ||
| 61 | CS420X_AUTO, | 62 | CS420X_AUTO, |
| 62 | /* aliases */ | 63 | /* aliases */ |
| 63 | CS420X_IMAC27_122 = CS420X_GPIO_23, | 64 | CS420X_IMAC27_122 = CS420X_GPIO_23, |
| @@ -346,6 +347,7 @@ static const struct hda_model_fixup cs420x_models[] = { | |||
| 346 | { .id = CS420X_APPLE, .name = "apple" }, | 347 | { .id = CS420X_APPLE, .name = "apple" }, |
| 347 | { .id = CS420X_MBP101, .name = "mbp101" }, | 348 | { .id = CS420X_MBP101, .name = "mbp101" }, |
| 348 | { .id = CS420X_MBP81, .name = "mbp81" }, | 349 | { .id = CS420X_MBP81, .name = "mbp81" }, |
| 350 | { .id = CS420X_MBA42, .name = "mba42" }, | ||
| 349 | {} | 351 | {} |
| 350 | }; | 352 | }; |
| 351 | 353 | ||
| @@ -361,6 +363,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { | |||
| 361 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), | 363 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), |
| 362 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), | 364 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), |
| 363 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), | 365 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), |
| 366 | SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), | ||
| 364 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), | 367 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), |
| 365 | {} /* terminator */ | 368 | {} /* terminator */ |
| 366 | }; | 369 | }; |
| @@ -414,6 +417,20 @@ static const struct hda_pintbl mbp101_pincfgs[] = { | |||
| 414 | {} /* terminator */ | 417 | {} /* terminator */ |
| 415 | }; | 418 | }; |
| 416 | 419 | ||
| 420 | static const struct hda_pintbl mba42_pincfgs[] = { | ||
| 421 | { 0x09, 0x012b4030 }, /* HP */ | ||
| 422 | { 0x0a, 0x400000f0 }, | ||
| 423 | { 0x0b, 0x90100120 }, /* speaker */ | ||
| 424 | { 0x0c, 0x400000f0 }, | ||
| 425 | { 0x0d, 0x90a00110 }, /* mic */ | ||
| 426 | { 0x0e, 0x400000f0 }, | ||
| 427 | { 0x0f, 0x400000f0 }, | ||
| 428 | { 0x10, 0x400000f0 }, | ||
| 429 | { 0x12, 0x400000f0 }, | ||
| 430 | { 0x15, 0x400000f0 }, | ||
| 431 | {} /* terminator */ | ||
| 432 | }; | ||
| 433 | |||
| 417 | static void cs420x_fixup_gpio_13(struct hda_codec *codec, | 434 | static void cs420x_fixup_gpio_13(struct hda_codec *codec, |
| 418 | const struct hda_fixup *fix, int action) | 435 | const struct hda_fixup *fix, int action) |
| 419 | { | 436 | { |
| @@ -482,6 +499,12 @@ static const struct hda_fixup cs420x_fixups[] = { | |||
| 482 | .chained = true, | 499 | .chained = true, |
| 483 | .chain_id = CS420X_GPIO_13, | 500 | .chain_id = CS420X_GPIO_13, |
| 484 | }, | 501 | }, |
| 502 | [CS420X_MBA42] = { | ||
| 503 | .type = HDA_FIXUP_PINS, | ||
| 504 | .v.pins = mba42_pincfgs, | ||
| 505 | .chained = true, | ||
| 506 | .chain_id = CS420X_GPIO_13, | ||
| 507 | }, | ||
| 485 | }; | 508 | }; |
| 486 | 509 | ||
| 487 | static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) | 510 | static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 02e22b4458d2..403010c9e82e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -3483,6 +3483,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
| 3483 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 3483 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
| 3484 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 3484 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
| 3485 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 3485 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
| 3486 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
| 3486 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3487 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 3487 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3488 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 3488 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3489 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| @@ -3494,6 +3495,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
| 3494 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3495 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 3495 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3496 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 3496 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3497 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 3498 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
| 3499 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
| 3497 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 3500 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
| 3498 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 3501 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
| 3499 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 3502 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
| @@ -3596,6 +3599,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
| 3596 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 3599 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
| 3597 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, | 3600 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
| 3598 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, | 3601 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, |
| 3602 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | ||
| 3603 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, | ||
| 3599 | {} | 3604 | {} |
| 3600 | }; | 3605 | }; |
| 3601 | 3606 | ||
| @@ -4275,6 +4280,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = { | |||
| 4275 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | 4280 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, |
| 4276 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | 4281 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
| 4277 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 4282 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
| 4283 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | ||
| 4278 | {} | 4284 | {} |
| 4279 | }; | 4285 | }; |
| 4280 | 4286 | ||
diff --git a/sound/usb/card.c b/sound/usb/card.c index 1a033177b83f..64952e2d3ed1 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -147,14 +147,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int | |||
| 147 | return -EINVAL; | 147 | return -EINVAL; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | alts = &iface->altsetting[0]; | ||
| 151 | altsd = get_iface_desc(alts); | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Android with both accessory and audio interfaces enabled gets the | ||
| 155 | * interface numbers wrong. | ||
| 156 | */ | ||
| 157 | if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || | ||
| 158 | chip->usb_id == USB_ID(0x18d1, 0x2d05)) && | ||
| 159 | interface == 0 && | ||
| 160 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && | ||
| 161 | altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { | ||
| 162 | interface = 2; | ||
| 163 | iface = usb_ifnum_to_if(dev, interface); | ||
| 164 | if (!iface) | ||
| 165 | return -EINVAL; | ||
| 166 | alts = &iface->altsetting[0]; | ||
| 167 | altsd = get_iface_desc(alts); | ||
| 168 | } | ||
| 169 | |||
| 150 | if (usb_interface_claimed(iface)) { | 170 | if (usb_interface_claimed(iface)) { |
| 151 | snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", | 171 | snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", |
| 152 | dev->devnum, ctrlif, interface); | 172 | dev->devnum, ctrlif, interface); |
| 153 | return -EINVAL; | 173 | return -EINVAL; |
| 154 | } | 174 | } |
| 155 | 175 | ||
| 156 | alts = &iface->altsetting[0]; | ||
| 157 | altsd = get_iface_desc(alts); | ||
| 158 | if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || | 176 | if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || |
| 159 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && | 177 | altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && |
| 160 | altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { | 178 | altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index e5c7f9f20fdd..d5438083fd6a 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -885,6 +885,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
| 885 | 885 | ||
| 886 | case USB_ID(0x046d, 0x0808): | 886 | case USB_ID(0x046d, 0x0808): |
| 887 | case USB_ID(0x046d, 0x0809): | 887 | case USB_ID(0x046d, 0x0809): |
| 888 | case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ | ||
| 888 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ | 889 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ |
| 889 | case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ | 890 | case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ |
| 890 | case USB_ID(0x046d, 0x0991): | 891 | case USB_ID(0x046d, 0x0991): |
