We want the USB fixes in here as well.
Unified · Split
| @@ -198,6 +198,9 @@ Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com> · 197 unmodified lines | |||
| 198 | Mayuresh Janorkar <mayur@ti.com> | 198 | Mayuresh Janorkar <mayur@ti.com> |
| 199 | Michael Buesch <m@bues.ch> | 199 | Michael Buesch <m@bues.ch> |
| 200 | Michel Dänzer <michel@tungstengraphics.com> | 200 | Michel Dänzer <michel@tungstengraphics.com> |
| 201 | Mike Rapoport <rppt@kernel.org> <mike@compulab.co.il> | ||
| 202 | Mike Rapoport <rppt@kernel.org> <mike.rapoport@gmail.com> | ||
| 203 | Mike Rapoport <rppt@kernel.org> <rppt@linux.ibm.com> | ||
| 201 | Miodrag Dinic <miodrag.dinic@mips.com> <miodrag.dinic@imgtec.com> | 204 | Miodrag Dinic <miodrag.dinic@mips.com> <miodrag.dinic@imgtec.com> |
| 202 | Miquel Raynal <miquel.raynal@bootlin.com> <miquel.raynal@free-electrons.com> | 205 | Miquel Raynal <miquel.raynal@bootlin.com> <miquel.raynal@free-electrons.com> |
| 203 | Mitesh shah <mshah@teja.com> | 206 | Mitesh shah <mshah@teja.com> |
| @@ -16,7 +16,16 @@ Description: Allow the root user to disable/enable in runtime the clock · 15 unmodified lines | |||
| 16 | gating mechanism in Gaudi. Due to how Gaudi is built, the | 16 | gating mechanism in Gaudi. Due to how Gaudi is built, the |
| 17 | clock gating needs to be disabled in order to access the | 17 | clock gating needs to be disabled in order to access the |
| 18 | registers of the TPC and MME engines. This is sometimes needed | 18 | registers of the TPC and MME engines. This is sometimes needed |
| 19 | during debug by the user and hence the user needs this option | 19 | during debug by the user and hence the user needs this option. |
| 20 | The user can supply a bitmask value, each bit represents | ||
| 21 | a different engine to disable/enable its clock gating feature. | ||
| 22 | The bitmask is composed of 20 bits: | ||
| 23 | 0 - 7 : DMA channels | ||
| 24 | 8 - 11 : MME engines | ||
| 25 | 12 - 19 : TPC engines | ||
| 26 | The bit's location of a specific engine can be determined | ||
| 27 | using (1 << GAUDI_ENGINE_ID_*). GAUDI_ENGINE_ID_* values | ||
| 28 | are defined in uapi habanalabs.h file in enum gaudi_engine_id | ||
| 20 | 29 | ||
| 21 | What: /sys/kernel/debug/habanalabs/hl<n>/command_buffers | 30 | What: /sys/kernel/debug/habanalabs/hl<n>/command_buffers |
| 22 | Date: Jan 2019 | 31 | Date: Jan 2019 |
| @@ -378,6 +378,8 @@ examples: · 377 unmodified lines | |||
| 378 | - | | 378 | - | |
| 379 | sound { | 379 | sound { |
| 380 | compatible = "simple-audio-card"; | 380 | compatible = "simple-audio-card"; |
| 381 | #address-cells = <1>; | ||
| 382 | #size-cells = <0>; | ||
| 381 | 383 | ||
| 382 | simple-audio-card,name = "rsnd-ak4643"; | 384 | simple-audio-card,name = "rsnd-ak4643"; |
| 383 | simple-audio-card,format = "left_j"; | 385 | simple-audio-card,format = "left_j"; |
| @@ -391,10 +393,12 @@ examples: · 7 unmodified lines | |||
| 391 | "ak4642 Playback", "DAI1 Playback"; | 393 | "ak4642 Playback", "DAI1 Playback"; |
| 392 | 394 | ||
| 393 | dpcmcpu: simple-audio-card,cpu@0 { | 395 | dpcmcpu: simple-audio-card,cpu@0 { |
| 396 | reg = <0>; | ||
| 394 | sound-dai = <&rcar_sound 0>; | 397 | sound-dai = <&rcar_sound 0>; |
| 395 | }; | 398 | }; |
| 396 | 399 | ||
| 397 | simple-audio-card,cpu@1 { | 400 | simple-audio-card,cpu@1 { |
| 401 | reg = <1>; | ||
| 398 | sound-dai = <&rcar_sound 1>; | 402 | sound-dai = <&rcar_sound 1>; |
| 399 | }; | 403 | }; |
| 400 | 404 | ||
| @@ -418,6 +422,8 @@ examples: · 17 unmodified lines | |||
| 418 | - | | 422 | - | |
| 419 | sound { | 423 | sound { |
| 420 | compatible = "simple-audio-card"; | 424 | compatible = "simple-audio-card"; |
| 425 | #address-cells = <1>; | ||
| 426 | #size-cells = <0>; | ||
| 421 | 427 | ||
| 422 | simple-audio-card,routing = | 428 | simple-audio-card,routing = |
| 423 | "pcm3168a Playback", "DAI1 Playback", | 429 | "pcm3168a Playback", "DAI1 Playback", |
| @@ -426,6 +432,7 @@ examples: · 2 unmodified lines | |||
| 426 | "pcm3168a Playback", "DAI4 Playback"; | 432 | "pcm3168a Playback", "DAI4 Playback"; |
| 427 | 433 | ||
| 428 | simple-audio-card,dai-link@0 { | 434 | simple-audio-card,dai-link@0 { |
| 435 | reg = <0>; | ||
| 429 | format = "left_j"; | 436 | format = "left_j"; |
| 430 | bitclock-master = <&sndcpu0>; | 437 | bitclock-master = <&sndcpu0>; |
| 431 | frame-master = <&sndcpu0>; | 438 | frame-master = <&sndcpu0>; |
| @@ -439,22 +446,23 @@ examples: · 7 unmodified lines | |||
| 439 | }; | 446 | }; |
| 440 | 447 | ||
| 441 | simple-audio-card,dai-link@1 { | 448 | simple-audio-card,dai-link@1 { |
| 449 | reg = <1>; | ||
| 442 | format = "i2s"; | 450 | format = "i2s"; |
| 443 | bitclock-master = <&sndcpu1>; | 451 | bitclock-master = <&sndcpu1>; |
| 444 | frame-master = <&sndcpu1>; | 452 | frame-master = <&sndcpu1>; |
| 445 | 453 | ||
| 446 | convert-channels = <8>; /* TDM Split */ | 454 | convert-channels = <8>; /* TDM Split */ |
| 447 | 455 | ||
| 448 | sndcpu1: cpu@0 { | 456 | sndcpu1: cpu0 { |
| 449 | sound-dai = <&rcar_sound 1>; | 457 | sound-dai = <&rcar_sound 1>; |
| 450 | }; | 458 | }; |
| 451 | cpu@1 { | 459 | cpu1 { |
| 452 | sound-dai = <&rcar_sound 2>; | 460 | sound-dai = <&rcar_sound 2>; |
| 453 | }; | 461 | }; |
| 454 | cpu@2 { | 462 | cpu2 { |
| 455 | sound-dai = <&rcar_sound 3>; | 463 | sound-dai = <&rcar_sound 3>; |
| 456 | }; | 464 | }; |
| 457 | cpu@3 { | 465 | cpu3 { |
| 458 | sound-dai = <&rcar_sound 4>; | 466 | sound-dai = <&rcar_sound 4>; |
| 459 | }; | 467 | }; |
| 460 | codec { | 468 | codec { |
| @@ -466,6 +474,7 @@ examples: · 5 unmodified lines | |||
| 466 | }; | 474 | }; |
| 467 | 475 | ||
| 468 | simple-audio-card,dai-link@2 { | 476 | simple-audio-card,dai-link@2 { |
| 477 | reg = <2>; | ||
| 469 | format = "i2s"; | 478 | format = "i2s"; |
| 470 | bitclock-master = <&sndcpu2>; | 479 | bitclock-master = <&sndcpu2>; |
| 471 | frame-master = <&sndcpu2>; | 480 | frame-master = <&sndcpu2>; |
| @@ -23,6 +23,7 @@ PTP hardware clock infrastructure for Linux · 22 unmodified lines | |||
| 23 | + Ancillary clock features | 23 | + Ancillary clock features |
| 24 | - Time stamp external events | 24 | - Time stamp external events |
| 25 | - Period output signals configurable from user space | 25 | - Period output signals configurable from user space |
| 26 | - Low Pass Filter (LPF) access from user space | ||
| 26 | - Synchronization of the Linux system time via the PPS subsystem | 27 | - Synchronization of the Linux system time via the PPS subsystem |
| 27 | 28 | ||
| 28 | PTP hardware clock kernel API | 29 | PTP hardware clock kernel API |
| @@ -94,3 +95,14 @@ Supported hardware · 65 unmodified lines | |||
| 94 | 95 | ||
| 95 | - Auxiliary Slave/Master Mode Snapshot (optional interrupt) | 96 | - Auxiliary Slave/Master Mode Snapshot (optional interrupt) |
| 96 | - Target Time (optional interrupt) | 97 | - Target Time (optional interrupt) |
| 98 | |||
| 99 | * Renesas (IDT) ClockMatrix™ | ||
| 100 | |||
| 101 | - Up to 4 independent PHC channels | ||
| 102 | - Integrated low pass filter (LPF), access via .adjPhase (compliant to ITU-T G.8273.2) | ||
| 103 | - Programmable output periodic signals | ||
| 104 | - Programmable inputs can time stamp external triggers | ||
| 105 | - Driver and/or hardware configuration through firmware (idtcm.bin) | ||
| 106 | - LPF settings (bandwidth, phase limiting, automatic holdover, physical layer assist (per ITU-T G.8273.2)) | ||
| 107 | - Programmable output PTP clocks, any frequency up to 1GHz (to other PHY/MAC time stampers, refclk to ASSPs/SoCs/FPGAs) | ||
| 108 | - Lock to GNSS input, automatic switching between GNSS and user-space PHC control (optional) | ||
| @@ -26,7 +26,7 @@ Usage · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | 1) Device creation & deletion | 27 | 1) Device creation & deletion |
| 28 | 28 | ||
| 29 | a) ip link add dev bareudp0 type bareudp dstport 6635 ethertype 0x8847. | 29 | a) ip link add dev bareudp0 type bareudp dstport 6635 ethertype mpls_uc |
| 30 | 30 | ||
| 31 | This creates a bareudp tunnel device which tunnels L3 traffic with ethertype | 31 | This creates a bareudp tunnel device which tunnels L3 traffic with ethertype |
| 32 | 0x8847 (MPLS traffic). The destination port of the UDP header will be set to | 32 | 0x8847 (MPLS traffic). The destination port of the UDP header will be set to |
| @@ -34,14 +34,21 @@ Usage · 1 unmodified line | |||
| 34 | 34 | ||
| 35 | b) ip link delete bareudp0 | 35 | b) ip link delete bareudp0 |
| 36 | 36 | ||
| 37 | 2) Device creation with multiple proto mode enabled | 37 | 2) Device creation with multiproto mode enabled |
| 38 | 38 | ||
| 39 | There are two ways to create a bareudp device for MPLS & IP with multiproto mode | 39 | The multiproto mode allows bareudp tunnels to handle several protocols of the |
| 40 | enabled. | 40 | same family. It is currently only available for IP and MPLS. This mode has to |
| 41 | be enabled explicitly with the "multiproto" flag. | ||
| 41 | 42 | ||
| 42 | a) ip link add dev bareudp0 type bareudp dstport 6635 ethertype 0x8847 multiproto | 43 | a) ip link add dev bareudp0 type bareudp dstport 6635 ethertype ipv4 multiproto |
| 43 | 44 | ||
| 44 | b) ip link add dev bareudp0 type bareudp dstport 6635 ethertype mpls | 45 | For an IPv4 tunnel the multiproto mode allows the tunnel to also handle |
| 46 | IPv6. | ||
| 47 | |||
| 48 | b) ip link add dev bareudp0 type bareudp dstport 6635 ethertype mpls_uc multiproto | ||
| 49 | |||
| 50 | For MPLS, the multiproto mode allows the tunnel to handle both unicast | ||
| 51 | and multicast MPLS packets. | ||
| 45 | 52 | ||
| 46 | 3) Device Usage | 53 | 3) Device Usage |
| 47 | 54 | ||
| @@ -6956,6 +6956,7 @@ M: Timur Tabi <timur@kernel.org> · 6955 unmodified lines | |||
| 6956 | M: Nicolin Chen <nicoleotsuka@gmail.com> | 6956 | M: Nicolin Chen <nicoleotsuka@gmail.com> |
| 6957 | M: Xiubo Li <Xiubo.Lee@gmail.com> | 6957 | M: Xiubo Li <Xiubo.Lee@gmail.com> |
| 6958 | R: Fabio Estevam <festevam@gmail.com> | 6958 | R: Fabio Estevam <festevam@gmail.com> |
| 6959 | R: Shengjiu Wang <shengjiu.wang@gmail.com> | ||
| 6959 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 6960 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 6960 | L: linuxppc-dev@lists.ozlabs.org | 6961 | L: linuxppc-dev@lists.ozlabs.org |
| 6961 | S: Maintained | 6962 | S: Maintained |
| @@ -9312,6 +9313,17 @@ F: Documentation/kbuild/kconfig* · 2350 unmodified lines | |||
| 9312 | F: scripts/Kconfig.include | 9313 | F: scripts/Kconfig.include |
| 9313 | F: scripts/kconfig/ | 9314 | F: scripts/kconfig/ |
| 9314 | 9315 | ||
| 9316 | KCOV | ||
| 9317 | R: Dmitry Vyukov <dvyukov@google.com> | ||
| 9318 | R: Andrey Konovalov <andreyknvl@google.com> | ||
| 9319 | L: kasan-dev@googlegroups.com | ||
| 9320 | S: Maintained | ||
| 9321 | F: Documentation/dev-tools/kcov.rst | ||
| 9322 | F: include/linux/kcov.h | ||
| 9323 | F: include/uapi/linux/kcov.h | ||
| 9324 | F: kernel/kcov.c | ||
| 9325 | F: scripts/Makefile.kcov | ||
| 9326 | |||
| 9315 | KCSAN | 9327 | KCSAN |
| 9316 | M: Marco Elver <elver@google.com> | 9328 | M: Marco Elver <elver@google.com> |
| 9317 | R: Dmitry Vyukov <dvyukov@google.com> | 9329 | R: Dmitry Vyukov <dvyukov@google.com> |
| @@ -11247,7 +11259,7 @@ S: Maintained · 1929 unmodified lines | |||
| 11247 | F: drivers/crypto/atmel-ecc.* | 11259 | F: drivers/crypto/atmel-ecc.* |
| 11248 | 11260 | ||
| 11249 | MICROCHIP I2C DRIVER | 11261 | MICROCHIP I2C DRIVER |
| 11250 | M: Ludovic Desroches <ludovic.desroches@microchip.com> | 11262 | M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> |
| 11251 | L: linux-i2c@vger.kernel.org | 11263 | L: linux-i2c@vger.kernel.org |
| 11252 | S: Supported | 11264 | S: Supported |
| 11253 | F: drivers/i2c/busses/i2c-at91-*.c | 11265 | F: drivers/i2c/busses/i2c-at91-*.c |
| @@ -11340,17 +11352,17 @@ F: drivers/iio/adc/at91-sama5d2_adc.c · 86 unmodified lines | |||
| 11340 | F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h | 11352 | F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h |
| 11341 | 11353 | ||
| 11342 | MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER | 11354 | MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER |
| 11343 | M: Nicolas Ferre <nicolas.ferre@microchip.com> | 11355 | M: Claudiu Beznea <claudiu.beznea@microchip.com> |
| 11344 | S: Supported | 11356 | S: Supported |
| 11345 | F: drivers/power/reset/at91-sama5d2_shdwc.c | 11357 | F: drivers/power/reset/at91-sama5d2_shdwc.c |
| 11346 | 11358 | ||
| 11347 | MICROCHIP SPI DRIVER | 11359 | MICROCHIP SPI DRIVER |
| 11348 | M: Nicolas Ferre <nicolas.ferre@microchip.com> | 11360 | M: Tudor Ambarus <tudor.ambarus@microchip.com> |
| 11349 | S: Supported | 11361 | S: Supported |
| 11350 | F: drivers/spi/spi-atmel.* | 11362 | F: drivers/spi/spi-atmel.* |
| 11351 | 11363 | ||
| 11352 | MICROCHIP SSC DRIVER | 11364 | MICROCHIP SSC DRIVER |
| 11353 | M: Nicolas Ferre <nicolas.ferre@microchip.com> | 11365 | M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> |
| 11354 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 11366 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 11355 | S: Supported | 11367 | S: Supported |
| 11356 | F: drivers/misc/atmel-ssc.c | 11368 | F: drivers/misc/atmel-ssc.c |
| @@ -14869,6 +14881,7 @@ F: drivers/s390/block/dasd* · 3512 unmodified lines | |||
| 14869 | F: include/linux/dasd_mod.h | 14881 | F: include/linux/dasd_mod.h |
| 14870 | 14882 | ||
| 14871 | S390 IOMMU (PCI) | 14883 | S390 IOMMU (PCI) |
| 14884 | M: Matthew Rosato <mjrosato@linux.ibm.com> | ||
| 14872 | M: Gerald Schaefer <gerald.schaefer@linux.ibm.com> | 14885 | M: Gerald Schaefer <gerald.schaefer@linux.ibm.com> |
| 14873 | L: linux-s390@vger.kernel.org | 14886 | L: linux-s390@vger.kernel.org |
| 14874 | S: Supported | 14887 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 8 | 3 | PATCHLEVEL = 8 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc6 | 5 | EXTRAVERSION = -rc7 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -567,7 +567,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) · 558 unmodified lines | |||
| 567 | ifneq ($(CROSS_COMPILE),) | 567 | ifneq ($(CROSS_COMPILE),) |
| 568 | CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) | 568 | CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) |
| 569 | GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) | 569 | GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) |
| 570 | CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) | 570 | CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) |
| 571 | GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) | 571 | GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) |
| 572 | endif | 572 | endif |
| 573 | ifneq ($(GCC_TOOLCHAIN),) | 573 | ifneq ($(GCC_TOOLCHAIN),) |
| @@ -1754,7 +1754,7 @@ PHONY += descend $(build-dirs) · 1180 unmodified lines | |||
| 1754 | descend: $(build-dirs) | 1754 | descend: $(build-dirs) |
| 1755 | $(build-dirs): prepare | 1755 | $(build-dirs): prepare |
| 1756 | $(Q)$(MAKE) $(build)=$@ \ | 1756 | $(Q)$(MAKE) $(build)=$@ \ |
| 1757 | single-build=$(if $(filter-out $@/, $(filter $@/%, $(single-no-ko))),1) \ | 1757 | single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1) \ |
| 1758 | need-builtin=1 need-modorder=1 | 1758 | need-builtin=1 need-modorder=1 |
| 1759 | 1759 | ||
| 1760 | clean-dirs := $(addprefix _clean_, $(clean-dirs)) | 1760 | clean-dirs := $(addprefix _clean_, $(clean-dirs)) |
| @@ -137,7 +137,7 @@ export TEXT_OFFSET · 136 unmodified lines | |||
| 137 | 137 | ||
| 138 | core-y += arch/arm64/ | 138 | core-y += arch/arm64/ |
| 139 | libs-y := arch/arm64/lib/ $(libs-y) | 139 | libs-y := arch/arm64/lib/ $(libs-y) |
| 140 | core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a | 140 | libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a |
| 141 | 141 | ||
| 142 | # Default target when executing plain make | 142 | # Default target when executing plain make |
| 143 | boot := arch/arm64/boot | 143 | boot := arch/arm64/boot |
| @@ -454,10 +454,7 @@ · 453 unmodified lines | |||
| 454 | status = "okay"; | 454 | status = "okay"; |
| 455 | phy-mode = "2500base-x"; | 455 | phy-mode = "2500base-x"; |
| 456 | phys = <&cp1_comphy5 2>; | 456 | phys = <&cp1_comphy5 2>; |
| 457 | fixed-link { | 457 | managed = "in-band-status"; |
| 458 | speed = <2500>; | ||
| 459 | full-duplex; | ||
| 460 | }; | ||
| 461 | }; | 458 | }; |
| 462 | 459 | ||
| 463 | &cp1_spi1 { | 460 | &cp1_spi1 { |
| @@ -14,7 +14,7 @@ COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit)) · 13 unmodified lines | |||
| 14 | COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..) | 14 | COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..) |
| 15 | 15 | ||
| 16 | CC_COMPAT_CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%)) | 16 | CC_COMPAT_CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%)) |
| 17 | CC_COMPAT_CLANG_FLAGS += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR) | 17 | CC_COMPAT_CLANG_FLAGS += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE_COMPAT)) |
| 18 | CC_COMPAT_CLANG_FLAGS += -no-integrated-as -Qunused-arguments | 18 | CC_COMPAT_CLANG_FLAGS += -no-integrated-as -Qunused-arguments |
| 19 | ifneq ($(COMPAT_GCC_TOOLCHAIN),) | 19 | ifneq ($(COMPAT_GCC_TOOLCHAIN),) |
| 20 | CC_COMPAT_CLANG_FLAGS += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN) | 20 | CC_COMPAT_CLANG_FLAGS += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN) |
| @@ -212,6 +212,8 @@ atomic64_set(atomic64_t *v, s64 i) · 211 unmodified lines | |||
| 212 | _atomic_spin_unlock_irqrestore(v, flags); | 212 | _atomic_spin_unlock_irqrestore(v, flags); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | #define atomic64_set_release(v, i) atomic64_set((v), (i)) | ||
| 216 | |||
| 215 | static __inline__ s64 | 217 | static __inline__ s64 |
| 216 | atomic64_read(const atomic64_t *v) | 218 | atomic64_read(const atomic64_t *v) |
| 217 | { | 219 | { |
| @@ -60,6 +60,7 @@ extern void __cmpxchg_called_with_bad_pointer(void); · 59 unmodified lines | |||
| 60 | extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, | 60 | extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, |
| 61 | unsigned int new_); | 61 | unsigned int new_); |
| 62 | extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_); | 62 | extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_); |
| 63 | extern u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new_); | ||
| 63 | 64 | ||
| 64 | /* don't worry...optimizer will get rid of most of this */ | 65 | /* don't worry...optimizer will get rid of most of this */ |
| 65 | static inline unsigned long | 66 | static inline unsigned long |
| @@ -71,6 +72,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) · 5 unmodified lines | |||
| 71 | #endif | 72 | #endif |
| 72 | case 4: return __cmpxchg_u32((unsigned int *)ptr, | 73 | case 4: return __cmpxchg_u32((unsigned int *)ptr, |
| 73 | (unsigned int)old, (unsigned int)new_); | 74 | (unsigned int)old, (unsigned int)new_); |
| 75 | case 1: return __cmpxchg_u8((u8 *)ptr, (u8)old, (u8)new_); | ||
| 74 | } | 76 | } |
| 75 | __cmpxchg_called_with_bad_pointer(); | 77 | __cmpxchg_called_with_bad_pointer(); |
| 76 | return old; | 78 | return old; |
| @@ -79,3 +79,15 @@ unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsign · 78 unmodified lines | |||
| 79 | _atomic_spin_unlock_irqrestore(ptr, flags); | 79 | _atomic_spin_unlock_irqrestore(ptr, flags); |
| 80 | return (unsigned long)prev; | 80 | return (unsigned long)prev; |
| 81 | } | 81 | } |
| 82 | |||
| 83 | u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new) | ||
| 84 | { | ||
| 85 | unsigned long flags; | ||
| 86 | u8 prev; | ||
| 87 | |||
| 88 | _atomic_spin_lock_irqsave(ptr, flags); | ||
| 89 | if ((prev = *ptr) == old) | ||
| 90 | *ptr = new; | ||
| 91 | _atomic_spin_unlock_irqrestore(ptr, flags); | ||
| 92 | return prev; | ||
| 93 | } | ||
| @@ -95,19 +95,40 @@ void __init mem_init(void) · 94 unmodified lines | |||
| 95 | #ifdef CONFIG_BLK_DEV_INITRD | 95 | #ifdef CONFIG_BLK_DEV_INITRD |
| 96 | static void __init setup_initrd(void) | 96 | static void __init setup_initrd(void) |
| 97 | { | 97 | { |
| 98 | phys_addr_t start; | ||
| 98 | unsigned long size; | 99 | unsigned long size; |
| 99 | 100 | ||
| 100 | if (initrd_start >= initrd_end) { | 101 | /* Ignore the virtul address computed during device tree parsing */ |
| 101 | pr_info("initrd not found or empty"); | 102 | initrd_start = initrd_end = 0; |
| 103 | |||
| 104 | if (!phys_initrd_size) | ||
| 105 | return; | ||
| 106 | /* | ||
| 107 | * Round the memory region to page boundaries as per free_initrd_mem() | ||
| 108 | * This allows us to detect whether the pages overlapping the initrd | ||
| 109 | * are in use, but more importantly, reserves the entire set of pages | ||
| 110 | * as we don't want these pages allocated for other purposes. | ||
| 111 | */ | ||
| 112 | start = round_down(phys_initrd_start, PAGE_SIZE); | ||
| 113 | size = phys_initrd_size + (phys_initrd_start - start); | ||
| 114 | size = round_up(size, PAGE_SIZE); | ||
| 115 | |||
| 116 | if (!memblock_is_region_memory(start, size)) { | ||
| 117 | pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region", | ||
| 118 | (u64)start, size); | ||
| 102 | goto disable; | 119 | goto disable; |
| 103 | } | 120 | } |
| 104 | if (__pa_symbol(initrd_end) > PFN_PHYS(max_low_pfn)) { | 121 | |
| 105 | pr_err("initrd extends beyond end of memory"); | 122 | if (memblock_is_region_reserved(start, size)) { |
| 123 | pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region\n", | ||
| 124 | (u64)start, size); | ||
| 106 | goto disable; | 125 | goto disable; |
| 107 | } | 126 | } |
| 108 | 127 | ||
| 109 | size = initrd_end - initrd_start; | 128 | memblock_reserve(start, size); |
| 110 | memblock_reserve(__pa_symbol(initrd_start), size); | 129 | /* Now convert initrd to virtual addresses */ |
| 130 | initrd_start = (unsigned long)__va(phys_initrd_start); | ||
| 131 | initrd_end = initrd_start + phys_initrd_size; | ||
| 111 | initrd_below_start_ok = 1; | 132 | initrd_below_start_ok = 1; |
| 112 | 133 | ||
| 113 | pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", | 134 | pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n", |
| @@ -126,33 +147,36 @@ void __init setup_bootmem(void) · 12 unmodified lines | |||
| 126 | { | 147 | { |
| 127 | struct memblock_region *reg; | 148 | struct memblock_region *reg; |
| 128 | phys_addr_t mem_size = 0; | 149 | phys_addr_t mem_size = 0; |
| 150 | phys_addr_t total_mem = 0; | ||
| 151 | phys_addr_t mem_start, end = 0; | ||
| 129 | phys_addr_t vmlinux_end = __pa_symbol(&_end); | 152 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 130 | phys_addr_t vmlinux_start = __pa_symbol(&_start); | 153 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 131 | 154 | ||
| 132 | /* Find the memory region containing the kernel */ | 155 | /* Find the memory region containing the kernel */ |
| 133 | for_each_memblock(memory, reg) { | 156 | for_each_memblock(memory, reg) { |
| 134 | phys_addr_t end = reg->base + reg->size; | 157 | end = reg->base + reg->size; |
| 135 | 158 | if (!total_mem) | |
| 136 | if (reg->base <= vmlinux_start && vmlinux_end <= end) { | 159 | mem_start = reg->base; |
| 137 | mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET); | 160 | if (reg->base <= vmlinux_start && vmlinux_end <= end) |
| 138 | 161 | BUG_ON(reg->size == 0); | |
| 139 | /* | 162 | total_mem = total_mem + reg->size; |
| 140 | * Remove memblock from the end of usable area to the | ||
| 141 | * end of region | ||
| 142 | */ | ||
| 143 | if (reg->base + mem_size < end) | ||
| 144 | memblock_remove(reg->base + mem_size, | ||
| 145 | end - reg->base - mem_size); | ||
| 146 | } | ||
| 147 | } | 163 | } |
| 148 | BUG_ON(mem_size == 0); | 164 | |
| 165 | /* | ||
| 166 | * Remove memblock from the end of usable area to the | ||
| 167 | * end of region | ||
| 168 | */ | ||
| 169 | mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET); | ||
| 170 | if (mem_start + mem_size < end) | ||
| 171 | memblock_remove(mem_start + mem_size, | ||
| 172 | end - mem_start - mem_size); | ||
| 149 | 173 | ||
| 150 | /* Reserve from the start of the kernel to the end of the kernel */ | 174 | /* Reserve from the start of the kernel to the end of the kernel */ |
| 151 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); | 175 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); |
| 152 | 176 | ||
| 153 | set_max_mapnr(PFN_DOWN(mem_size)); | ||
| 154 | max_pfn = PFN_DOWN(memblock_end_of_DRAM()); | 177 | max_pfn = PFN_DOWN(memblock_end_of_DRAM()); |
| 155 | max_low_pfn = max_pfn; | 178 | max_low_pfn = max_pfn; |
| 179 | set_max_mapnr(max_low_pfn); | ||
| 156 | 180 | ||
| 157 | #ifdef CONFIG_BLK_DEV_INITRD | 181 | #ifdef CONFIG_BLK_DEV_INITRD |
| 158 | setup_initrd(); | 182 | setup_initrd(); |
| @@ -44,7 +44,7 @@ asmlinkage void __init kasan_early_init(void) · 43 unmodified lines | |||
| 44 | (__pa(((uintptr_t) kasan_early_shadow_pmd))), | 44 | (__pa(((uintptr_t) kasan_early_shadow_pmd))), |
| 45 | __pgprot(_PAGE_TABLE))); | 45 | __pgprot(_PAGE_TABLE))); |
| 46 | 46 | ||
| 47 | flush_tlb_all(); | 47 | local_flush_tlb_all(); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static void __init populate(void *start, void *end) | 50 | static void __init populate(void *start, void *end) |
| @@ -79,7 +79,7 @@ static void __init populate(void *start, void *end) · 28 unmodified lines | |||
| 79 | pfn_pgd(PFN_DOWN(__pa(&pmd[offset])), | 79 | pfn_pgd(PFN_DOWN(__pa(&pmd[offset])), |
| 80 | __pgprot(_PAGE_TABLE))); | 80 | __pgprot(_PAGE_TABLE))); |
| 81 | 81 | ||
| 82 | flush_tlb_all(); | 82 | local_flush_tlb_all(); |
| 83 | memset(start, 0, end - start); | 83 | memset(start, 0, end - start); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| @@ -292,7 +292,7 @@ CPUMF_EVENT_ATTR(cf_z15, TX_C_TABORT_SPECIAL, 0x00f5); · 291 unmodified lines | |||
| 292 | CPUMF_EVENT_ATTR(cf_z15, DFLT_ACCESS, 0x00f7); | 292 | CPUMF_EVENT_ATTR(cf_z15, DFLT_ACCESS, 0x00f7); |
| 293 | CPUMF_EVENT_ATTR(cf_z15, DFLT_CYCLES, 0x00fc); | 293 | CPUMF_EVENT_ATTR(cf_z15, DFLT_CYCLES, 0x00fc); |
| 294 | CPUMF_EVENT_ATTR(cf_z15, DFLT_CC, 0x00108); | 294 | CPUMF_EVENT_ATTR(cf_z15, DFLT_CC, 0x00108); |
| 295 | CPUMF_EVENT_ATTR(cf_z15, DFLT_CCERROR, 0x00109); | 295 | CPUMF_EVENT_ATTR(cf_z15, DFLT_CCFINISH, 0x00109); |
| 296 | CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); | 296 | CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); |
| 297 | CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); | 297 | CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); |
| 298 | 298 | ||
| @@ -629,7 +629,7 @@ static struct attribute *cpumcf_z15_pmu_event_attr[] __initdata = { · 330 unmodified lines | |||
| 629 | CPUMF_EVENT_PTR(cf_z15, DFLT_ACCESS), | 629 | CPUMF_EVENT_PTR(cf_z15, DFLT_ACCESS), |
| 630 | CPUMF_EVENT_PTR(cf_z15, DFLT_CYCLES), | 630 | CPUMF_EVENT_PTR(cf_z15, DFLT_CYCLES), |
| 631 | CPUMF_EVENT_PTR(cf_z15, DFLT_CC), | 631 | CPUMF_EVENT_PTR(cf_z15, DFLT_CC), |
| 632 | CPUMF_EVENT_PTR(cf_z15, DFLT_CCERROR), | 632 | CPUMF_EVENT_PTR(cf_z15, DFLT_CCFINISH), |
| 633 | CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE), | 633 | CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE), |
| 634 | CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE), | 634 | CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE), |
| 635 | NULL, | 635 | NULL, |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | |||
| 39 | #define BT_MBI_UNIT_PMC 0x04 | 39 | #define BT_MBI_UNIT_PMC 0x04 |
| 40 | #define BT_MBI_UNIT_GFX 0x06 | 40 | #define BT_MBI_UNIT_GFX 0x06 |
| 41 | #define BT_MBI_UNIT_SMI 0x0C | 41 | #define BT_MBI_UNIT_SMI 0x0C |
| 42 | #define BT_MBI_UNIT_CCK 0x14 | ||
| 42 | #define BT_MBI_UNIT_USB 0x43 | 43 | #define BT_MBI_UNIT_USB 0x43 |
| 43 | #define BT_MBI_UNIT_SATA 0xA3 | 44 | #define BT_MBI_UNIT_SATA 0xA3 |
| 44 | #define BT_MBI_UNIT_PCIE 0xA6 | 45 | #define BT_MBI_UNIT_PCIE 0xA6 |
| @@ -71,6 +71,22 @@ static void printk_stack_address(unsigned long address, int reliable, · 70 unmodified lines | |||
| 71 | printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); | 71 | printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static int copy_code(struct pt_regs *regs, u8 *buf, unsigned long src, | ||
| 75 | unsigned int nbytes) | ||
| 76 | { | ||
| 77 | if (!user_mode(regs)) | ||
| 78 | return copy_from_kernel_nofault(buf, (u8 *)src, nbytes); | ||
| 79 | |||
| 80 | /* | ||
| 81 | * Make sure userspace isn't trying to trick us into dumping kernel | ||
| 82 | * memory by pointing the userspace instruction pointer at it. | ||
| 83 | */ | ||
| 84 | if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX)) | ||
| 85 | return -EINVAL; | ||
| 86 | |||
| 87 | return copy_from_user_nmi(buf, (void __user *)src, nbytes); | ||
| 88 | } | ||
| 89 | |||
| 74 | /* | 90 | /* |
| 75 | * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus: | 91 | * There are a couple of reasons for the 2/3rd prologue, courtesy of Linus: |
| 76 | * | 92 | * |
| @@ -97,17 +113,8 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl) · 20 unmodified lines | |||
| 97 | #define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE) | 113 | #define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE) |
| 98 | u8 opcodes[OPCODE_BUFSIZE]; | 114 | u8 opcodes[OPCODE_BUFSIZE]; |
| 99 | unsigned long prologue = regs->ip - PROLOGUE_SIZE; | 115 | unsigned long prologue = regs->ip - PROLOGUE_SIZE; |
| 100 | bool bad_ip; | ||
| 101 | |||
| 102 | /* | ||
| 103 | * Make sure userspace isn't trying to trick us into dumping kernel | ||
| 104 | * memory by pointing the userspace instruction pointer at it. | ||
| 105 | */ | ||
| 106 | bad_ip = user_mode(regs) && | ||
| 107 | __chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX); | ||
| 108 | 116 | ||
| 109 | if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue, | 117 | if (copy_code(regs, opcodes, prologue, sizeof(opcodes))) { |
| 110 | OPCODE_BUFSIZE)) { | ||
| 111 | printk("%sCode: Bad RIP value.\n", loglvl); | 118 | printk("%sCode: Bad RIP value.\n", loglvl); |
| 112 | } else { | 119 | } else { |
| 113 | printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %" | 120 | printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %" |
| @@ -1074,7 +1074,7 @@ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int of · 1073 unmodified lines | |||
| 1074 | copy_part(offsetof(struct fxregs_state, st_space), 128, | 1074 | copy_part(offsetof(struct fxregs_state, st_space), 128, |
| 1075 | &xsave->i387.st_space, &kbuf, &offset_start, &count); | 1075 | &xsave->i387.st_space, &kbuf, &offset_start, &count); |
| 1076 | if (header.xfeatures & XFEATURE_MASK_SSE) | 1076 | if (header.xfeatures & XFEATURE_MASK_SSE) |
| 1077 | copy_part(xstate_offsets[XFEATURE_MASK_SSE], 256, | 1077 | copy_part(xstate_offsets[XFEATURE_SSE], 256, |
| 1078 | &xsave->i387.xmm_space, &kbuf, &offset_start, &count); | 1078 | &xsave->i387.xmm_space, &kbuf, &offset_start, &count); |
| 1079 | /* | 1079 | /* |
| 1080 | * Fill xsave->i387.sw_reserved value for ptrace frame: | 1080 | * Fill xsave->i387.sw_reserved value for ptrace frame: |
| @@ -58,7 +58,6 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, · 57 unmodified lines | |||
| 58 | * or a page fault), which can make frame pointers | 58 | * or a page fault), which can make frame pointers |
| 59 | * unreliable. | 59 | * unreliable. |
| 60 | */ | 60 | */ |
| 61 | |||
| 62 | if (IS_ENABLED(CONFIG_FRAME_POINTER)) | 61 | if (IS_ENABLED(CONFIG_FRAME_POINTER)) |
| 63 | return -EINVAL; | 62 | return -EINVAL; |
| 64 | } | 63 | } |
| @@ -81,10 +80,6 @@ int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, · 16 unmodified lines | |||
| 81 | if (unwind_error(&state)) | 80 | if (unwind_error(&state)) |
| 82 | return -EINVAL; | 81 | return -EINVAL; |
| 83 | 82 | ||
| 84 | /* Success path for non-user tasks, i.e. kthreads and idle tasks */ | ||
| 85 | if (!(task->flags & (PF_KTHREAD | PF_IDLE))) | ||
| 86 | return -EINVAL; | ||
| 87 | |||
| 88 | return 0; | 83 | return 0; |
| 89 | } | 84 | } |
| 90 | 85 | ||
| @@ -440,8 +440,11 @@ bool unwind_next_frame(struct unwind_state *state) · 439 unmodified lines | |||
| 440 | /* | 440 | /* |
| 441 | * Find the orc_entry associated with the text address. | 441 | * Find the orc_entry associated with the text address. |
| 442 | * | 442 | * |
| 443 | * Decrement call return addresses by one so they work for sibling | 443 | * For a call frame (as opposed to a signal frame), state->ip points to |
| 444 | * calls and calls to noreturn functions. | 444 | * the instruction after the call. That instruction's stack layout |
| 445 | * could be different from the call instruction's layout, for example | ||
| 446 | * if the call was to a noreturn function. So get the ORC data for the | ||
| 447 | * call instruction itself. | ||
| 445 | */ | 448 | */ |
| 446 | orc = orc_find(state->signal ? state->ip : state->ip - 1); | 449 | orc = orc_find(state->signal ? state->ip : state->ip - 1); |
| 447 | if (!orc) { | 450 | if (!orc) { |
| @@ -662,6 +665,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, · 214 unmodified lines | |||
| 662 | state->sp = task->thread.sp; | 665 | state->sp = task->thread.sp; |
| 663 | state->bp = READ_ONCE_NOCHECK(frame->bp); | 666 | state->bp = READ_ONCE_NOCHECK(frame->bp); |
| 664 | state->ip = READ_ONCE_NOCHECK(frame->ret_addr); | 667 | state->ip = READ_ONCE_NOCHECK(frame->ret_addr); |
| 668 | state->signal = (void *)state->ip == ret_from_fork; | ||
| 665 | } | 669 | } |
| 666 | 670 | ||
| 667 | if (get_stack_info((unsigned long *)state->sp, state->task, | 671 | if (get_stack_info((unsigned long *)state->sp, state->task, |
| @@ -358,6 +358,7 @@ SECTIONS · 357 unmodified lines | |||
| 358 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { | 358 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
| 359 | __bss_start = .; | 359 | __bss_start = .; |
| 360 | *(.bss..page_aligned) | 360 | *(.bss..page_aligned) |
| 361 | . = ALIGN(PAGE_SIZE); | ||
| 361 | *(BSS_MAIN) | 362 | *(BSS_MAIN) |
| 362 | BSS_DECRYPTED | 363 | BSS_DECRYPTED |
| 363 | . = ALIGN(PAGE_SIZE); | 364 | . = ALIGN(PAGE_SIZE); |
| @@ -57,7 +57,7 @@ static inline · 56 unmodified lines | |||
| 57 | __wsum csum_and_copy_from_user(const void __user *src, void *dst, | 57 | __wsum csum_and_copy_from_user(const void __user *src, void *dst, |
| 58 | int len, __wsum sum, int *err_ptr) | 58 | int len, __wsum sum, int *err_ptr) |
| 59 | { | 59 | { |
| 60 | if (access_ok(dst, len)) | 60 | if (access_ok(src, len)) |
| 61 | return csum_partial_copy_generic((__force const void *)src, dst, | 61 | return csum_partial_copy_generic((__force const void *)src, dst, |
| 62 | len, sum, err_ptr, NULL); | 62 | len, sum, err_ptr, NULL); |
| 63 | if (len) | 63 | if (len) |
| @@ -947,7 +947,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, · 946 unmodified lines | |||
| 947 | trace_binder_unmap_user_end(alloc, index); | 947 | trace_binder_unmap_user_end(alloc, index); |
| 948 | } | 948 | } |
| 949 | mmap_read_unlock(mm); | 949 | mmap_read_unlock(mm); |
| 950 | mmput(mm); | 950 | mmput_async(mm); |
| 951 | 951 | ||
| 952 | trace_binder_unmap_kernel_start(alloc, index); | 952 | trace_binder_unmap_kernel_start(alloc, index); |
| 953 | 953 | ||
| @@ -721,7 +721,7 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev, · 720 unmodified lines | |||
| 721 | return next; | 721 | return next; |
| 722 | 722 | ||
| 723 | /* When no more children in primary, continue with secondary */ | 723 | /* When no more children in primary, continue with secondary */ |
| 724 | if (!IS_ERR_OR_NULL(fwnode->secondary)) | 724 | if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) |
| 725 | next = fwnode_get_next_child_node(fwnode->secondary, child); | 725 | next = fwnode_get_next_child_node(fwnode->secondary, child); |
| 726 | 726 | ||
| 727 | return next; | 727 | return next; |
| @@ -2865,6 +2865,24 @@ static int sysc_check_disabled_devices(struct sysc *ddata) · 2864 unmodified lines | |||
| 2865 | return error; | 2865 | return error; |
| 2866 | } | 2866 | } |
| 2867 | 2867 | ||
| 2868 | /* | ||
| 2869 | * Ignore timers tagged with no-reset and no-idle. These are likely in use, | ||
| 2870 | * for example by drivers/clocksource/timer-ti-dm-systimer.c. If more checks | ||
| 2871 | * are needed, we could also look at the timer register configuration. | ||
| 2872 | */ | ||
| 2873 | static int sysc_check_active_timer(struct sysc *ddata) | ||
| 2874 | { | ||
| 2875 | if (ddata->cap->type != TI_SYSC_OMAP2_TIMER && | ||
| 2876 | ddata->cap->type != TI_SYSC_OMAP4_TIMER) | ||
| 2877 | return 0; | ||
| 2878 | |||
| 2879 | if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && | ||
| 2880 | (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) | ||
| 2881 | return -EBUSY; | ||
| 2882 | |||
| 2883 | return 0; | ||
| 2884 | } | ||
| 2885 | |||
| 2868 | static const struct of_device_id sysc_match_table[] = { | 2886 | static const struct of_device_id sysc_match_table[] = { |
| 2869 | { .compatible = "simple-bus", }, | 2887 | { .compatible = "simple-bus", }, |
| 2870 | { /* sentinel */ }, | 2888 | { /* sentinel */ }, |
| @@ -2921,6 +2939,10 @@ static int sysc_probe(struct platform_device *pdev) · 50 unmodified lines | |||
| 2921 | if (error) | 2939 | if (error) |
| 2922 | return error; | 2940 | return error; |
| 2923 | 2941 | ||
| 2942 | error = sysc_check_active_timer(ddata); | ||
| 2943 | if (error) | ||
| 2944 | return error; | ||
| 2945 | |||
| 2924 | error = sysc_get_clocks(ddata); | 2946 | error = sysc_get_clocks(ddata); |
| 2925 | if (error) | 2947 | if (error) |
| 2926 | return error; | 2948 | return error; |
| @@ -814,7 +814,8 @@ static struct inode *devmem_inode; · 813 unmodified lines | |||
| 814 | #ifdef CONFIG_IO_STRICT_DEVMEM | 814 | #ifdef CONFIG_IO_STRICT_DEVMEM |
| 815 | void revoke_devmem(struct resource *res) | 815 | void revoke_devmem(struct resource *res) |
| 816 | { | 816 | { |
| 817 | struct inode *inode = READ_ONCE(devmem_inode); | 817 | /* pairs with smp_store_release() in devmem_init_inode() */ |
| 818 | struct inode *inode = smp_load_acquire(&devmem_inode); | ||
| 818 | 819 | ||
| 819 | /* | 820 | /* |
| 820 | * Check that the initialization has completed. Losing the race | 821 | * Check that the initialization has completed. Losing the race |
| @@ -1028,8 +1029,11 @@ static int devmem_init_inode(void) · 207 unmodified lines | |||
| 1028 | return rc; | 1029 | return rc; |
| 1029 | } | 1030 | } |
| 1030 | 1031 | ||
| 1031 | /* publish /dev/mem initialized */ | 1032 | /* |
| 1032 | WRITE_ONCE(devmem_inode, inode); | 1033 | * Publish /dev/mem initialized. |
| 1034 | * Pairs with smp_load_acquire() in revoke_devmem(). | ||
| 1035 | */ | ||
| 1036 | smp_store_release(&devmem_inode, inode); | ||
| 1033 | 1037 | ||
| 1034 | return 0; | 1038 | return 0; |
| 1035 | } | 1039 | } |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 19 | /* For type1, set SYSC_OMAP2_CLOCKACTIVITY for fck off on idle, l4 clock on */ | 19 | /* For type1, set SYSC_OMAP2_CLOCKACTIVITY for fck off on idle, l4 clock on */ |
| 20 | #define DMTIMER_TYPE1_ENABLE ((1 << 9) | (SYSC_IDLE_SMART << 3) | \ | 20 | #define DMTIMER_TYPE1_ENABLE ((1 << 9) | (SYSC_IDLE_SMART << 3) | \ |
| 21 | SYSC_OMAP2_ENAWAKEUP | SYSC_OMAP2_AUTOIDLE) | 21 | SYSC_OMAP2_ENAWAKEUP | SYSC_OMAP2_AUTOIDLE) |
| 22 | 22 | #define DMTIMER_TYPE1_DISABLE (SYSC_OMAP2_SOFTRESET | SYSC_OMAP2_AUTOIDLE) | |
| 23 | #define DMTIMER_TYPE2_ENABLE (SYSC_IDLE_SMART_WKUP << 2) | 23 | #define DMTIMER_TYPE2_ENABLE (SYSC_IDLE_SMART_WKUP << 2) |
| 24 | #define DMTIMER_RESET_WAIT 100000 | 24 | #define DMTIMER_RESET_WAIT 100000 |
| 25 | 25 | ||
| @@ -44,6 +44,8 @@ struct dmtimer_systimer { · 18 unmodified lines | |||
| 44 | u8 ctrl; | 44 | u8 ctrl; |
| 45 | u8 wakeup; | 45 | u8 wakeup; |
| 46 | u8 ifctrl; | 46 | u8 ifctrl; |
| 47 | struct clk *fck; | ||
| 48 | struct clk *ick; | ||
| 47 | unsigned long rate; | 49 | unsigned long rate; |
| 48 | }; | 50 | }; |
| 49 | 51 | ||
| @@ -298,16 +300,20 @@ static void __init dmtimer_systimer_select_best(void) · 248 unmodified lines | |||
| 298 | } | 300 | } |
| 299 | 301 | ||
| 300 | /* Interface clocks are only available on some SoCs variants */ | 302 | /* Interface clocks are only available on some SoCs variants */ |
| 301 | static int __init dmtimer_systimer_init_clock(struct device_node *np, | 303 | static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t, |
| 304 | struct device_node *np, | ||
| 302 | const char *name, | 305 | const char *name, |
| 303 | unsigned long *rate) | 306 | unsigned long *rate) |
| 304 | { | 307 | { |
| 305 | struct clk *clock; | 308 | struct clk *clock; |
| 306 | unsigned long r; | 309 | unsigned long r; |
| 310 | bool is_ick = false; | ||
| 307 | int error; | 311 | int error; |
| 308 | 312 | ||
| 313 | is_ick = !strncmp(name, "ick", 3); | ||
| 314 | |||
| 309 | clock = of_clk_get_by_name(np, name); | 315 | clock = of_clk_get_by_name(np, name); |
| 310 | if ((PTR_ERR(clock) == -EINVAL) && !strncmp(name, "ick", 3)) | 316 | if ((PTR_ERR(clock) == -EINVAL) && is_ick) |
| 311 | return 0; | 317 | return 0; |
| 312 | else if (IS_ERR(clock)) | 318 | else if (IS_ERR(clock)) |
| 313 | return PTR_ERR(clock); | 319 | return PTR_ERR(clock); |
| @@ -320,6 +326,11 @@ static int __init dmtimer_systimer_init_clock(struct device_node *np, · 6 unmodified lines | |||
| 320 | if (!r) | 326 | if (!r) |
| 321 | return -ENODEV; | 327 | return -ENODEV; |
| 322 | 328 | ||
| 329 | if (is_ick) | ||
| 330 | t->ick = clock; | ||
| 331 | else | ||
| 332 | t->fck = clock; | ||
| 333 | |||
| 323 | *rate = r; | 334 | *rate = r; |
| 324 | 335 | ||
| 325 | return 0; | 336 | return 0; |
| @@ -339,7 +350,10 @@ static void dmtimer_systimer_enable(struct dmtimer_systimer *t) · 13 unmodified lines | |||
| 339 | 350 | ||
| 340 | static void dmtimer_systimer_disable(struct dmtimer_systimer *t) | 351 | static void dmtimer_systimer_disable(struct dmtimer_systimer *t) |
| 341 | { | 352 | { |
| 342 | writel_relaxed(0, t->base + t->sysc); | 353 | if (!dmtimer_systimer_revision1(t)) |
| 354 | return; | ||
| 355 | |||
| 356 | writel_relaxed(DMTIMER_TYPE1_DISABLE, t->base + t->sysc); | ||
| 343 | } | 357 | } |
| 344 | 358 | ||
| 345 | static int __init dmtimer_systimer_setup(struct device_node *np, | 359 | static int __init dmtimer_systimer_setup(struct device_node *np, |
| @@ -366,13 +380,13 @@ static int __init dmtimer_systimer_setup(struct device_node *np, · 20 unmodified lines | |||
| 366 | pr_err("%s: clock source init failed: %i\n", __func__, error); | 380 | pr_err("%s: clock source init failed: %i\n", __func__, error); |
| 367 | 381 | ||
| 368 | /* For ti-sysc, we have timer clocks at the parent module level */ | 382 | /* For ti-sysc, we have timer clocks at the parent module level */ |
| 369 | error = dmtimer_systimer_init_clock(np->parent, "fck", &rate); | 383 | error = dmtimer_systimer_init_clock(t, np->parent, "fck", &rate); |
| 370 | if (error) | 384 | if (error) |
| 371 | goto err_unmap; | 385 | goto err_unmap; |
| 372 | 386 | ||
| 373 | t->rate = rate; | 387 | t->rate = rate; |
| 374 | 388 | ||
| 375 | error = dmtimer_systimer_init_clock(np->parent, "ick", &rate); | 389 | error = dmtimer_systimer_init_clock(t, np->parent, "ick", &rate); |
| 376 | if (error) | 390 | if (error) |
| 377 | goto err_unmap; | 391 | goto err_unmap; |
| 378 | 392 | ||
| @@ -496,12 +510,18 @@ static void omap_clockevent_idle(struct clock_event_device *evt) · 117 unmodified lines | |||
| 496 | struct dmtimer_systimer *t = &clkevt->t; | 510 | struct dmtimer_systimer *t = &clkevt->t; |
| 497 | 511 | ||
| 498 | dmtimer_systimer_disable(t); | 512 | dmtimer_systimer_disable(t); |
| 513 | clk_disable(t->fck); | ||
| 499 | } | 514 | } |
| 500 | 515 | ||
| 501 | static void omap_clockevent_unidle(struct clock_event_device *evt) | 516 | static void omap_clockevent_unidle(struct clock_event_device *evt) |
| 502 | { | 517 | { |
| 503 | struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); | 518 | struct dmtimer_clockevent *clkevt = to_dmtimer_clockevent(evt); |
| 504 | struct dmtimer_systimer *t = &clkevt->t; | 519 | struct dmtimer_systimer *t = &clkevt->t; |
| 520 | int error; | ||
| 521 | |||
| 522 | error = clk_enable(t->fck); | ||
| 523 | if (error) | ||
| 524 | pr_err("could not enable timer fck on resume: %i\n", error); | ||
| 505 | 525 | ||
| 506 | dmtimer_systimer_enable(t); | 526 | dmtimer_systimer_enable(t); |
| 507 | writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); | 527 | writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); |
| @@ -570,8 +590,8 @@ static int __init dmtimer_clockevent_init(struct device_node *np) · 62 unmodified lines | |||
| 570 | 3, /* Timer internal resynch latency */ | 590 | 3, /* Timer internal resynch latency */ |
| 571 | 0xffffffff); | 591 | 0xffffffff); |
| 572 | 592 | ||
| 573 | if (of_device_is_compatible(np, "ti,am33xx") || | 593 | if (of_machine_is_compatible("ti,am33xx") || |
| 574 | of_device_is_compatible(np, "ti,am43")) { | 594 | of_machine_is_compatible("ti,am43")) { |
| 575 | dev->suspend = omap_clockevent_idle; | 595 | dev->suspend = omap_clockevent_idle; |
| 576 | dev->resume = omap_clockevent_unidle; | 596 | dev->resume = omap_clockevent_unidle; |
| 577 | } | 597 | } |
| @@ -616,12 +636,18 @@ static void dmtimer_clocksource_suspend(struct clocksource *cs) · 38 unmodified lines | |||
| 616 | 636 | ||
| 617 | clksrc->loadval = readl_relaxed(t->base + t->counter); | 637 | clksrc->loadval = readl_relaxed(t->base + t->counter); |
| 618 | dmtimer_systimer_disable(t); | 638 | dmtimer_systimer_disable(t); |
| 639 | clk_disable(t->fck); | ||
| 619 | } | 640 | } |
| 620 | 641 | ||
| 621 | static void dmtimer_clocksource_resume(struct clocksource *cs) | 642 | static void dmtimer_clocksource_resume(struct clocksource *cs) |
| 622 | { | 643 | { |
| 623 | struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); | 644 | struct dmtimer_clocksource *clksrc = to_dmtimer_clocksource(cs); |
| 624 | struct dmtimer_systimer *t = &clksrc->t; | 645 | struct dmtimer_systimer *t = &clksrc->t; |
| 646 | int error; | ||
| 647 | |||
| 648 | error = clk_enable(t->fck); | ||
| 649 | if (error) | ||
| 650 | pr_err("could not enable timer fck on resume: %i\n", error); | ||
| 625 | 651 | ||
| 626 | dmtimer_systimer_enable(t); | 652 | dmtimer_systimer_enable(t); |
| 627 | writel_relaxed(clksrc->loadval, t->base + t->counter); | 653 | writel_relaxed(clksrc->loadval, t->base + t->counter); |
| @@ -653,8 +679,8 @@ static int __init dmtimer_clocksource_init(struct device_node *np) · 25 unmodified lines | |||
| 653 | dev->mask = CLOCKSOURCE_MASK(32); | 679 | dev->mask = CLOCKSOURCE_MASK(32); |
| 654 | dev->flags = CLOCK_SOURCE_IS_CONTINUOUS; | 680 | dev->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
| 655 | 681 | ||
| 656 | if (of_device_is_compatible(np, "ti,am33xx") || | 682 | /* Unlike for clockevent, legacy code sets suspend only for am4 */ |
| 657 | of_device_is_compatible(np, "ti,am43")) { | 683 | if (of_machine_is_compatible("ti,am43")) { |
| 658 | dev->suspend = dmtimer_clocksource_suspend; | 684 | dev->suspend = dmtimer_clocksource_suspend; |
| 659 | dev->resume = dmtimer_clocksource_resume; | 685 | dev->resume = dmtimer_clocksource_resume; |
| 660 | } | 686 | } |
| @@ -102,7 +102,7 @@ static struct net_device *chtls_find_netdev(struct chtls_dev *cdev, · 101 unmodified lines | |||
| 102 | case PF_INET: | 102 | case PF_INET: |
| 103 | if (likely(!inet_sk(sk)->inet_rcv_saddr)) | 103 | if (likely(!inet_sk(sk)->inet_rcv_saddr)) |
| 104 | return ndev; | 104 | return ndev; |
| 105 | ndev = ip_dev_find(&init_net, inet_sk(sk)->inet_rcv_saddr); | 105 | ndev = __ip_dev_find(&init_net, inet_sk(sk)->inet_rcv_saddr, false); |
| 106 | break; | 106 | break; |
| 107 | #if IS_ENABLED(CONFIG_IPV6) | 107 | #if IS_ENABLED(CONFIG_IPV6) |
| 108 | case PF_INET6: | 108 | case PF_INET6: |
| @@ -1052,14 +1052,15 @@ int chtls_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) · 1051 unmodified lines | |||
| 1052 | &record_type); | 1052 | &record_type); |
| 1053 | if (err) | 1053 | if (err) |
| 1054 | goto out_err; | 1054 | goto out_err; |
| 1055 | |||
| 1056 | /* Avoid appending tls handshake, alert to tls data */ | ||
| 1057 | if (skb) | ||
| 1058 | tx_skb_finalize(skb); | ||
| 1055 | } | 1059 | } |
| 1056 | 1060 | ||
| 1057 | recordsz = size; | 1061 | recordsz = size; |
| 1058 | csk->tlshws.txleft = recordsz; | 1062 | csk->tlshws.txleft = recordsz; |
| 1059 | csk->tlshws.type = record_type; | 1063 | csk->tlshws.type = record_type; |
| 1060 | |||
| 1061 | if (skb) | ||
| 1062 | ULP_SKB_CB(skb)->ulp.tls.type = record_type; | ||
| 1063 | } | 1064 | } |
| 1064 | 1065 | ||
| 1065 | if (!skb || (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND) || | 1066 | if (!skb || (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND) || |
| @@ -356,10 +356,7 @@ static struct pstore_info efi_pstore_info = { · 355 unmodified lines | |||
| 356 | 356 | ||
| 357 | static __init int efivars_pstore_init(void) | 357 | static __init int efivars_pstore_init(void) |
| 358 | { | 358 | { |
| 359 | if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) | 359 | if (!efivars_kobject() || !efivar_supports_writes()) |
| 360 | return 0; | ||
| 361 | |||
| 362 | if (!efivars_kobject()) | ||
| 363 | return 0; | 360 | return 0; |
| 364 | 361 | ||
| 365 | if (efivars_pstore_disable) | 362 | if (efivars_pstore_disable) |
| @@ -176,11 +176,13 @@ static struct efivar_operations generic_ops; · 175 unmodified lines | |||
| 176 | static int generic_ops_register(void) | 176 | static int generic_ops_register(void) |
| 177 | { | 177 | { |
| 178 | generic_ops.get_variable = efi.get_variable; | 178 | generic_ops.get_variable = efi.get_variable; |
| 179 | generic_ops.set_variable = efi.set_variable; | ||
| 180 | generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; | ||
| 181 | generic_ops.get_next_variable = efi.get_next_variable; | 179 | generic_ops.get_next_variable = efi.get_next_variable; |
| 182 | generic_ops.query_variable_store = efi_query_variable_store; | 180 | generic_ops.query_variable_store = efi_query_variable_store; |
| 183 | 181 | ||
| 182 | if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) { | ||
| 183 | generic_ops.set_variable = efi.set_variable; | ||
| 184 | generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; | ||
| 185 | } | ||
| 184 | return efivars_register(&generic_efivars, &generic_ops, efi_kobj); | 186 | return efivars_register(&generic_efivars, &generic_ops, efi_kobj); |
| 185 | } | 187 | } |
| 186 | 188 | ||
| @@ -382,7 +384,8 @@ static int __init efisubsys_init(void) · 195 unmodified lines | |||
| 382 | return -ENOMEM; | 384 | return -ENOMEM; |
| 383 | } | 385 | } |
| 384 | 386 | ||
| 385 | if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) { | 387 | if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE | |
| 388 | EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) { | ||
| 386 | efivar_ssdt_load(); | 389 | efivar_ssdt_load(); |
| 387 | error = generic_ops_register(); | 390 | error = generic_ops_register(); |
| 388 | if (error) | 391 | if (error) |
| @@ -416,7 +419,8 @@ static int __init efisubsys_init(void) · 27 unmodified lines | |||
| 416 | err_remove_group: | 419 | err_remove_group: |
| 417 | sysfs_remove_group(efi_kobj, &efi_subsys_attr_group); | 420 | sysfs_remove_group(efi_kobj, &efi_subsys_attr_group); |
| 418 | err_unregister: | 421 | err_unregister: |
| 419 | if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) | 422 | if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE | |
| 423 | EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) | ||
| 420 | generic_ops_unregister(); | 424 | generic_ops_unregister(); |
| 421 | err_put: | 425 | err_put: |
| 422 | kobject_put(efi_kobj); | 426 | kobject_put(efi_kobj); |
| @@ -680,11 +680,8 @@ int efivars_sysfs_init(void) · 679 unmodified lines | |||
| 680 | struct kobject *parent_kobj = efivars_kobject(); | 680 | struct kobject *parent_kobj = efivars_kobject(); |
| 681 | int error = 0; | 681 | int error = 0; |
| 682 | 682 | ||
| 683 | if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) | ||
| 684 | return -ENODEV; | ||
| 685 | |||
| 686 | /* No efivars has been registered yet */ | 683 | /* No efivars has been registered yet */ |
| 687 | if (!parent_kobj) | 684 | if (!parent_kobj || !efivar_supports_writes()) |
| 688 | return 0; | 685 | return 0; |
| 689 | 686 | ||
| 690 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, | 687 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, |
| @@ -6,8 +6,7 @@ · 5 unmodified lines | |||
| 6 | # enabled, even if doing so doesn't break the build. | 6 | # enabled, even if doing so doesn't break the build. |
| 7 | # | 7 | # |
| 8 | cflags-$(CONFIG_X86_32) := -march=i386 | 8 | cflags-$(CONFIG_X86_32) := -march=i386 |
| 9 | cflags-$(CONFIG_X86_64) := -mcmodel=small \ | 9 | cflags-$(CONFIG_X86_64) := -mcmodel=small |
| 10 | $(call cc-option,-maccumulate-outgoing-args) | ||
| 11 | cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ | 10 | cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ |
| 12 | -fPIC -fno-strict-aliasing -mno-red-zone \ | 11 | -fPIC -fno-strict-aliasing -mno-red-zone \ |
| 13 | -mno-mmx -mno-sse -fshort-wchar \ | 12 | -mno-mmx -mno-sse -fshort-wchar \ |
| @@ -44,7 +44,7 @@ efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr, · 43 unmodified lines | |||
| 44 | *addr = ALIGN((unsigned long)alloc_addr, align); | 44 | *addr = ALIGN((unsigned long)alloc_addr, align); |
| 45 | 45 | ||
| 46 | if (slack > 0) { | 46 | if (slack > 0) { |
| 47 | int l = (alloc_addr % align) / EFI_PAGE_SIZE; | 47 | int l = (alloc_addr & (align - 1)) / EFI_PAGE_SIZE; |
| 48 | 48 | ||
| 49 | if (l) { | 49 | if (l) { |
| 50 | efi_bs_call(free_pages, alloc_addr, slack - l + 1); | 50 | efi_bs_call(free_pages, alloc_addr, slack - l + 1); |
| @@ -121,23 +121,6 @@ static unsigned long get_dram_base(void) · 120 unmodified lines | |||
| 121 | return membase; | 121 | return membase; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | /* | ||
| 125 | * This function handles the architcture specific differences between arm and | ||
| 126 | * arm64 regarding where the kernel image must be loaded and any memory that | ||
| 127 | * must be reserved. On failure it is required to free all | ||
| 128 | * all allocations it has made. | ||
| 129 | */ | ||
| 130 | efi_status_t handle_kernel_image(unsigned long *image_addr, | ||
| 131 | unsigned long *image_size, | ||
| 132 | unsigned long *reserve_addr, | ||
| 133 | unsigned long *reserve_size, | ||
| 134 | unsigned long dram_base, | ||
| 135 | efi_loaded_image_t *image); | ||
| 136 | |||
| 137 | asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint, | ||
| 138 | unsigned long fdt_addr, | ||
| 139 | unsigned long fdt_size); | ||
| 140 | |||
| 141 | /* | 124 | /* |
| 142 | * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint | 125 | * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint |
| 143 | * that is described in the PE/COFF header. Most of the code is the same | 126 | * that is described in the PE/COFF header. Most of the code is the same |
| @@ -776,6 +776,22 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, · 775 unmodified lines | |||
| 776 | unsigned long *load_size, | 776 | unsigned long *load_size, |
| 777 | unsigned long soft_limit, | 777 | unsigned long soft_limit, |
| 778 | unsigned long hard_limit); | 778 | unsigned long hard_limit); |
| 779 | /* | ||
| 780 | * This function handles the architcture specific differences between arm and | ||
| 781 | * arm64 regarding where the kernel image must be loaded and any memory that | ||
| 782 | * must be reserved. On failure it is required to free all | ||
| 783 | * all allocations it has made. | ||
| 784 | */ | ||
| 785 | efi_status_t handle_kernel_image(unsigned long *image_addr, | ||
| 786 | unsigned long *image_size, | ||
| 787 | unsigned long *reserve_addr, | ||
| 788 | unsigned long *reserve_size, | ||
| 789 | unsigned long dram_base, | ||
| 790 | efi_loaded_image_t *image); | ||
| 791 | |||
| 792 | asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint, | ||
| 793 | unsigned long fdt_addr, | ||
| 794 | unsigned long fdt_size); | ||
| 779 | 795 | ||
| 780 | void efi_handle_post_ebs_state(void); | 796 | void efi_handle_post_ebs_state(void); |
| 781 | 797 | ||
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | #include <linux/efi.h> | 9 | #include <linux/efi.h> |
| 10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
| 11 | #include <linux/stddef.h> | ||
| 11 | 12 | ||
| 12 | #include <asm/efi.h> | 13 | #include <asm/efi.h> |
| 13 | #include <asm/e820/types.h> | 14 | #include <asm/e820/types.h> |
| @@ -361,8 +362,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, · 347 unmodified lines | |||
| 361 | int options_size = 0; | 362 | int options_size = 0; |
| 362 | efi_status_t status; | 363 | efi_status_t status; |
| 363 | char *cmdline_ptr; | 364 | char *cmdline_ptr; |
| 364 | unsigned long ramdisk_addr; | ||
| 365 | unsigned long ramdisk_size; | ||
| 366 | 365 | ||
| 367 | efi_system_table = sys_table_arg; | 366 | efi_system_table = sys_table_arg; |
| 368 | 367 | ||
| @@ -390,8 +389,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, · 21 unmodified lines | |||
| 390 | 389 | ||
| 391 | hdr = &boot_params->hdr; | 390 | hdr = &boot_params->hdr; |
| 392 | 391 | ||
| 393 | /* Copy the second sector to boot_params */ | 392 | /* Copy the setup header from the second sector to boot_params */ |
| 394 | memcpy(&hdr->jump, image_base + 512, 512); | 393 | memcpy(&hdr->jump, image_base + 512, |
| 394 | sizeof(struct setup_header) - offsetof(struct setup_header, jump)); | ||
| 395 | 395 | ||
| 396 | /* | 396 | /* |
| 397 | * Fill out some of the header fields ourselves because the | 397 | * Fill out some of the header fields ourselves because the |
| @@ -1229,3 +1229,9 @@ out: · 1228 unmodified lines | |||
| 1229 | return rv; | 1229 | return rv; |
| 1230 | } | 1230 | } |
| 1231 | EXPORT_SYMBOL_GPL(efivars_unregister); | 1231 | EXPORT_SYMBOL_GPL(efivars_unregister); |
| 1232 | |||
| 1233 | int efivar_supports_writes(void) | ||
| 1234 | { | ||
| 1235 | return __efivars && __efivars->ops->set_variable; | ||
| 1236 | } | ||
| 1237 | EXPORT_SYMBOL_GPL(efivar_supports_writes); | ||
| @@ -83,7 +83,8 @@ int __afu_port_disable(struct platform_device *pdev) · 82 unmodified lines | |||
| 83 | * on this port and minimum soft reset pulse width has elapsed. | 83 | * on this port and minimum soft reset pulse width has elapsed. |
| 84 | * Driver polls port_soft_reset_ack to determine if reset done by HW. | 84 | * Driver polls port_soft_reset_ack to determine if reset done by HW. |
| 85 | */ | 85 | */ |
| 86 | if (readq_poll_timeout(base + PORT_HDR_CTRL, v, v & PORT_CTRL_SFTRST, | 86 | if (readq_poll_timeout(base + PORT_HDR_CTRL, v, |
| 87 | v & PORT_CTRL_SFTRST_ACK, | ||
| 87 | RST_POLL_INVL, RST_POLL_TIMEOUT)) { | 88 | RST_POLL_INVL, RST_POLL_TIMEOUT)) { |
| 88 | dev_err(&pdev->dev, "timeout, fail to reset device\n"); | 89 | dev_err(&pdev->dev, "timeout, fail to reset device\n"); |
| 89 | return -ETIMEDOUT; | 90 | return -ETIMEDOUT; |
| @@ -227,7 +227,6 @@ static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs) · 226 unmodified lines | |||
| 227 | { | 227 | { |
| 228 | struct cci_drvdata *drvdata = pci_get_drvdata(pcidev); | 228 | struct cci_drvdata *drvdata = pci_get_drvdata(pcidev); |
| 229 | struct dfl_fpga_cdev *cdev = drvdata->cdev; | 229 | struct dfl_fpga_cdev *cdev = drvdata->cdev; |
| 230 | int ret = 0; | ||
| 231 | 230 | ||
| 232 | if (!num_vfs) { | 231 | if (!num_vfs) { |
| 233 | /* | 232 | /* |
| @@ -239,6 +238,8 @@ static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs) · 5 unmodified lines | |||
| 239 | dfl_fpga_cdev_config_ports_pf(cdev); | 238 | dfl_fpga_cdev_config_ports_pf(cdev); |
| 240 | 239 | ||
| 241 | } else { | 240 | } else { |
| 241 | int ret; | ||
| 242 | |||
| 242 | /* | 243 | /* |
| 243 | * before enable SRIOV, put released ports into VF access mode | 244 | * before enable SRIOV, put released ports into VF access mode |
| 244 | * first of all. | 245 | * first of all. |
| @@ -778,8 +778,7 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, · 777 unmodified lines | |||
| 778 | tmp_str++; | 778 | tmp_str++; |
| 779 | while (isspace(*++tmp_str)); | 779 | while (isspace(*++tmp_str)); |
| 780 | 780 | ||
| 781 | while (tmp_str[0]) { | 781 | while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { |
| 782 | sub_str = strsep(&tmp_str, delimiter); | ||
| 783 | ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); | 782 | ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); |
| 784 | if (ret) | 783 | if (ret) |
| 785 | return -EINVAL; | 784 | return -EINVAL; |
| @@ -1039,8 +1038,7 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask) · 253 unmodified lines | |||
| 1039 | memcpy(buf_cpy, buf, bytes); | 1038 | memcpy(buf_cpy, buf, bytes); |
| 1040 | buf_cpy[bytes] = '\0'; | 1039 | buf_cpy[bytes] = '\0'; |
| 1041 | tmp = buf_cpy; | 1040 | tmp = buf_cpy; |
| 1042 | while (tmp[0]) { | 1041 | while ((sub_str = strsep(&tmp, delimiter)) != NULL) { |
| 1043 | sub_str = strsep(&tmp, delimiter); | ||
| 1044 | if (strlen(sub_str)) { | 1042 | if (strlen(sub_str)) { |
| 1045 | ret = kstrtol(sub_str, 0, &level); | 1043 | ret = kstrtol(sub_str, 0, &level); |
| 1046 | if (ret) | 1044 | if (ret) |
| @@ -1637,8 +1635,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, · 590 unmodified lines | |||
| 1637 | i++; | 1635 | i++; |
| 1638 | memcpy(buf_cpy, buf, count-i); | 1636 | memcpy(buf_cpy, buf, count-i); |
| 1639 | tmp_str = buf_cpy; | 1637 | tmp_str = buf_cpy; |
| 1640 | while (tmp_str[0]) { | 1638 | while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { |
| 1641 | sub_str = strsep(&tmp_str, delimiter); | ||
| 1642 | ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); | 1639 | ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); |
| 1643 | if (ret) | 1640 | if (ret) |
| 1644 | return -EINVAL; | 1641 | return -EINVAL; |
| @@ -644,9 +644,6 @@ static int vegam_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, · 643 unmodified lines | |||
| 644 | 644 | ||
| 645 | /* sclk is bigger than max sclk in the dependence table */ | 645 | /* sclk is bigger than max sclk in the dependence table */ |
| 646 | *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; | 646 | *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; |
| 647 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), | ||
| 648 | (dep_table->entries[i - 1].vddc - | ||
| 649 | (uint16_t)VDDC_VDDCI_DELTA)); | ||
| 650 | 647 | ||
| 651 | if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) | 648 | if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) |
| 652 | *voltage |= (data->vbios_boot_state.vddci_bootup_value * | 649 | *voltage |= (data->vbios_boot_state.vddci_bootup_value * |
| @@ -654,8 +651,13 @@ static int vegam_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, · 1 unmodified line | |||
| 654 | else if (dep_table->entries[i - 1].vddci) | 651 | else if (dep_table->entries[i - 1].vddci) |
| 655 | *voltage |= (dep_table->entries[i - 1].vddci * | 652 | *voltage |= (dep_table->entries[i - 1].vddci * |
| 656 | VOLTAGE_SCALE) << VDDC_SHIFT; | 653 | VOLTAGE_SCALE) << VDDC_SHIFT; |
| 657 | else | 654 | else { |
| 655 | vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), | ||
| 656 | (dep_table->entries[i - 1].vddc - | ||
| 657 | (uint16_t)VDDC_VDDCI_DELTA)); | ||
| 658 | |||
| 658 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; | 659 | *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; |
| 660 | } | ||
| 659 | 661 | ||
| 660 | if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) | 662 | if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) |
| 661 | *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; | 663 | *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; |
| @@ -271,6 +271,8 @@ void lima_pp_fini(struct lima_ip *ip) · 270 unmodified lines | |||
| 271 | 271 | ||
| 272 | int lima_pp_bcast_resume(struct lima_ip *ip) | 272 | int lima_pp_bcast_resume(struct lima_ip *ip) |
| 273 | { | 273 | { |
| 274 | /* PP has been reset by individual PP resume */ | ||
| 275 | ip->data.async_reset = false; | ||
| 274 | return 0; | 276 | return 0; |
| 275 | } | 277 | } |
| 276 | 278 | ||
| @@ -260,7 +260,7 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force) · 259 unmodified lines | |||
| 260 | unsigned long reg; | 260 | unsigned long reg; |
| 261 | 261 | ||
| 262 | reg = readl(hdmi->base + SUN4I_HDMI_HPD_REG); | 262 | reg = readl(hdmi->base + SUN4I_HDMI_HPD_REG); |
| 263 | if (reg & SUN4I_HDMI_HPD_HIGH) { | 263 | if (!(reg & SUN4I_HDMI_HPD_HIGH)) { |
| 264 | cec_phys_addr_invalidate(hdmi->cec_adap); | 264 | cec_phys_addr_invalidate(hdmi->cec_adap); |
| 265 | return connector_status_disconnected; | 265 | return connector_status_disconnected; |
| 266 | } | 266 | } |
| @@ -421,20 +421,21 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr) · 420 unmodified lines | |||
| 421 | /* Read data if receive data valid is set */ | 421 | /* Read data if receive data valid is set */ |
| 422 | while (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & | 422 | while (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & |
| 423 | CDNS_I2C_SR_RXDV) { | 423 | CDNS_I2C_SR_RXDV) { |
| 424 | /* | ||
| 425 | * Clear hold bit that was set for FIFO control if | ||
| 426 | * RX data left is less than FIFO depth, unless | ||
| 427 | * repeated start is selected. | ||
| 428 | */ | ||
| 429 | if ((id->recv_count < CDNS_I2C_FIFO_DEPTH) && | ||
| 430 | !id->bus_hold_flag) | ||
| 431 | cdns_i2c_clear_bus_hold(id); | ||
| 432 | |||
| 433 | if (id->recv_count > 0) { | 424 | if (id->recv_count > 0) { |
| 434 | *(id->p_recv_buf)++ = | 425 | *(id->p_recv_buf)++ = |
| 435 | cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET); | 426 | cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET); |
| 436 | id->recv_count--; | 427 | id->recv_count--; |
| 437 | id->curr_recv_count--; | 428 | id->curr_recv_count--; |
| 429 | |||
| 430 | /* | ||
| 431 | * Clear hold bit that was set for FIFO control | ||
| 432 | * if RX data left is less than or equal to | ||
| 433 | * FIFO DEPTH unless repeated start is selected | ||
| 434 | */ | ||
| 435 | if (id->recv_count <= CDNS_I2C_FIFO_DEPTH && | ||
| 436 | !id->bus_hold_flag) | ||
| 437 | cdns_i2c_clear_bus_hold(id); | ||
| 438 | |||
| 438 | } else { | 439 | } else { |
| 439 | dev_err(id->adap.dev.parent, | 440 | dev_err(id->adap.dev.parent, |
| 440 | "xfer_size reg rollover. xfer aborted!\n"); | 441 | "xfer_size reg rollover. xfer aborted!\n"); |
| @@ -594,10 +595,8 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) · 153 unmodified lines | |||
| 594 | * Check for the message size against FIFO depth and set the | 595 | * Check for the message size against FIFO depth and set the |
| 595 | * 'hold bus' bit if it is greater than FIFO depth. | 596 | * 'hold bus' bit if it is greater than FIFO depth. |
| 596 | */ | 597 | */ |
| 597 | if ((id->recv_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag) | 598 | if (id->recv_count > CDNS_I2C_FIFO_DEPTH) |
| 598 | ctrl_reg |= CDNS_I2C_CR_HOLD; | 599 | ctrl_reg |= CDNS_I2C_CR_HOLD; |
| 599 | else | ||
| 600 | ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD; | ||
| 601 | 600 | ||
| 602 | cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); | 601 | cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); |
| 603 | 602 | ||
| @@ -654,11 +653,8 @@ static void cdns_i2c_msend(struct cdns_i2c *id) · 50 unmodified lines | |||
| 654 | * Check for the message size against FIFO depth and set the | 653 | * Check for the message size against FIFO depth and set the |
| 655 | * 'hold bus' bit if it is greater than FIFO depth. | 654 | * 'hold bus' bit if it is greater than FIFO depth. |
| 656 | */ | 655 | */ |
| 657 | if ((id->send_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag) | 656 | if (id->send_count > CDNS_I2C_FIFO_DEPTH) |
| 658 | ctrl_reg |= CDNS_I2C_CR_HOLD; | 657 | ctrl_reg |= CDNS_I2C_CR_HOLD; |
| 659 | else | ||
| 660 | ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD; | ||
| 661 | |||
| 662 | cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); | 658 | cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); |
| 663 | 659 | ||
| 664 | /* Clear the interrupts in interrupt status register. */ | 660 | /* Clear the interrupts in interrupt status register. */ |
| @@ -367,7 +367,6 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, · 366 unmodified lines | |||
| 367 | geni_se_select_mode(se, GENI_SE_FIFO); | 367 | geni_se_select_mode(se, GENI_SE_FIFO); |
| 368 | 368 | ||
| 369 | writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN); | 369 | writel_relaxed(len, se->base + SE_I2C_RX_TRANS_LEN); |
| 370 | geni_se_setup_m_cmd(se, I2C_READ, m_param); | ||
| 371 | 370 | ||
| 372 | if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) { | 371 | if (dma_buf && geni_se_rx_dma_prep(se, dma_buf, len, &rx_dma)) { |
| 373 | geni_se_select_mode(se, GENI_SE_FIFO); | 372 | geni_se_select_mode(se, GENI_SE_FIFO); |
| @@ -375,6 +374,8 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, · 1 unmodified line | |||
| 375 | dma_buf = NULL; | 374 | dma_buf = NULL; |
| 376 | } | 375 | } |
| 377 | 376 | ||
| 377 | geni_se_setup_m_cmd(se, I2C_READ, m_param); | ||
| 378 | |||
| 378 | time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); | 379 | time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); |
| 379 | if (!time_left) | 380 | if (!time_left) |
| 380 | geni_i2c_abort_xfer(gi2c); | 381 | geni_i2c_abort_xfer(gi2c); |
| @@ -408,7 +409,6 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, · 27 unmodified lines | |||
| 408 | geni_se_select_mode(se, GENI_SE_FIFO); | 409 | geni_se_select_mode(se, GENI_SE_FIFO); |
| 409 | 410 | ||
| 410 | writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN); | 411 | writel_relaxed(len, se->base + SE_I2C_TX_TRANS_LEN); |
| 411 | geni_se_setup_m_cmd(se, I2C_WRITE, m_param); | ||
| 412 | 412 | ||
| 413 | if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) { | 413 | if (dma_buf && geni_se_tx_dma_prep(se, dma_buf, len, &tx_dma)) { |
| 414 | geni_se_select_mode(se, GENI_SE_FIFO); | 414 | geni_se_select_mode(se, GENI_SE_FIFO); |
| @@ -416,6 +416,8 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, · 1 unmodified line | |||
| 416 | dma_buf = NULL; | 416 | dma_buf = NULL; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | geni_se_setup_m_cmd(se, I2C_WRITE, m_param); | ||
| 420 | |||
| 419 | if (!dma_buf) /* Get FIFO IRQ */ | 421 | if (!dma_buf) /* Get FIFO IRQ */ |
| 420 | writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG); | 422 | writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG); |
| 421 | 423 | ||
| @@ -868,6 +868,7 @@ static int rcar_unreg_slave(struct i2c_client *slave) · 867 unmodified lines | |||
| 868 | /* disable irqs and ensure none is running before clearing ptr */ | 868 | /* disable irqs and ensure none is running before clearing ptr */ |
| 869 | rcar_i2c_write(priv, ICSIER, 0); | 869 | rcar_i2c_write(priv, ICSIER, 0); |
| 870 | rcar_i2c_write(priv, ICSCR, 0); | 870 | rcar_i2c_write(priv, ICSCR, 0); |
| 871 | rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */ | ||
| 871 | 872 | ||
| 872 | synchronize_irq(priv->irq); | 873 | synchronize_irq(priv->irq); |
| 873 | priv->slave = NULL; | 874 | priv->slave = NULL; |
| @@ -969,6 +970,8 @@ static int rcar_i2c_probe(struct platform_device *pdev) · 95 unmodified lines | |||
| 969 | if (ret < 0) | 970 | if (ret < 0) |
| 970 | goto out_pm_put; | 971 | goto out_pm_put; |
| 971 | 972 | ||
| 973 | rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */ | ||
| 974 | |||
| 972 | if (priv->devtype == I2C_RCAR_GEN3) { | 975 | if (priv->devtype == I2C_RCAR_GEN3) { |
| 973 | priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); | 976 | priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
| 974 | if (!IS_ERR(priv->rstc)) { | 977 | if (!IS_ERR(priv->rstc)) { |
| @@ -3676,10 +3676,12 @@ static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv, · 3675 unmodified lines | |||
| 3676 | return ret; | 3676 | return ret; |
| 3677 | } | 3677 | } |
| 3678 | cm_id_priv->id.state = IB_CM_IDLE; | 3678 | cm_id_priv->id.state = IB_CM_IDLE; |
| 3679 | spin_lock_irq(&cm.lock); | ||
| 3679 | if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) { | 3680 | if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) { |
| 3680 | rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); | 3681 | rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); |
| 3681 | RB_CLEAR_NODE(&cm_id_priv->sidr_id_node); | 3682 | RB_CLEAR_NODE(&cm_id_priv->sidr_id_node); |
| 3682 | } | 3683 | } |
| 3684 | spin_unlock_irq(&cm.lock); | ||
| 3683 | return 0; | 3685 | return 0; |
| 3684 | } | 3686 | } |
| 3685 | 3687 | ||
| @@ -649,9 +649,6 @@ void rdma_alloc_commit_uobject(struct ib_uobject *uobj, · 648 unmodified lines | |||
| 649 | { | 649 | { |
| 650 | struct ib_uverbs_file *ufile = attrs->ufile; | 650 | struct ib_uverbs_file *ufile = attrs->ufile; |
| 651 | 651 | ||
| 652 | /* alloc_commit consumes the uobj kref */ | ||
| 653 | uobj->uapi_object->type_class->alloc_commit(uobj); | ||
| 654 | |||
| 655 | /* kref is held so long as the uobj is on the uobj list. */ | 652 | /* kref is held so long as the uobj is on the uobj list. */ |
| 656 | uverbs_uobject_get(uobj); | 653 | uverbs_uobject_get(uobj); |
| 657 | spin_lock_irq(&ufile->uobjects_lock); | 654 | spin_lock_irq(&ufile->uobjects_lock); |
| @@ -661,6 +658,9 @@ void rdma_alloc_commit_uobject(struct ib_uobject *uobj, · 3 unmodified lines | |||
| 661 | /* matches atomic_set(-1) in alloc_uobj */ | 658 | /* matches atomic_set(-1) in alloc_uobj */ |
| 662 | atomic_set(&uobj->usecnt, 0); | 659 | atomic_set(&uobj->usecnt, 0); |
| 663 | 660 | ||
| 661 | /* alloc_commit consumes the uobj kref */ | ||
| 662 | uobj->uapi_object->type_class->alloc_commit(uobj); | ||
| 663 | |||
| 664 | /* Matches the down_read in rdma_alloc_begin_uobject */ | 664 | /* Matches the down_read in rdma_alloc_begin_uobject */ |
| 665 | up_read(&ufile->hw_destroy_rwsem); | 665 | up_read(&ufile->hw_destroy_rwsem); |
| 666 | } | 666 | } |
| @@ -3954,6 +3954,15 @@ static int config_qp_sq_buf(struct hns_roce_dev *hr_dev, · 3953 unmodified lines | |||
| 3954 | return 0; | 3954 | return 0; |
| 3955 | } | 3955 | } |
| 3956 | 3956 | ||
| 3957 | static inline enum ib_mtu get_mtu(struct ib_qp *ibqp, | ||
| 3958 | const struct ib_qp_attr *attr) | ||
| 3959 | { | ||
| 3960 | if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD) | ||
| 3961 | return IB_MTU_4096; | ||
| 3962 | |||
| 3963 | return attr->path_mtu; | ||
| 3964 | } | ||
| 3965 | |||
| 3957 | static int modify_qp_init_to_rtr(struct ib_qp *ibqp, | 3966 | static int modify_qp_init_to_rtr(struct ib_qp *ibqp, |
| 3958 | const struct ib_qp_attr *attr, int attr_mask, | 3967 | const struct ib_qp_attr *attr, int attr_mask, |
| 3959 | struct hns_roce_v2_qp_context *context, | 3968 | struct hns_roce_v2_qp_context *context, |
| @@ -3965,6 +3974,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, · 5 unmodified lines | |||
| 3965 | struct ib_device *ibdev = &hr_dev->ib_dev; | 3974 | struct ib_device *ibdev = &hr_dev->ib_dev; |
| 3966 | dma_addr_t trrl_ba; | 3975 | dma_addr_t trrl_ba; |
| 3967 | dma_addr_t irrl_ba; | 3976 | dma_addr_t irrl_ba; |
| 3977 | enum ib_mtu mtu; | ||
| 3968 | u8 port_num; | 3978 | u8 port_num; |
| 3969 | u64 *mtts; | 3979 | u64 *mtts; |
| 3970 | u8 *dmac; | 3980 | u8 *dmac; |
| @@ -4062,23 +4072,23 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, · 91 unmodified lines | |||
| 4062 | roce_set_field(qpc_mask->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M, | 4072 | roce_set_field(qpc_mask->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M, |
| 4063 | V2_QPC_BYTE_52_DMAC_S, 0); | 4073 | V2_QPC_BYTE_52_DMAC_S, 0); |
| 4064 | 4074 | ||
| 4065 | /* mtu*(2^LP_PKTN_INI) should not bigger than 1 message length 64kb */ | 4075 | mtu = get_mtu(ibqp, attr); |
| 4076 | |||
| 4077 | if (attr_mask & IB_QP_PATH_MTU) { | ||
| 4078 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | ||
| 4079 | V2_QPC_BYTE_24_MTU_S, mtu); | ||
| 4080 | roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | ||
| 4081 | V2_QPC_BYTE_24_MTU_S, 0); | ||
| 4082 | } | ||
| 4083 | |||
| 4084 | #define MAX_LP_MSG_LEN 65536 | ||
| 4085 | /* MTU*(2^LP_PKTN_INI) shouldn't be bigger than 64kb */ | ||
| 4066 | roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M, | 4086 | roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M, |
| 4067 | V2_QPC_BYTE_56_LP_PKTN_INI_S, | 4087 | V2_QPC_BYTE_56_LP_PKTN_INI_S, |
| 4068 | ilog2(hr_dev->caps.max_sq_inline / IB_MTU_4096)); | 4088 | ilog2(MAX_LP_MSG_LEN / ib_mtu_enum_to_int(mtu))); |
| 4069 | roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M, | 4089 | roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M, |
| 4070 | V2_QPC_BYTE_56_LP_PKTN_INI_S, 0); | 4090 | V2_QPC_BYTE_56_LP_PKTN_INI_S, 0); |
| 4071 | 4091 | ||
| 4072 | if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_UD) | ||
| 4073 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | ||
| 4074 | V2_QPC_BYTE_24_MTU_S, IB_MTU_4096); | ||
| 4075 | else if (attr_mask & IB_QP_PATH_MTU) | ||
| 4076 | roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | ||
| 4077 | V2_QPC_BYTE_24_MTU_S, attr->path_mtu); | ||
| 4078 | |||
| 4079 | roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_MTU_M, | ||
| 4080 | V2_QPC_BYTE_24_MTU_S, 0); | ||
| 4081 | |||
| 4082 | roce_set_bit(qpc_mask->byte_108_rx_reqepsn, | 4092 | roce_set_bit(qpc_mask->byte_108_rx_reqepsn, |
| 4083 | V2_QPC_BYTE_108_RX_REQ_PSN_ERR_S, 0); | 4093 | V2_QPC_BYTE_108_RX_REQ_PSN_ERR_S, 0); |
| 4084 | roce_set_field(qpc_mask->byte_96_rx_reqmsn, V2_QPC_BYTE_96_RX_REQ_MSN_M, | 4094 | roce_set_field(qpc_mask->byte_96_rx_reqmsn, V2_QPC_BYTE_96_RX_REQ_MSN_M, |
| @@ -120,7 +120,7 @@ static int alloc_mr_pbl(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr, · 119 unmodified lines | |||
| 120 | 120 | ||
| 121 | mr->pbl_hop_num = is_fast ? 1 : hr_dev->caps.pbl_hop_num; | 121 | mr->pbl_hop_num = is_fast ? 1 : hr_dev->caps.pbl_hop_num; |
| 122 | buf_attr.page_shift = is_fast ? PAGE_SHIFT : | 122 | buf_attr.page_shift = is_fast ? PAGE_SHIFT : |
| 123 | hr_dev->caps.pbl_buf_pg_sz + HNS_HW_PAGE_SHIFT; | 123 | hr_dev->caps.pbl_buf_pg_sz + PAGE_SHIFT; |
| 124 | buf_attr.region[0].size = length; | 124 | buf_attr.region[0].size = length; |
| 125 | buf_attr.region[0].hopnum = mr->pbl_hop_num; | 125 | buf_attr.region[0].hopnum = mr->pbl_hop_num; |
| 126 | buf_attr.region_count = 1; | 126 | buf_attr.region_count = 1; |
| @@ -601,6 +601,23 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr) · 600 unmodified lines | |||
| 601 | */ | 601 | */ |
| 602 | synchronize_srcu(&dev->odp_srcu); | 602 | synchronize_srcu(&dev->odp_srcu); |
| 603 | 603 | ||
| 604 | /* | ||
| 605 | * All work on the prefetch list must be completed, xa_erase() prevented | ||
| 606 | * new work from being created. | ||
| 607 | */ | ||
| 608 | wait_event(imr->q_deferred_work, !atomic_read(&imr->num_deferred_work)); | ||
| 609 | |||
| 610 | /* | ||
| 611 | * At this point it is forbidden for any other thread to enter | ||
| 612 | * pagefault_mr() on this imr. It is already forbidden to call | ||
| 613 | * pagefault_mr() on an implicit child. Due to this additions to | ||
| 614 | * implicit_children are prevented. | ||
| 615 | */ | ||
| 616 | |||
| 617 | /* | ||
| 618 | * Block destroy_unused_implicit_child_mr() from incrementing | ||
| 619 | * num_deferred_work. | ||
| 620 | */ | ||
| 604 | xa_lock(&imr->implicit_children); | 621 | xa_lock(&imr->implicit_children); |
| 605 | xa_for_each (&imr->implicit_children, idx, mtt) { | 622 | xa_for_each (&imr->implicit_children, idx, mtt) { |
| 606 | __xa_erase(&imr->implicit_children, idx); | 623 | __xa_erase(&imr->implicit_children, idx); |
| @@ -609,9 +626,8 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr) · 2 unmodified lines | |||
| 609 | xa_unlock(&imr->implicit_children); | 626 | xa_unlock(&imr->implicit_children); |
| 610 | 627 | ||
| 611 | /* | 628 | /* |
| 612 | * num_deferred_work can only be incremented inside the odp_srcu, or | 629 | * Wait for any concurrent destroy_unused_implicit_child_mr() to |
| 613 | * under xa_lock while the child is in the xarray. Thus at this point | 630 | * complete. |
| 614 | * it is only decreasing, and all work holding it is now on the wq. | ||
| 615 | */ | 631 | */ |
| 616 | wait_event(imr->q_deferred_work, !atomic_read(&imr->num_deferred_work)); | 632 | wait_event(imr->q_deferred_work, !atomic_read(&imr->num_deferred_work)); |
| 617 | 633 | ||
| @@ -83,11 +83,11 @@ struct mlx5_core_srq *mlx5_cmd_get_srq(struct mlx5_ib_dev *dev, u32 srqn) · 82 unmodified lines | |||
| 83 | struct mlx5_srq_table *table = &dev->srq_table; | 83 | struct mlx5_srq_table *table = &dev->srq_table; |
| 84 | struct mlx5_core_srq *srq; | 84 | struct mlx5_core_srq *srq; |
| 85 | 85 | ||
| 86 | xa_lock(&table->array); | 86 | xa_lock_irq(&table->array); |
| 87 | srq = xa_load(&table->array, srqn); | 87 | srq = xa_load(&table->array, srqn); |
| 88 | if (srq) | 88 | if (srq) |
| 89 | refcount_inc(&srq->common.refcount); | 89 | refcount_inc(&srq->common.refcount); |
| 90 | xa_unlock(&table->array); | 90 | xa_unlock_irq(&table->array); |
| 91 | 91 | ||
| 92 | return srq; | 92 | return srq; |
| 93 | } | 93 | } |
| @@ -243,6 +243,7 @@ static int aggregate_requests(struct icc_node *node) · 242 unmodified lines | |||
| 243 | { | 243 | { |
| 244 | struct icc_provider *p = node->provider; | 244 | struct icc_provider *p = node->provider; |
| 245 | struct icc_req *r; | 245 | struct icc_req *r; |
| 246 | u32 avg_bw, peak_bw; | ||
| 246 | 247 | ||
| 247 | node->avg_bw = 0; | 248 | node->avg_bw = 0; |
| 248 | node->peak_bw = 0; | 249 | node->peak_bw = 0; |
| @@ -251,9 +252,14 @@ static int aggregate_requests(struct icc_node *node) · 2 unmodified lines | |||
| 251 | p->pre_aggregate(node); | 252 | p->pre_aggregate(node); |
| 252 | 253 | ||
| 253 | hlist_for_each_entry(r, &node->req_list, req_node) { | 254 | hlist_for_each_entry(r, &node->req_list, req_node) { |
| 254 | if (!r->enabled) | 255 | if (r->enabled) { |
| 255 | continue; | 256 | avg_bw = r->avg_bw; |
| 256 | p->aggregate(node, r->tag, r->avg_bw, r->peak_bw, | 257 | peak_bw = r->peak_bw; |
| 258 | } else { | ||
| 259 | avg_bw = 0; | ||
| 260 | peak_bw = 0; | ||
| 261 | } | ||
| 262 | p->aggregate(node, r->tag, avg_bw, peak_bw, | ||
| 257 | &node->avg_bw, &node->peak_bw); | 263 | &node->avg_bw, &node->peak_bw); |
| 258 | } | 264 | } |
| 259 | 265 | ||
| @@ -197,13 +197,13 @@ DEFINE_QNODE(pcnoc_int_0, MSM8916_PNOC_INT_0, 8, -1, -1, MSM8916_PNOC_SNOC_MAS, · 196 unmodified lines | |||
| 197 | DEFINE_QNODE(pcnoc_int_1, MSM8916_PNOC_INT_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); | 197 | DEFINE_QNODE(pcnoc_int_1, MSM8916_PNOC_INT_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); |
| 198 | DEFINE_QNODE(pcnoc_m_0, MSM8916_PNOC_MAS_0, 8, -1, -1, MSM8916_PNOC_INT_0); | 198 | DEFINE_QNODE(pcnoc_m_0, MSM8916_PNOC_MAS_0, 8, -1, -1, MSM8916_PNOC_INT_0); |
| 199 | DEFINE_QNODE(pcnoc_m_1, MSM8916_PNOC_MAS_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); | 199 | DEFINE_QNODE(pcnoc_m_1, MSM8916_PNOC_MAS_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); |
| 200 | DEFINE_QNODE(pcnoc_s_0, MSM8916_PNOC_SLV_0, 8, -1, -1, MSM8916_SLAVE_CLK_CTL, MSM8916_SLAVE_TLMM, MSM8916_SLAVE_TCSR, MSM8916_SLAVE_SECURITY, MSM8916_SLAVE_MSS); | 200 | DEFINE_QNODE(pcnoc_s_0, MSM8916_PNOC_SLV_0, 4, -1, -1, MSM8916_SLAVE_CLK_CTL, MSM8916_SLAVE_TLMM, MSM8916_SLAVE_TCSR, MSM8916_SLAVE_SECURITY, MSM8916_SLAVE_MSS); |
| 201 | DEFINE_QNODE(pcnoc_s_1, MSM8916_PNOC_SLV_1, 8, -1, -1, MSM8916_SLAVE_IMEM_CFG, MSM8916_SLAVE_CRYPTO_0_CFG, MSM8916_SLAVE_MSG_RAM, MSM8916_SLAVE_PDM, MSM8916_SLAVE_PRNG); | 201 | DEFINE_QNODE(pcnoc_s_1, MSM8916_PNOC_SLV_1, 4, -1, -1, MSM8916_SLAVE_IMEM_CFG, MSM8916_SLAVE_CRYPTO_0_CFG, MSM8916_SLAVE_MSG_RAM, MSM8916_SLAVE_PDM, MSM8916_SLAVE_PRNG); |
| 202 | DEFINE_QNODE(pcnoc_s_2, MSM8916_PNOC_SLV_2, 8, -1, -1, MSM8916_SLAVE_SPDM, MSM8916_SLAVE_BOOT_ROM, MSM8916_SLAVE_BIMC_CFG, MSM8916_SLAVE_PNOC_CFG, MSM8916_SLAVE_PMIC_ARB); | 202 | DEFINE_QNODE(pcnoc_s_2, MSM8916_PNOC_SLV_2, 4, -1, -1, MSM8916_SLAVE_SPDM, MSM8916_SLAVE_BOOT_ROM, MSM8916_SLAVE_BIMC_CFG, MSM8916_SLAVE_PNOC_CFG, MSM8916_SLAVE_PMIC_ARB); |
| 203 | DEFINE_QNODE(pcnoc_s_3, MSM8916_PNOC_SLV_3, 8, -1, -1, MSM8916_SLAVE_MPM, MSM8916_SLAVE_SNOC_CFG, MSM8916_SLAVE_RBCPR_CFG, MSM8916_SLAVE_QDSS_CFG, MSM8916_SLAVE_DEHR_CFG); | 203 | DEFINE_QNODE(pcnoc_s_3, MSM8916_PNOC_SLV_3, 4, -1, -1, MSM8916_SLAVE_MPM, MSM8916_SLAVE_SNOC_CFG, MSM8916_SLAVE_RBCPR_CFG, MSM8916_SLAVE_QDSS_CFG, MSM8916_SLAVE_DEHR_CFG); |
| 204 | DEFINE_QNODE(pcnoc_s_4, MSM8916_PNOC_SLV_4, 8, -1, -1, MSM8916_SLAVE_VENUS_CFG, MSM8916_SLAVE_CAMERA_CFG, MSM8916_SLAVE_DISPLAY_CFG); | 204 | DEFINE_QNODE(pcnoc_s_4, MSM8916_PNOC_SLV_4, 4, -1, -1, MSM8916_SLAVE_VENUS_CFG, MSM8916_SLAVE_CAMERA_CFG, MSM8916_SLAVE_DISPLAY_CFG); |
| 205 | DEFINE_QNODE(pcnoc_s_8, MSM8916_PNOC_SLV_8, 8, -1, -1, MSM8916_SLAVE_USB_HS, MSM8916_SLAVE_SDCC_1, MSM8916_SLAVE_BLSP_1); | 205 | DEFINE_QNODE(pcnoc_s_8, MSM8916_PNOC_SLV_8, 4, -1, -1, MSM8916_SLAVE_USB_HS, MSM8916_SLAVE_SDCC_1, MSM8916_SLAVE_BLSP_1); |
| 206 | DEFINE_QNODE(pcnoc_s_9, MSM8916_PNOC_SLV_9, 8, -1, -1, MSM8916_SLAVE_SDCC_2, MSM8916_SLAVE_LPASS, MSM8916_SLAVE_GRAPHICS_3D_CFG); | 206 | DEFINE_QNODE(pcnoc_s_9, MSM8916_PNOC_SLV_9, 4, -1, -1, MSM8916_SLAVE_SDCC_2, MSM8916_SLAVE_LPASS, MSM8916_SLAVE_GRAPHICS_3D_CFG); |
| 207 | DEFINE_QNODE(pcnoc_snoc_mas, MSM8916_PNOC_SNOC_MAS, 8, 29, -1, MSM8916_PNOC_SNOC_SLV); | 207 | DEFINE_QNODE(pcnoc_snoc_mas, MSM8916_PNOC_SNOC_MAS, 8, 29, -1, MSM8916_PNOC_SNOC_SLV); |
| 208 | DEFINE_QNODE(pcnoc_snoc_slv, MSM8916_PNOC_SNOC_SLV, 8, -1, 45, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC, MSM8916_SNOC_INT_1); | 208 | DEFINE_QNODE(pcnoc_snoc_slv, MSM8916_PNOC_SNOC_SLV, 8, -1, 45, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC, MSM8916_SNOC_INT_1); |
| 209 | DEFINE_QNODE(qdss_int, MSM8916_SNOC_QDSS_INT, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC); | 209 | DEFINE_QNODE(qdss_int, MSM8916_SNOC_QDSS_INT, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC); |
| @@ -65,6 +65,7 @@ struct qcom_iommu_domain { · 64 unmodified lines | |||
| 65 | struct mutex init_mutex; /* Protects iommu pointer */ | 65 | struct mutex init_mutex; /* Protects iommu pointer */ |
| 66 | struct iommu_domain domain; | 66 | struct iommu_domain domain; |
| 67 | struct qcom_iommu_dev *iommu; | 67 | struct qcom_iommu_dev *iommu; |
| 68 | struct iommu_fwspec *fwspec; | ||
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| 70 | static struct qcom_iommu_domain *to_qcom_iommu_domain(struct iommu_domain *dom) | 71 | static struct qcom_iommu_domain *to_qcom_iommu_domain(struct iommu_domain *dom) |
| @@ -84,9 +85,9 @@ static struct qcom_iommu_dev * to_iommu(struct device *dev) · 13 unmodified lines | |||
| 84 | return dev_iommu_priv_get(dev); | 85 | return dev_iommu_priv_get(dev); |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | static struct qcom_iommu_ctx * to_ctx(struct device *dev, unsigned asid) | 88 | static struct qcom_iommu_ctx * to_ctx(struct qcom_iommu_domain *d, unsigned asid) |
| 88 | { | 89 | { |
| 89 | struct qcom_iommu_dev *qcom_iommu = to_iommu(dev); | 90 | struct qcom_iommu_dev *qcom_iommu = d->iommu; |
| 90 | if (!qcom_iommu) | 91 | if (!qcom_iommu) |
| 91 | return NULL; | 92 | return NULL; |
| 92 | return qcom_iommu->ctxs[asid - 1]; | 93 | return qcom_iommu->ctxs[asid - 1]; |
| @@ -118,14 +119,12 @@ iommu_readq(struct qcom_iommu_ctx *ctx, unsigned reg) · 25 unmodified lines | |||
| 118 | 119 | ||
| 119 | static void qcom_iommu_tlb_sync(void *cookie) | 120 | static void qcom_iommu_tlb_sync(void *cookie) |
| 120 | { | 121 | { |
| 121 | struct iommu_fwspec *fwspec; | 122 | struct qcom_iommu_domain *qcom_domain = cookie; |
| 122 | struct device *dev = cookie; | 123 | struct iommu_fwspec *fwspec = qcom_domain->fwspec; |
| 123 | unsigned i; | 124 | unsigned i; |
| 124 | 125 | ||
| 125 | fwspec = dev_iommu_fwspec_get(dev); | ||
| 126 | |||
| 127 | for (i = 0; i < fwspec->num_ids; i++) { | 126 | for (i = 0; i < fwspec->num_ids; i++) { |
| 128 | struct qcom_iommu_ctx *ctx = to_ctx(dev, fwspec->ids[i]); | 127 | struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, fwspec->ids[i]); |
| 129 | unsigned int val, ret; | 128 | unsigned int val, ret; |
| 130 | 129 | ||
| 131 | iommu_writel(ctx, ARM_SMMU_CB_TLBSYNC, 0); | 130 | iommu_writel(ctx, ARM_SMMU_CB_TLBSYNC, 0); |
| @@ -139,14 +138,12 @@ static void qcom_iommu_tlb_sync(void *cookie) · 7 unmodified lines | |||
| 139 | 138 | ||
| 140 | static void qcom_iommu_tlb_inv_context(void *cookie) | 139 | static void qcom_iommu_tlb_inv_context(void *cookie) |
| 141 | { | 140 | { |
| 142 | struct device *dev = cookie; | 141 | struct qcom_iommu_domain *qcom_domain = cookie; |
| 143 | struct iommu_fwspec *fwspec; | 142 | struct iommu_fwspec *fwspec = qcom_domain->fwspec; |
| 144 | unsigned i; | 143 | unsigned i; |
| 145 | 144 | ||
| 146 | fwspec = dev_iommu_fwspec_get(dev); | ||
| 147 | |||
| 148 | for (i = 0; i < fwspec->num_ids; i++) { | 145 | for (i = 0; i < fwspec->num_ids; i++) { |
| 149 | struct qcom_iommu_ctx *ctx = to_ctx(dev, fwspec->ids[i]); | 146 | struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, fwspec->ids[i]); |
| 150 | iommu_writel(ctx, ARM_SMMU_CB_S1_TLBIASID, ctx->asid); | 147 | iommu_writel(ctx, ARM_SMMU_CB_S1_TLBIASID, ctx->asid); |
| 151 | } | 148 | } |
| 152 | 149 | ||
| @@ -156,16 +153,14 @@ static void qcom_iommu_tlb_inv_context(void *cookie) · 3 unmodified lines | |||
| 156 | static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size, | 153 | static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size, |
| 157 | size_t granule, bool leaf, void *cookie) | 154 | size_t granule, bool leaf, void *cookie) |
| 158 | { | 155 | { |
| 159 | struct device *dev = cookie; | 156 | struct qcom_iommu_domain *qcom_domain = cookie; |
| 160 | struct iommu_fwspec *fwspec; | 157 | struct iommu_fwspec *fwspec = qcom_domain->fwspec; |
| 161 | unsigned i, reg; | 158 | unsigned i, reg; |
| 162 | 159 | ||
| 163 | reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA; | 160 | reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA; |
| 164 | 161 | ||
| 165 | fwspec = dev_iommu_fwspec_get(dev); | ||
| 166 | |||
| 167 | for (i = 0; i < fwspec->num_ids; i++) { | 162 | for (i = 0; i < fwspec->num_ids; i++) { |
| 168 | struct qcom_iommu_ctx *ctx = to_ctx(dev, fwspec->ids[i]); | 163 | struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, fwspec->ids[i]); |
| 169 | size_t s = size; | 164 | size_t s = size; |
| 170 | 165 | ||
| 171 | iova = (iova >> 12) << 12; | 166 | iova = (iova >> 12) << 12; |
| @@ -256,7 +251,9 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, · 84 unmodified lines | |||
| 256 | }; | 251 | }; |
| 257 | 252 | ||
| 258 | qcom_domain->iommu = qcom_iommu; | 253 | qcom_domain->iommu = qcom_iommu; |
| 259 | pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, dev); | 254 | qcom_domain->fwspec = fwspec; |
| 255 | |||
| 256 | pgtbl_ops = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &pgtbl_cfg, qcom_domain); | ||
| 260 | if (!pgtbl_ops) { | 257 | if (!pgtbl_ops) { |
| 261 | dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n"); | 258 | dev_err(qcom_iommu->dev, "failed to allocate pagetable ops\n"); |
| 262 | ret = -ENOMEM; | 259 | ret = -ENOMEM; |
| @@ -269,7 +266,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain, · 6 unmodified lines | |||
| 269 | domain->geometry.force_aperture = true; | 266 | domain->geometry.force_aperture = true; |
| 270 | 267 | ||
| 271 | for (i = 0; i < fwspec->num_ids; i++) { | 268 | for (i = 0; i < fwspec->num_ids; i++) { |
| 272 | struct qcom_iommu_ctx *ctx = to_ctx(dev, fwspec->ids[i]); | 269 | struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, fwspec->ids[i]); |
| 273 | 270 | ||
| 274 | if (!ctx->secure_init) { | 271 | if (!ctx->secure_init) { |
| 275 | ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, ctx->asid); | 272 | ret = qcom_scm_restore_sec_cfg(qcom_iommu->sec_id, ctx->asid); |
| @@ -419,7 +416,7 @@ static void qcom_iommu_detach_dev(struct iommu_domain *domain, struct device *de · 143 unmodified lines | |||
| 419 | 416 | ||
| 420 | pm_runtime_get_sync(qcom_iommu->dev); | 417 | pm_runtime_get_sync(qcom_iommu->dev); |
| 421 | for (i = 0; i < fwspec->num_ids; i++) { | 418 | for (i = 0; i < fwspec->num_ids; i++) { |
| 422 | struct qcom_iommu_ctx *ctx = to_ctx(dev, fwspec->ids[i]); | 419 | struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, fwspec->ids[i]); |
| 423 | 420 | ||
| 424 | /* Disable the context bank: */ | 421 | /* Disable the context bank: */ |
| 425 | iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); | 422 | iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); |
| @@ -2420,7 +2420,7 @@ static void integrity_writer(struct work_struct *w) · 2419 unmodified lines | |||
| 2420 | unsigned prev_free_sectors; | 2420 | unsigned prev_free_sectors; |
| 2421 | 2421 | ||
| 2422 | /* the following test is not needed, but it tests the replay code */ | 2422 | /* the following test is not needed, but it tests the replay code */ |
| 2423 | if (unlikely(dm_suspended(ic->ti)) && !ic->meta_dev) | 2423 | if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev) |
| 2424 | return; | 2424 | return; |
| 2425 | 2425 | ||
| 2426 | spin_lock_irq(&ic->endio_wait.lock); | 2426 | spin_lock_irq(&ic->endio_wait.lock); |
| @@ -2481,7 +2481,7 @@ static void integrity_recalc(struct work_struct *w) · 54 unmodified lines | |||
| 2481 | 2481 | ||
| 2482 | next_chunk: | 2482 | next_chunk: |
| 2483 | 2483 | ||
| 2484 | if (unlikely(dm_suspended(ic->ti))) | 2484 | if (unlikely(dm_post_suspending(ic->ti))) |
| 2485 | goto unlock_ret; | 2485 | goto unlock_ret; |
| 2486 | 2486 | ||
| 2487 | range.logical_sector = le64_to_cpu(ic->sb->recalc_sector); | 2487 | range.logical_sector = le64_to_cpu(ic->sb->recalc_sector); |
| @@ -143,6 +143,7 @@ EXPORT_SYMBOL_GPL(dm_bio_get_target_bio_nr); · 142 unmodified lines | |||
| 143 | #define DMF_NOFLUSH_SUSPENDING 5 | 143 | #define DMF_NOFLUSH_SUSPENDING 5 |
| 144 | #define DMF_DEFERRED_REMOVE 6 | 144 | #define DMF_DEFERRED_REMOVE 6 |
| 145 | #define DMF_SUSPENDED_INTERNALLY 7 | 145 | #define DMF_SUSPENDED_INTERNALLY 7 |
| 146 | #define DMF_POST_SUSPENDING 8 | ||
| 146 | 147 | ||
| 147 | #define DM_NUMA_NODE NUMA_NO_NODE | 148 | #define DM_NUMA_NODE NUMA_NO_NODE |
| 148 | static int dm_numa_node = DM_NUMA_NODE; | 149 | static int dm_numa_node = DM_NUMA_NODE; |
| @@ -2408,6 +2409,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait) · 2259 unmodified lines | |||
| 2408 | if (!dm_suspended_md(md)) { | 2409 | if (!dm_suspended_md(md)) { |
| 2409 | dm_table_presuspend_targets(map); | 2410 | dm_table_presuspend_targets(map); |
| 2410 | set_bit(DMF_SUSPENDED, &md->flags); | 2411 | set_bit(DMF_SUSPENDED, &md->flags); |
| 2412 | set_bit(DMF_POST_SUSPENDING, &md->flags); | ||
| 2411 | dm_table_postsuspend_targets(map); | 2413 | dm_table_postsuspend_targets(map); |
| 2412 | } | 2414 | } |
| 2413 | /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ | 2415 | /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ |
| @@ -2766,7 +2768,9 @@ retry: · 352 unmodified lines | |||
| 2766 | if (r) | 2768 | if (r) |
| 2767 | goto out_unlock; | 2769 | goto out_unlock; |
| 2768 | 2770 | ||
| 2771 | set_bit(DMF_POST_SUSPENDING, &md->flags); | ||
| 2769 | dm_table_postsuspend_targets(map); | 2772 | dm_table_postsuspend_targets(map); |
| 2773 | clear_bit(DMF_POST_SUSPENDING, &md->flags); | ||
| 2770 | 2774 | ||
| 2771 | out_unlock: | 2775 | out_unlock: |
| 2772 | mutex_unlock(&md->suspend_lock); | 2776 | mutex_unlock(&md->suspend_lock); |
| @@ -2863,7 +2867,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla · 90 unmodified lines | |||
| 2863 | (void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE, | 2867 | (void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE, |
| 2864 | DMF_SUSPENDED_INTERNALLY); | 2868 | DMF_SUSPENDED_INTERNALLY); |
| 2865 | 2869 | ||
| 2870 | set_bit(DMF_POST_SUSPENDING, &md->flags); | ||
| 2866 | dm_table_postsuspend_targets(map); | 2871 | dm_table_postsuspend_targets(map); |
| 2872 | clear_bit(DMF_POST_SUSPENDING, &md->flags); | ||
| 2867 | } | 2873 | } |
| 2868 | 2874 | ||
| 2869 | static void __dm_internal_resume(struct mapped_device *md) | 2875 | static void __dm_internal_resume(struct mapped_device *md) |
| @@ -3024,6 +3030,11 @@ int dm_suspended_md(struct mapped_device *md) · 154 unmodified lines | |||
| 3024 | return test_bit(DMF_SUSPENDED, &md->flags); | 3030 | return test_bit(DMF_SUSPENDED, &md->flags); |
| 3025 | } | 3031 | } |
| 3026 | 3032 | ||
| 3033 | static int dm_post_suspending_md(struct mapped_device *md) | ||
| 3034 | { | ||
| 3035 | return test_bit(DMF_POST_SUSPENDING, &md->flags); | ||
| 3036 | } | ||
| 3037 | |||
| 3027 | int dm_suspended_internally_md(struct mapped_device *md) | 3038 | int dm_suspended_internally_md(struct mapped_device *md) |
| 3028 | { | 3039 | { |
| 3029 | return test_bit(DMF_SUSPENDED_INTERNALLY, &md->flags); | 3040 | return test_bit(DMF_SUSPENDED_INTERNALLY, &md->flags); |
| @@ -3040,6 +3051,12 @@ int dm_suspended(struct dm_target *ti) · 10 unmodified lines | |||
| 3040 | } | 3051 | } |
| 3041 | EXPORT_SYMBOL_GPL(dm_suspended); | 3052 | EXPORT_SYMBOL_GPL(dm_suspended); |
| 3042 | 3053 | ||
| 3054 | int dm_post_suspending(struct dm_target *ti) | ||
| 3055 | { | ||
| 3056 | return dm_post_suspending_md(dm_table_get_md(ti->table)); | ||
| 3057 | } | ||
| 3058 | EXPORT_SYMBOL_GPL(dm_post_suspending); | ||
| 3059 | |||
| 3043 | int dm_noflush_suspending(struct dm_target *ti) | 3060 | int dm_noflush_suspending(struct dm_target *ti) |
| 3044 | { | 3061 | { |
| 3045 | return __noflush_suspending(dm_table_get_md(ti->table)); | 3062 | return __noflush_suspending(dm_table_get_md(ti->table)); |
| @@ -499,11 +499,19 @@ static int validate_queue_index(struct hl_device *hdev, · 498 unmodified lines | |||
| 499 | struct asic_fixed_properties *asic = &hdev->asic_prop; | 499 | struct asic_fixed_properties *asic = &hdev->asic_prop; |
| 500 | struct hw_queue_properties *hw_queue_prop; | 500 | struct hw_queue_properties *hw_queue_prop; |
| 501 | 501 | ||
| 502 | /* This must be checked here to prevent out-of-bounds access to | ||
| 503 | * hw_queues_props array | ||
| 504 | */ | ||
| 505 | if (chunk->queue_index >= HL_MAX_QUEUES) { | ||
| 506 | dev_err(hdev->dev, "Queue index %d is invalid\n", | ||
| 507 | chunk->queue_index); | ||
| 508 | return -EINVAL; | ||
| 509 | } | ||
| 510 | |||
| 502 | hw_queue_prop = &asic->hw_queues_props[chunk->queue_index]; | 511 | hw_queue_prop = &asic->hw_queues_props[chunk->queue_index]; |
| 503 | 512 | ||
| 504 | if ((chunk->queue_index >= HL_MAX_QUEUES) || | 513 | if (hw_queue_prop->type == QUEUE_TYPE_NA) { |
| 505 | (hw_queue_prop->type == QUEUE_TYPE_NA)) { | 514 | dev_err(hdev->dev, "Queue index %d is not applicable\n", |
| 506 | dev_err(hdev->dev, "Queue index %d is invalid\n", | ||
| 507 | chunk->queue_index); | 515 | chunk->queue_index); |
| 508 | return -EINVAL; | 516 | return -EINVAL; |
| 509 | } | 517 | } |
| @@ -36,7 +36,7 @@ static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, · 35 unmodified lines | |||
| 36 | pkt.i2c_reg = i2c_reg; | 36 | pkt.i2c_reg = i2c_reg; |
| 37 | 37 | ||
| 38 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 38 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 39 | HL_DEVICE_TIMEOUT_USEC, (long *) val); | 39 | 0, (long *) val); |
| 40 | 40 | ||
| 41 | if (rc) | 41 | if (rc) |
| 42 | dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc); | 42 | dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc); |
| @@ -63,7 +63,7 @@ static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, · 20 unmodified lines | |||
| 63 | pkt.value = cpu_to_le64(val); | 63 | pkt.value = cpu_to_le64(val); |
| 64 | 64 | ||
| 65 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 65 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 66 | HL_DEVICE_TIMEOUT_USEC, NULL); | 66 | 0, NULL); |
| 67 | 67 | ||
| 68 | if (rc) | 68 | if (rc) |
| 69 | dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc); | 69 | dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc); |
| @@ -87,7 +87,7 @@ static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state) · 17 unmodified lines | |||
| 87 | pkt.value = cpu_to_le64(state); | 87 | pkt.value = cpu_to_le64(state); |
| 88 | 88 | ||
| 89 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 89 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 90 | HL_DEVICE_TIMEOUT_USEC, NULL); | 90 | 0, NULL); |
| 91 | 91 | ||
| 92 | if (rc) | 92 | if (rc) |
| 93 | dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc); | 93 | dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc); |
| @@ -981,7 +981,7 @@ static ssize_t hl_clk_gate_read(struct file *f, char __user *buf, · 887 unmodified lines | |||
| 981 | if (*ppos) | 981 | if (*ppos) |
| 982 | return 0; | 982 | return 0; |
| 983 | 983 | ||
| 984 | sprintf(tmp_buf, "%d\n", hdev->clock_gating); | 984 | sprintf(tmp_buf, "0x%llx\n", hdev->clock_gating_mask); |
| 985 | rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf, | 985 | rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf, |
| 986 | strlen(tmp_buf) + 1); | 986 | strlen(tmp_buf) + 1); |
| 987 | 987 | ||
| @@ -993,7 +993,7 @@ static ssize_t hl_clk_gate_write(struct file *f, const char __user *buf, · 5 unmodified lines | |||
| 993 | { | 993 | { |
| 994 | struct hl_dbg_device_entry *entry = file_inode(f)->i_private; | 994 | struct hl_dbg_device_entry *entry = file_inode(f)->i_private; |
| 995 | struct hl_device *hdev = entry->hdev; | 995 | struct hl_device *hdev = entry->hdev; |
| 996 | u32 value; | 996 | u64 value; |
| 997 | ssize_t rc; | 997 | ssize_t rc; |
| 998 | 998 | ||
| 999 | if (atomic_read(&hdev->in_reset)) { | 999 | if (atomic_read(&hdev->in_reset)) { |
| @@ -1002,19 +1002,12 @@ static ssize_t hl_clk_gate_write(struct file *f, const char __user *buf, · 2 unmodified lines | |||
| 1002 | return 0; | 1002 | return 0; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | rc = kstrtouint_from_user(buf, count, 10, &value); | 1005 | rc = kstrtoull_from_user(buf, count, 16, &value); |
| 1006 | if (rc) | 1006 | if (rc) |
| 1007 | return rc; | 1007 | return rc; |
| 1008 | 1008 | ||
| 1009 | if (value) { | 1009 | hdev->clock_gating_mask = value; |
| 1010 | hdev->clock_gating = 1; | 1010 | hdev->asic_funcs->set_clock_gating(hdev); |
| 1011 | if (hdev->asic_funcs->enable_clock_gating) | ||
| 1012 | hdev->asic_funcs->enable_clock_gating(hdev); | ||
| 1013 | } else { | ||
| 1014 | if (hdev->asic_funcs->disable_clock_gating) | ||
| 1015 | hdev->asic_funcs->disable_clock_gating(hdev); | ||
| 1016 | hdev->clock_gating = 0; | ||
| 1017 | } | ||
| 1018 | 1011 | ||
| 1019 | return count; | 1012 | return count; |
| 1020 | } | 1013 | } |
| @@ -608,7 +608,7 @@ int hl_device_set_debug_mode(struct hl_device *hdev, bool enable) · 607 unmodified lines | |||
| 608 | hdev->in_debug = 0; | 608 | hdev->in_debug = 0; |
| 609 | 609 | ||
| 610 | if (!hdev->hard_reset_pending) | 610 | if (!hdev->hard_reset_pending) |
| 611 | hdev->asic_funcs->enable_clock_gating(hdev); | 611 | hdev->asic_funcs->set_clock_gating(hdev); |
| 612 | 612 | ||
| 613 | goto out; | 613 | goto out; |
| 614 | } | 614 | } |
| @@ -61,7 +61,7 @@ int hl_fw_send_pci_access_msg(struct hl_device *hdev, u32 opcode) · 60 unmodified lines | |||
| 61 | pkt.ctl = cpu_to_le32(opcode << ARMCP_PKT_CTL_OPCODE_SHIFT); | 61 | pkt.ctl = cpu_to_le32(opcode << ARMCP_PKT_CTL_OPCODE_SHIFT); |
| 62 | 62 | ||
| 63 | return hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, | 63 | return hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, |
| 64 | sizeof(pkt), HL_DEVICE_TIMEOUT_USEC, NULL); | 64 | sizeof(pkt), 0, NULL); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, | 67 | int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, |
| @@ -144,7 +144,7 @@ int hl_fw_unmask_irq(struct hl_device *hdev, u16 event_type) · 76 unmodified lines | |||
| 144 | pkt.value = cpu_to_le64(event_type); | 144 | pkt.value = cpu_to_le64(event_type); |
| 145 | 145 | ||
| 146 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 146 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 147 | HL_DEVICE_TIMEOUT_USEC, &result); | 147 | 0, &result); |
| 148 | 148 | ||
| 149 | if (rc) | 149 | if (rc) |
| 150 | dev_err(hdev->dev, "failed to unmask RAZWI IRQ %d", event_type); | 150 | dev_err(hdev->dev, "failed to unmask RAZWI IRQ %d", event_type); |
| @@ -183,7 +183,7 @@ int hl_fw_unmask_irq_arr(struct hl_device *hdev, const u32 *irq_arr, · 32 unmodified lines | |||
| 183 | ARMCP_PKT_CTL_OPCODE_SHIFT); | 183 | ARMCP_PKT_CTL_OPCODE_SHIFT); |
| 184 | 184 | ||
| 185 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) pkt, | 185 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) pkt, |
| 186 | total_pkt_size, HL_DEVICE_TIMEOUT_USEC, &result); | 186 | total_pkt_size, 0, &result); |
| 187 | 187 | ||
| 188 | if (rc) | 188 | if (rc) |
| 189 | dev_err(hdev->dev, "failed to unmask IRQ array\n"); | 189 | dev_err(hdev->dev, "failed to unmask IRQ array\n"); |
| @@ -204,7 +204,7 @@ int hl_fw_test_cpu_queue(struct hl_device *hdev) · 14 unmodified lines | |||
| 204 | test_pkt.value = cpu_to_le64(ARMCP_PACKET_FENCE_VAL); | 204 | test_pkt.value = cpu_to_le64(ARMCP_PACKET_FENCE_VAL); |
| 205 | 205 | ||
| 206 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &test_pkt, | 206 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &test_pkt, |
| 207 | sizeof(test_pkt), HL_DEVICE_TIMEOUT_USEC, &result); | 207 | sizeof(test_pkt), 0, &result); |
| 208 | 208 | ||
| 209 | if (!rc) { | 209 | if (!rc) { |
| 210 | if (result != ARMCP_PACKET_FENCE_VAL) | 210 | if (result != ARMCP_PACKET_FENCE_VAL) |
| @@ -248,7 +248,7 @@ int hl_fw_send_heartbeat(struct hl_device *hdev) · 37 unmodified lines | |||
| 248 | hb_pkt.value = cpu_to_le64(ARMCP_PACKET_FENCE_VAL); | 248 | hb_pkt.value = cpu_to_le64(ARMCP_PACKET_FENCE_VAL); |
| 249 | 249 | ||
| 250 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &hb_pkt, | 250 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &hb_pkt, |
| 251 | sizeof(hb_pkt), HL_DEVICE_TIMEOUT_USEC, &result); | 251 | sizeof(hb_pkt), 0, &result); |
| 252 | 252 | ||
| 253 | if ((rc) || (result != ARMCP_PACKET_FENCE_VAL)) | 253 | if ((rc) || (result != ARMCP_PACKET_FENCE_VAL)) |
| 254 | rc = -EIO; | 254 | rc = -EIO; |
| @@ -80,6 +80,7 @@ · 79 unmodified lines | |||
| 80 | #define GAUDI_PLDM_QMAN0_TIMEOUT_USEC (HL_DEVICE_TIMEOUT_USEC * 30) | 80 | #define GAUDI_PLDM_QMAN0_TIMEOUT_USEC (HL_DEVICE_TIMEOUT_USEC * 30) |
| 81 | #define GAUDI_PLDM_TPC_KERNEL_WAIT_USEC (HL_DEVICE_TIMEOUT_USEC * 30) | 81 | #define GAUDI_PLDM_TPC_KERNEL_WAIT_USEC (HL_DEVICE_TIMEOUT_USEC * 30) |
| 82 | #define GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC 1000000 /* 1s */ | 82 | #define GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC 1000000 /* 1s */ |
| 83 | #define GAUDI_MSG_TO_CPU_TIMEOUT_USEC 4000000 /* 4s */ | ||
| 83 | 84 | ||
| 84 | #define GAUDI_QMAN0_FENCE_VAL 0x72E91AB9 | 85 | #define GAUDI_QMAN0_FENCE_VAL 0x72E91AB9 |
| 85 | 86 | ||
| @@ -98,6 +99,11 @@ · 12 unmodified lines | |||
| 98 | 99 | ||
| 99 | #define GAUDI_ARB_WDT_TIMEOUT 0x1000000 | 100 | #define GAUDI_ARB_WDT_TIMEOUT 0x1000000 |
| 100 | 101 | ||
| 102 | #define GAUDI_CLK_GATE_DEBUGFS_MASK (\ | ||
| 103 | BIT(GAUDI_ENGINE_ID_MME_0) |\ | ||
| 104 | BIT(GAUDI_ENGINE_ID_MME_2) |\ | ||
| 105 | GENMASK_ULL(GAUDI_ENGINE_ID_TPC_7, GAUDI_ENGINE_ID_TPC_0)) | ||
| 106 | |||
| 101 | static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { | 107 | static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { |
| 102 | "gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3", | 108 | "gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3", |
| 103 | "gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3", | 109 | "gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3", |
| @@ -106,14 +112,14 @@ static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { · 2 unmodified lines | |||
| 106 | }; | 112 | }; |
| 107 | 113 | ||
| 108 | static const u8 gaudi_dma_assignment[GAUDI_DMA_MAX] = { | 114 | static const u8 gaudi_dma_assignment[GAUDI_DMA_MAX] = { |
| 109 | [GAUDI_PCI_DMA_1] = 0, | 115 | [GAUDI_PCI_DMA_1] = GAUDI_ENGINE_ID_DMA_0, |
| 110 | [GAUDI_PCI_DMA_2] = 1, | 116 | [GAUDI_PCI_DMA_2] = GAUDI_ENGINE_ID_DMA_1, |
| 111 | [GAUDI_PCI_DMA_3] = 5, | 117 | [GAUDI_PCI_DMA_3] = GAUDI_ENGINE_ID_DMA_5, |
| 112 | [GAUDI_HBM_DMA_1] = 2, | 118 | [GAUDI_HBM_DMA_1] = GAUDI_ENGINE_ID_DMA_2, |
| 113 | [GAUDI_HBM_DMA_2] = 3, | 119 | [GAUDI_HBM_DMA_2] = GAUDI_ENGINE_ID_DMA_3, |
| 114 | [GAUDI_HBM_DMA_3] = 4, | 120 | [GAUDI_HBM_DMA_3] = GAUDI_ENGINE_ID_DMA_4, |
| 115 | [GAUDI_HBM_DMA_4] = 6, | 121 | [GAUDI_HBM_DMA_4] = GAUDI_ENGINE_ID_DMA_6, |
| 116 | [GAUDI_HBM_DMA_5] = 7 | 122 | [GAUDI_HBM_DMA_5] = GAUDI_ENGINE_ID_DMA_7 |
| 117 | }; | 123 | }; |
| 118 | 124 | ||
| 119 | static const u8 gaudi_cq_assignment[NUMBER_OF_CMPLT_QUEUES] = { | 125 | static const u8 gaudi_cq_assignment[NUMBER_OF_CMPLT_QUEUES] = { |
| @@ -1819,7 +1825,7 @@ static void gaudi_init_golden_registers(struct hl_device *hdev) · 1699 unmodified lines | |||
| 1819 | 1825 | ||
| 1820 | gaudi_init_rate_limiter(hdev); | 1826 | gaudi_init_rate_limiter(hdev); |
| 1821 | 1827 | ||
| 1822 | gaudi_disable_clock_gating(hdev); | 1828 | hdev->asic_funcs->disable_clock_gating(hdev); |
| 1823 | 1829 | ||
| 1824 | for (tpc_id = 0, tpc_offset = 0; | 1830 | for (tpc_id = 0, tpc_offset = 0; |
| 1825 | tpc_id < TPC_NUMBER_OF_ENGINES; | 1831 | tpc_id < TPC_NUMBER_OF_ENGINES; |
| @@ -2531,46 +2537,55 @@ static void gaudi_tpc_stall(struct hl_device *hdev) · 705 unmodified lines | |||
| 2531 | WREG32(mmTPC7_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT); | 2537 | WREG32(mmTPC7_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT); |
| 2532 | } | 2538 | } |
| 2533 | 2539 | ||
| 2534 | static void gaudi_enable_clock_gating(struct hl_device *hdev) | 2540 | static void gaudi_set_clock_gating(struct hl_device *hdev) |
| 2535 | { | 2541 | { |
| 2536 | struct gaudi_device *gaudi = hdev->asic_specific; | 2542 | struct gaudi_device *gaudi = hdev->asic_specific; |
| 2537 | u32 qman_offset; | 2543 | u32 qman_offset; |
| 2538 | int i; | 2544 | int i; |
| 2539 | 2545 | ||
| 2540 | if (!hdev->clock_gating) | ||
| 2541 | return; | ||
| 2542 | |||
| 2543 | if (gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) | ||
| 2544 | return; | ||
| 2545 | |||
| 2546 | /* In case we are during debug session, don't enable the clock gate | 2546 | /* In case we are during debug session, don't enable the clock gate |
| 2547 | * as it may interfere | 2547 | * as it may interfere |
| 2548 | */ | 2548 | */ |
| 2549 | if (hdev->in_debug) | 2549 | if (hdev->in_debug) |
| 2550 | return; | 2550 | return; |
| 2551 | 2551 | ||
| 2552 | for (i = 0, qman_offset = 0 ; i < PCI_DMA_NUMBER_OF_CHNLS ; i++) { | 2552 | for (i = GAUDI_PCI_DMA_1, qman_offset = 0 ; i < GAUDI_HBM_DMA_1 ; i++) { |
| 2553 | if (!(hdev->clock_gating_mask & | ||
| 2554 | (BIT_ULL(gaudi_dma_assignment[i])))) | ||
| 2555 | continue; | ||
| 2556 | |||
| 2553 | qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET; | 2557 | qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET; |
| 2554 | WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, QMAN_CGM1_PWR_GATE_EN); | 2558 | WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, QMAN_CGM1_PWR_GATE_EN); |
| 2555 | WREG32(mmDMA0_QM_CGM_CFG + qman_offset, | 2559 | WREG32(mmDMA0_QM_CGM_CFG + qman_offset, |
| 2556 | QMAN_UPPER_CP_CGM_PWR_GATE_EN); | 2560 | QMAN_UPPER_CP_CGM_PWR_GATE_EN); |
| 2557 | } | 2561 | } |
| 2558 | 2562 | ||
| 2559 | for (; i < HBM_DMA_NUMBER_OF_CHNLS ; i++) { | 2563 | for (i = GAUDI_HBM_DMA_1 ; i < GAUDI_DMA_MAX ; i++) { |
| 2564 | if (!(hdev->clock_gating_mask & | ||
| 2565 | (BIT_ULL(gaudi_dma_assignment[i])))) | ||
| 2566 | continue; | ||
| 2567 | |||
| 2560 | qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET; | 2568 | qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET; |
| 2561 | WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, QMAN_CGM1_PWR_GATE_EN); | 2569 | WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, QMAN_CGM1_PWR_GATE_EN); |
| 2562 | WREG32(mmDMA0_QM_CGM_CFG + qman_offset, | 2570 | WREG32(mmDMA0_QM_CGM_CFG + qman_offset, |
| 2563 | QMAN_COMMON_CP_CGM_PWR_GATE_EN); | 2571 | QMAN_COMMON_CP_CGM_PWR_GATE_EN); |
| 2564 | } | 2572 | } |
| 2565 | 2573 | ||
| 2566 | WREG32(mmMME0_QM_CGM_CFG1, QMAN_CGM1_PWR_GATE_EN); | 2574 | if (hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_0))) { |
| 2567 | WREG32(mmMME0_QM_CGM_CFG, | 2575 | WREG32(mmMME0_QM_CGM_CFG1, QMAN_CGM1_PWR_GATE_EN); |
| 2568 | QMAN_COMMON_CP_CGM_PWR_GATE_EN); | 2576 | WREG32(mmMME0_QM_CGM_CFG, QMAN_COMMON_CP_CGM_PWR_GATE_EN); |
| 2569 | WREG32(mmMME2_QM_CGM_CFG1, QMAN_CGM1_PWR_GATE_EN); | 2577 | } |
| 2570 | WREG32(mmMME2_QM_CGM_CFG, | 2578 | |
| 2571 | QMAN_COMMON_CP_CGM_PWR_GATE_EN); | 2579 | if (hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_2))) { |
| 2580 | WREG32(mmMME2_QM_CGM_CFG1, QMAN_CGM1_PWR_GATE_EN); | ||
| 2581 | WREG32(mmMME2_QM_CGM_CFG, QMAN_COMMON_CP_CGM_PWR_GATE_EN); | ||
| 2582 | } | ||
| 2572 | 2583 | ||
| 2573 | for (i = 0, qman_offset = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) { | 2584 | for (i = 0, qman_offset = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) { |
| 2585 | if (!(hdev->clock_gating_mask & | ||
| 2586 | (BIT_ULL(GAUDI_ENGINE_ID_TPC_0 + i)))) | ||
| 2587 | continue; | ||
| 2588 | |||
| 2574 | WREG32(mmTPC0_QM_CGM_CFG1 + qman_offset, | 2589 | WREG32(mmTPC0_QM_CGM_CFG1 + qman_offset, |
| 2575 | QMAN_CGM1_PWR_GATE_EN); | 2590 | QMAN_CGM1_PWR_GATE_EN); |
| 2576 | WREG32(mmTPC0_QM_CGM_CFG + qman_offset, | 2591 | WREG32(mmTPC0_QM_CGM_CFG + qman_offset, |
| @@ -2663,7 +2678,7 @@ static void gaudi_halt_engines(struct hl_device *hdev, bool hard_reset) · 86 unmodified lines | |||
| 2663 | gaudi_stop_hbm_dma_qmans(hdev); | 2678 | gaudi_stop_hbm_dma_qmans(hdev); |
| 2664 | gaudi_stop_pci_dma_qmans(hdev); | 2679 | gaudi_stop_pci_dma_qmans(hdev); |
| 2665 | 2680 | ||
| 2666 | gaudi_disable_clock_gating(hdev); | 2681 | hdev->asic_funcs->disable_clock_gating(hdev); |
| 2667 | 2682 | ||
| 2668 | msleep(wait_timeout_ms); | 2683 | msleep(wait_timeout_ms); |
| 2669 | 2684 | ||
| @@ -3003,7 +3018,7 @@ static int gaudi_hw_init(struct hl_device *hdev) · 333 unmodified lines | |||
| 3003 | 3018 | ||
| 3004 | gaudi_init_tpc_qmans(hdev); | 3019 | gaudi_init_tpc_qmans(hdev); |
| 3005 | 3020 | ||
| 3006 | gaudi_enable_clock_gating(hdev); | 3021 | hdev->asic_funcs->set_clock_gating(hdev); |
| 3007 | 3022 | ||
| 3008 | gaudi_enable_timestamp(hdev); | 3023 | gaudi_enable_timestamp(hdev); |
| 3009 | 3024 | ||
| @@ -3112,7 +3127,9 @@ static void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset) · 102 unmodified lines | |||
| 3112 | HW_CAP_HBM_DMA | HW_CAP_PLL | | 3127 | HW_CAP_HBM_DMA | HW_CAP_PLL | |
| 3113 | HW_CAP_MMU | | 3128 | HW_CAP_MMU | |
| 3114 | HW_CAP_SRAM_SCRAMBLER | | 3129 | HW_CAP_SRAM_SCRAMBLER | |
| 3115 | HW_CAP_HBM_SCRAMBLER); | 3130 | HW_CAP_HBM_SCRAMBLER | |
| 3131 | HW_CAP_CLK_GATE); | ||
| 3132 | |||
| 3116 | memset(gaudi->events_stat, 0, sizeof(gaudi->events_stat)); | 3133 | memset(gaudi->events_stat, 0, sizeof(gaudi->events_stat)); |
| 3117 | } | 3134 | } |
| 3118 | 3135 | ||
| @@ -3463,6 +3480,9 @@ static int gaudi_send_cpu_message(struct hl_device *hdev, u32 *msg, · 344 unmodified lines | |||
| 3463 | return 0; | 3480 | return 0; |
| 3464 | } | 3481 | } |
| 3465 | 3482 | ||
| 3483 | if (!timeout) | ||
| 3484 | timeout = GAUDI_MSG_TO_CPU_TIMEOUT_USEC; | ||
| 3485 | |||
| 3466 | return hl_fw_send_cpu_message(hdev, GAUDI_QUEUE_ID_CPU_PQ, msg, len, | 3486 | return hl_fw_send_cpu_message(hdev, GAUDI_QUEUE_ID_CPU_PQ, msg, len, |
| 3467 | timeout, result); | 3487 | timeout, result); |
| 3468 | } | 3488 | } |
| @@ -3865,6 +3885,12 @@ static int gaudi_validate_cb(struct hl_device *hdev, · 396 unmodified lines | |||
| 3865 | rc = -EPERM; | 3885 | rc = -EPERM; |
| 3866 | break; | 3886 | break; |
| 3867 | 3887 | ||
| 3888 | case PACKET_WREG_BULK: | ||
| 3889 | dev_err(hdev->dev, | ||
| 3890 | "User not allowed to use WREG_BULK\n"); | ||
| 3891 | rc = -EPERM; | ||
| 3892 | break; | ||
| 3893 | |||
| 3868 | case PACKET_LOAD_AND_EXE: | 3894 | case PACKET_LOAD_AND_EXE: |
| 3869 | rc = gaudi_validate_load_and_exe_pkt(hdev, parser, | 3895 | rc = gaudi_validate_load_and_exe_pkt(hdev, parser, |
| 3870 | (struct packet_load_and_exe *) user_pkt); | 3896 | (struct packet_load_and_exe *) user_pkt); |
| @@ -3880,7 +3906,6 @@ static int gaudi_validate_cb(struct hl_device *hdev, · 9 unmodified lines | |||
| 3880 | break; | 3906 | break; |
| 3881 | 3907 | ||
| 3882 | case PACKET_WREG_32: | 3908 | case PACKET_WREG_32: |
| 3883 | case PACKET_WREG_BULK: | ||
| 3884 | case PACKET_MSG_LONG: | 3909 | case PACKET_MSG_LONG: |
| 3885 | case PACKET_MSG_SHORT: | 3910 | case PACKET_MSG_SHORT: |
| 3886 | case PACKET_REPEAT: | 3911 | case PACKET_REPEAT: |
| @@ -4521,13 +4546,18 @@ static int gaudi_debugfs_read32(struct hl_device *hdev, u64 addr, u32 *val) · 634 unmodified lines | |||
| 4521 | int rc = 0; | 4546 | int rc = 0; |
| 4522 | 4547 | ||
| 4523 | if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) { | 4548 | if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) { |
| 4524 | if (gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) { | 4549 | |
| 4550 | if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) && | ||
| 4551 | (hdev->clock_gating_mask & | ||
| 4552 | GAUDI_CLK_GATE_DEBUGFS_MASK)) { | ||
| 4553 | |||
| 4525 | dev_err_ratelimited(hdev->dev, | 4554 | dev_err_ratelimited(hdev->dev, |
| 4526 | "Can't read register - clock gating is enabled!\n"); | 4555 | "Can't read register - clock gating is enabled!\n"); |
| 4527 | rc = -EFAULT; | 4556 | rc = -EFAULT; |
| 4528 | } else { | 4557 | } else { |
| 4529 | *val = RREG32(addr - CFG_BASE); | 4558 | *val = RREG32(addr - CFG_BASE); |
| 4530 | } | 4559 | } |
| 4560 | |||
| 4531 | } else if ((addr >= SRAM_BASE_ADDR) && | 4561 | } else if ((addr >= SRAM_BASE_ADDR) && |
| 4532 | (addr < SRAM_BASE_ADDR + SRAM_BAR_SIZE)) { | 4562 | (addr < SRAM_BASE_ADDR + SRAM_BAR_SIZE)) { |
| 4533 | *val = readl(hdev->pcie_bar[SRAM_BAR_ID] + | 4563 | *val = readl(hdev->pcie_bar[SRAM_BAR_ID] + |
| @@ -4563,13 +4593,18 @@ static int gaudi_debugfs_write32(struct hl_device *hdev, u64 addr, u32 val) · 29 unmodified lines | |||
| 4563 | int rc = 0; | 4593 | int rc = 0; |
| 4564 | 4594 | ||
| 4565 | if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) { | 4595 | if ((addr >= CFG_BASE) && (addr < CFG_BASE + CFG_SIZE)) { |
| 4566 | if (gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) { | 4596 | |
| 4597 | if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) && | ||
| 4598 | (hdev->clock_gating_mask & | ||
| 4599 | GAUDI_CLK_GATE_DEBUGFS_MASK)) { | ||
| 4600 | |||
| 4567 | dev_err_ratelimited(hdev->dev, | 4601 | dev_err_ratelimited(hdev->dev, |
| 4568 | "Can't write register - clock gating is enabled!\n"); | 4602 | "Can't write register - clock gating is enabled!\n"); |
| 4569 | rc = -EFAULT; | 4603 | rc = -EFAULT; |
| 4570 | } else { | 4604 | } else { |
| 4571 | WREG32(addr - CFG_BASE, val); | 4605 | WREG32(addr - CFG_BASE, val); |
| 4572 | } | 4606 | } |
| 4607 | |||
| 4573 | } else if ((addr >= SRAM_BASE_ADDR) && | 4608 | } else if ((addr >= SRAM_BASE_ADDR) && |
| 4574 | (addr < SRAM_BASE_ADDR + SRAM_BAR_SIZE)) { | 4609 | (addr < SRAM_BASE_ADDR + SRAM_BAR_SIZE)) { |
| 4575 | writel(val, hdev->pcie_bar[SRAM_BAR_ID] + | 4610 | writel(val, hdev->pcie_bar[SRAM_BAR_ID] + |
| @@ -4605,7 +4640,11 @@ static int gaudi_debugfs_read64(struct hl_device *hdev, u64 addr, u64 *val) · 29 unmodified lines | |||
| 4605 | int rc = 0; | 4640 | int rc = 0; |
| 4606 | 4641 | ||
| 4607 | if ((addr >= CFG_BASE) && (addr <= CFG_BASE + CFG_SIZE - sizeof(u64))) { | 4642 | if ((addr >= CFG_BASE) && (addr <= CFG_BASE + CFG_SIZE - sizeof(u64))) { |
| 4608 | if (gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) { | 4643 | |
| 4644 | if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) && | ||
| 4645 | (hdev->clock_gating_mask & | ||
| 4646 | GAUDI_CLK_GATE_DEBUGFS_MASK)) { | ||
| 4647 | |||
| 4609 | dev_err_ratelimited(hdev->dev, | 4648 | dev_err_ratelimited(hdev->dev, |
| 4610 | "Can't read register - clock gating is enabled!\n"); | 4649 | "Can't read register - clock gating is enabled!\n"); |
| 4611 | rc = -EFAULT; | 4650 | rc = -EFAULT; |
| @@ -4615,6 +4654,7 @@ static int gaudi_debugfs_read64(struct hl_device *hdev, u64 addr, u64 *val) · 3 unmodified lines | |||
| 4615 | 4654 | ||
| 4616 | *val = (((u64) val_h) << 32) | val_l; | 4655 | *val = (((u64) val_h) << 32) | val_l; |
| 4617 | } | 4656 | } |
| 4657 | |||
| 4618 | } else if ((addr >= SRAM_BASE_ADDR) && | 4658 | } else if ((addr >= SRAM_BASE_ADDR) && |
| 4619 | (addr <= SRAM_BASE_ADDR + SRAM_BAR_SIZE - sizeof(u64))) { | 4659 | (addr <= SRAM_BASE_ADDR + SRAM_BAR_SIZE - sizeof(u64))) { |
| 4620 | *val = readq(hdev->pcie_bar[SRAM_BAR_ID] + | 4660 | *val = readq(hdev->pcie_bar[SRAM_BAR_ID] + |
| @@ -4651,7 +4691,11 @@ static int gaudi_debugfs_write64(struct hl_device *hdev, u64 addr, u64 val) · 30 unmodified lines | |||
| 4651 | int rc = 0; | 4691 | int rc = 0; |
| 4652 | 4692 | ||
| 4653 | if ((addr >= CFG_BASE) && (addr <= CFG_BASE + CFG_SIZE - sizeof(u64))) { | 4693 | if ((addr >= CFG_BASE) && (addr <= CFG_BASE + CFG_SIZE - sizeof(u64))) { |
| 4654 | if (gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) { | 4694 | |
| 4695 | if ((gaudi->hw_cap_initialized & HW_CAP_CLK_GATE) && | ||
| 4696 | (hdev->clock_gating_mask & | ||
| 4697 | GAUDI_CLK_GATE_DEBUGFS_MASK)) { | ||
| 4698 | |||
| 4655 | dev_err_ratelimited(hdev->dev, | 4699 | dev_err_ratelimited(hdev->dev, |
| 4656 | "Can't write register - clock gating is enabled!\n"); | 4700 | "Can't write register - clock gating is enabled!\n"); |
| 4657 | rc = -EFAULT; | 4701 | rc = -EFAULT; |
| @@ -4660,6 +4704,7 @@ static int gaudi_debugfs_write64(struct hl_device *hdev, u64 addr, u64 val) · 2 unmodified lines | |||
| 4660 | WREG32(addr + sizeof(u32) - CFG_BASE, | 4704 | WREG32(addr + sizeof(u32) - CFG_BASE, |
| 4661 | upper_32_bits(val)); | 4705 | upper_32_bits(val)); |
| 4662 | } | 4706 | } |
| 4707 | |||
| 4663 | } else if ((addr >= SRAM_BASE_ADDR) && | 4708 | } else if ((addr >= SRAM_BASE_ADDR) && |
| 4664 | (addr <= SRAM_BASE_ADDR + SRAM_BAR_SIZE - sizeof(u64))) { | 4709 | (addr <= SRAM_BASE_ADDR + SRAM_BAR_SIZE - sizeof(u64))) { |
| 4665 | writeq(val, hdev->pcie_bar[SRAM_BAR_ID] + | 4710 | writeq(val, hdev->pcie_bar[SRAM_BAR_ID] + |
| @@ -4881,7 +4926,7 @@ static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid) · 215 unmodified lines | |||
| 4881 | gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_ARUSER, asid); | 4926 | gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_ARUSER, asid); |
| 4882 | gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_AWUSER, asid); | 4927 | gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_AWUSER, asid); |
| 4883 | 4928 | ||
| 4884 | hdev->asic_funcs->enable_clock_gating(hdev); | 4929 | hdev->asic_funcs->set_clock_gating(hdev); |
| 4885 | 4930 | ||
| 4886 | mutex_unlock(&gaudi->clk_gate_mutex); | 4931 | mutex_unlock(&gaudi->clk_gate_mutex); |
| 4887 | } | 4932 | } |
| @@ -5262,7 +5307,7 @@ static void gaudi_print_ecc_info_generic(struct hl_device *hdev, · 374 unmodified lines | |||
| 5262 | } | 5307 | } |
| 5263 | 5308 | ||
| 5264 | if (disable_clock_gating) { | 5309 | if (disable_clock_gating) { |
| 5265 | hdev->asic_funcs->enable_clock_gating(hdev); | 5310 | hdev->asic_funcs->set_clock_gating(hdev); |
| 5266 | mutex_unlock(&gaudi->clk_gate_mutex); | 5311 | mutex_unlock(&gaudi->clk_gate_mutex); |
| 5267 | } | 5312 | } |
| 5268 | } | 5313 | } |
| @@ -5749,7 +5794,7 @@ static bool gaudi_tpc_read_interrupts(struct hl_device *hdev, u8 tpc_id, · 480 unmodified lines | |||
| 5749 | /* Clear interrupts */ | 5794 | /* Clear interrupts */ |
| 5750 | WREG32(mmTPC0_CFG_TPC_INTR_CAUSE + tpc_offset, 0); | 5795 | WREG32(mmTPC0_CFG_TPC_INTR_CAUSE + tpc_offset, 0); |
| 5751 | 5796 | ||
| 5752 | hdev->asic_funcs->enable_clock_gating(hdev); | 5797 | hdev->asic_funcs->set_clock_gating(hdev); |
| 5753 | 5798 | ||
| 5754 | mutex_unlock(&gaudi->clk_gate_mutex); | 5799 | mutex_unlock(&gaudi->clk_gate_mutex); |
| 5755 | 5800 | ||
| @@ -6265,7 +6310,7 @@ static bool gaudi_is_device_idle(struct hl_device *hdev, u32 *mask, · 509 unmodified lines | |||
| 6265 | if (s) | 6310 | if (s) |
| 6266 | seq_puts(s, "\n"); | 6311 | seq_puts(s, "\n"); |
| 6267 | 6312 | ||
| 6268 | hdev->asic_funcs->enable_clock_gating(hdev); | 6313 | hdev->asic_funcs->set_clock_gating(hdev); |
| 6269 | 6314 | ||
| 6270 | mutex_unlock(&gaudi->clk_gate_mutex); | 6315 | mutex_unlock(&gaudi->clk_gate_mutex); |
| 6271 | 6316 | ||
| @@ -6366,7 +6411,7 @@ static int gaudi_run_tpc_kernel(struct hl_device *hdev, u64 tpc_kernel, · 94 unmodified lines | |||
| 6366 | dev_err(hdev->dev, | 6411 | dev_err(hdev->dev, |
| 6367 | "Timeout while waiting for TPC%d icache prefetch\n", | 6412 | "Timeout while waiting for TPC%d icache prefetch\n", |
| 6368 | tpc_id); | 6413 | tpc_id); |
| 6369 | hdev->asic_funcs->enable_clock_gating(hdev); | 6414 | hdev->asic_funcs->set_clock_gating(hdev); |
| 6370 | mutex_unlock(&gaudi->clk_gate_mutex); | 6415 | mutex_unlock(&gaudi->clk_gate_mutex); |
| 6371 | return -EIO; | 6416 | return -EIO; |
| 6372 | } | 6417 | } |
| @@ -6395,7 +6440,7 @@ static int gaudi_run_tpc_kernel(struct hl_device *hdev, u64 tpc_kernel, · 22 unmodified lines | |||
| 6395 | 1000, | 6440 | 1000, |
| 6396 | kernel_timeout); | 6441 | kernel_timeout); |
| 6397 | 6442 | ||
| 6398 | hdev->asic_funcs->enable_clock_gating(hdev); | 6443 | hdev->asic_funcs->set_clock_gating(hdev); |
| 6399 | mutex_unlock(&gaudi->clk_gate_mutex); | 6444 | mutex_unlock(&gaudi->clk_gate_mutex); |
| 6400 | 6445 | ||
| 6401 | if (rc) { | 6446 | if (rc) { |
| @@ -6736,7 +6781,7 @@ static const struct hl_asic_funcs gaudi_funcs = { · 334 unmodified lines | |||
| 6736 | .mmu_invalidate_cache = gaudi_mmu_invalidate_cache, | 6781 | .mmu_invalidate_cache = gaudi_mmu_invalidate_cache, |
| 6737 | .mmu_invalidate_cache_range = gaudi_mmu_invalidate_cache_range, | 6782 | .mmu_invalidate_cache_range = gaudi_mmu_invalidate_cache_range, |
| 6738 | .send_heartbeat = gaudi_send_heartbeat, | 6783 | .send_heartbeat = gaudi_send_heartbeat, |
| 6739 | .enable_clock_gating = gaudi_enable_clock_gating, | 6784 | .set_clock_gating = gaudi_set_clock_gating, |
| 6740 | .disable_clock_gating = gaudi_disable_clock_gating, | 6785 | .disable_clock_gating = gaudi_disable_clock_gating, |
| 6741 | .debug_coresight = gaudi_debug_coresight, | 6786 | .debug_coresight = gaudi_debug_coresight, |
| 6742 | .is_device_idle = gaudi_is_device_idle, | 6787 | .is_device_idle = gaudi_is_device_idle, |
| @@ -88,6 +88,7 @@ · 87 unmodified lines | |||
| 88 | #define GOYA_PLDM_MMU_TIMEOUT_USEC (MMU_CONFIG_TIMEOUT_USEC * 100) | 88 | #define GOYA_PLDM_MMU_TIMEOUT_USEC (MMU_CONFIG_TIMEOUT_USEC * 100) |
| 89 | #define GOYA_PLDM_QMAN0_TIMEOUT_USEC (HL_DEVICE_TIMEOUT_USEC * 30) | 89 | #define GOYA_PLDM_QMAN0_TIMEOUT_USEC (HL_DEVICE_TIMEOUT_USEC * 30) |
| 90 | #define GOYA_BOOT_FIT_REQ_TIMEOUT_USEC 1000000 /* 1s */ | 90 | #define GOYA_BOOT_FIT_REQ_TIMEOUT_USEC 1000000 /* 1s */ |
| 91 | #define GOYA_MSG_TO_CPU_TIMEOUT_USEC 4000000 /* 4s */ | ||
| 91 | 92 | ||
| 92 | #define GOYA_QMAN0_FENCE_VAL 0xD169B243 | 93 | #define GOYA_QMAN0_FENCE_VAL 0xD169B243 |
| 93 | 94 | ||
| @@ -2830,6 +2831,9 @@ int goya_send_cpu_message(struct hl_device *hdev, u32 *msg, u16 len, · 2736 unmodified lines | |||
| 2830 | return 0; | 2831 | return 0; |
| 2831 | } | 2832 | } |
| 2832 | 2833 | ||
| 2834 | if (!timeout) | ||
| 2835 | timeout = GOYA_MSG_TO_CPU_TIMEOUT_USEC; | ||
| 2836 | |||
| 2833 | return hl_fw_send_cpu_message(hdev, GOYA_QUEUE_ID_CPU_PQ, msg, len, | 2837 | return hl_fw_send_cpu_message(hdev, GOYA_QUEUE_ID_CPU_PQ, msg, len, |
| 2834 | timeout, result); | 2838 | timeout, result); |
| 2835 | } | 2839 | } |
| @@ -4431,8 +4435,8 @@ static int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr, · 1595 unmodified lines | |||
| 4431 | pkt->armcp_pkt.ctl = cpu_to_le32(ARMCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY << | 4435 | pkt->armcp_pkt.ctl = cpu_to_le32(ARMCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY << |
| 4432 | ARMCP_PKT_CTL_OPCODE_SHIFT); | 4436 | ARMCP_PKT_CTL_OPCODE_SHIFT); |
| 4433 | 4437 | ||
| 4434 | rc = goya_send_cpu_message(hdev, (u32 *) pkt, total_pkt_size, | 4438 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) pkt, |
| 4435 | HL_DEVICE_TIMEOUT_USEC, &result); | 4439 | total_pkt_size, 0, &result); |
| 4436 | 4440 | ||
| 4437 | if (rc) | 4441 | if (rc) |
| 4438 | dev_err(hdev->dev, "failed to unmask IRQ array\n"); | 4442 | dev_err(hdev->dev, "failed to unmask IRQ array\n"); |
| @@ -4464,8 +4468,8 @@ static int goya_unmask_irq(struct hl_device *hdev, u16 event_type) · 25 unmodified lines | |||
| 4464 | ARMCP_PKT_CTL_OPCODE_SHIFT); | 4468 | ARMCP_PKT_CTL_OPCODE_SHIFT); |
| 4465 | pkt.value = cpu_to_le64(event_type); | 4469 | pkt.value = cpu_to_le64(event_type); |
| 4466 | 4470 | ||
| 4467 | rc = goya_send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 4471 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 4468 | HL_DEVICE_TIMEOUT_USEC, &result); | 4472 | 0, &result); |
| 4469 | 4473 | ||
| 4470 | if (rc) | 4474 | if (rc) |
| 4471 | dev_err(hdev->dev, "failed to unmask RAZWI IRQ %d", event_type); | 4475 | dev_err(hdev->dev, "failed to unmask RAZWI IRQ %d", event_type); |
| @@ -5028,14 +5032,14 @@ int goya_armcp_info_get(struct hl_device *hdev) · 556 unmodified lines | |||
| 5028 | return 0; | 5032 | return 0; |
| 5029 | } | 5033 | } |
| 5030 | 5034 | ||
| 5031 | static void goya_enable_clock_gating(struct hl_device *hdev) | 5035 | static void goya_set_clock_gating(struct hl_device *hdev) |
| 5032 | { | 5036 | { |
| 5033 | 5037 | /* clock gating not supported in Goya */ | |
| 5034 | } | 5038 | } |
| 5035 | 5039 | ||
| 5036 | static void goya_disable_clock_gating(struct hl_device *hdev) | 5040 | static void goya_disable_clock_gating(struct hl_device *hdev) |
| 5037 | { | 5041 | { |
| 5038 | 5042 | /* clock gating not supported in Goya */ | |
| 5039 | } | 5043 | } |
| 5040 | 5044 | ||
| 5041 | static bool goya_is_device_idle(struct hl_device *hdev, u32 *mask, | 5045 | static bool goya_is_device_idle(struct hl_device *hdev, u32 *mask, |
| @@ -5259,7 +5263,7 @@ static const struct hl_asic_funcs goya_funcs = { · 217 unmodified lines | |||
| 5259 | .mmu_invalidate_cache = goya_mmu_invalidate_cache, | 5263 | .mmu_invalidate_cache = goya_mmu_invalidate_cache, |
| 5260 | .mmu_invalidate_cache_range = goya_mmu_invalidate_cache_range, | 5264 | .mmu_invalidate_cache_range = goya_mmu_invalidate_cache_range, |
| 5261 | .send_heartbeat = goya_send_heartbeat, | 5265 | .send_heartbeat = goya_send_heartbeat, |
| 5262 | .enable_clock_gating = goya_enable_clock_gating, | 5266 | .set_clock_gating = goya_set_clock_gating, |
| 5263 | .disable_clock_gating = goya_disable_clock_gating, | 5267 | .disable_clock_gating = goya_disable_clock_gating, |
| 5264 | .debug_coresight = goya_debug_coresight, | 5268 | .debug_coresight = goya_debug_coresight, |
| 5265 | .is_device_idle = goya_is_device_idle, | 5269 | .is_device_idle = goya_is_device_idle, |
| @@ -578,8 +578,9 @@ enum hl_pll_frequency { · 577 unmodified lines | |||
| 578 | * @mmu_invalidate_cache_range: flush specific MMU STLB cache lines with | 578 | * @mmu_invalidate_cache_range: flush specific MMU STLB cache lines with |
| 579 | * ASID-VA-size mask. | 579 | * ASID-VA-size mask. |
| 580 | * @send_heartbeat: send is-alive packet to ArmCP and verify response. | 580 | * @send_heartbeat: send is-alive packet to ArmCP and verify response. |
| 581 | * @enable_clock_gating: enable clock gating for reducing power consumption. | 581 | * @set_clock_gating: enable/disable clock gating per engine according to |
| 582 | * @disable_clock_gating: disable clock for accessing registers on HBW. | 582 | * clock gating mask in hdev |
| 583 | * @disable_clock_gating: disable clock gating completely | ||
| 583 | * @debug_coresight: perform certain actions on Coresight for debugging. | 584 | * @debug_coresight: perform certain actions on Coresight for debugging. |
| 584 | * @is_device_idle: return true if device is idle, false otherwise. | 585 | * @is_device_idle: return true if device is idle, false otherwise. |
| 585 | * @soft_reset_late_init: perform certain actions needed after soft reset. | 586 | * @soft_reset_late_init: perform certain actions needed after soft reset. |
| @@ -587,7 +588,11 @@ enum hl_pll_frequency { · 1 unmodified line | |||
| 587 | * @hw_queues_unlock: release H/W queues lock. | 588 | * @hw_queues_unlock: release H/W queues lock. |
| 588 | * @get_pci_id: retrieve PCI ID. | 589 | * @get_pci_id: retrieve PCI ID. |
| 589 | * @get_eeprom_data: retrieve EEPROM data from F/W. | 590 | * @get_eeprom_data: retrieve EEPROM data from F/W. |
| 590 | * @send_cpu_message: send buffer to ArmCP. | 591 | * @send_cpu_message: send message to F/W. If the message is timedout, the |
| 592 | * driver will eventually reset the device. The timeout can | ||
| 593 | * be determined by the calling function or it can be 0 and | ||
| 594 | * then the timeout is the default timeout for the specific | ||
| 595 | * ASIC | ||
| 591 | * @get_hw_state: retrieve the H/W state | 596 | * @get_hw_state: retrieve the H/W state |
| 592 | * @pci_bars_map: Map PCI BARs. | 597 | * @pci_bars_map: Map PCI BARs. |
| 593 | * @set_dram_bar_base: Set DRAM BAR to map specific device address. Returns | 598 | * @set_dram_bar_base: Set DRAM BAR to map specific device address. Returns |
| @@ -680,7 +685,7 @@ struct hl_asic_funcs { · 86 unmodified lines | |||
| 680 | int (*mmu_invalidate_cache_range)(struct hl_device *hdev, bool is_hard, | 685 | int (*mmu_invalidate_cache_range)(struct hl_device *hdev, bool is_hard, |
| 681 | u32 asid, u64 va, u64 size); | 686 | u32 asid, u64 va, u64 size); |
| 682 | int (*send_heartbeat)(struct hl_device *hdev); | 687 | int (*send_heartbeat)(struct hl_device *hdev); |
| 683 | void (*enable_clock_gating)(struct hl_device *hdev); | 688 | void (*set_clock_gating)(struct hl_device *hdev); |
| 684 | void (*disable_clock_gating)(struct hl_device *hdev); | 689 | void (*disable_clock_gating)(struct hl_device *hdev); |
| 685 | int (*debug_coresight)(struct hl_device *hdev, void *data); | 690 | int (*debug_coresight)(struct hl_device *hdev, void *data); |
| 686 | bool (*is_device_idle)(struct hl_device *hdev, u32 *mask, | 691 | bool (*is_device_idle)(struct hl_device *hdev, u32 *mask, |
| @@ -1398,6 +1403,9 @@ struct hl_device_idle_busy_ts { · 711 unmodified lines | |||
| 1398 | * @max_power: the max power of the device, as configured by the sysadmin. This | 1403 | * @max_power: the max power of the device, as configured by the sysadmin. This |
| 1399 | * value is saved so in case of hard-reset, the driver will restore | 1404 | * value is saved so in case of hard-reset, the driver will restore |
| 1400 | * this value and update the F/W after the re-initialization | 1405 | * this value and update the F/W after the re-initialization |
| 1406 | * @clock_gating_mask: is clock gating enabled. bitmask that represents the | ||
| 1407 | * different engines. See debugfs-driver-habanalabs for | ||
| 1408 | * details. | ||
| 1401 | * @in_reset: is device in reset flow. | 1409 | * @in_reset: is device in reset flow. |
| 1402 | * @curr_pll_profile: current PLL profile. | 1410 | * @curr_pll_profile: current PLL profile. |
| 1403 | * @cs_active_cnt: number of active command submissions on this device (active | 1411 | * @cs_active_cnt: number of active command submissions on this device (active |
| @@ -1425,7 +1433,6 @@ struct hl_device_idle_busy_ts { · 21 unmodified lines | |||
| 1425 | * @init_done: is the initialization of the device done. | 1433 | * @init_done: is the initialization of the device done. |
| 1426 | * @mmu_enable: is MMU enabled. | 1434 | * @mmu_enable: is MMU enabled. |
| 1427 | * @mmu_huge_page_opt: is MMU huge pages optimization enabled. | 1435 | * @mmu_huge_page_opt: is MMU huge pages optimization enabled. |
| 1428 | * @clock_gating: is clock gating enabled. | ||
| 1429 | * @device_cpu_disabled: is the device CPU disabled (due to timeouts) | 1436 | * @device_cpu_disabled: is the device CPU disabled (due to timeouts) |
| 1430 | * @dma_mask: the dma mask that was set for this device | 1437 | * @dma_mask: the dma mask that was set for this device |
| 1431 | * @in_debug: is device under debug. This, together with fpriv_list, enforces | 1438 | * @in_debug: is device under debug. This, together with fpriv_list, enforces |
| @@ -1493,6 +1500,7 @@ struct hl_device { · 61 unmodified lines | |||
| 1493 | atomic64_t dram_used_mem; | 1500 | atomic64_t dram_used_mem; |
| 1494 | u64 timeout_jiffies; | 1501 | u64 timeout_jiffies; |
| 1495 | u64 max_power; | 1502 | u64 max_power; |
| 1503 | u64 clock_gating_mask; | ||
| 1496 | atomic_t in_reset; | 1504 | atomic_t in_reset; |
| 1497 | enum hl_pll_frequency curr_pll_profile; | 1505 | enum hl_pll_frequency curr_pll_profile; |
| 1498 | int cs_active_cnt; | 1506 | int cs_active_cnt; |
| @@ -1514,7 +1522,6 @@ struct hl_device { · 15 unmodified lines | |||
| 1514 | u8 dram_default_page_mapping; | 1522 | u8 dram_default_page_mapping; |
| 1515 | u8 pmmu_huge_range; | 1523 | u8 pmmu_huge_range; |
| 1516 | u8 init_done; | 1524 | u8 init_done; |
| 1517 | u8 clock_gating; | ||
| 1518 | u8 device_cpu_disabled; | 1525 | u8 device_cpu_disabled; |
| 1519 | u8 dma_mask; | 1526 | u8 dma_mask; |
| 1520 | u8 in_debug; | 1527 | u8 in_debug; |
| @@ -232,7 +232,7 @@ static void set_driver_behavior_per_device(struct hl_device *hdev) · 231 unmodified lines | |||
| 232 | hdev->fw_loading = 1; | 232 | hdev->fw_loading = 1; |
| 233 | hdev->cpu_queues_enable = 1; | 233 | hdev->cpu_queues_enable = 1; |
| 234 | hdev->heartbeat = 1; | 234 | hdev->heartbeat = 1; |
| 235 | hdev->clock_gating = 1; | 235 | hdev->clock_gating_mask = ULONG_MAX; |
| 236 | 236 | ||
| 237 | hdev->reset_pcilink = 0; | 237 | hdev->reset_pcilink = 0; |
| 238 | hdev->axi_drain = 0; | 238 | hdev->axi_drain = 0; |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
| 11 | #include <linux/hwmon.h> | 11 | #include <linux/hwmon.h> |
| 12 | 12 | ||
| 13 | #define SENSORS_PKT_TIMEOUT 1000000 /* 1s */ | ||
| 14 | #define HWMON_NR_SENSOR_TYPES (hwmon_pwm + 1) | 13 | #define HWMON_NR_SENSOR_TYPES (hwmon_pwm + 1) |
| 15 | 14 | ||
| 16 | int hl_build_hwmon_channel_info(struct hl_device *hdev, | 15 | int hl_build_hwmon_channel_info(struct hl_device *hdev, |
| @@ -323,7 +322,7 @@ int hl_get_temperature(struct hl_device *hdev, · 306 unmodified lines | |||
| 323 | pkt.type = __cpu_to_le16(attr); | 322 | pkt.type = __cpu_to_le16(attr); |
| 324 | 323 | ||
| 325 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 324 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 326 | SENSORS_PKT_TIMEOUT, value); | 325 | 0, value); |
| 327 | 326 | ||
| 328 | if (rc) { | 327 | if (rc) { |
| 329 | dev_err(hdev->dev, | 328 | dev_err(hdev->dev, |
| @@ -350,7 +349,7 @@ int hl_set_temperature(struct hl_device *hdev, · 20 unmodified lines | |||
| 350 | pkt.value = __cpu_to_le64(value); | 349 | pkt.value = __cpu_to_le64(value); |
| 351 | 350 | ||
| 352 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 351 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 353 | SENSORS_PKT_TIMEOUT, NULL); | 352 | 0, NULL); |
| 354 | 353 | ||
| 355 | if (rc) | 354 | if (rc) |
| 356 | dev_err(hdev->dev, | 355 | dev_err(hdev->dev, |
| @@ -374,7 +373,7 @@ int hl_get_voltage(struct hl_device *hdev, · 17 unmodified lines | |||
| 374 | pkt.type = __cpu_to_le16(attr); | 373 | pkt.type = __cpu_to_le16(attr); |
| 375 | 374 | ||
| 376 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 375 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 377 | SENSORS_PKT_TIMEOUT, value); | 376 | 0, value); |
| 378 | 377 | ||
| 379 | if (rc) { | 378 | if (rc) { |
| 380 | dev_err(hdev->dev, | 379 | dev_err(hdev->dev, |
| @@ -400,7 +399,7 @@ int hl_get_current(struct hl_device *hdev, · 19 unmodified lines | |||
| 400 | pkt.type = __cpu_to_le16(attr); | 399 | pkt.type = __cpu_to_le16(attr); |
| 401 | 400 | ||
| 402 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 401 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 403 | SENSORS_PKT_TIMEOUT, value); | 402 | 0, value); |
| 404 | 403 | ||
| 405 | if (rc) { | 404 | if (rc) { |
| 406 | dev_err(hdev->dev, | 405 | dev_err(hdev->dev, |
| @@ -426,7 +425,7 @@ int hl_get_fan_speed(struct hl_device *hdev, · 19 unmodified lines | |||
| 426 | pkt.type = __cpu_to_le16(attr); | 425 | pkt.type = __cpu_to_le16(attr); |
| 427 | 426 | ||
| 428 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 427 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 429 | SENSORS_PKT_TIMEOUT, value); | 428 | 0, value); |
| 430 | 429 | ||
| 431 | if (rc) { | 430 | if (rc) { |
| 432 | dev_err(hdev->dev, | 431 | dev_err(hdev->dev, |
| @@ -452,7 +451,7 @@ int hl_get_pwm_info(struct hl_device *hdev, · 19 unmodified lines | |||
| 452 | pkt.type = __cpu_to_le16(attr); | 451 | pkt.type = __cpu_to_le16(attr); |
| 453 | 452 | ||
| 454 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 453 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 455 | SENSORS_PKT_TIMEOUT, value); | 454 | 0, value); |
| 456 | 455 | ||
| 457 | if (rc) { | 456 | if (rc) { |
| 458 | dev_err(hdev->dev, | 457 | dev_err(hdev->dev, |
| @@ -479,7 +478,7 @@ void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr, · 20 unmodified lines | |||
| 479 | pkt.value = cpu_to_le64(value); | 478 | pkt.value = cpu_to_le64(value); |
| 480 | 479 | ||
| 481 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 480 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 482 | SENSORS_PKT_TIMEOUT, NULL); | 481 | 0, NULL); |
| 483 | 482 | ||
| 484 | if (rc) | 483 | if (rc) |
| 485 | dev_err(hdev->dev, | 484 | dev_err(hdev->dev, |
| @@ -502,7 +501,7 @@ int hl_set_voltage(struct hl_device *hdev, · 16 unmodified lines | |||
| 502 | pkt.value = __cpu_to_le64(value); | 501 | pkt.value = __cpu_to_le64(value); |
| 503 | 502 | ||
| 504 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 503 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 505 | SENSORS_PKT_TIMEOUT, NULL); | 504 | 0, NULL); |
| 506 | 505 | ||
| 507 | if (rc) | 506 | if (rc) |
| 508 | dev_err(hdev->dev, | 507 | dev_err(hdev->dev, |
| @@ -527,7 +526,7 @@ int hl_set_current(struct hl_device *hdev, · 18 unmodified lines | |||
| 527 | pkt.value = __cpu_to_le64(value); | 526 | pkt.value = __cpu_to_le64(value); |
| 528 | 527 | ||
| 529 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 528 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 530 | SENSORS_PKT_TIMEOUT, NULL); | 529 | 0, NULL); |
| 531 | 530 | ||
| 532 | if (rc) | 531 | if (rc) |
| 533 | dev_err(hdev->dev, | 532 | dev_err(hdev->dev, |
| @@ -9,9 +9,6 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
| 11 | 11 | ||
| 12 | #define SET_CLK_PKT_TIMEOUT 1000000 /* 1s */ | ||
| 13 | #define SET_PWR_PKT_TIMEOUT 1000000 /* 1s */ | ||
| 14 | |||
| 15 | long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr) | 12 | long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr) |
| 16 | { | 13 | { |
| 17 | struct armcp_packet pkt; | 14 | struct armcp_packet pkt; |
| @@ -29,7 +26,7 @@ long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr) · 11 unmodified lines | |||
| 29 | pkt.pll_index = cpu_to_le32(pll_index); | 26 | pkt.pll_index = cpu_to_le32(pll_index); |
| 30 | 27 | ||
| 31 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 28 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 32 | SET_CLK_PKT_TIMEOUT, &result); | 29 | 0, &result); |
| 33 | 30 | ||
| 34 | if (rc) { | 31 | if (rc) { |
| 35 | dev_err(hdev->dev, | 32 | dev_err(hdev->dev, |
| @@ -54,7 +51,7 @@ void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq) · 18 unmodified lines | |||
| 54 | pkt.value = cpu_to_le64(freq); | 51 | pkt.value = cpu_to_le64(freq); |
| 55 | 52 | ||
| 56 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 53 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 57 | SET_CLK_PKT_TIMEOUT, NULL); | 54 | 0, NULL); |
| 58 | 55 | ||
| 59 | if (rc) | 56 | if (rc) |
| 60 | dev_err(hdev->dev, | 57 | dev_err(hdev->dev, |
| @@ -74,7 +71,7 @@ u64 hl_get_max_power(struct hl_device *hdev) · 13 unmodified lines | |||
| 74 | ARMCP_PKT_CTL_OPCODE_SHIFT); | 71 | ARMCP_PKT_CTL_OPCODE_SHIFT); |
| 75 | 72 | ||
| 76 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 73 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 77 | SET_PWR_PKT_TIMEOUT, &result); | 74 | 0, &result); |
| 78 | 75 | ||
| 79 | if (rc) { | 76 | if (rc) { |
| 80 | dev_err(hdev->dev, "Failed to get max power, error %d\n", rc); | 77 | dev_err(hdev->dev, "Failed to get max power, error %d\n", rc); |
| @@ -96,7 +93,7 @@ void hl_set_max_power(struct hl_device *hdev, u64 value) · 15 unmodified lines | |||
| 96 | pkt.value = cpu_to_le64(value); | 93 | pkt.value = cpu_to_le64(value); |
| 97 | 94 | ||
| 98 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), | 95 | rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), |
| 99 | SET_PWR_PKT_TIMEOUT, NULL); | 96 | 0, NULL); |
| 100 | 97 | ||
| 101 | if (rc) | 98 | if (rc) |
| 102 | dev_err(hdev->dev, "Failed to set max power, error %d\n", rc); | 99 | dev_err(hdev->dev, "Failed to set max power, error %d\n", rc); |
| @@ -68,7 +68,7 @@ static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) · 67 unmodified lines | |||
| 68 | if (WARN_ON(clock > host->max_clk)) | 68 | if (WARN_ON(clock > host->max_clk)) |
| 69 | clock = host->max_clk; | 69 | clock = host->max_clk; |
| 70 | 70 | ||
| 71 | for (div = 1; div < 256; div *= 2) { | 71 | for (div = 2; div < 256; div *= 2) { |
| 72 | if ((parent / div) <= clock) | 72 | if ((parent / div) <= clock) |
| 73 | break; | 73 | break; |
| 74 | } | 74 | } |
| @@ -5053,15 +5053,19 @@ int bond_create(struct net *net, const char *name) · 5052 unmodified lines | |||
| 5053 | bond_dev->rtnl_link_ops = &bond_link_ops; | 5053 | bond_dev->rtnl_link_ops = &bond_link_ops; |
| 5054 | 5054 | ||
| 5055 | res = register_netdevice(bond_dev); | 5055 | res = register_netdevice(bond_dev); |
| 5056 | if (res < 0) { | ||
| 5057 | free_netdev(bond_dev); | ||
| 5058 | rtnl_unlock(); | ||
| 5059 | |||
| 5060 | return res; | ||
| 5061 | } | ||
| 5056 | 5062 | ||
| 5057 | netif_carrier_off(bond_dev); | 5063 | netif_carrier_off(bond_dev); |
| 5058 | 5064 | ||
| 5059 | bond_work_init_all(bond); | 5065 | bond_work_init_all(bond); |
| 5060 | 5066 | ||
| 5061 | rtnl_unlock(); | 5067 | rtnl_unlock(); |
| 5062 | if (res < 0) | 5068 | return 0; |
| 5063 | free_netdev(bond_dev); | ||
| 5064 | return res; | ||
| 5065 | } | 5069 | } |
| 5066 | 5070 | ||
| 5067 | static int __net_init bond_net_init(struct net *net) | 5071 | static int __net_init bond_net_init(struct net *net) |
| @@ -456,11 +456,10 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev, · 455 unmodified lines | |||
| 456 | return err; | 456 | return err; |
| 457 | 457 | ||
| 458 | err = register_netdevice(bond_dev); | 458 | err = register_netdevice(bond_dev); |
| 459 | |||
| 460 | netif_carrier_off(bond_dev); | ||
| 461 | if (!err) { | 459 | if (!err) { |
| 462 | struct bonding *bond = netdev_priv(bond_dev); | 460 | struct bonding *bond = netdev_priv(bond_dev); |
| 463 | 461 | ||
| 462 | netif_carrier_off(bond_dev); | ||
| 464 | bond_work_init_all(bond); | 463 | bond_work_init_all(bond); |
| 465 | } | 464 | } |
| 466 | 465 | ||
| @@ -974,23 +974,6 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port, · 973 unmodified lines | |||
| 974 | PORT_MIRROR_SNIFFER, false); | 974 | PORT_MIRROR_SNIFFER, false); |
| 975 | } | 975 | } |
| 976 | 976 | ||
| 977 | static void ksz9477_phy_setup(struct ksz_device *dev, int port, | ||
| 978 | struct phy_device *phy) | ||
| 979 | { | ||
| 980 | /* Only apply to port with PHY. */ | ||
| 981 | if (port >= dev->phy_port_cnt) | ||
| 982 | return; | ||
| 983 | |||
| 984 | /* The MAC actually cannot run in 1000 half-duplex mode. */ | ||
| 985 | phy_remove_link_mode(phy, | ||
| 986 | ETHTOOL_LINK_MODE_1000baseT_Half_BIT); | ||
| 987 | |||
| 988 | /* PHY does not support gigabit. */ | ||
| 989 | if (!(dev->features & GBIT_SUPPORT)) | ||
| 990 | phy_remove_link_mode(phy, | ||
| 991 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT); | ||
| 992 | } | ||
| 993 | |||
| 994 | static bool ksz9477_get_gbit(struct ksz_device *dev, u8 data) | 977 | static bool ksz9477_get_gbit(struct ksz_device *dev, u8 data) |
| 995 | { | 978 | { |
| 996 | bool gbit; | 979 | bool gbit; |
| @@ -1603,7 +1586,6 @@ static const struct ksz_dev_ops ksz9477_dev_ops = { · 606 unmodified lines | |||
| 1603 | .get_port_addr = ksz9477_get_port_addr, | 1586 | .get_port_addr = ksz9477_get_port_addr, |
| 1604 | .cfg_port_member = ksz9477_cfg_port_member, | 1587 | .cfg_port_member = ksz9477_cfg_port_member, |
| 1605 | .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, | 1588 | .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, |
| 1606 | .phy_setup = ksz9477_phy_setup, | ||
| 1607 | .port_setup = ksz9477_port_setup, | 1589 | .port_setup = ksz9477_port_setup, |
| 1608 | .r_mib_cnt = ksz9477_r_mib_cnt, | 1590 | .r_mib_cnt = ksz9477_r_mib_cnt, |
| 1609 | .r_mib_pkt = ksz9477_r_mib_pkt, | 1591 | .r_mib_pkt = ksz9477_r_mib_pkt, |
| @@ -1617,7 +1599,29 @@ static const struct ksz_dev_ops ksz9477_dev_ops = { · 7 unmodified lines | |||
| 1617 | 1599 | ||
| 1618 | int ksz9477_switch_register(struct ksz_device *dev) | 1600 | int ksz9477_switch_register(struct ksz_device *dev) |
| 1619 | { | 1601 | { |
| 1620 | return ksz_switch_register(dev, &ksz9477_dev_ops); | 1602 | int ret, i; |
| 1603 | struct phy_device *phydev; | ||
| 1604 | |||
| 1605 | ret = ksz_switch_register(dev, &ksz9477_dev_ops); | ||
| 1606 | if (ret) | ||
| 1607 | return ret; | ||
| 1608 | |||
| 1609 | for (i = 0; i < dev->phy_port_cnt; ++i) { | ||
| 1610 | if (!dsa_is_user_port(dev->ds, i)) | ||
| 1611 | continue; | ||
| 1612 | |||
| 1613 | phydev = dsa_to_port(dev->ds, i)->slave->phydev; | ||
| 1614 | |||
| 1615 | /* The MAC actually cannot run in 1000 half-duplex mode. */ | ||
| 1616 | phy_remove_link_mode(phydev, | ||
| 1617 | ETHTOOL_LINK_MODE_1000baseT_Half_BIT); | ||
| 1618 | |||
| 1619 | /* PHY does not support gigabit. */ | ||
| 1620 | if (!(dev->features & GBIT_SUPPORT)) | ||
| 1621 | phy_remove_link_mode(phydev, | ||
| 1622 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT); | ||
| 1623 | } | ||
| 1624 | return ret; | ||
| 1621 | } | 1625 | } |
| 1622 | EXPORT_SYMBOL(ksz9477_switch_register); | 1626 | EXPORT_SYMBOL(ksz9477_switch_register); |
| 1623 | 1627 | ||
| @@ -358,8 +358,6 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) · 357 unmodified lines | |||
| 358 | 358 | ||
| 359 | /* setup slave port */ | 359 | /* setup slave port */ |
| 360 | dev->dev_ops->port_setup(dev, port, false); | 360 | dev->dev_ops->port_setup(dev, port, false); |
| 361 | if (dev->dev_ops->phy_setup) | ||
| 362 | dev->dev_ops->phy_setup(dev, port, phy); | ||
| 363 | 361 | ||
| 364 | /* port_stp_state_set() will be called after to enable the port so | 362 | /* port_stp_state_set() will be called after to enable the port so |
| 365 | * there is no need to do anything. | 363 | * there is no need to do anything. |
| @@ -119,8 +119,6 @@ struct ksz_dev_ops { · 118 unmodified lines | |||
| 119 | u32 (*get_port_addr)(int port, int offset); | 119 | u32 (*get_port_addr)(int port, int offset); |
| 120 | void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); | 120 | void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); |
| 121 | void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); | 121 | void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); |
| 122 | void (*phy_setup)(struct ksz_device *dev, int port, | ||
| 123 | struct phy_device *phy); | ||
| 124 | void (*port_cleanup)(struct ksz_device *dev, int port); | 122 | void (*port_cleanup)(struct ksz_device *dev, int port); |
| 125 | void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); | 123 | void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); |
| 126 | void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); | 124 | void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); |
| @@ -664,8 +664,11 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, · 663 unmodified lines | |||
| 664 | const struct phylink_link_state *state) | 664 | const struct phylink_link_state *state) |
| 665 | { | 665 | { |
| 666 | struct mv88e6xxx_chip *chip = ds->priv; | 666 | struct mv88e6xxx_chip *chip = ds->priv; |
| 667 | struct mv88e6xxx_port *p; | ||
| 667 | int err; | 668 | int err; |
| 668 | 669 | ||
| 670 | p = &chip->ports[port]; | ||
| 671 | |||
| 669 | /* FIXME: is this the correct test? If we're in fixed mode on an | 672 | /* FIXME: is this the correct test? If we're in fixed mode on an |
| 670 | * internal port, why should we process this any different from | 673 | * internal port, why should we process this any different from |
| 671 | * PHY mode? On the other hand, the port may be automedia between | 674 | * PHY mode? On the other hand, the port may be automedia between |
| @@ -675,10 +678,14 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, · 3 unmodified lines | |||
| 675 | return; | 678 | return; |
| 676 | 679 | ||
| 677 | mv88e6xxx_reg_lock(chip); | 680 | mv88e6xxx_reg_lock(chip); |
| 678 | /* FIXME: should we force the link down here - but if we do, how | 681 | /* In inband mode, the link may come up at any time while the link |
| 679 | * do we restore the link force/unforce state? The driver layering | 682 | * is not forced down. Force the link down while we reconfigure the |
| 680 | * gets in the way. | 683 | * interface mode. |
| 681 | */ | 684 | */ |
| 685 | if (mode == MLO_AN_INBAND && p->interface != state->interface && | ||
| 686 | chip->info->ops->port_set_link) | ||
| 687 | chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN); | ||
| 688 | |||
| 682 | err = mv88e6xxx_port_config_interface(chip, port, state->interface); | 689 | err = mv88e6xxx_port_config_interface(chip, port, state->interface); |
| 683 | if (err && err != -EOPNOTSUPP) | 690 | if (err && err != -EOPNOTSUPP) |
| 684 | goto err_unlock; | 691 | goto err_unlock; |
| @@ -691,6 +698,15 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port, · 6 unmodified lines | |||
| 691 | if (err > 0) | 698 | if (err > 0) |
| 692 | err = 0; | 699 | err = 0; |
| 693 | 700 | ||
| 701 | /* Undo the forced down state above after completing configuration | ||
| 702 | * irrespective of its state on entry, which allows the link to come up. | ||
| 703 | */ | ||
| 704 | if (mode == MLO_AN_INBAND && p->interface != state->interface && | ||
| 705 | chip->info->ops->port_set_link) | ||
| 706 | chip->info->ops->port_set_link(chip, port, LINK_UNFORCED); | ||
| 707 | |||
| 708 | p->interface = state->interface; | ||
| 709 | |||
| 694 | err_unlock: | 710 | err_unlock: |
| 695 | mv88e6xxx_reg_unlock(chip); | 711 | mv88e6xxx_reg_unlock(chip); |
| 696 | 712 | ||
| @@ -232,6 +232,7 @@ struct mv88e6xxx_port { · 231 unmodified lines | |||
| 232 | u64 atu_full_violation; | 232 | u64 atu_full_violation; |
| 233 | u64 vtu_member_violation; | 233 | u64 vtu_member_violation; |
| 234 | u64 vtu_miss_violation; | 234 | u64 vtu_miss_violation; |
| 235 | phy_interface_t interface; | ||
| 235 | u8 cmode; | 236 | u8 cmode; |
| 236 | bool mirror_ingress; | 237 | bool mirror_ingress; |
| 237 | bool mirror_egress; | 238 | bool mirror_egress; |
| @@ -64,6 +64,7 @@ struct aq_hw_caps_s { · 63 unmodified lines | |||
| 64 | u8 rx_rings; | 64 | u8 rx_rings; |
| 65 | bool flow_control; | 65 | bool flow_control; |
| 66 | bool is_64_dma; | 66 | bool is_64_dma; |
| 67 | u32 quirks; | ||
| 67 | u32 priv_data_len; | 68 | u32 priv_data_len; |
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| @@ -415,6 +415,15 @@ int aq_nic_init(struct aq_nic_s *self) · 414 unmodified lines | |||
| 415 | self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) { | 415 | self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) { |
| 416 | self->aq_hw->phy_id = HW_ATL_PHY_ID_MAX; | 416 | self->aq_hw->phy_id = HW_ATL_PHY_ID_MAX; |
| 417 | err = aq_phy_init(self->aq_hw); | 417 | err = aq_phy_init(self->aq_hw); |
| 418 | |||
| 419 | /* Disable the PTP on NICs where it's known to cause datapath | ||
| 420 | * problems. | ||
| 421 | * Ideally this should have been done by PHY provisioning, but | ||
| 422 | * many units have been shipped with enabled PTP block already. | ||
| 423 | */ | ||
| 424 | if (self->aq_nic_cfg.aq_hw_caps->quirks & AQ_NIC_QUIRK_BAD_PTP) | ||
| 425 | if (self->aq_hw->phy_id != HW_ATL_PHY_ID_MAX) | ||
| 426 | aq_phy_disable_ptp(self->aq_hw); | ||
| 418 | } | 427 | } |
| 419 | 428 | ||
| 420 | for (i = 0U; i < self->aq_vecs; i++) { | 429 | for (i = 0U; i < self->aq_vecs; i++) { |
| @@ -81,6 +81,8 @@ struct aq_nic_cfg_s { · 80 unmodified lines | |||
| 81 | #define AQ_NIC_FLAG_ERR_UNPLUG 0x40000000U | 81 | #define AQ_NIC_FLAG_ERR_UNPLUG 0x40000000U |
| 82 | #define AQ_NIC_FLAG_ERR_HW 0x80000000U | 82 | #define AQ_NIC_FLAG_ERR_HW 0x80000000U |
| 83 | 83 | ||
| 84 | #define AQ_NIC_QUIRK_BAD_PTP BIT(0) | ||
| 85 | |||
| 84 | #define AQ_NIC_WOL_MODES (WAKE_MAGIC |\ | 86 | #define AQ_NIC_WOL_MODES (WAKE_MAGIC |\ |
| 85 | WAKE_PHY) | 87 | WAKE_PHY) |
| 86 | 88 | ||
| @@ -1,10 +1,14 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* aQuantia Corporation Network Driver | 2 | /* Atlantic Network Driver |
| 3 | * Copyright (C) 2018-2019 aQuantia Corporation. All rights reserved | 3 | * |
| 4 | * Copyright (C) 2018-2019 aQuantia Corporation | ||
| 5 | * Copyright (C) 2019-2020 Marvell International Ltd. | ||
| 4 | */ | 6 | */ |
| 5 | 7 | ||
| 6 | #include "aq_phy.h" | 8 | #include "aq_phy.h" |
| 7 | 9 | ||
| 10 | #define HW_ATL_PTP_DISABLE_MSK BIT(10) | ||
| 11 | |||
| 8 | bool aq_mdio_busy_wait(struct aq_hw_s *aq_hw) | 12 | bool aq_mdio_busy_wait(struct aq_hw_s *aq_hw) |
| 9 | { | 13 | { |
| 10 | int err = 0; | 14 | int err = 0; |
| @@ -145,3 +149,24 @@ bool aq_phy_init(struct aq_hw_s *aq_hw) · 134 unmodified lines | |||
| 145 | 149 | ||
| 146 | return true; | 150 | return true; |
| 147 | } | 151 | } |
| 152 | |||
| 153 | void aq_phy_disable_ptp(struct aq_hw_s *aq_hw) | ||
| 154 | { | ||
| 155 | static const u16 ptp_registers[] = { | ||
| 156 | 0x031e, | ||
| 157 | 0x031d, | ||
| 158 | 0x031c, | ||
| 159 | 0x031b, | ||
| 160 | }; | ||
| 161 | u16 val; | ||
| 162 | int i; | ||
| 163 | |||
| 164 | for (i = 0; i < ARRAY_SIZE(ptp_registers); i++) { | ||
| 165 | val = aq_phy_read_reg(aq_hw, MDIO_MMD_VEND1, | ||
| 166 | ptp_registers[i]); | ||
| 167 | |||
| 168 | aq_phy_write_reg(aq_hw, MDIO_MMD_VEND1, | ||
| 169 | ptp_registers[i], | ||
| 170 | val & ~HW_ATL_PTP_DISABLE_MSK); | ||
| 171 | } | ||
| 172 | } | ||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* aQuantia Corporation Network Driver | 2 | /* Atlantic Network Driver |
| 3 | * Copyright (C) 2018-2019 aQuantia Corporation. All rights reserved | 3 | * |
| 4 | * Copyright (C) 2018-2019 aQuantia Corporation | ||
| 5 | * Copyright (C) 2019-2020 Marvell International Ltd. | ||
| 4 | */ | 6 | */ |
| 5 | 7 | ||
| 6 | #ifndef AQ_PHY_H | 8 | #ifndef AQ_PHY_H |
| @@ -29,4 +31,6 @@ bool aq_phy_init_phy_id(struct aq_hw_s *aq_hw); · 22 unmodified lines | |||
| 29 | 31 | ||
| 30 | bool aq_phy_init(struct aq_hw_s *aq_hw); | 32 | bool aq_phy_init(struct aq_hw_s *aq_hw); |
| 31 | 33 | ||
| 34 | void aq_phy_disable_ptp(struct aq_hw_s *aq_hw); | ||
| 35 | |||
| 32 | #endif /* AQ_PHY_H */ | 36 | #endif /* AQ_PHY_H */ |
| @@ -93,6 +93,25 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc109 = { · 92 unmodified lines | |||
| 93 | AQ_NIC_RATE_100M, | 93 | AQ_NIC_RATE_100M, |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | const struct aq_hw_caps_s hw_atl_b0_caps_aqc111 = { | ||
| 97 | DEFAULT_B0_BOARD_BASIC_CAPABILITIES, | ||
| 98 | .media_type = AQ_HW_MEDIA_TYPE_TP, | ||
| 99 | .link_speed_msk = AQ_NIC_RATE_5G | | ||
| 100 | AQ_NIC_RATE_2G5 | | ||
| 101 | AQ_NIC_RATE_1G | | ||
| 102 | AQ_NIC_RATE_100M, | ||
| 103 | .quirks = AQ_NIC_QUIRK_BAD_PTP, | ||
| 104 | }; | ||
| 105 | |||
| 106 | const struct aq_hw_caps_s hw_atl_b0_caps_aqc112 = { | ||
| 107 | DEFAULT_B0_BOARD_BASIC_CAPABILITIES, | ||
| 108 | .media_type = AQ_HW_MEDIA_TYPE_TP, | ||
| 109 | .link_speed_msk = AQ_NIC_RATE_2G5 | | ||
| 110 | AQ_NIC_RATE_1G | | ||
| 111 | AQ_NIC_RATE_100M, | ||
| 112 | .quirks = AQ_NIC_QUIRK_BAD_PTP, | ||
| 113 | }; | ||
| 114 | |||
| 96 | static int hw_atl_b0_hw_reset(struct aq_hw_s *self) | 115 | static int hw_atl_b0_hw_reset(struct aq_hw_s *self) |
| 97 | { | 116 | { |
| 98 | int err = 0; | 117 | int err = 0; |
| @@ -354,8 +373,13 @@ static int hw_atl_b0_hw_init_tx_tc_rate_limit(struct aq_hw_s *self) · 255 unmodified lines | |||
| 354 | 373 | ||
| 355 | /* WSP, if min_rate is set for at least one TC. | 374 | /* WSP, if min_rate is set for at least one TC. |
| 356 | * RR otherwise. | 375 | * RR otherwise. |
| 376 | * | ||
| 377 | * NB! MAC FW sets arb mode itself if PTP is enabled. We shouldn't | ||
| 378 | * overwrite it here in that case. | ||
| 357 | */ | 379 | */ |
| 358 | hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, min_rate_msk ? 1U : 0U); | 380 | if (!nic_cfg->is_ptp) |
| 381 | hw_atl_tps_tx_pkt_shed_data_arb_mode_set(self, min_rate_msk ? 1U : 0U); | ||
| 382 | |||
| 359 | /* Data TC Arbiter takes precedence over Descriptor TC Arbiter, | 383 | /* Data TC Arbiter takes precedence over Descriptor TC Arbiter, |
| 360 | * leave Descriptor TC Arbiter as RR. | 384 | * leave Descriptor TC Arbiter as RR. |
| 361 | */ | 385 | */ |
| @@ -18,17 +18,15 @@ extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc100; · 17 unmodified lines | |||
| 18 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc107; | 18 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc107; |
| 19 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc108; | 19 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc108; |
| 20 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc109; | 20 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc109; |
| 21 | 21 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc111; | |
| 22 | #define hw_atl_b0_caps_aqc111 hw_atl_b0_caps_aqc108 | 22 | extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc112; |
| 23 | #define hw_atl_b0_caps_aqc112 hw_atl_b0_caps_aqc109 | ||
| 24 | 23 | ||
| 25 | #define hw_atl_b0_caps_aqc100s hw_atl_b0_caps_aqc100 | 24 | #define hw_atl_b0_caps_aqc100s hw_atl_b0_caps_aqc100 |
| 26 | #define hw_atl_b0_caps_aqc107s hw_atl_b0_caps_aqc107 | 25 | #define hw_atl_b0_caps_aqc107s hw_atl_b0_caps_aqc107 |
| 27 | #define hw_atl_b0_caps_aqc108s hw_atl_b0_caps_aqc108 | 26 | #define hw_atl_b0_caps_aqc108s hw_atl_b0_caps_aqc108 |
| 28 | #define hw_atl_b0_caps_aqc109s hw_atl_b0_caps_aqc109 | 27 | #define hw_atl_b0_caps_aqc109s hw_atl_b0_caps_aqc109 |
| 29 | 28 | #define hw_atl_b0_caps_aqc111s hw_atl_b0_caps_aqc111 | |
| 30 | #define hw_atl_b0_caps_aqc111s hw_atl_b0_caps_aqc108 | 29 | #define hw_atl_b0_caps_aqc112s hw_atl_b0_caps_aqc112 |
| 31 | #define hw_atl_b0_caps_aqc112s hw_atl_b0_caps_aqc109 | ||
| 32 | 30 | ||
| 33 | extern const struct aq_hw_ops hw_atl_ops_b0; | 31 | extern const struct aq_hw_ops hw_atl_ops_b0; |
| 34 | 32 | ||
| @@ -556,7 +556,8 @@ static int ag71xx_mdio_probe(struct ag71xx *ag) · 555 unmodified lines | |||
| 556 | ag->mdio_reset = of_reset_control_get_exclusive(np, "mdio"); | 556 | ag->mdio_reset = of_reset_control_get_exclusive(np, "mdio"); |
| 557 | if (IS_ERR(ag->mdio_reset)) { | 557 | if (IS_ERR(ag->mdio_reset)) { |
| 558 | netif_err(ag, probe, ndev, "Failed to get reset mdio.\n"); | 558 | netif_err(ag, probe, ndev, "Failed to get reset mdio.\n"); |
| 559 | return PTR_ERR(ag->mdio_reset); | 559 | err = PTR_ERR(ag->mdio_reset); |
| 560 | goto mdio_err_put_clk; | ||
| 560 | } | 561 | } |
| 561 | 562 | ||
| 562 | mii_bus->name = "ag71xx_mdio"; | 563 | mii_bus->name = "ag71xx_mdio"; |
| @@ -3418,7 +3418,7 @@ void bnxt_set_tpa_flags(struct bnxt *bp) · 3417 unmodified lines | |||
| 3418 | */ | 3418 | */ |
| 3419 | void bnxt_set_ring_params(struct bnxt *bp) | 3419 | void bnxt_set_ring_params(struct bnxt *bp) |
| 3420 | { | 3420 | { |
| 3421 | u32 ring_size, rx_size, rx_space; | 3421 | u32 ring_size, rx_size, rx_space, max_rx_cmpl; |
| 3422 | u32 agg_factor = 0, agg_ring_size = 0; | 3422 | u32 agg_factor = 0, agg_ring_size = 0; |
| 3423 | 3423 | ||
| 3424 | /* 8 for CRC and VLAN */ | 3424 | /* 8 for CRC and VLAN */ |
| @@ -3474,7 +3474,15 @@ void bnxt_set_ring_params(struct bnxt *bp) · 49 unmodified lines | |||
| 3474 | bp->tx_nr_pages = bnxt_calc_nr_ring_pages(ring_size, TX_DESC_CNT); | 3474 | bp->tx_nr_pages = bnxt_calc_nr_ring_pages(ring_size, TX_DESC_CNT); |
| 3475 | bp->tx_ring_mask = (bp->tx_nr_pages * TX_DESC_CNT) - 1; | 3475 | bp->tx_ring_mask = (bp->tx_nr_pages * TX_DESC_CNT) - 1; |
| 3476 | 3476 | ||
| 3477 | ring_size = bp->rx_ring_size * (2 + agg_factor) + bp->tx_ring_size; | 3477 | max_rx_cmpl = bp->rx_ring_size; |
| 3478 | /* MAX TPA needs to be added because TPA_START completions are | ||
| 3479 | * immediately recycled, so the TPA completions are not bound by | ||
| 3480 | * the RX ring size. | ||
| 3481 | */ | ||
| 3482 | if (bp->flags & BNXT_FLAG_TPA) | ||
| 3483 | max_rx_cmpl += bp->max_tpa; | ||
| 3484 | /* RX and TPA completions are 32-byte, all others are 16-byte */ | ||
| 3485 | ring_size = max_rx_cmpl * 2 + agg_ring_size + bp->tx_ring_size; | ||
| 3478 | bp->cp_ring_size = ring_size; | 3486 | bp->cp_ring_size = ring_size; |
| 3479 | 3487 | ||
| 3480 | bp->cp_nr_pages = bnxt_calc_nr_ring_pages(ring_size, CP_DESC_CNT); | 3488 | bp->cp_nr_pages = bnxt_calc_nr_ring_pages(ring_size, CP_DESC_CNT); |
| @@ -10385,15 +10393,15 @@ static void bnxt_sp_task(struct work_struct *work) · 6904 unmodified lines | |||
| 10385 | &bp->sp_event)) | 10393 | &bp->sp_event)) |
| 10386 | bnxt_hwrm_phy_qcaps(bp); | 10394 | bnxt_hwrm_phy_qcaps(bp); |
| 10387 | 10395 | ||
| 10388 | if (test_and_clear_bit(BNXT_LINK_CFG_CHANGE_SP_EVENT, | ||
| 10389 | &bp->sp_event)) | ||
| 10390 | bnxt_init_ethtool_link_settings(bp); | ||
| 10391 | |||
| 10392 | rc = bnxt_update_link(bp, true); | 10396 | rc = bnxt_update_link(bp, true); |
| 10393 | mutex_unlock(&bp->link_lock); | ||
| 10394 | if (rc) | 10397 | if (rc) |
| 10395 | netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", | 10398 | netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", |
| 10396 | rc); | 10399 | rc); |
| 10400 | |||
| 10401 | if (test_and_clear_bit(BNXT_LINK_CFG_CHANGE_SP_EVENT, | ||
| 10402 | &bp->sp_event)) | ||
| 10403 | bnxt_init_ethtool_link_settings(bp); | ||
| 10404 | mutex_unlock(&bp->link_lock); | ||
| 10397 | } | 10405 | } |
| 10398 | if (test_and_clear_bit(BNXT_UPDATE_PHY_SP_EVENT, &bp->sp_event)) { | 10406 | if (test_and_clear_bit(BNXT_UPDATE_PHY_SP_EVENT, &bp->sp_event)) { |
| 10399 | int rc; | 10407 | int rc; |
| @@ -1765,8 +1765,11 @@ static int bnxt_set_pauseparam(struct net_device *dev, · 1764 unmodified lines | |||
| 1765 | if (epause->tx_pause) | 1765 | if (epause->tx_pause) |
| 1766 | link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX; | 1766 | link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_TX; |
| 1767 | 1767 | ||
| 1768 | if (netif_running(dev)) | 1768 | if (netif_running(dev)) { |
| 1769 | mutex_lock(&bp->link_lock); | ||
| 1769 | rc = bnxt_hwrm_set_pause(bp); | 1770 | rc = bnxt_hwrm_set_pause(bp); |
| 1771 | mutex_unlock(&bp->link_lock); | ||
| 1772 | } | ||
| 1770 | return rc; | 1773 | return rc; |
| 1771 | } | 1774 | } |
| 1772 | 1775 | ||
| @@ -543,14 +543,14 @@ static int bcmgenet_hfb_validate_mask(void *mask, size_t size) · 542 unmodified lines | |||
| 543 | #define VALIDATE_MASK(x) \ | 543 | #define VALIDATE_MASK(x) \ |
| 544 | bcmgenet_hfb_validate_mask(&(x), sizeof(x)) | 544 | bcmgenet_hfb_validate_mask(&(x), sizeof(x)) |
| 545 | 545 | ||
| 546 | static int bcmgenet_hfb_insert_data(u32 *f, int offset, | 546 | static int bcmgenet_hfb_insert_data(struct bcmgenet_priv *priv, u32 f_index, |
| 547 | void *val, void *mask, size_t size) | 547 | u32 offset, void *val, void *mask, |
| 548 | size_t size) | ||
| 548 | { | 549 | { |
| 549 | int index; | 550 | u32 index, tmp; |
| 550 | u32 tmp; | ||
| 551 | 551 | ||
| 552 | index = offset / 2; | 552 | index = f_index * priv->hw_params->hfb_filter_size + offset / 2; |
| 553 | tmp = f[index]; | 553 | tmp = bcmgenet_hfb_readl(priv, index * sizeof(u32)); |
| 554 | 554 | ||
| 555 | while (size--) { | 555 | while (size--) { |
| 556 | if (offset++ & 1) { | 556 | if (offset++ & 1) { |
| @@ -567,9 +567,10 @@ static int bcmgenet_hfb_insert_data(u32 *f, int offset, · 10 unmodified lines | |||
| 567 | tmp |= 0x10000; | 567 | tmp |= 0x10000; |
| 568 | break; | 568 | break; |
| 569 | } | 569 | } |
| 570 | f[index++] = tmp; | 570 | bcmgenet_hfb_writel(priv, tmp, index++ * sizeof(u32)); |
| 571 | if (size) | 571 | if (size) |
| 572 | tmp = f[index]; | 572 | tmp = bcmgenet_hfb_readl(priv, |
| 573 | index * sizeof(u32)); | ||
| 573 | } else { | 574 | } else { |
| 574 | tmp &= ~0xCFF00; | 575 | tmp &= ~0xCFF00; |
| 575 | tmp |= (*(unsigned char *)val++) << 8; | 576 | tmp |= (*(unsigned char *)val++) << 8; |
| @@ -585,44 +586,26 @@ static int bcmgenet_hfb_insert_data(u32 *f, int offset, · 9 unmodified lines | |||
| 585 | break; | 586 | break; |
| 586 | } | 587 | } |
| 587 | if (!size) | 588 | if (!size) |
| 588 | f[index] = tmp; | 589 | bcmgenet_hfb_writel(priv, tmp, index * sizeof(u32)); |
| 589 | } | 590 | } |
| 590 | } | 591 | } |
| 591 | 592 | ||
| 592 | return 0; | 593 | return 0; |
| 593 | } | 594 | } |
| 594 | 595 | ||
| 595 | static void bcmgenet_hfb_set_filter(struct bcmgenet_priv *priv, u32 *f_data, | 596 | static void bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, |
| 596 | u32 f_length, u32 rx_queue, int f_index) | 597 | struct bcmgenet_rxnfc_rule *rule) |
| 597 | { | ||
| 598 | u32 base = f_index * priv->hw_params->hfb_filter_size; | ||
| 599 | int i; | ||
| 600 | |||
| 601 | for (i = 0; i < f_length; i++) | ||
| 602 | bcmgenet_hfb_writel(priv, f_data[i], (base + i) * sizeof(u32)); | ||
| 603 | |||
| 604 | bcmgenet_hfb_set_filter_length(priv, f_index, 2 * f_length); | ||
| 605 | bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f_index, rx_queue); | ||
| 606 | } | ||
| 607 | |||
| 608 | static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, | ||
| 609 | struct bcmgenet_rxnfc_rule *rule) | ||
| 610 | { | 598 | { |
| 611 | struct ethtool_rx_flow_spec *fs = &rule->fs; | 599 | struct ethtool_rx_flow_spec *fs = &rule->fs; |
| 612 | int err = 0, offset = 0, f_length = 0; | 600 | u32 offset = 0, f_length = 0, f; |
| 613 | u8 val_8, mask_8; | 601 | u8 val_8, mask_8; |
| 614 | __be16 val_16; | 602 | __be16 val_16; |
| 615 | u16 mask_16; | 603 | u16 mask_16; |
| 616 | size_t size; | 604 | size_t size; |
| 617 | u32 *f_data; | ||
| 618 | |||
| 619 | f_data = kcalloc(priv->hw_params->hfb_filter_size, sizeof(u32), | ||
| 620 | GFP_KERNEL); | ||
| 621 | if (!f_data) | ||
| 622 | return -ENOMEM; | ||
| 623 | 605 | ||
| 606 | f = fs->location; | ||
| 624 | if (fs->flow_type & FLOW_MAC_EXT) { | 607 | if (fs->flow_type & FLOW_MAC_EXT) { |
| 625 | bcmgenet_hfb_insert_data(f_data, 0, | 608 | bcmgenet_hfb_insert_data(priv, f, 0, |
| 626 | &fs->h_ext.h_dest, &fs->m_ext.h_dest, | 609 | &fs->h_ext.h_dest, &fs->m_ext.h_dest, |
| 627 | sizeof(fs->h_ext.h_dest)); | 610 | sizeof(fs->h_ext.h_dest)); |
| 628 | } | 611 | } |
| @@ -630,11 +613,11 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 1 unmodified line | |||
| 630 | if (fs->flow_type & FLOW_EXT) { | 613 | if (fs->flow_type & FLOW_EXT) { |
| 631 | if (fs->m_ext.vlan_etype || | 614 | if (fs->m_ext.vlan_etype || |
| 632 | fs->m_ext.vlan_tci) { | 615 | fs->m_ext.vlan_tci) { |
| 633 | bcmgenet_hfb_insert_data(f_data, 12, | 616 | bcmgenet_hfb_insert_data(priv, f, 12, |
| 634 | &fs->h_ext.vlan_etype, | 617 | &fs->h_ext.vlan_etype, |
| 635 | &fs->m_ext.vlan_etype, | 618 | &fs->m_ext.vlan_etype, |
| 636 | sizeof(fs->h_ext.vlan_etype)); | 619 | sizeof(fs->h_ext.vlan_etype)); |
| 637 | bcmgenet_hfb_insert_data(f_data, 14, | 620 | bcmgenet_hfb_insert_data(priv, f, 14, |
| 638 | &fs->h_ext.vlan_tci, | 621 | &fs->h_ext.vlan_tci, |
| 639 | &fs->m_ext.vlan_tci, | 622 | &fs->m_ext.vlan_tci, |
| 640 | sizeof(fs->h_ext.vlan_tci)); | 623 | sizeof(fs->h_ext.vlan_tci)); |
| @@ -646,15 +629,15 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 5 unmodified lines | |||
| 646 | switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { | 629 | switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { |
| 647 | case ETHER_FLOW: | 630 | case ETHER_FLOW: |
| 648 | f_length += DIV_ROUND_UP(ETH_HLEN, 2); | 631 | f_length += DIV_ROUND_UP(ETH_HLEN, 2); |
| 649 | bcmgenet_hfb_insert_data(f_data, 0, | 632 | bcmgenet_hfb_insert_data(priv, f, 0, |
| 650 | &fs->h_u.ether_spec.h_dest, | 633 | &fs->h_u.ether_spec.h_dest, |
| 651 | &fs->m_u.ether_spec.h_dest, | 634 | &fs->m_u.ether_spec.h_dest, |
| 652 | sizeof(fs->h_u.ether_spec.h_dest)); | 635 | sizeof(fs->h_u.ether_spec.h_dest)); |
| 653 | bcmgenet_hfb_insert_data(f_data, ETH_ALEN, | 636 | bcmgenet_hfb_insert_data(priv, f, ETH_ALEN, |
| 654 | &fs->h_u.ether_spec.h_source, | 637 | &fs->h_u.ether_spec.h_source, |
| 655 | &fs->m_u.ether_spec.h_source, | 638 | &fs->m_u.ether_spec.h_source, |
| 656 | sizeof(fs->h_u.ether_spec.h_source)); | 639 | sizeof(fs->h_u.ether_spec.h_source)); |
| 657 | bcmgenet_hfb_insert_data(f_data, (2 * ETH_ALEN) + offset, | 640 | bcmgenet_hfb_insert_data(priv, f, (2 * ETH_ALEN) + offset, |
| 658 | &fs->h_u.ether_spec.h_proto, | 641 | &fs->h_u.ether_spec.h_proto, |
| 659 | &fs->m_u.ether_spec.h_proto, | 642 | &fs->m_u.ether_spec.h_proto, |
| 660 | sizeof(fs->h_u.ether_spec.h_proto)); | 643 | sizeof(fs->h_u.ether_spec.h_proto)); |
| @@ -664,21 +647,21 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 3 unmodified lines | |||
| 664 | /* Specify IP Ether Type */ | 647 | /* Specify IP Ether Type */ |
| 665 | val_16 = htons(ETH_P_IP); | 648 | val_16 = htons(ETH_P_IP); |
| 666 | mask_16 = 0xFFFF; | 649 | mask_16 = 0xFFFF; |
| 667 | bcmgenet_hfb_insert_data(f_data, (2 * ETH_ALEN) + offset, | 650 | bcmgenet_hfb_insert_data(priv, f, (2 * ETH_ALEN) + offset, |
| 668 | &val_16, &mask_16, sizeof(val_16)); | 651 | &val_16, &mask_16, sizeof(val_16)); |
| 669 | bcmgenet_hfb_insert_data(f_data, 15 + offset, | 652 | bcmgenet_hfb_insert_data(priv, f, 15 + offset, |
| 670 | &fs->h_u.usr_ip4_spec.tos, | 653 | &fs->h_u.usr_ip4_spec.tos, |
| 671 | &fs->m_u.usr_ip4_spec.tos, | 654 | &fs->m_u.usr_ip4_spec.tos, |
| 672 | sizeof(fs->h_u.usr_ip4_spec.tos)); | 655 | sizeof(fs->h_u.usr_ip4_spec.tos)); |
| 673 | bcmgenet_hfb_insert_data(f_data, 23 + offset, | 656 | bcmgenet_hfb_insert_data(priv, f, 23 + offset, |
| 674 | &fs->h_u.usr_ip4_spec.proto, | 657 | &fs->h_u.usr_ip4_spec.proto, |
| 675 | &fs->m_u.usr_ip4_spec.proto, | 658 | &fs->m_u.usr_ip4_spec.proto, |
| 676 | sizeof(fs->h_u.usr_ip4_spec.proto)); | 659 | sizeof(fs->h_u.usr_ip4_spec.proto)); |
| 677 | bcmgenet_hfb_insert_data(f_data, 26 + offset, | 660 | bcmgenet_hfb_insert_data(priv, f, 26 + offset, |
| 678 | &fs->h_u.usr_ip4_spec.ip4src, | 661 | &fs->h_u.usr_ip4_spec.ip4src, |
| 679 | &fs->m_u.usr_ip4_spec.ip4src, | 662 | &fs->m_u.usr_ip4_spec.ip4src, |
| 680 | sizeof(fs->h_u.usr_ip4_spec.ip4src)); | 663 | sizeof(fs->h_u.usr_ip4_spec.ip4src)); |
| 681 | bcmgenet_hfb_insert_data(f_data, 30 + offset, | 664 | bcmgenet_hfb_insert_data(priv, f, 30 + offset, |
| 682 | &fs->h_u.usr_ip4_spec.ip4dst, | 665 | &fs->h_u.usr_ip4_spec.ip4dst, |
| 683 | &fs->m_u.usr_ip4_spec.ip4dst, | 666 | &fs->m_u.usr_ip4_spec.ip4dst, |
| 684 | sizeof(fs->h_u.usr_ip4_spec.ip4dst)); | 667 | sizeof(fs->h_u.usr_ip4_spec.ip4dst)); |
| @@ -688,11 +671,11 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 3 unmodified lines | |||
| 688 | /* Only supports 20 byte IPv4 header */ | 671 | /* Only supports 20 byte IPv4 header */ |
| 689 | val_8 = 0x45; | 672 | val_8 = 0x45; |
| 690 | mask_8 = 0xFF; | 673 | mask_8 = 0xFF; |
| 691 | bcmgenet_hfb_insert_data(f_data, ETH_HLEN + offset, | 674 | bcmgenet_hfb_insert_data(priv, f, ETH_HLEN + offset, |
| 692 | &val_8, &mask_8, | 675 | &val_8, &mask_8, |
| 693 | sizeof(val_8)); | 676 | sizeof(val_8)); |
| 694 | size = sizeof(fs->h_u.usr_ip4_spec.l4_4_bytes); | 677 | size = sizeof(fs->h_u.usr_ip4_spec.l4_4_bytes); |
| 695 | bcmgenet_hfb_insert_data(f_data, | 678 | bcmgenet_hfb_insert_data(priv, f, |
| 696 | ETH_HLEN + 20 + offset, | 679 | ETH_HLEN + 20 + offset, |
| 697 | &fs->h_u.usr_ip4_spec.l4_4_bytes, | 680 | &fs->h_u.usr_ip4_spec.l4_4_bytes, |
| 698 | &fs->m_u.usr_ip4_spec.l4_4_bytes, | 681 | &fs->m_u.usr_ip4_spec.l4_4_bytes, |
| @@ -701,34 +684,42 @@ static int bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv, · 2 unmodified lines | |||
| 701 | break; | 684 | break; |
| 702 | } | 685 | } |
| 703 | 686 | ||
| 687 | bcmgenet_hfb_set_filter_length(priv, f, 2 * f_length); | ||
| 704 | if (!fs->ring_cookie || fs->ring_cookie == RX_CLS_FLOW_WAKE) { | 688 | if (!fs->ring_cookie || fs->ring_cookie == RX_CLS_FLOW_WAKE) { |
| 705 | /* Ring 0 flows can be handled by the default Descriptor Ring | 689 | /* Ring 0 flows can be handled by the default Descriptor Ring |
| 706 | * We'll map them to ring 0, but don't enable the filter | 690 | * We'll map them to ring 0, but don't enable the filter |
| 707 | */ | 691 | */ |
| 708 | bcmgenet_hfb_set_filter(priv, f_data, f_length, 0, | 692 | bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f, 0); |
| 709 | fs->location); | ||
| 710 | rule->state = BCMGENET_RXNFC_STATE_DISABLED; | 693 | rule->state = BCMGENET_RXNFC_STATE_DISABLED; |
| 711 | } else { | 694 | } else { |
| 712 | /* Other Rx rings are direct mapped here */ | 695 | /* Other Rx rings are direct mapped here */ |
| 713 | bcmgenet_hfb_set_filter(priv, f_data, f_length, | 696 | bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f, |
| 714 | fs->ring_cookie, fs->location); | 697 | fs->ring_cookie); |
| 715 | bcmgenet_hfb_enable_filter(priv, fs->location); | 698 | bcmgenet_hfb_enable_filter(priv, f); |
| 716 | rule->state = BCMGENET_RXNFC_STATE_ENABLED; | 699 | rule->state = BCMGENET_RXNFC_STATE_ENABLED; |
| 717 | } | 700 | } |
| 718 | |||
| 719 | kfree(f_data); | ||
| 720 | |||
| 721 | return err; | ||
| 722 | } | 701 | } |
| 723 | 702 | ||
| 724 | /* bcmgenet_hfb_clear | 703 | /* bcmgenet_hfb_clear |
| 725 | * | 704 | * |
| 726 | * Clear Hardware Filter Block and disable all filtering. | 705 | * Clear Hardware Filter Block and disable all filtering. |
| 727 | */ | 706 | */ |
| 707 | static void bcmgenet_hfb_clear_filter(struct bcmgenet_priv *priv, u32 f_index) | ||
| 708 | { | ||
| 709 | u32 base, i; | ||
| 710 | |||
| 711 | base = f_index * priv->hw_params->hfb_filter_size; | ||
| 712 | for (i = 0; i < priv->hw_params->hfb_filter_size; i++) | ||
| 713 | bcmgenet_hfb_writel(priv, 0x0, (base + i) * sizeof(u32)); | ||
| 714 | } | ||
| 715 | |||
| 728 | static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) | 716 | static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) |
| 729 | { | 717 | { |
| 730 | u32 i; | 718 | u32 i; |
| 731 | 719 | ||
| 720 | if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) | ||
| 721 | return; | ||
| 722 | |||
| 732 | bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL); | 723 | bcmgenet_hfb_reg_writel(priv, 0x0, HFB_CTRL); |
| 733 | bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS); | 724 | bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS); |
| 734 | bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4); | 725 | bcmgenet_hfb_reg_writel(priv, 0x0, HFB_FLT_ENABLE_V3PLUS + 4); |
| @@ -740,19 +731,18 @@ static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv) · 5 unmodified lines | |||
| 740 | bcmgenet_hfb_reg_writel(priv, 0x0, | 731 | bcmgenet_hfb_reg_writel(priv, 0x0, |
| 741 | HFB_FLT_LEN_V3PLUS + i * sizeof(u32)); | 732 | HFB_FLT_LEN_V3PLUS + i * sizeof(u32)); |
| 742 | 733 | ||
| 743 | for (i = 0; i < priv->hw_params->hfb_filter_cnt * | 734 | for (i = 0; i < priv->hw_params->hfb_filter_cnt; i++) |
| 744 | priv->hw_params->hfb_filter_size; i++) | 735 | bcmgenet_hfb_clear_filter(priv, i); |
| 745 | bcmgenet_hfb_writel(priv, 0x0, i * sizeof(u32)); | ||
| 746 | } | 736 | } |
| 747 | 737 | ||
| 748 | static void bcmgenet_hfb_init(struct bcmgenet_priv *priv) | 738 | static void bcmgenet_hfb_init(struct bcmgenet_priv *priv) |
| 749 | { | 739 | { |
| 750 | int i; | 740 | int i; |
| 751 | 741 | ||
| 742 | INIT_LIST_HEAD(&priv->rxnfc_list); | ||
| 752 | if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) | 743 | if (GENET_IS_V1(priv) || GENET_IS_V2(priv)) |
| 753 | return; | 744 | return; |
| 754 | 745 | ||
| 755 | INIT_LIST_HEAD(&priv->rxnfc_list); | ||
| 756 | for (i = 0; i < MAX_NUM_OF_FS_RULES; i++) { | 746 | for (i = 0; i < MAX_NUM_OF_FS_RULES; i++) { |
| 757 | INIT_LIST_HEAD(&priv->rxnfc_rules[i].list); | 747 | INIT_LIST_HEAD(&priv->rxnfc_rules[i].list); |
| 758 | priv->rxnfc_rules[i].state = BCMGENET_RXNFC_STATE_UNUSED; | 748 | priv->rxnfc_rules[i].state = BCMGENET_RXNFC_STATE_UNUSED; |
| @@ -1437,18 +1427,15 @@ static int bcmgenet_insert_flow(struct net_device *dev, · 678 unmodified lines | |||
| 1437 | loc_rule = &priv->rxnfc_rules[cmd->fs.location]; | 1427 | loc_rule = &priv->rxnfc_rules[cmd->fs.location]; |
| 1438 | if (loc_rule->state == BCMGENET_RXNFC_STATE_ENABLED) | 1428 | if (loc_rule->state == BCMGENET_RXNFC_STATE_ENABLED) |
| 1439 | bcmgenet_hfb_disable_filter(priv, cmd->fs.location); | 1429 | bcmgenet_hfb_disable_filter(priv, cmd->fs.location); |
| 1440 | if (loc_rule->state != BCMGENET_RXNFC_STATE_UNUSED) | 1430 | if (loc_rule->state != BCMGENET_RXNFC_STATE_UNUSED) { |
| 1441 | list_del(&loc_rule->list); | 1431 | list_del(&loc_rule->list); |
| 1432 | bcmgenet_hfb_clear_filter(priv, cmd->fs.location); | ||
| 1433 | } | ||
| 1442 | loc_rule->state = BCMGENET_RXNFC_STATE_UNUSED; | 1434 | loc_rule->state = BCMGENET_RXNFC_STATE_UNUSED; |
| 1443 | memcpy(&loc_rule->fs, &cmd->fs, | 1435 | memcpy(&loc_rule->fs, &cmd->fs, |
| 1444 | sizeof(struct ethtool_rx_flow_spec)); | 1436 | sizeof(struct ethtool_rx_flow_spec)); |
| 1445 | 1437 | ||
| 1446 | err = bcmgenet_hfb_create_rxnfc_filter(priv, loc_rule); | 1438 | bcmgenet_hfb_create_rxnfc_filter(priv, loc_rule); |
| 1447 | if (err) { | ||
| 1448 | netdev_err(dev, "rxnfc: Could not install rule (%d)\n", | ||
| 1449 | err); | ||
| 1450 | return err; | ||
| 1451 | } | ||
| 1452 | 1439 | ||
| 1453 | list_add_tail(&loc_rule->list, &priv->rxnfc_list); | 1440 | list_add_tail(&loc_rule->list, &priv->rxnfc_list); |
| 1454 | 1441 | ||
| @@ -1473,8 +1460,10 @@ static int bcmgenet_delete_flow(struct net_device *dev, · 18 unmodified lines | |||
| 1473 | 1460 | ||
| 1474 | if (rule->state == BCMGENET_RXNFC_STATE_ENABLED) | 1461 | if (rule->state == BCMGENET_RXNFC_STATE_ENABLED) |
| 1475 | bcmgenet_hfb_disable_filter(priv, cmd->fs.location); | 1462 | bcmgenet_hfb_disable_filter(priv, cmd->fs.location); |
| 1476 | if (rule->state != BCMGENET_RXNFC_STATE_UNUSED) | 1463 | if (rule->state != BCMGENET_RXNFC_STATE_UNUSED) { |
| 1477 | list_del(&rule->list); | 1464 | list_del(&rule->list); |
| 1465 | bcmgenet_hfb_clear_filter(priv, cmd->fs.location); | ||
| 1466 | } | ||
| 1478 | rule->state = BCMGENET_RXNFC_STATE_UNUSED; | 1467 | rule->state = BCMGENET_RXNFC_STATE_UNUSED; |
| 1479 | memset(&rule->fs, 0, sizeof(struct ethtool_rx_flow_spec)); | 1468 | memset(&rule->fs, 0, sizeof(struct ethtool_rx_flow_spec)); |
| 1480 | 1469 | ||
| @@ -3999,7 +3988,7 @@ static int bcmgenet_probe(struct platform_device *pdev) · 2518 unmodified lines | |||
| 3999 | if (err) | 3988 | if (err) |
| 4000 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | 3989 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); |
| 4001 | if (err) | 3990 | if (err) |
| 4002 | goto err; | 3991 | goto err_clk_disable; |
| 4003 | 3992 | ||
| 4004 | /* Mii wait queue */ | 3993 | /* Mii wait queue */ |
| 4005 | init_waitqueue_head(&priv->wq); | 3994 | init_waitqueue_head(&priv->wq); |
| @@ -4011,14 +4000,14 @@ static int bcmgenet_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 4011 | if (IS_ERR(priv->clk_wol)) { | 4000 | if (IS_ERR(priv->clk_wol)) { |
| 4012 | dev_dbg(&priv->pdev->dev, "failed to get enet-wol clock\n"); | 4001 | dev_dbg(&priv->pdev->dev, "failed to get enet-wol clock\n"); |
| 4013 | err = PTR_ERR(priv->clk_wol); | 4002 | err = PTR_ERR(priv->clk_wol); |
| 4014 | goto err; | 4003 | goto err_clk_disable; |
| 4015 | } | 4004 | } |
| 4016 | 4005 | ||
| 4017 | priv->clk_eee = devm_clk_get_optional(&priv->pdev->dev, "enet-eee"); | 4006 | priv->clk_eee = devm_clk_get_optional(&priv->pdev->dev, "enet-eee"); |
| 4018 | if (IS_ERR(priv->clk_eee)) { | 4007 | if (IS_ERR(priv->clk_eee)) { |
| 4019 | dev_dbg(&priv->pdev->dev, "failed to get enet-eee clock\n"); | 4008 | dev_dbg(&priv->pdev->dev, "failed to get enet-eee clock\n"); |
| 4020 | err = PTR_ERR(priv->clk_eee); | 4009 | err = PTR_ERR(priv->clk_eee); |
| 4021 | goto err; | 4010 | goto err_clk_disable; |
| 4022 | } | 4011 | } |
| 4023 | 4012 | ||
| 4024 | /* If this is an internal GPHY, power it on now, before UniMAC is | 4013 | /* If this is an internal GPHY, power it on now, before UniMAC is |
| @@ -4129,8 +4118,9 @@ static int bcmgenet_resume(struct device *d) · 104 unmodified lines | |||
| 4129 | { | 4118 | { |
| 4130 | struct net_device *dev = dev_get_drvdata(d); | 4119 | struct net_device *dev = dev_get_drvdata(d); |
| 4131 | struct bcmgenet_priv *priv = netdev_priv(dev); | 4120 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 4121 | struct bcmgenet_rxnfc_rule *rule; | ||
| 4132 | unsigned long dma_ctrl; | 4122 | unsigned long dma_ctrl; |
| 4133 | u32 offset, reg; | 4123 | u32 reg; |
| 4134 | int ret; | 4124 | int ret; |
| 4135 | 4125 | ||
| 4136 | if (!netif_running(dev)) | 4126 | if (!netif_running(dev)) |
| @@ -4161,10 +4151,11 @@ static int bcmgenet_resume(struct device *d) · 24 unmodified lines | |||
| 4161 | 4151 | ||
| 4162 | bcmgenet_set_hw_addr(priv, dev->dev_addr); | 4152 | bcmgenet_set_hw_addr(priv, dev->dev_addr); |
| 4163 | 4153 | ||
| 4164 | offset = HFB_FLT_ENABLE_V3PLUS; | 4154 | /* Restore hardware filters */ |
| 4165 | bcmgenet_hfb_reg_writel(priv, priv->hfb_en[1], offset); | 4155 | bcmgenet_hfb_clear(priv); |
| 4166 | bcmgenet_hfb_reg_writel(priv, priv->hfb_en[2], offset + sizeof(u32)); | 4156 | list_for_each_entry(rule, &priv->rxnfc_list, list) |
| 4167 | bcmgenet_hfb_reg_writel(priv, priv->hfb_en[0], HFB_CTRL); | 4157 | if (rule->state != BCMGENET_RXNFC_STATE_UNUSED) |
| 4158 | bcmgenet_hfb_create_rxnfc_filter(priv, rule); | ||
| 4168 | 4159 | ||
| 4169 | if (priv->internal_phy) { | 4160 | if (priv->internal_phy) { |
| 4170 | reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); | 4161 | reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); |
| @@ -4208,7 +4199,6 @@ static int bcmgenet_suspend(struct device *d) · 37 unmodified lines | |||
| 4208 | { | 4199 | { |
| 4209 | struct net_device *dev = dev_get_drvdata(d); | 4200 | struct net_device *dev = dev_get_drvdata(d); |
| 4210 | struct bcmgenet_priv *priv = netdev_priv(dev); | 4201 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| 4211 | u32 offset; | ||
| 4212 | 4202 | ||
| 4213 | if (!netif_running(dev)) | 4203 | if (!netif_running(dev)) |
| 4214 | return 0; | 4204 | return 0; |
| @@ -4220,11 +4210,7 @@ static int bcmgenet_suspend(struct device *d) · 5 unmodified lines | |||
| 4220 | if (!device_may_wakeup(d)) | 4210 | if (!device_may_wakeup(d)) |
| 4221 | phy_suspend(dev->phydev); | 4211 | phy_suspend(dev->phydev); |
| 4222 | 4212 | ||
| 4223 | /* Preserve filter state and disable filtering */ | 4213 | /* Disable filtering */ |
| 4224 | priv->hfb_en[0] = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); | ||
| 4225 | offset = HFB_FLT_ENABLE_V3PLUS; | ||
| 4226 | priv->hfb_en[1] = bcmgenet_hfb_reg_readl(priv, offset); | ||
| 4227 | priv->hfb_en[2] = bcmgenet_hfb_reg_readl(priv, offset + sizeof(u32)); | ||
| 4228 | bcmgenet_hfb_reg_writel(priv, 0, HFB_CTRL); | 4214 | bcmgenet_hfb_reg_writel(priv, 0, HFB_CTRL); |
| 4229 | 4215 | ||
| 4230 | return 0; | 4216 | return 0; |
| @@ -696,7 +696,6 @@ struct bcmgenet_priv { · 695 unmodified lines | |||
| 696 | u32 wolopts; | 696 | u32 wolopts; |
| 697 | u8 sopass[SOPASS_MAX]; | 697 | u8 sopass[SOPASS_MAX]; |
| 698 | bool wol_active; | 698 | bool wol_active; |
| 699 | u32 hfb_en[3]; | ||
| 700 | 699 | ||
| 701 | struct bcmgenet_mib_counters mib; | 700 | struct bcmgenet_mib_counters mib; |
| 702 | 701 | ||
| @@ -217,20 +217,28 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, · 216 unmodified lines | |||
| 217 | 217 | ||
| 218 | priv->wol_active = 0; | 218 | priv->wol_active = 0; |
| 219 | clk_disable_unprepare(priv->clk_wol); | 219 | clk_disable_unprepare(priv->clk_wol); |
| 220 | priv->crc_fwd_en = 0; | ||
| 220 | 221 | ||
| 221 | /* Disable Magic Packet Detection */ | 222 | /* Disable Magic Packet Detection */ |
| 222 | reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); | 223 | if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { |
| 223 | reg &= ~(MPD_EN | MPD_PW_EN); | 224 | reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); |
| 224 | bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); | 225 | if (!(reg & MPD_EN)) |
| 226 | return; /* already reset so skip the rest */ | ||
| 227 | reg &= ~(MPD_EN | MPD_PW_EN); | ||
| 228 | bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); | ||
| 229 | } | ||
| 225 | 230 | ||
| 226 | /* Disable WAKE_FILTER Detection */ | 231 | /* Disable WAKE_FILTER Detection */ |
| 227 | reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); | 232 | if (priv->wolopts & WAKE_FILTER) { |
| 228 | reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN); | 233 | reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); |
| 229 | bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); | 234 | if (!(reg & RBUF_ACPI_EN)) |
| 235 | return; /* already reset so skip the rest */ | ||
| 236 | reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN); | ||
| 237 | bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); | ||
| 238 | } | ||
| 230 | 239 | ||
| 231 | /* Disable CRC Forward */ | 240 | /* Disable CRC Forward */ |
| 232 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); | 241 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 233 | reg &= ~CMD_CRC_FWD; | 242 | reg &= ~CMD_CRC_FWD; |
| 234 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); | 243 | bcmgenet_umac_writel(priv, reg, UMAC_CMD); |
| 235 | priv->crc_fwd_en = 0; | ||
| 236 | } | 244 | } |
| @@ -3736,7 +3736,7 @@ static int macb_init(struct platform_device *pdev) · 3735 unmodified lines | |||
| 3736 | 3736 | ||
| 3737 | if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) { | 3737 | if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) { |
| 3738 | val = 0; | 3738 | val = 0; |
| 3739 | if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII) | 3739 | if (phy_interface_mode_is_rgmii(bp->phy_interface)) |
| 3740 | val = GEM_BIT(RGMII); | 3740 | val = GEM_BIT(RGMII); |
| 3741 | else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && | 3741 | else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && |
| 3742 | (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII)) | 3742 | (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII)) |
| @@ -2938,6 +2938,7 @@ static inline int uld_send(struct adapter *adap, struct sk_buff *skb, · 2937 unmodified lines | |||
| 2938 | txq_info = adap->sge.uld_txq_info[tx_uld_type]; | 2938 | txq_info = adap->sge.uld_txq_info[tx_uld_type]; |
| 2939 | if (unlikely(!txq_info)) { | 2939 | if (unlikely(!txq_info)) { |
| 2940 | WARN_ON(true); | 2940 | WARN_ON(true); |
| 2941 | kfree_skb(skb); | ||
| 2941 | return NET_XMIT_DROP; | 2942 | return NET_XMIT_DROP; |
| 2942 | } | 2943 | } |
| 2943 | 2944 | ||
| @@ -2938,7 +2938,7 @@ static int dpaa_eth_probe(struct platform_device *pdev) · 2937 unmodified lines | |||
| 2938 | DMA_BIT_MASK(40)); | 2938 | DMA_BIT_MASK(40)); |
| 2939 | if (err) { | 2939 | if (err) { |
| 2940 | netdev_err(net_dev, "dma_coerce_mask_and_coherent() failed\n"); | 2940 | netdev_err(net_dev, "dma_coerce_mask_and_coherent() failed\n"); |
| 2941 | return err; | 2941 | goto free_netdev; |
| 2942 | } | 2942 | } |
| 2943 | 2943 | ||
| 2944 | /* If fsl_fm_max_frm is set to a higher value than the all-common 1500, | 2944 | /* If fsl_fm_max_frm is set to a higher value than the all-common 1500, |
| @@ -3632,7 +3632,7 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) · 3631 unmodified lines | |||
| 3632 | 3632 | ||
| 3633 | dpni_dev = to_fsl_mc_device(priv->net_dev->dev.parent); | 3633 | dpni_dev = to_fsl_mc_device(priv->net_dev->dev.parent); |
| 3634 | dpmac_dev = fsl_mc_get_endpoint(dpni_dev); | 3634 | dpmac_dev = fsl_mc_get_endpoint(dpni_dev); |
| 3635 | if (IS_ERR(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) | 3635 | if (IS_ERR_OR_NULL(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) |
| 3636 | return 0; | 3636 | return 0; |
| 3637 | 3637 | ||
| 3638 | if (dpaa2_mac_is_type_fixed(dpmac_dev, priv->mc_io)) | 3638 | if (dpaa2_mac_is_type_fixed(dpmac_dev, priv->mc_io)) |
| @@ -906,6 +906,7 @@ static int enetc_pf_probe(struct pci_dev *pdev, · 905 unmodified lines | |||
| 906 | return 0; | 906 | return 0; |
| 907 | 907 | ||
| 908 | err_reg_netdev: | 908 | err_reg_netdev: |
| 909 | enetc_mdio_remove(pf); | ||
| 909 | enetc_of_put_phy(priv); | 910 | enetc_of_put_phy(priv); |
| 910 | enetc_free_msix(priv); | 911 | enetc_free_msix(priv); |
| 911 | err_alloc_msix: | 912 | err_alloc_msix: |
| @@ -590,6 +590,7 @@ struct fec_enet_private { · 589 unmodified lines | |||
| 590 | void fec_ptp_init(struct platform_device *pdev, int irq_idx); | 590 | void fec_ptp_init(struct platform_device *pdev, int irq_idx); |
| 591 | void fec_ptp_stop(struct platform_device *pdev); | 591 | void fec_ptp_stop(struct platform_device *pdev); |
| 592 | void fec_ptp_start_cyclecounter(struct net_device *ndev); | 592 | void fec_ptp_start_cyclecounter(struct net_device *ndev); |
| 593 | void fec_ptp_disable_hwts(struct net_device *ndev); | ||
| 593 | int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr); | 594 | int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr); |
| 594 | int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); | 595 | int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); |
| 595 | 596 | ||
| @@ -1294,8 +1294,13 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) · 1293 unmodified lines | |||
| 1294 | ndev->stats.tx_bytes += skb->len; | 1294 | ndev->stats.tx_bytes += skb->len; |
| 1295 | } | 1295 | } |
| 1296 | 1296 | ||
| 1297 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) && | 1297 | /* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who |
| 1298 | fep->bufdesc_ex) { | 1298 | * are to time stamp the packet, so we still need to check time |
| 1299 | * stamping enabled flag. | ||
| 1300 | */ | ||
| 1301 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS && | ||
| 1302 | fep->hwts_tx_en) && | ||
| 1303 | fep->bufdesc_ex) { | ||
| 1299 | struct skb_shared_hwtstamps shhwtstamps; | 1304 | struct skb_shared_hwtstamps shhwtstamps; |
| 1300 | struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; | 1305 | struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; |
| 1301 | 1306 | ||
| @@ -2723,10 +2728,16 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) · 1421 unmodified lines | |||
| 2723 | return -ENODEV; | 2728 | return -ENODEV; |
| 2724 | 2729 | ||
| 2725 | if (fep->bufdesc_ex) { | 2730 | if (fep->bufdesc_ex) { |
| 2726 | if (cmd == SIOCSHWTSTAMP) | 2731 | bool use_fec_hwts = !phy_has_hwtstamp(phydev); |
| 2727 | return fec_ptp_set(ndev, rq); | 2732 | |
| 2728 | if (cmd == SIOCGHWTSTAMP) | 2733 | if (cmd == SIOCSHWTSTAMP) { |
| 2729 | return fec_ptp_get(ndev, rq); | 2734 | if (use_fec_hwts) |
| 2735 | return fec_ptp_set(ndev, rq); | ||
| 2736 | fec_ptp_disable_hwts(ndev); | ||
| 2737 | } else if (cmd == SIOCGHWTSTAMP) { | ||
| 2738 | if (use_fec_hwts) | ||
| 2739 | return fec_ptp_get(ndev, rq); | ||
| 2740 | } | ||
| 2730 | } | 2741 | } |
| 2731 | 2742 | ||
| 2732 | return phy_mii_ioctl(phydev, rq, cmd); | 2743 | return phy_mii_ioctl(phydev, rq, cmd); |
| @@ -452,6 +452,18 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, · 451 unmodified lines | |||
| 452 | return -EOPNOTSUPP; | 452 | return -EOPNOTSUPP; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | /** | ||
| 456 | * fec_ptp_disable_hwts - disable hardware time stamping | ||
| 457 | * @ndev: pointer to net_device | ||
| 458 | */ | ||
| 459 | void fec_ptp_disable_hwts(struct net_device *ndev) | ||
| 460 | { | ||
| 461 | struct fec_enet_private *fep = netdev_priv(ndev); | ||
| 462 | |||
| 463 | fep->hwts_tx_en = 0; | ||
| 464 | fep->hwts_rx_en = 0; | ||
| 465 | } | ||
| 466 | |||
| 455 | int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr) | 467 | int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr) |
| 456 | { | 468 | { |
| 457 | struct fec_enet_private *fep = netdev_priv(ndev); | 469 | struct fec_enet_private *fep = netdev_priv(ndev); |
| @@ -779,8 +779,12 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) · 778 unmodified lines | |||
| 779 | 779 | ||
| 780 | mac_addr = of_get_mac_address(np); | 780 | mac_addr = of_get_mac_address(np); |
| 781 | 781 | ||
| 782 | if (!IS_ERR(mac_addr)) | 782 | if (!IS_ERR(mac_addr)) { |
| 783 | ether_addr_copy(dev->dev_addr, mac_addr); | 783 | ether_addr_copy(dev->dev_addr, mac_addr); |
| 784 | } else { | ||
| 785 | eth_hw_addr_random(dev); | ||
| 786 | dev_info(&ofdev->dev, "Using random MAC address: %pM\n", dev->dev_addr); | ||
| 787 | } | ||
| 784 | 788 | ||
| 785 | if (model && !strcasecmp(model, "TSEC")) | 789 | if (model && !strcasecmp(model, "TSEC")) |
| 786 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT | | 790 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT | |
| @@ -77,6 +77,7 @@ · 76 unmodified lines | |||
| 77 | ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num) | 77 | ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num) |
| 78 | 78 | ||
| 79 | enum hns_desc_type { | 79 | enum hns_desc_type { |
| 80 | DESC_TYPE_UNKNOWN, | ||
| 80 | DESC_TYPE_SKB, | 81 | DESC_TYPE_SKB, |
| 81 | DESC_TYPE_FRAGLIST_SKB, | 82 | DESC_TYPE_FRAGLIST_SKB, |
| 82 | DESC_TYPE_PAGE, | 83 | DESC_TYPE_PAGE, |
| @@ -1118,12 +1118,12 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, · 1117 unmodified lines | |||
| 1118 | return -ENOMEM; | 1118 | return -ENOMEM; |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | desc_cb->priv = priv; | ||
| 1121 | desc_cb->length = size; | 1122 | desc_cb->length = size; |
| 1123 | desc_cb->dma = dma; | ||
| 1124 | desc_cb->type = type; | ||
| 1122 | 1125 | ||
| 1123 | if (likely(size <= HNS3_MAX_BD_SIZE)) { | 1126 | if (likely(size <= HNS3_MAX_BD_SIZE)) { |
| 1124 | desc_cb->priv = priv; | ||
| 1125 | desc_cb->dma = dma; | ||
| 1126 | desc_cb->type = type; | ||
| 1127 | desc->addr = cpu_to_le64(dma); | 1127 | desc->addr = cpu_to_le64(dma); |
| 1128 | desc->tx.send_size = cpu_to_le16(size); | 1128 | desc->tx.send_size = cpu_to_le16(size); |
| 1129 | desc->tx.bdtp_fe_sc_vld_ra_ri = | 1129 | desc->tx.bdtp_fe_sc_vld_ra_ri = |
| @@ -1135,18 +1135,11 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, · 5 unmodified lines | |||
| 1135 | } | 1135 | } |
| 1136 | 1136 | ||
| 1137 | frag_buf_num = hns3_tx_bd_count(size); | 1137 | frag_buf_num = hns3_tx_bd_count(size); |
| 1138 | sizeoflast = size & HNS3_TX_LAST_SIZE_M; | 1138 | sizeoflast = size % HNS3_MAX_BD_SIZE; |
| 1139 | sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE; | 1139 | sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE; |
| 1140 | 1140 | ||
| 1141 | /* When frag size is bigger than hardware limit, split this frag */ | 1141 | /* When frag size is bigger than hardware limit, split this frag */ |
| 1142 | for (k = 0; k < frag_buf_num; k++) { | 1142 | for (k = 0; k < frag_buf_num; k++) { |
| 1143 | /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */ | ||
| 1144 | desc_cb->priv = priv; | ||
| 1145 | desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k; | ||
| 1146 | desc_cb->type = ((type == DESC_TYPE_FRAGLIST_SKB || | ||
| 1147 | type == DESC_TYPE_SKB) && !k) ? | ||
| 1148 | type : DESC_TYPE_PAGE; | ||
| 1149 | |||
| 1150 | /* now, fill the descriptor */ | 1143 | /* now, fill the descriptor */ |
| 1151 | desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k); | 1144 | desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k); |
| 1152 | desc->tx.send_size = cpu_to_le16((k == frag_buf_num - 1) ? | 1145 | desc->tx.send_size = cpu_to_le16((k == frag_buf_num - 1) ? |
| @@ -1158,7 +1151,6 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, · 5 unmodified lines | |||
| 1158 | /* move ring pointer to next */ | 1151 | /* move ring pointer to next */ |
| 1159 | ring_ptr_move_fw(ring, next_to_use); | 1152 | ring_ptr_move_fw(ring, next_to_use); |
| 1160 | 1153 | ||
| 1161 | desc_cb = &ring->desc_cb[ring->next_to_use]; | ||
| 1162 | desc = &ring->desc[ring->next_to_use]; | 1154 | desc = &ring->desc[ring->next_to_use]; |
| 1163 | } | 1155 | } |
| 1164 | 1156 | ||
| @@ -1346,6 +1338,10 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) · 181 unmodified lines | |||
| 1346 | unsigned int i; | 1338 | unsigned int i; |
| 1347 | 1339 | ||
| 1348 | for (i = 0; i < ring->desc_num; i++) { | 1340 | for (i = 0; i < ring->desc_num; i++) { |
| 1341 | struct hns3_desc *desc = &ring->desc[ring->next_to_use]; | ||
| 1342 | |||
| 1343 | memset(desc, 0, sizeof(*desc)); | ||
| 1344 | |||
| 1349 | /* check if this is where we started */ | 1345 | /* check if this is where we started */ |
| 1350 | if (ring->next_to_use == next_to_use_orig) | 1346 | if (ring->next_to_use == next_to_use_orig) |
| 1351 | break; | 1347 | break; |
| @@ -1353,6 +1349,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) · 1 unmodified line | |||
| 1353 | /* rollback one */ | 1349 | /* rollback one */ |
| 1354 | ring_ptr_move_bw(ring, next_to_use); | 1350 | ring_ptr_move_bw(ring, next_to_use); |
| 1355 | 1351 | ||
| 1352 | if (!ring->desc_cb[ring->next_to_use].dma) | ||
| 1353 | continue; | ||
| 1354 | |||
| 1356 | /* unmap the descriptor dma address */ | 1355 | /* unmap the descriptor dma address */ |
| 1357 | if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB || | 1356 | if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB || |
| 1358 | ring->desc_cb[ring->next_to_use].type == | 1357 | ring->desc_cb[ring->next_to_use].type == |
| @@ -1369,6 +1368,7 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) · 10 unmodified lines | |||
| 1369 | 1368 | ||
| 1370 | ring->desc_cb[ring->next_to_use].length = 0; | 1369 | ring->desc_cb[ring->next_to_use].length = 0; |
| 1371 | ring->desc_cb[ring->next_to_use].dma = 0; | 1370 | ring->desc_cb[ring->next_to_use].dma = 0; |
| 1371 | ring->desc_cb[ring->next_to_use].type = DESC_TYPE_UNKNOWN; | ||
| 1372 | } | 1372 | } |
| 1373 | } | 1373 | } |
| 1374 | 1374 | ||
| @@ -165,8 +165,6 @@ enum hns3_nic_state { · 164 unmodified lines | |||
| 165 | #define HNS3_TXD_MSS_S 0 | 165 | #define HNS3_TXD_MSS_S 0 |
| 166 | #define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S) | 166 | #define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S) |
| 167 | 167 | ||
| 168 | #define HNS3_TX_LAST_SIZE_M 0xffff | ||
| 169 | |||
| 170 | #define HNS3_VECTOR_TX_IRQ BIT_ULL(0) | 168 | #define HNS3_VECTOR_TX_IRQ BIT_ULL(0) |
| 171 | #define HNS3_VECTOR_RX_IRQ BIT_ULL(1) | 169 | #define HNS3_VECTOR_RX_IRQ BIT_ULL(1) |
| 172 | 170 | ||
| @@ -2673,11 +2673,10 @@ void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time) · 2672 unmodified lines | |||
| 2673 | delay_time); | 2673 | delay_time); |
| 2674 | } | 2674 | } |
| 2675 | 2675 | ||
| 2676 | static int hclge_get_mac_link_status(struct hclge_dev *hdev) | 2676 | static int hclge_get_mac_link_status(struct hclge_dev *hdev, int *link_status) |
| 2677 | { | 2677 | { |
| 2678 | struct hclge_link_status_cmd *req; | 2678 | struct hclge_link_status_cmd *req; |
| 2679 | struct hclge_desc desc; | 2679 | struct hclge_desc desc; |
| 2680 | int link_status; | ||
| 2681 | int ret; | 2680 | int ret; |
| 2682 | 2681 | ||
| 2683 | hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_LINK_STATUS, true); | 2682 | hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_LINK_STATUS, true); |
| @@ -2689,33 +2688,25 @@ static int hclge_get_mac_link_status(struct hclge_dev *hdev) · 5 unmodified lines | |||
| 2689 | } | 2688 | } |
| 2690 | 2689 | ||
| 2691 | req = (struct hclge_link_status_cmd *)desc.data; | 2690 | req = (struct hclge_link_status_cmd *)desc.data; |
| 2692 | link_status = req->status & HCLGE_LINK_STATUS_UP_M; | 2691 | *link_status = (req->status & HCLGE_LINK_STATUS_UP_M) > 0 ? |
| 2692 | HCLGE_LINK_STATUS_UP : HCLGE_LINK_STATUS_DOWN; | ||
| 2693 | 2693 | ||
| 2694 | return !!link_status; | 2694 | return 0; |
| 2695 | } | 2695 | } |
| 2696 | 2696 | ||
| 2697 | static int hclge_get_mac_phy_link(struct hclge_dev *hdev) | 2697 | static int hclge_get_mac_phy_link(struct hclge_dev *hdev, int *link_status) |
| 2698 | { | 2698 | { |
| 2699 | unsigned int mac_state; | 2699 | struct phy_device *phydev = hdev->hw.mac.phydev; |
| 2700 | int link_stat; | 2700 | |
| 2701 | *link_status = HCLGE_LINK_STATUS_DOWN; | ||
| 2701 | 2702 | ||
| 2702 | if (test_bit(HCLGE_STATE_DOWN, &hdev->state)) | 2703 | if (test_bit(HCLGE_STATE_DOWN, &hdev->state)) |
| 2703 | return 0; | 2704 | return 0; |
| 2704 | 2705 | ||
| 2705 | mac_state = hclge_get_mac_link_status(hdev); | 2706 | if (phydev && (phydev->state != PHY_RUNNING || !phydev->link)) |
| 2706 | 2707 | return 0; | |
| 2707 | if (hdev->hw.mac.phydev) { | ||
| 2708 | if (hdev->hw.mac.phydev->state == PHY_RUNNING) | ||
| 2709 | link_stat = mac_state & | ||
| 2710 | hdev->hw.mac.phydev->link; | ||
| 2711 | else | ||
| 2712 | link_stat = 0; | ||
| 2713 | |||
| 2714 | } else { | ||
| 2715 | link_stat = mac_state; | ||
| 2716 | } | ||
| 2717 | 2708 | ||
| 2718 | return !!link_stat; | 2709 | return hclge_get_mac_link_status(hdev, link_status); |
| 2719 | } | 2710 | } |
| 2720 | 2711 | ||
| 2721 | static void hclge_update_link_status(struct hclge_dev *hdev) | 2712 | static void hclge_update_link_status(struct hclge_dev *hdev) |
| @@ -2725,6 +2716,7 @@ static void hclge_update_link_status(struct hclge_dev *hdev) · 3 unmodified lines | |||
| 2725 | struct hnae3_handle *rhandle; | 2716 | struct hnae3_handle *rhandle; |
| 2726 | struct hnae3_handle *handle; | 2717 | struct hnae3_handle *handle; |
| 2727 | int state; | 2718 | int state; |
| 2719 | int ret; | ||
| 2728 | int i; | 2720 | int i; |
| 2729 | 2721 | ||
| 2730 | if (!client) | 2722 | if (!client) |
| @@ -2733,7 +2725,12 @@ static void hclge_update_link_status(struct hclge_dev *hdev) · 2 unmodified lines | |||
| 2733 | if (test_and_set_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state)) | 2725 | if (test_and_set_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state)) |
| 2734 | return; | 2726 | return; |
| 2735 | 2727 | ||
| 2736 | state = hclge_get_mac_phy_link(hdev); | 2728 | ret = hclge_get_mac_phy_link(hdev, &state); |
| 2729 | if (ret) { | ||
| 2730 | clear_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state); | ||
| 2731 | return; | ||
| 2732 | } | ||
| 2733 | |||
| 2737 | if (state != hdev->hw.mac.link) { | 2734 | if (state != hdev->hw.mac.link) { |
| 2738 | for (i = 0; i < hdev->num_vmdq_vport + 1; i++) { | 2735 | for (i = 0; i < hdev->num_vmdq_vport + 1; i++) { |
| 2739 | handle = &hdev->vport[i].nic; | 2736 | handle = &hdev->vport[i].nic; |
| @@ -6524,14 +6521,15 @@ static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret) · 3784 unmodified lines | |||
| 6524 | { | 6521 | { |
| 6525 | #define HCLGE_MAC_LINK_STATUS_NUM 100 | 6522 | #define HCLGE_MAC_LINK_STATUS_NUM 100 |
| 6526 | 6523 | ||
| 6524 | int link_status; | ||
| 6527 | int i = 0; | 6525 | int i = 0; |
| 6528 | int ret; | 6526 | int ret; |
| 6529 | 6527 | ||
| 6530 | do { | 6528 | do { |
| 6531 | ret = hclge_get_mac_link_status(hdev); | 6529 | ret = hclge_get_mac_link_status(hdev, &link_status); |
| 6532 | if (ret < 0) | 6530 | if (ret) |
| 6533 | return ret; | 6531 | return ret; |
| 6534 | else if (ret == link_ret) | 6532 | if (link_status == link_ret) |
| 6535 | return 0; | 6533 | return 0; |
| 6536 | 6534 | ||
| 6537 | msleep(HCLGE_LINK_STATUS_MS); | 6535 | msleep(HCLGE_LINK_STATUS_MS); |
| @@ -6542,9 +6540,6 @@ static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret) · 4 unmodified lines | |||
| 6542 | static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en, | 6540 | static int hclge_mac_phy_link_status_wait(struct hclge_dev *hdev, bool en, |
| 6543 | bool is_phy) | 6541 | bool is_phy) |
| 6544 | { | 6542 | { |
| 6545 | #define HCLGE_LINK_STATUS_DOWN 0 | ||
| 6546 | #define HCLGE_LINK_STATUS_UP 1 | ||
| 6547 | |||
| 6548 | int link_ret; | 6543 | int link_ret; |
| 6549 | 6544 | ||
| 6550 | link_ret = en ? HCLGE_LINK_STATUS_UP : HCLGE_LINK_STATUS_DOWN; | 6545 | link_ret = en ? HCLGE_LINK_STATUS_UP : HCLGE_LINK_STATUS_DOWN; |
| @@ -317,6 +317,9 @@ enum hclge_link_fail_code { · 316 unmodified lines | |||
| 317 | HCLGE_LF_XSFP_ABSENT, | 317 | HCLGE_LF_XSFP_ABSENT, |
| 318 | }; | 318 | }; |
| 319 | 319 | ||
| 320 | #define HCLGE_LINK_STATUS_DOWN 0 | ||
| 321 | #define HCLGE_LINK_STATUS_UP 1 | ||
| 322 | |||
| 320 | #define HCLGE_PG_NUM 4 | 323 | #define HCLGE_PG_NUM 4 |
| 321 | #define HCLGE_SCH_MODE_SP 0 | 324 | #define HCLGE_SCH_MODE_SP 0 |
| 322 | #define HCLGE_SCH_MODE_DWRR 1 | 325 | #define HCLGE_SCH_MODE_DWRR 1 |
| @@ -710,7 +710,7 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) · 709 unmodified lines | |||
| 710 | err = mlxsw_core_trap_register(mlxsw_core, &mlxsw_emad_rx_listener, | 710 | err = mlxsw_core_trap_register(mlxsw_core, &mlxsw_emad_rx_listener, |
| 711 | mlxsw_core); | 711 | mlxsw_core); |
| 712 | if (err) | 712 | if (err) |
| 713 | return err; | 713 | goto err_trap_register; |
| 714 | 714 | ||
| 715 | err = mlxsw_core->driver->basic_trap_groups_set(mlxsw_core); | 715 | err = mlxsw_core->driver->basic_trap_groups_set(mlxsw_core); |
| 716 | if (err) | 716 | if (err) |
| @@ -722,6 +722,7 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) · 5 unmodified lines | |||
| 722 | err_emad_trap_set: | 722 | err_emad_trap_set: |
| 723 | mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, | 723 | mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, |
| 724 | mlxsw_core); | 724 | mlxsw_core); |
| 725 | err_trap_register: | ||
| 725 | destroy_workqueue(mlxsw_core->emad_wq); | 726 | destroy_workqueue(mlxsw_core->emad_wq); |
| 726 | return err; | 727 | return err; |
| 727 | } | 728 | } |
| @@ -45,7 +45,7 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id, · 44 unmodified lines | |||
| 45 | static int | 45 | static int |
| 46 | mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module, | 46 | mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module, |
| 47 | u16 offset, u16 size, void *data, | 47 | u16 offset, u16 size, void *data, |
| 48 | unsigned int *p_read_size) | 48 | bool qsfp, unsigned int *p_read_size) |
| 49 | { | 49 | { |
| 50 | char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE]; | 50 | char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE]; |
| 51 | char mcia_pl[MLXSW_REG_MCIA_LEN]; | 51 | char mcia_pl[MLXSW_REG_MCIA_LEN]; |
| @@ -54,6 +54,10 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module, · 2 unmodified lines | |||
| 54 | int status; | 54 | int status; |
| 55 | int err; | 55 | int err; |
| 56 | 56 | ||
| 57 | /* MCIA register accepts buffer size <= 48. Page of size 128 should be | ||
| 58 | * read by chunks of size 48, 48, 32. Align the size of the last chunk | ||
| 59 | * to avoid reading after the end of the page. | ||
| 60 | */ | ||
| 57 | size = min_t(u16, size, MLXSW_REG_MCIA_EEPROM_SIZE); | 61 | size = min_t(u16, size, MLXSW_REG_MCIA_EEPROM_SIZE); |
| 58 | 62 | ||
| 59 | if (offset < MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH && | 63 | if (offset < MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH && |
| @@ -63,18 +67,25 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module, · 3 unmodified lines | |||
| 63 | 67 | ||
| 64 | i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_LOW; | 68 | i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_LOW; |
| 65 | if (offset >= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) { | 69 | if (offset >= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) { |
| 66 | page = MLXSW_REG_MCIA_PAGE_GET(offset); | 70 | if (qsfp) { |
| 67 | offset -= MLXSW_REG_MCIA_EEPROM_UP_PAGE_LENGTH * page; | 71 | /* When reading upper pages 1, 2 and 3 the offset |
| 68 | /* When reading upper pages 1, 2 and 3 the offset starts at | 72 | * starts at 128. Please refer to "QSFP+ Memory Map" |
| 69 | * 128. Please refer to "QSFP+ Memory Map" figure in SFF-8436 | 73 | * figure in SFF-8436 specification for graphical |
| 70 | * specification for graphical depiction. | 74 | * depiction. |
| 71 | * MCIA register accepts buffer size <= 48. Page of size 128 | 75 | */ |
| 72 | * should be read by chunks of size 48, 48, 32. Align the size | 76 | page = MLXSW_REG_MCIA_PAGE_GET(offset); |
| 73 | * of the last chunk to avoid reading after the end of the | 77 | offset -= MLXSW_REG_MCIA_EEPROM_UP_PAGE_LENGTH * page; |
| 74 | * page. | 78 | if (offset + size > MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) |
| 75 | */ | 79 | size = MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH - offset; |
| 76 | if (offset + size > MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) | 80 | } else { |
| 77 | size = MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH - offset; | 81 | /* When reading upper pages 1, 2 and 3 the offset |
| 82 | * starts at 0 and I2C high address is used. Please refer | ||
| 83 | * refer to "Memory Organization" figure in SFF-8472 | ||
| 84 | * specification for graphical depiction. | ||
| 85 | */ | ||
| 86 | i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_HIGH; | ||
| 87 | offset -= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH; | ||
| 88 | } | ||
| 78 | } | 89 | } |
| 79 | 90 | ||
| 80 | mlxsw_reg_mcia_pack(mcia_pl, module, 0, page, offset, size, i2c_addr); | 91 | mlxsw_reg_mcia_pack(mcia_pl, module, 0, page, offset, size, i2c_addr); |
| @@ -166,7 +177,7 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module, · 85 unmodified lines | |||
| 166 | int err; | 177 | int err; |
| 167 | 178 | ||
| 168 | err = mlxsw_env_query_module_eeprom(mlxsw_core, module, 0, offset, | 179 | err = mlxsw_env_query_module_eeprom(mlxsw_core, module, 0, offset, |
| 169 | module_info, &read_size); | 180 | module_info, false, &read_size); |
| 170 | if (err) | 181 | if (err) |
| 171 | return err; | 182 | return err; |
| 172 | 183 | ||
| @@ -197,7 +208,7 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module, · 24 unmodified lines | |||
| 197 | /* Verify if transceiver provides diagnostic monitoring page */ | 208 | /* Verify if transceiver provides diagnostic monitoring page */ |
| 198 | err = mlxsw_env_query_module_eeprom(mlxsw_core, module, | 209 | err = mlxsw_env_query_module_eeprom(mlxsw_core, module, |
| 199 | SFP_DIAGMON, 1, &diag_mon, | 210 | SFP_DIAGMON, 1, &diag_mon, |
| 200 | &read_size); | 211 | false, &read_size); |
| 201 | if (err) | 212 | if (err) |
| 202 | return err; | 213 | return err; |
| 203 | 214 | ||
| @@ -225,17 +236,22 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev, · 21 unmodified lines | |||
| 225 | int offset = ee->offset; | 236 | int offset = ee->offset; |
| 226 | unsigned int read_size; | 237 | unsigned int read_size; |
| 227 | int i = 0; | 238 | int i = 0; |
| 239 | bool qsfp; | ||
| 228 | int err; | 240 | int err; |
| 229 | 241 | ||
| 230 | if (!ee->len) | 242 | if (!ee->len) |
| 231 | return -EINVAL; | 243 | return -EINVAL; |
| 232 | 244 | ||
| 233 | memset(data, 0, ee->len); | 245 | memset(data, 0, ee->len); |
| 246 | /* Validate module identifier value. */ | ||
| 247 | err = mlxsw_env_validate_cable_ident(mlxsw_core, module, &qsfp); | ||
| 248 | if (err) | ||
| 249 | return err; | ||
| 234 | 250 | ||
| 235 | while (i < ee->len) { | 251 | while (i < ee->len) { |
| 236 | err = mlxsw_env_query_module_eeprom(mlxsw_core, module, offset, | 252 | err = mlxsw_env_query_module_eeprom(mlxsw_core, module, offset, |
| 237 | ee->len - i, data + i, | 253 | ee->len - i, data + i, |
| 238 | &read_size); | 254 | qsfp, &read_size); |
| 239 | if (err) { | 255 | if (err) { |
| 240 | netdev_err(netdev, "Eeprom query failed\n"); | 256 | netdev_err(netdev, "Eeprom query failed\n"); |
| 241 | return err; | 257 | return err; |
| @@ -98,7 +98,7 @@ static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo) · 97 unmodified lines | |||
| 98 | { | 98 | { |
| 99 | struct sk_buff **skb_ptr = NULL; | 99 | struct sk_buff **skb_ptr = NULL; |
| 100 | struct sk_buff **temp; | 100 | struct sk_buff **temp; |
| 101 | #define NR_SKB_COMPLETED 128 | 101 | #define NR_SKB_COMPLETED 16 |
| 102 | struct sk_buff *completed[NR_SKB_COMPLETED]; | 102 | struct sk_buff *completed[NR_SKB_COMPLETED]; |
| 103 | int more; | 103 | int more; |
| 104 | 104 | ||
| @@ -103,15 +103,18 @@ static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs, · 102 unmodified lines | |||
| 103 | void *p) | 103 | void *p) |
| 104 | { | 104 | { |
| 105 | struct ionic_lif *lif = netdev_priv(netdev); | 105 | struct ionic_lif *lif = netdev_priv(netdev); |
| 106 | unsigned int offset; | ||
| 106 | unsigned int size; | 107 | unsigned int size; |
| 107 | 108 | ||
| 108 | regs->version = IONIC_DEV_CMD_REG_VERSION; | 109 | regs->version = IONIC_DEV_CMD_REG_VERSION; |
| 109 | 110 | ||
| 111 | offset = 0; | ||
| 110 | size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32); | 112 | size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32); |
| 111 | memcpy_fromio(p, lif->ionic->idev.dev_info_regs->words, size); | 113 | memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size); |
| 112 | 114 | ||
| 115 | offset += size; | ||
| 113 | size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32); | 116 | size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32); |
| 114 | memcpy_fromio(p, lif->ionic->idev.dev_cmd_regs->words, size); | 117 | memcpy_fromio(p + offset, lif->ionic->idev.dev_cmd_regs->words, size); |
| 115 | } | 118 | } |
| 116 | 119 | ||
| 117 | static int ionic_get_link_ksettings(struct net_device *netdev, | 120 | static int ionic_get_link_ksettings(struct net_device *netdev, |
| @@ -96,8 +96,7 @@ static void ionic_link_status_check(struct ionic_lif *lif) · 95 unmodified lines | |||
| 96 | u16 link_status; | 96 | u16 link_status; |
| 97 | bool link_up; | 97 | bool link_up; |
| 98 | 98 | ||
| 99 | if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state) || | 99 | if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state)) |
| 100 | test_bit(IONIC_LIF_F_QUEUE_RESET, lif->state)) | ||
| 101 | return; | 100 | return; |
| 102 | 101 | ||
| 103 | link_status = le16_to_cpu(lif->info->status.link_status); | 102 | link_status = le16_to_cpu(lif->info->status.link_status); |
| @@ -114,16 +113,22 @@ static void ionic_link_status_check(struct ionic_lif *lif) · 10 unmodified lines | |||
| 114 | netif_carrier_on(netdev); | 113 | netif_carrier_on(netdev); |
| 115 | } | 114 | } |
| 116 | 115 | ||
| 117 | if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) | 116 | if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) { |
| 117 | mutex_lock(&lif->queue_lock); | ||
| 118 | ionic_start_queues(lif); | 118 | ionic_start_queues(lif); |
| 119 | mutex_unlock(&lif->queue_lock); | ||
| 120 | } | ||
| 119 | } else { | 121 | } else { |
| 120 | if (netif_carrier_ok(netdev)) { | 122 | if (netif_carrier_ok(netdev)) { |
| 121 | netdev_info(netdev, "Link down\n"); | 123 | netdev_info(netdev, "Link down\n"); |
| 122 | netif_carrier_off(netdev); | 124 | netif_carrier_off(netdev); |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) | 127 | if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) { |
| 128 | mutex_lock(&lif->queue_lock); | ||
| 126 | ionic_stop_queues(lif); | 129 | ionic_stop_queues(lif); |
| 130 | mutex_unlock(&lif->queue_lock); | ||
| 131 | } | ||
| 127 | } | 132 | } |
| 128 | 133 | ||
| 129 | clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state); | 134 | clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state); |
| @@ -863,8 +868,7 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr) · 733 unmodified lines | |||
| 863 | if (f) | 868 | if (f) |
| 864 | return 0; | 869 | return 0; |
| 865 | 870 | ||
| 866 | netdev_dbg(lif->netdev, "rx_filter add ADDR %pM (id %d)\n", addr, | 871 | netdev_dbg(lif->netdev, "rx_filter add ADDR %pM\n", addr); |
| 867 | ctx.comp.rx_filter_add.filter_id); | ||
| 868 | 872 | ||
| 869 | memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); | 873 | memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); |
| 870 | err = ionic_adminq_post_wait(lif, &ctx); | 874 | err = ionic_adminq_post_wait(lif, &ctx); |
| @@ -893,6 +897,9 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr) · 22 unmodified lines | |||
| 893 | return -ENOENT; | 897 | return -ENOENT; |
| 894 | } | 898 | } |
| 895 | 899 | ||
| 900 | netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", | ||
| 901 | addr, f->filter_id); | ||
| 902 | |||
| 896 | ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); | 903 | ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); |
| 897 | ionic_rx_filter_free(lif, f); | 904 | ionic_rx_filter_free(lif, f); |
| 898 | spin_unlock_bh(&lif->rx_filters.lock); | 905 | spin_unlock_bh(&lif->rx_filters.lock); |
| @@ -901,9 +908,6 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr) · 2 unmodified lines | |||
| 901 | if (err && err != -EEXIST) | 908 | if (err && err != -EEXIST) |
| 902 | return err; | 909 | return err; |
| 903 | 910 | ||
| 904 | netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", addr, | ||
| 905 | ctx.cmd.rx_filter_del.filter_id); | ||
| 906 | |||
| 907 | return 0; | 911 | return 0; |
| 908 | } | 912 | } |
| 909 | 913 | ||
| @@ -1351,13 +1355,11 @@ static int ionic_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, · 441 unmodified lines | |||
| 1351 | }; | 1355 | }; |
| 1352 | int err; | 1356 | int err; |
| 1353 | 1357 | ||
| 1358 | netdev_dbg(netdev, "rx_filter add VLAN %d\n", vid); | ||
| 1354 | err = ionic_adminq_post_wait(lif, &ctx); | 1359 | err = ionic_adminq_post_wait(lif, &ctx); |
| 1355 | if (err) | 1360 | if (err) |
| 1356 | return err; | 1361 | return err; |
| 1357 | 1362 | ||
| 1358 | netdev_dbg(netdev, "rx_filter add VLAN %d (id %d)\n", vid, | ||
| 1359 | ctx.comp.rx_filter_add.filter_id); | ||
| 1360 | |||
| 1361 | return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); | 1363 | return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); |
| 1362 | } | 1364 | } |
| 1363 | 1365 | ||
| @@ -1382,8 +1384,8 @@ static int ionic_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, · 18 unmodified lines | |||
| 1382 | return -ENOENT; | 1384 | return -ENOENT; |
| 1383 | } | 1385 | } |
| 1384 | 1386 | ||
| 1385 | netdev_dbg(netdev, "rx_filter del VLAN %d (id %d)\n", vid, | 1387 | netdev_dbg(netdev, "rx_filter del VLAN %d (id %d)\n", |
| 1386 | le32_to_cpu(ctx.cmd.rx_filter_del.filter_id)); | 1388 | vid, f->filter_id); |
| 1387 | 1389 | ||
| 1388 | ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); | 1390 | ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); |
| 1389 | ionic_rx_filter_free(lif, f); | 1391 | ionic_rx_filter_free(lif, f); |
| @@ -1993,16 +1995,13 @@ int ionic_reset_queues(struct ionic_lif *lif, ionic_reset_cb cb, void *arg) · 603 unmodified lines | |||
| 1993 | bool running; | 1995 | bool running; |
| 1994 | int err = 0; | 1996 | int err = 0; |
| 1995 | 1997 | ||
| 1996 | err = ionic_wait_for_bit(lif, IONIC_LIF_F_QUEUE_RESET); | 1998 | mutex_lock(&lif->queue_lock); |
| 1997 | if (err) | ||
| 1998 | return err; | ||
| 1999 | |||
| 2000 | running = netif_running(lif->netdev); | 1999 | running = netif_running(lif->netdev); |
| 2001 | if (running) { | 2000 | if (running) { |
| 2002 | netif_device_detach(lif->netdev); | 2001 | netif_device_detach(lif->netdev); |
| 2003 | err = ionic_stop(lif->netdev); | 2002 | err = ionic_stop(lif->netdev); |
| 2004 | if (err) | 2003 | if (err) |
| 2005 | goto reset_out; | 2004 | return err; |
| 2006 | } | 2005 | } |
| 2007 | 2006 | ||
| 2008 | if (cb) | 2007 | if (cb) |
| @@ -2012,9 +2011,7 @@ int ionic_reset_queues(struct ionic_lif *lif, ionic_reset_cb cb, void *arg) · 3 unmodified lines | |||
| 2012 | err = ionic_open(lif->netdev); | 2011 | err = ionic_open(lif->netdev); |
| 2013 | netif_device_attach(lif->netdev); | 2012 | netif_device_attach(lif->netdev); |
| 2014 | } | 2013 | } |
| 2015 | 2014 | mutex_unlock(&lif->queue_lock); | |
| 2016 | reset_out: | ||
| 2017 | clear_bit(IONIC_LIF_F_QUEUE_RESET, lif->state); | ||
| 2018 | 2015 | ||
| 2019 | return err; | 2016 | return err; |
| 2020 | } | 2017 | } |
| @@ -2161,7 +2158,9 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif) · 140 unmodified lines | |||
| 2161 | 2158 | ||
| 2162 | if (test_bit(IONIC_LIF_F_UP, lif->state)) { | 2159 | if (test_bit(IONIC_LIF_F_UP, lif->state)) { |
| 2163 | dev_info(ionic->dev, "Surprise FW stop, stopping queues\n"); | 2160 | dev_info(ionic->dev, "Surprise FW stop, stopping queues\n"); |
| 2161 | mutex_lock(&lif->queue_lock); | ||
| 2164 | ionic_stop_queues(lif); | 2162 | ionic_stop_queues(lif); |
| 2163 | mutex_unlock(&lif->queue_lock); | ||
| 2165 | } | 2164 | } |
| 2166 | 2165 | ||
| 2167 | if (netif_running(lif->netdev)) { | 2166 | if (netif_running(lif->netdev)) { |
| @@ -2280,15 +2279,15 @@ static void ionic_lif_deinit(struct ionic_lif *lif) · 112 unmodified lines | |||
| 2280 | cancel_work_sync(&lif->deferred.work); | 2279 | cancel_work_sync(&lif->deferred.work); |
| 2281 | cancel_work_sync(&lif->tx_timeout_work); | 2280 | cancel_work_sync(&lif->tx_timeout_work); |
| 2282 | ionic_rx_filters_deinit(lif); | 2281 | ionic_rx_filters_deinit(lif); |
| 2282 | if (lif->netdev->features & NETIF_F_RXHASH) | ||
| 2283 | ionic_lif_rss_deinit(lif); | ||
| 2283 | } | 2284 | } |
| 2284 | 2285 | ||
| 2285 | if (lif->netdev->features & NETIF_F_RXHASH) | ||
| 2286 | ionic_lif_rss_deinit(lif); | ||
| 2287 | |||
| 2288 | napi_disable(&lif->adminqcq->napi); | 2286 | napi_disable(&lif->adminqcq->napi); |
| 2289 | ionic_lif_qcq_deinit(lif, lif->notifyqcq); | 2287 | ionic_lif_qcq_deinit(lif, lif->notifyqcq); |
| 2290 | ionic_lif_qcq_deinit(lif, lif->adminqcq); | 2288 | ionic_lif_qcq_deinit(lif, lif->adminqcq); |
| 2291 | 2289 | ||
| 2290 | mutex_destroy(&lif->queue_lock); | ||
| 2292 | ionic_lif_reset(lif); | 2291 | ionic_lif_reset(lif); |
| 2293 | } | 2292 | } |
| 2294 | 2293 | ||
| @@ -2465,6 +2464,7 @@ static int ionic_lif_init(struct ionic_lif *lif) · 170 unmodified lines | |||
| 2465 | return err; | 2464 | return err; |
| 2466 | 2465 | ||
| 2467 | lif->hw_index = le16_to_cpu(comp.hw_index); | 2466 | lif->hw_index = le16_to_cpu(comp.hw_index); |
| 2467 | mutex_init(&lif->queue_lock); | ||
| 2468 | 2468 | ||
| 2469 | /* now that we have the hw_index we can figure out our doorbell page */ | 2469 | /* now that we have the hw_index we can figure out our doorbell page */ |
| 2470 | lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif); | 2470 | lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif); |
| @@ -135,7 +135,6 @@ enum ionic_lif_state_flags { · 134 unmodified lines | |||
| 135 | IONIC_LIF_F_SW_DEBUG_STATS, | 135 | IONIC_LIF_F_SW_DEBUG_STATS, |
| 136 | IONIC_LIF_F_UP, | 136 | IONIC_LIF_F_UP, |
| 137 | IONIC_LIF_F_LINK_CHECK_REQUESTED, | 137 | IONIC_LIF_F_LINK_CHECK_REQUESTED, |
| 138 | IONIC_LIF_F_QUEUE_RESET, | ||
| 139 | IONIC_LIF_F_FW_RESET, | 138 | IONIC_LIF_F_FW_RESET, |
| 140 | 139 | ||
| 141 | /* leave this as last */ | 140 | /* leave this as last */ |
| @@ -165,6 +164,7 @@ struct ionic_lif { · 23 unmodified lines | |||
| 165 | unsigned int hw_index; | 164 | unsigned int hw_index; |
| 166 | unsigned int kern_pid; | 165 | unsigned int kern_pid; |
| 167 | u64 __iomem *kern_dbpage; | 166 | u64 __iomem *kern_dbpage; |
| 167 | struct mutex queue_lock; /* lock for queue structures */ | ||
| 168 | spinlock_t adminq_lock; /* lock for AdminQ operations */ | 168 | spinlock_t adminq_lock; /* lock for AdminQ operations */ |
| 169 | struct ionic_qcq *adminqcq; | 169 | struct ionic_qcq *adminqcq; |
| 170 | struct ionic_qcq *notifyqcq; | 170 | struct ionic_qcq *notifyqcq; |
| @@ -213,12 +213,6 @@ struct ionic_lif { · 42 unmodified lines | |||
| 213 | #define lif_to_txq(lif, i) (&lif_to_txqcq((lif), i)->q) | 213 | #define lif_to_txq(lif, i) (&lif_to_txqcq((lif), i)->q) |
| 214 | #define lif_to_rxq(lif, i) (&lif_to_txqcq((lif), i)->q) | 214 | #define lif_to_rxq(lif, i) (&lif_to_txqcq((lif), i)->q) |
| 215 | 215 | ||
| 216 | /* return 0 if successfully set the bit, else non-zero */ | ||
| 217 | static inline int ionic_wait_for_bit(struct ionic_lif *lif, int bitname) | ||
| 218 | { | ||
| 219 | return wait_on_bit_lock(lif->state, bitname, TASK_INTERRUPTIBLE); | ||
| 220 | } | ||
| 221 | |||
| 222 | static inline u32 ionic_coal_usec_to_hw(struct ionic *ionic, u32 usecs) | 216 | static inline u32 ionic_coal_usec_to_hw(struct ionic *ionic, u32 usecs) |
| 223 | { | 217 | { |
| 224 | u32 mult = le32_to_cpu(ionic->ident.dev.intr_coal_mult); | 218 | u32 mult = le32_to_cpu(ionic->ident.dev.intr_coal_mult); |
| @@ -21,13 +21,16 @@ void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f) · 20 unmodified lines | |||
| 21 | void ionic_rx_filter_replay(struct ionic_lif *lif) | 21 | void ionic_rx_filter_replay(struct ionic_lif *lif) |
| 22 | { | 22 | { |
| 23 | struct ionic_rx_filter_add_cmd *ac; | 23 | struct ionic_rx_filter_add_cmd *ac; |
| 24 | struct hlist_head new_id_list; | ||
| 24 | struct ionic_admin_ctx ctx; | 25 | struct ionic_admin_ctx ctx; |
| 25 | struct ionic_rx_filter *f; | 26 | struct ionic_rx_filter *f; |
| 26 | struct hlist_head *head; | 27 | struct hlist_head *head; |
| 27 | struct hlist_node *tmp; | 28 | struct hlist_node *tmp; |
| 29 | unsigned int key; | ||
| 28 | unsigned int i; | 30 | unsigned int i; |
| 29 | int err; | 31 | int err; |
| 30 | 32 | ||
| 33 | INIT_HLIST_HEAD(&new_id_list); | ||
| 31 | ac = &ctx.cmd.rx_filter_add; | 34 | ac = &ctx.cmd.rx_filter_add; |
| 32 | 35 | ||
| 33 | for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { | 36 | for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { |
| @@ -58,9 +61,30 @@ void ionic_rx_filter_replay(struct ionic_lif *lif) · 24 unmodified lines | |||
| 58 | ac->mac.addr); | 61 | ac->mac.addr); |
| 59 | break; | 62 | break; |
| 60 | } | 63 | } |
| 64 | spin_lock_bh(&lif->rx_filters.lock); | ||
| 65 | ionic_rx_filter_free(lif, f); | ||
| 66 | spin_unlock_bh(&lif->rx_filters.lock); | ||
| 67 | |||
| 68 | continue; | ||
| 61 | } | 69 | } |
| 70 | |||
| 71 | /* remove from old id list, save new id in tmp list */ | ||
| 72 | spin_lock_bh(&lif->rx_filters.lock); | ||
| 73 | hlist_del(&f->by_id); | ||
| 74 | spin_unlock_bh(&lif->rx_filters.lock); | ||
| 75 | f->filter_id = le32_to_cpu(ctx.comp.rx_filter_add.filter_id); | ||
| 76 | hlist_add_head(&f->by_id, &new_id_list); | ||
| 62 | } | 77 | } |
| 63 | } | 78 | } |
| 79 | |||
| 80 | /* rebuild the by_id hash lists with the new filter ids */ | ||
| 81 | spin_lock_bh(&lif->rx_filters.lock); | ||
| 82 | hlist_for_each_entry_safe(f, tmp, &new_id_list, by_id) { | ||
| 83 | key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK; | ||
| 84 | head = &lif->rx_filters.by_id[key]; | ||
| 85 | hlist_add_head(&f->by_id, head); | ||
| 86 | } | ||
| 87 | spin_unlock_bh(&lif->rx_filters.lock); | ||
| 64 | } | 88 | } |
| 65 | 89 | ||
| 66 | int ionic_rx_filters_init(struct ionic_lif *lif) | 90 | int ionic_rx_filters_init(struct ionic_lif *lif) |
| @@ -69,10 +93,12 @@ int ionic_rx_filters_init(struct ionic_lif *lif) · 2 unmodified lines | |||
| 69 | 93 | ||
| 70 | spin_lock_init(&lif->rx_filters.lock); | 94 | spin_lock_init(&lif->rx_filters.lock); |
| 71 | 95 | ||
| 96 | spin_lock_bh(&lif->rx_filters.lock); | ||
| 72 | for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { | 97 | for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { |
| 73 | INIT_HLIST_HEAD(&lif->rx_filters.by_hash[i]); | 98 | INIT_HLIST_HEAD(&lif->rx_filters.by_hash[i]); |
| 74 | INIT_HLIST_HEAD(&lif->rx_filters.by_id[i]); | 99 | INIT_HLIST_HEAD(&lif->rx_filters.by_id[i]); |
| 75 | } | 100 | } |
| 101 | spin_unlock_bh(&lif->rx_filters.lock); | ||
| 76 | 102 | ||
| 77 | return 0; | 103 | return 0; |
| 78 | } | 104 | } |
| @@ -84,11 +110,13 @@ void ionic_rx_filters_deinit(struct ionic_lif *lif) · 5 unmodified lines | |||
| 84 | struct hlist_node *tmp; | 110 | struct hlist_node *tmp; |
| 85 | unsigned int i; | 111 | unsigned int i; |
| 86 | 112 | ||
| 113 | spin_lock_bh(&lif->rx_filters.lock); | ||
| 87 | for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { | 114 | for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { |
| 88 | head = &lif->rx_filters.by_id[i]; | 115 | head = &lif->rx_filters.by_id[i]; |
| 89 | hlist_for_each_entry_safe(f, tmp, head, by_id) | 116 | hlist_for_each_entry_safe(f, tmp, head, by_id) |
| 90 | ionic_rx_filter_free(lif, f); | 117 | ionic_rx_filter_free(lif, f); |
| 91 | } | 118 | } |
| 119 | spin_unlock_bh(&lif->rx_filters.lock); | ||
| 92 | } | 120 | } |
| 93 | 121 | ||
| 94 | int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index, | 122 | int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index, |
| @@ -124,6 +152,7 @@ int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index, · 29 unmodified lines | |||
| 124 | f->filter_id = le32_to_cpu(ctx->comp.rx_filter_add.filter_id); | 152 | f->filter_id = le32_to_cpu(ctx->comp.rx_filter_add.filter_id); |
| 125 | f->rxq_index = rxq_index; | 153 | f->rxq_index = rxq_index; |
| 126 | memcpy(&f->cmd, ac, sizeof(f->cmd)); | 154 | memcpy(&f->cmd, ac, sizeof(f->cmd)); |
| 155 | netdev_dbg(lif->netdev, "rx_filter add filter_id %d\n", f->filter_id); | ||
| 127 | 156 | ||
| 128 | INIT_HLIST_NODE(&f->by_hash); | 157 | INIT_HLIST_NODE(&f->by_hash); |
| 129 | INIT_HLIST_NODE(&f->by_id); | 158 | INIT_HLIST_NODE(&f->by_id); |
| @@ -161,12 +161,6 @@ static void ionic_rx_clean(struct ionic_queue *q, · 160 unmodified lines | |||
| 161 | return; | 161 | return; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /* no packet processing while resetting */ | ||
| 165 | if (unlikely(test_bit(IONIC_LIF_F_QUEUE_RESET, q->lif->state))) { | ||
| 166 | stats->dropped++; | ||
| 167 | return; | ||
| 168 | } | ||
| 169 | |||
| 170 | stats->pkts++; | 164 | stats->pkts++; |
| 171 | stats->bytes += le16_to_cpu(comp->len); | 165 | stats->bytes += le16_to_cpu(comp->len); |
| 172 | 166 | ||
| @@ -2008,8 +2008,8 @@ static void qed_rdma_set_pf_params(struct qed_hwfn *p_hwfn, · 2007 unmodified lines | |||
| 2008 | enum protocol_type proto; | 2008 | enum protocol_type proto; |
| 2009 | 2009 | ||
| 2010 | if (p_hwfn->mcp_info->func_info.protocol == QED_PCI_ETH_RDMA) { | 2010 | if (p_hwfn->mcp_info->func_info.protocol == QED_PCI_ETH_RDMA) { |
| 2011 | DP_NOTICE(p_hwfn, | 2011 | DP_VERBOSE(p_hwfn, QED_MSG_SP, |
| 2012 | "Current day drivers don't support RoCE & iWARP simultaneously on the same PF. Default to RoCE-only\n"); | 2012 | "Current day drivers don't support RoCE & iWARP simultaneously on the same PF. Default to RoCE-only\n"); |
| 2013 | p_hwfn->hw_info.personality = QED_PCI_ETH_ROCE; | 2013 | p_hwfn->hw_info.personality = QED_PCI_ETH_ROCE; |
| 2014 | } | 2014 | } |
| 2015 | 2015 | ||
| @@ -3102,7 +3102,7 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params) · 3101 unmodified lines | |||
| 3102 | } | 3102 | } |
| 3103 | 3103 | ||
| 3104 | /* Log and clear previous pglue_b errors if such exist */ | 3104 | /* Log and clear previous pglue_b errors if such exist */ |
| 3105 | qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt); | 3105 | qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt, true); |
| 3106 | 3106 | ||
| 3107 | /* Enable the PF's internal FID_enable in the PXP */ | 3107 | /* Enable the PF's internal FID_enable in the PXP */ |
| 3108 | rc = qed_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt, | 3108 | rc = qed_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt, |
| @@ -257,9 +257,10 @@ out: · 256 unmodified lines | |||
| 257 | #define PGLUE_ATTENTION_ZLR_VALID (1 << 25) | 257 | #define PGLUE_ATTENTION_ZLR_VALID (1 << 25) |
| 258 | #define PGLUE_ATTENTION_ILT_VALID (1 << 23) | 258 | #define PGLUE_ATTENTION_ILT_VALID (1 << 23) |
| 259 | 259 | ||
| 260 | int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, | 260 | int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
| 261 | struct qed_ptt *p_ptt) | 261 | bool hw_init) |
| 262 | { | 262 | { |
| 263 | char msg[256]; | ||
| 263 | u32 tmp; | 264 | u32 tmp; |
| 264 | 265 | ||
| 265 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2); | 266 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2); |
| @@ -273,22 +274,23 @@ int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, · 7 unmodified lines | |||
| 273 | details = qed_rd(p_hwfn, p_ptt, | 274 | details = qed_rd(p_hwfn, p_ptt, |
| 274 | PGLUE_B_REG_TX_ERR_WR_DETAILS); | 275 | PGLUE_B_REG_TX_ERR_WR_DETAILS); |
| 275 | 276 | ||
| 276 | DP_NOTICE(p_hwfn, | 277 | snprintf(msg, sizeof(msg), |
| 277 | "Illegal write by chip to [%08x:%08x] blocked.\n" | 278 | "Illegal write by chip to [%08x:%08x] blocked.\n" |
| 278 | "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" | 279 | "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" |
| 279 | "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", | 280 | "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]", |
| 280 | addr_hi, addr_lo, details, | 281 | addr_hi, addr_lo, details, |
| 281 | (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), | 282 | (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), |
| 282 | (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), | 283 | (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), |
| 283 | GET_FIELD(details, | 284 | !!GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VF_VALID), |
| 284 | PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, | 285 | tmp, |
| 285 | tmp, | 286 | !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR), |
| 286 | GET_FIELD(tmp, | 287 | !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME), |
| 287 | PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0, | 288 | !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN)); |
| 288 | GET_FIELD(tmp, | 289 | |
| 289 | PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, | 290 | if (hw_init) |
| 290 | GET_FIELD(tmp, | 291 | DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg); |
| 291 | PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0); | 292 | else |
| 293 | DP_NOTICE(p_hwfn, "%s\n", msg); | ||
| 292 | } | 294 | } |
| 293 | 295 | ||
| 294 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2); | 296 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2); |
| @@ -321,8 +323,14 @@ int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, · 26 unmodified lines | |||
| 321 | } | 323 | } |
| 322 | 324 | ||
| 323 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL); | 325 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL); |
| 324 | if (tmp & PGLUE_ATTENTION_ICPL_VALID) | 326 | if (tmp & PGLUE_ATTENTION_ICPL_VALID) { |
| 325 | DP_NOTICE(p_hwfn, "ICPL error - %08x\n", tmp); | 327 | snprintf(msg, sizeof(msg), "ICPL error - %08x", tmp); |
| 328 | |||
| 329 | if (hw_init) | ||
| 330 | DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg); | ||
| 331 | else | ||
| 332 | DP_NOTICE(p_hwfn, "%s\n", msg); | ||
| 333 | } | ||
| 326 | 334 | ||
| 327 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS); | 335 | tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS); |
| 328 | if (tmp & PGLUE_ATTENTION_ZLR_VALID) { | 336 | if (tmp & PGLUE_ATTENTION_ZLR_VALID) { |
| @@ -361,7 +369,7 @@ int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, · 32 unmodified lines | |||
| 361 | 369 | ||
| 362 | static int qed_pglueb_rbc_attn_cb(struct qed_hwfn *p_hwfn) | 370 | static int qed_pglueb_rbc_attn_cb(struct qed_hwfn *p_hwfn) |
| 363 | { | 371 | { |
| 364 | return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt); | 372 | return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt, false); |
| 365 | } | 373 | } |
| 366 | 374 | ||
| 367 | static int qed_fw_assertion(struct qed_hwfn *p_hwfn) | 375 | static int qed_fw_assertion(struct qed_hwfn *p_hwfn) |
| @@ -1193,7 +1201,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn) · 825 unmodified lines | |||
| 1193 | index, attn_bits, attn_acks, asserted_bits, | 1201 | index, attn_bits, attn_acks, asserted_bits, |
| 1194 | deasserted_bits, p_sb_attn_sw->known_attn); | 1202 | deasserted_bits, p_sb_attn_sw->known_attn); |
| 1195 | } else if (asserted_bits == 0x100) { | 1203 | } else if (asserted_bits == 0x100) { |
| 1196 | DP_INFO(p_hwfn, "MFW indication via attention\n"); | 1204 | DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, |
| 1205 | "MFW indication via attention\n"); | ||
| 1197 | } else { | 1206 | } else { |
| 1198 | DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, | 1207 | DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, |
| 1199 | "MFW indication [deassertion]\n"); | 1208 | "MFW indication [deassertion]\n"); |
| @@ -442,7 +442,7 @@ int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, · 441 unmodified lines | |||
| 442 | 442 | ||
| 443 | #define QED_MAPPING_MEMORY_SIZE(dev) (NUM_OF_SBS(dev)) | 443 | #define QED_MAPPING_MEMORY_SIZE(dev) (NUM_OF_SBS(dev)) |
| 444 | 444 | ||
| 445 | int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, | 445 | int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
| 446 | struct qed_ptt *p_ptt); | 446 | bool hw_init); |
| 447 | 447 | ||
| 448 | #endif | 448 | #endif |
| @@ -1450,6 +1450,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) · 1449 unmodified lines | |||
| 1450 | struct ravb_private *priv = container_of(work, struct ravb_private, | 1450 | struct ravb_private *priv = container_of(work, struct ravb_private, |
| 1451 | work); | 1451 | work); |
| 1452 | struct net_device *ndev = priv->ndev; | 1452 | struct net_device *ndev = priv->ndev; |
| 1453 | int error; | ||
| 1453 | 1454 | ||
| 1454 | netif_tx_stop_all_queues(ndev); | 1455 | netif_tx_stop_all_queues(ndev); |
| 1455 | 1456 | ||
| @@ -1458,15 +1459,36 @@ static void ravb_tx_timeout_work(struct work_struct *work) · 2 unmodified lines | |||
| 1458 | ravb_ptp_stop(ndev); | 1459 | ravb_ptp_stop(ndev); |
| 1459 | 1460 | ||
| 1460 | /* Wait for DMA stopping */ | 1461 | /* Wait for DMA stopping */ |
| 1461 | ravb_stop_dma(ndev); | 1462 | if (ravb_stop_dma(ndev)) { |
| 1463 | /* If ravb_stop_dma() fails, the hardware is still operating | ||
| 1464 | * for TX and/or RX. So, this should not call the following | ||
| 1465 | * functions because ravb_dmac_init() is possible to fail too. | ||
| 1466 | * Also, this should not retry ravb_stop_dma() again and again | ||
| 1467 | * here because it's possible to wait forever. So, this just | ||
| 1468 | * re-enables the TX and RX and skip the following | ||
| 1469 | * re-initialization procedure. | ||
| 1470 | */ | ||
| 1471 | ravb_rcv_snd_enable(ndev); | ||
| 1472 | goto out; | ||
| 1473 | } | ||
| 1462 | 1474 | ||
| 1463 | ravb_ring_free(ndev, RAVB_BE); | 1475 | ravb_ring_free(ndev, RAVB_BE); |
| 1464 | ravb_ring_free(ndev, RAVB_NC); | 1476 | ravb_ring_free(ndev, RAVB_NC); |
| 1465 | 1477 | ||
| 1466 | /* Device init */ | 1478 | /* Device init */ |
| 1467 | ravb_dmac_init(ndev); | 1479 | error = ravb_dmac_init(ndev); |
| 1480 | if (error) { | ||
| 1481 | /* If ravb_dmac_init() fails, descriptors are freed. So, this | ||
| 1482 | * should return here to avoid re-enabling the TX and RX in | ||
| 1483 | * ravb_emac_init(). | ||
| 1484 | */ | ||
| 1485 | netdev_err(ndev, "%s: ravb_dmac_init() failed, error %d\n", | ||
| 1486 | __func__, error); | ||
| 1487 | return; | ||
| 1488 | } | ||
| 1468 | ravb_emac_init(ndev); | 1489 | ravb_emac_init(ndev); |
| 1469 | 1490 | ||
| 1491 | out: | ||
| 1470 | /* Initialise PTP Clock driver */ | 1492 | /* Initialise PTP Clock driver */ |
| 1471 | if (priv->chip_id == RCAR_GEN2) | 1493 | if (priv->chip_id == RCAR_GEN2) |
| 1472 | ravb_ptp_init(ndev, priv->pdev); | 1494 | ravb_ptp_init(ndev, priv->pdev); |
| @@ -2274,7 +2274,7 @@ static int smc_drv_probe(struct platform_device *pdev) · 2273 unmodified lines | |||
| 2274 | ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio, | 2274 | ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio, |
| 2275 | "power", 0, 0, 100); | 2275 | "power", 0, 0, 100); |
| 2276 | if (ret) | 2276 | if (ret) |
| 2277 | return ret; | 2277 | goto out_free_netdev; |
| 2278 | 2278 | ||
| 2279 | /* | 2279 | /* |
| 2280 | * Optional reset GPIO configured? Minimum 100 ns reset needed | 2280 | * Optional reset GPIO configured? Minimum 100 ns reset needed |
| @@ -2283,7 +2283,7 @@ static int smc_drv_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 2283 | ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio, | 2283 | ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio, |
| 2284 | "reset", 0, 0, 100); | 2284 | "reset", 0, 0, 100); |
| 2285 | if (ret) | 2285 | if (ret) |
| 2286 | return ret; | 2286 | goto out_free_netdev; |
| 2287 | 2287 | ||
| 2288 | /* | 2288 | /* |
| 2289 | * Need to wait for optional EEPROM to load, max 750 us according | 2289 | * Need to wait for optional EEPROM to load, max 750 us according |
| @@ -1191,7 +1191,7 @@ static int ave_init(struct net_device *ndev) · 1190 unmodified lines | |||
| 1191 | ret = regmap_update_bits(priv->regmap, SG_ETPINMODE, | 1191 | ret = regmap_update_bits(priv->regmap, SG_ETPINMODE, |
| 1192 | priv->pinmode_mask, priv->pinmode_val); | 1192 | priv->pinmode_mask, priv->pinmode_val); |
| 1193 | if (ret) | 1193 | if (ret) |
| 1194 | return ret; | 1194 | goto out_reset_assert; |
| 1195 | 1195 | ||
| 1196 | ave_global_reset(ndev); | 1196 | ave_global_reset(ndev); |
| 1197 | 1197 | ||
| @@ -1850,7 +1850,8 @@ static int am65_cpsw_nuss_init_ndev_2g(struct am65_cpsw_common *common) · 1849 unmodified lines | |||
| 1850 | port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; | 1850 | port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; |
| 1851 | port->ndev->hw_features = NETIF_F_SG | | 1851 | port->ndev->hw_features = NETIF_F_SG | |
| 1852 | NETIF_F_RXCSUM | | 1852 | NETIF_F_RXCSUM | |
| 1853 | NETIF_F_HW_CSUM; | 1853 | NETIF_F_HW_CSUM | |
| 1854 | NETIF_F_HW_TC; | ||
| 1854 | port->ndev->features = port->ndev->hw_features | | 1855 | port->ndev->features = port->ndev->hw_features | |
| 1855 | NETIF_F_HW_VLAN_CTAG_FILTER; | 1856 | NETIF_F_HW_VLAN_CTAG_FILTER; |
| 1856 | port->ndev->vlan_features |= NETIF_F_SG; | 1857 | port->ndev->vlan_features |= NETIF_F_SG; |
| @@ -1615,11 +1615,11 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[], · 1614 unmodified lines | |||
| 1615 | struct netlink_ext_ack *extack) | 1615 | struct netlink_ext_ack *extack) |
| 1616 | { | 1616 | { |
| 1617 | struct geneve_dev *geneve = netdev_priv(dev); | 1617 | struct geneve_dev *geneve = netdev_priv(dev); |
| 1618 | enum ifla_geneve_df df = geneve->df; | ||
| 1618 | struct geneve_sock *gs4, *gs6; | 1619 | struct geneve_sock *gs4, *gs6; |
| 1619 | struct ip_tunnel_info info; | 1620 | struct ip_tunnel_info info; |
| 1620 | bool metadata; | 1621 | bool metadata; |
| 1621 | bool use_udp6_rx_checksums; | 1622 | bool use_udp6_rx_checksums; |
| 1622 | enum ifla_geneve_df df; | ||
| 1623 | bool ttl_inherit; | 1623 | bool ttl_inherit; |
| 1624 | int err; | 1624 | int err; |
| 1625 | 1625 | ||
| @@ -1242,7 +1242,7 @@ static int rr_open(struct net_device *dev) · 1241 unmodified lines | |||
| 1242 | rrpriv->info = NULL; | 1242 | rrpriv->info = NULL; |
| 1243 | } | 1243 | } |
| 1244 | if (rrpriv->rx_ctrl) { | 1244 | if (rrpriv->rx_ctrl) { |
| 1245 | pci_free_consistent(pdev, sizeof(struct ring_ctrl), | 1245 | pci_free_consistent(pdev, 256 * sizeof(struct ring_ctrl), |
| 1246 | rrpriv->rx_ctrl, rrpriv->rx_ctrl_dma); | 1246 | rrpriv->rx_ctrl, rrpriv->rx_ctrl_dma); |
| 1247 | rrpriv->rx_ctrl = NULL; | 1247 | rrpriv->rx_ctrl = NULL; |
| 1248 | } | 1248 | } |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | * | 4 | * |
| 5 | * Copyright 2009-2017 Analog Devices Inc. | 5 | * Copyright 2009-2017 Analog Devices Inc. |
| 6 | * | 6 | * |
| 7 | * http://www.analog.com/ADF7242 | 7 | * https://www.analog.com/ADF7242 |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| @@ -1262,7 +1262,7 @@ static int adf7242_probe(struct spi_device *spi) · 1251 unmodified lines | |||
| 1262 | WQ_MEM_RECLAIM); | 1262 | WQ_MEM_RECLAIM); |
| 1263 | if (unlikely(!lp->wqueue)) { | 1263 | if (unlikely(!lp->wqueue)) { |
| 1264 | ret = -ENOMEM; | 1264 | ret = -ENOMEM; |
| 1265 | goto err_hw_init; | 1265 | goto err_alloc_wq; |
| 1266 | } | 1266 | } |
| 1267 | 1267 | ||
| 1268 | ret = adf7242_hw_init(lp); | 1268 | ret = adf7242_hw_init(lp); |
| @@ -1294,6 +1294,8 @@ static int adf7242_probe(struct spi_device *spi) · 25 unmodified lines | |||
| 1294 | return ret; | 1294 | return ret; |
| 1295 | 1295 | ||
| 1296 | err_hw_init: | 1296 | err_hw_init: |
| 1297 | destroy_workqueue(lp->wqueue); | ||
| 1298 | err_alloc_wq: | ||
| 1297 | mutex_destroy(&lp->bmux); | 1299 | mutex_destroy(&lp->bmux); |
| 1298 | ieee802154_free_hw(lp->hw); | 1300 | ieee802154_free_hw(lp->hw); |
| 1299 | 1301 | ||
| @@ -302,7 +302,7 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port) · 301 unmodified lines | |||
| 302 | rtnl_lock(); | 302 | rtnl_lock(); |
| 303 | err = nsim_bpf_init(ns); | 303 | err = nsim_bpf_init(ns); |
| 304 | if (err) | 304 | if (err) |
| 305 | goto err_free_netdev; | 305 | goto err_rtnl_unlock; |
| 306 | 306 | ||
| 307 | nsim_ipsec_init(ns); | 307 | nsim_ipsec_init(ns); |
| 308 | 308 | ||
| @@ -316,8 +316,8 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port) · 7 unmodified lines | |||
| 316 | err_ipsec_teardown: | 316 | err_ipsec_teardown: |
| 317 | nsim_ipsec_teardown(ns); | 317 | nsim_ipsec_teardown(ns); |
| 318 | nsim_bpf_uninit(ns); | 318 | nsim_bpf_uninit(ns); |
| 319 | err_rtnl_unlock: | ||
| 319 | rtnl_unlock(); | 320 | rtnl_unlock(); |
| 320 | err_free_netdev: | ||
| 321 | free_netdev(dev); | 321 | free_netdev(dev); |
| 322 | return ERR_PTR(err); | 322 | return ERR_PTR(err); |
| 323 | } | 323 | } |
| @@ -1260,6 +1260,7 @@ static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) · 1259 unmodified lines | |||
| 1260 | dp83640->hwts_rx_en = 1; | 1260 | dp83640->hwts_rx_en = 1; |
| 1261 | dp83640->layer = PTP_CLASS_L4; | 1261 | dp83640->layer = PTP_CLASS_L4; |
| 1262 | dp83640->version = PTP_CLASS_V1; | 1262 | dp83640->version = PTP_CLASS_V1; |
| 1263 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; | ||
| 1263 | break; | 1264 | break; |
| 1264 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | 1265 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: |
| 1265 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | 1266 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: |
| @@ -1267,6 +1268,7 @@ static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) · 1 unmodified line | |||
| 1267 | dp83640->hwts_rx_en = 1; | 1268 | dp83640->hwts_rx_en = 1; |
| 1268 | dp83640->layer = PTP_CLASS_L4; | 1269 | dp83640->layer = PTP_CLASS_L4; |
| 1269 | dp83640->version = PTP_CLASS_V2; | 1270 | dp83640->version = PTP_CLASS_V2; |
| 1271 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; | ||
| 1270 | break; | 1272 | break; |
| 1271 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | 1273 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: |
| 1272 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | 1274 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: |
| @@ -1274,6 +1276,7 @@ static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) · 1 unmodified line | |||
| 1274 | dp83640->hwts_rx_en = 1; | 1276 | dp83640->hwts_rx_en = 1; |
| 1275 | dp83640->layer = PTP_CLASS_L2; | 1277 | dp83640->layer = PTP_CLASS_L2; |
| 1276 | dp83640->version = PTP_CLASS_V2; | 1278 | dp83640->version = PTP_CLASS_V2; |
| 1279 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; | ||
| 1277 | break; | 1280 | break; |
| 1278 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | 1281 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
| 1279 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | 1282 | case HWTSTAMP_FILTER_PTP_V2_SYNC: |
| @@ -1281,6 +1284,7 @@ static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) · 1 unmodified line | |||
| 1281 | dp83640->hwts_rx_en = 1; | 1284 | dp83640->hwts_rx_en = 1; |
| 1282 | dp83640->layer = PTP_CLASS_L4 | PTP_CLASS_L2; | 1285 | dp83640->layer = PTP_CLASS_L4 | PTP_CLASS_L2; |
| 1283 | dp83640->version = PTP_CLASS_V2; | 1286 | dp83640->version = PTP_CLASS_V2; |
| 1287 | cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | ||
| 1284 | break; | 1288 | break; |
| 1285 | default: | 1289 | default: |
| 1286 | return -ERANGE; | 1290 | return -ERANGE; |
| @@ -187,6 +187,7 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) · 186 unmodified lines | |||
| 187 | ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); | 187 | ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); |
| 188 | if (ret < ETH_ALEN) { | 188 | if (ret < ETH_ALEN) { |
| 189 | netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); | 189 | netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); |
| 190 | ret = -EIO; | ||
| 190 | goto free; | 191 | goto free; |
| 191 | } | 192 | } |
| 192 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); | 193 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); |
| @@ -1390,8 +1390,9 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) · 1389 unmodified lines | |||
| 1390 | unsigned long flags; | 1390 | unsigned long flags; |
| 1391 | 1391 | ||
| 1392 | if (old) | 1392 | if (old) |
| 1393 | hso_dbg(0x16, "Termios called with: cflags new[%d] - old[%d]\n", | 1393 | hso_dbg(0x16, "Termios called with: cflags new[%u] - old[%u]\n", |
| 1394 | tty->termios.c_cflag, old->c_cflag); | 1394 | (unsigned int)tty->termios.c_cflag, |
| 1395 | (unsigned int)old->c_cflag); | ||
| 1395 | 1396 | ||
| 1396 | /* the actual setup */ | 1397 | /* the actual setup */ |
| 1397 | spin_lock_irqsave(&serial->serial_lock, flags); | 1398 | spin_lock_irqsave(&serial->serial_lock, flags); |
| @@ -71,8 +71,10 @@ static int x25_data_indication(struct net_device *dev, struct sk_buff *skb) · 70 unmodified lines | |||
| 71 | { | 71 | { |
| 72 | unsigned char *ptr; | 72 | unsigned char *ptr; |
| 73 | 73 | ||
| 74 | if (skb_cow(skb, 1)) | 74 | if (skb_cow(skb, 1)) { |
| 75 | kfree_skb(skb); | ||
| 75 | return NET_RX_DROP; | 76 | return NET_RX_DROP; |
| 77 | } | ||
| 76 | 78 | ||
| 77 | skb_push(skb, 1); | 79 | skb_push(skb, 1); |
| 78 | skb_reset_network_header(skb); | 80 | skb_reset_network_header(skb); |
| @@ -128,10 +128,12 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb) · 127 unmodified lines | |||
| 128 | { | 128 | { |
| 129 | unsigned char *ptr; | 129 | unsigned char *ptr; |
| 130 | 130 | ||
| 131 | skb_push(skb, 1); | 131 | if (skb_cow(skb, 1)) { |
| 132 | 132 | kfree_skb(skb); | |
| 133 | if (skb_cow(skb, 1)) | ||
| 134 | return NET_RX_DROP; | 133 | return NET_RX_DROP; |
| 134 | } | ||
| 135 | |||
| 136 | skb_push(skb, 1); | ||
| 135 | 137 | ||
| 136 | ptr = skb->data; | 138 | ptr = skb->data; |
| 137 | *ptr = X25_IFACE_DATA; | 139 | *ptr = X25_IFACE_DATA; |
| @@ -183,7 +183,7 @@ static inline void x25_asy_unlock(struct x25_asy *sl) · 182 unmodified lines | |||
| 183 | netif_wake_queue(sl->dev); | 183 | netif_wake_queue(sl->dev); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | /* Send one completely decapsulated IP datagram to the IP layer. */ | 186 | /* Send an LAPB frame to the LAPB module to process. */ |
| 187 | 187 | ||
| 188 | static void x25_asy_bump(struct x25_asy *sl) | 188 | static void x25_asy_bump(struct x25_asy *sl) |
| 189 | { | 189 | { |
| @@ -195,13 +195,12 @@ static void x25_asy_bump(struct x25_asy *sl) · 5 unmodified lines | |||
| 195 | count = sl->rcount; | 195 | count = sl->rcount; |
| 196 | dev->stats.rx_bytes += count; | 196 | dev->stats.rx_bytes += count; |
| 197 | 197 | ||
| 198 | skb = dev_alloc_skb(count+1); | 198 | skb = dev_alloc_skb(count); |
| 199 | if (skb == NULL) { | 199 | if (skb == NULL) { |
| 200 | netdev_warn(sl->dev, "memory squeeze, dropping packet\n"); | 200 | netdev_warn(sl->dev, "memory squeeze, dropping packet\n"); |
| 201 | dev->stats.rx_dropped++; | 201 | dev->stats.rx_dropped++; |
| 202 | return; | 202 | return; |
| 203 | } | 203 | } |
| 204 | skb_push(skb, 1); /* LAPB internal control */ | ||
| 205 | skb_put_data(skb, sl->rbuff, count); | 204 | skb_put_data(skb, sl->rbuff, count); |
| 206 | skb->protocol = x25_type_trans(skb, sl->dev); | 205 | skb->protocol = x25_type_trans(skb, sl->dev); |
| 207 | err = lapb_data_received(skb->dev, skb); | 206 | err = lapb_data_received(skb->dev, skb); |
| @@ -209,7 +208,6 @@ static void x25_asy_bump(struct x25_asy *sl) · 1 unmodified line | |||
| 209 | kfree_skb(skb); | 208 | kfree_skb(skb); |
| 210 | printk(KERN_DEBUG "x25_asy: data received err - %d\n", err); | 209 | printk(KERN_DEBUG "x25_asy: data received err - %d\n", err); |
| 211 | } else { | 210 | } else { |
| 212 | netif_rx(skb); | ||
| 213 | dev->stats.rx_packets++; | 211 | dev->stats.rx_packets++; |
| 214 | } | 212 | } |
| 215 | } | 213 | } |
| @@ -356,12 +354,21 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb, · 140 unmodified lines | |||
| 356 | */ | 354 | */ |
| 357 | 355 | ||
| 358 | /* | 356 | /* |
| 359 | * Called when I frame data arrives. We did the work above - throw it | 357 | * Called when I frame data arrive. We add a pseudo header for upper |
| 360 | * at the net layer. | 358 | * layers and pass it to upper layers. |
| 361 | */ | 359 | */ |
| 362 | 360 | ||
| 363 | static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb) | 361 | static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb) |
| 364 | { | 362 | { |
| 363 | if (skb_cow(skb, 1)) { | ||
| 364 | kfree_skb(skb); | ||
| 365 | return NET_RX_DROP; | ||
| 366 | } | ||
| 367 | skb_push(skb, 1); | ||
| 368 | skb->data[0] = X25_IFACE_DATA; | ||
| 369 | |||
| 370 | skb->protocol = x25_type_trans(skb, dev); | ||
| 371 | |||
| 365 | return netif_rx(skb); | 372 | return netif_rx(skb); |
| 366 | } | 373 | } |
| 367 | 374 | ||
| @@ -657,7 +664,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) · 289 unmodified lines | |||
| 657 | switch (s) { | 664 | switch (s) { |
| 658 | case X25_END: | 665 | case X25_END: |
| 659 | if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && | 666 | if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && |
| 660 | sl->rcount > 2) | 667 | sl->rcount >= 2) |
| 661 | x25_asy_bump(sl); | 668 | x25_asy_bump(sl); |
| 662 | clear_bit(SLF_ESCAPE, &sl->flags); | 669 | clear_bit(SLF_ESCAPE, &sl->flags); |
| 663 | sl->rcount = 0; | 670 | sl->rcount = 0; |
| @@ -820,7 +820,7 @@ err_free_irq: · 819 unmodified lines | |||
| 820 | ath10k_ahb_release_irq_legacy(ar); | 820 | ath10k_ahb_release_irq_legacy(ar); |
| 821 | 821 | ||
| 822 | err_free_pipes: | 822 | err_free_pipes: |
| 823 | ath10k_pci_free_pipes(ar); | 823 | ath10k_pci_release_resource(ar); |
| 824 | 824 | ||
| 825 | err_resource_deinit: | 825 | err_resource_deinit: |
| 826 | ath10k_ahb_resource_deinit(ar); | 826 | ath10k_ahb_resource_deinit(ar); |
| @@ -3473,6 +3473,28 @@ int ath10k_pci_setup_resource(struct ath10k *ar) · 3472 unmodified lines | |||
| 3473 | 3473 | ||
| 3474 | timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); | 3474 | timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); |
| 3475 | 3475 | ||
| 3476 | ar_pci->attr = kmemdup(pci_host_ce_config_wlan, | ||
| 3477 | sizeof(pci_host_ce_config_wlan), | ||
| 3478 | GFP_KERNEL); | ||
| 3479 | if (!ar_pci->attr) | ||
| 3480 | return -ENOMEM; | ||
| 3481 | |||
| 3482 | ar_pci->pipe_config = kmemdup(pci_target_ce_config_wlan, | ||
| 3483 | sizeof(pci_target_ce_config_wlan), | ||
| 3484 | GFP_KERNEL); | ||
| 3485 | if (!ar_pci->pipe_config) { | ||
| 3486 | ret = -ENOMEM; | ||
| 3487 | goto err_free_attr; | ||
| 3488 | } | ||
| 3489 | |||
| 3490 | ar_pci->serv_to_pipe = kmemdup(pci_target_service_to_ce_map_wlan, | ||
| 3491 | sizeof(pci_target_service_to_ce_map_wlan), | ||
| 3492 | GFP_KERNEL); | ||
| 3493 | if (!ar_pci->serv_to_pipe) { | ||
| 3494 | ret = -ENOMEM; | ||
| 3495 | goto err_free_pipe_config; | ||
| 3496 | } | ||
| 3497 | |||
| 3476 | if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) | 3498 | if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) |
| 3477 | ath10k_pci_override_ce_config(ar); | 3499 | ath10k_pci_override_ce_config(ar); |
| 3478 | 3500 | ||
| @@ -3480,18 +3502,31 @@ int ath10k_pci_setup_resource(struct ath10k *ar) · 1 unmodified line | |||
| 3480 | if (ret) { | 3502 | if (ret) { |
| 3481 | ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", | 3503 | ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", |
| 3482 | ret); | 3504 | ret); |
| 3483 | return ret; | 3505 | goto err_free_serv_to_pipe; |
| 3484 | } | 3506 | } |
| 3485 | 3507 | ||
| 3486 | return 0; | 3508 | return 0; |
| 3509 | |||
| 3510 | err_free_serv_to_pipe: | ||
| 3511 | kfree(ar_pci->serv_to_pipe); | ||
| 3512 | err_free_pipe_config: | ||
| 3513 | kfree(ar_pci->pipe_config); | ||
| 3514 | err_free_attr: | ||
| 3515 | kfree(ar_pci->attr); | ||
| 3516 | return ret; | ||
| 3487 | } | 3517 | } |
| 3488 | 3518 | ||
| 3489 | void ath10k_pci_release_resource(struct ath10k *ar) | 3519 | void ath10k_pci_release_resource(struct ath10k *ar) |
| 3490 | { | 3520 | { |
| 3521 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
| 3522 | |||
| 3491 | ath10k_pci_rx_retry_sync(ar); | 3523 | ath10k_pci_rx_retry_sync(ar); |
| 3492 | netif_napi_del(&ar->napi); | 3524 | netif_napi_del(&ar->napi); |
| 3493 | ath10k_pci_ce_deinit(ar); | 3525 | ath10k_pci_ce_deinit(ar); |
| 3494 | ath10k_pci_free_pipes(ar); | 3526 | ath10k_pci_free_pipes(ar); |
| 3527 | kfree(ar_pci->attr); | ||
| 3528 | kfree(ar_pci->pipe_config); | ||
| 3529 | kfree(ar_pci->serv_to_pipe); | ||
| 3495 | } | 3530 | } |
| 3496 | 3531 | ||
| 3497 | static const struct ath10k_bus_ops ath10k_pci_bus_ops = { | 3532 | static const struct ath10k_bus_ops ath10k_pci_bus_ops = { |
| @@ -3601,30 +3636,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, · 103 unmodified lines | |||
| 3601 | 3636 | ||
| 3602 | timer_setup(&ar_pci->ps_timer, ath10k_pci_ps_timer, 0); | 3637 | timer_setup(&ar_pci->ps_timer, ath10k_pci_ps_timer, 0); |
| 3603 | 3638 | ||
| 3604 | ar_pci->attr = kmemdup(pci_host_ce_config_wlan, | ||
| 3605 | sizeof(pci_host_ce_config_wlan), | ||
| 3606 | GFP_KERNEL); | ||
| 3607 | if (!ar_pci->attr) { | ||
| 3608 | ret = -ENOMEM; | ||
| 3609 | goto err_free; | ||
| 3610 | } | ||
| 3611 | |||
| 3612 | ar_pci->pipe_config = kmemdup(pci_target_ce_config_wlan, | ||
| 3613 | sizeof(pci_target_ce_config_wlan), | ||
| 3614 | GFP_KERNEL); | ||
| 3615 | if (!ar_pci->pipe_config) { | ||
| 3616 | ret = -ENOMEM; | ||
| 3617 | goto err_free; | ||
| 3618 | } | ||
| 3619 | |||
| 3620 | ar_pci->serv_to_pipe = kmemdup(pci_target_service_to_ce_map_wlan, | ||
| 3621 | sizeof(pci_target_service_to_ce_map_wlan), | ||
| 3622 | GFP_KERNEL); | ||
| 3623 | if (!ar_pci->serv_to_pipe) { | ||
| 3624 | ret = -ENOMEM; | ||
| 3625 | goto err_free; | ||
| 3626 | } | ||
| 3627 | |||
| 3628 | ret = ath10k_pci_setup_resource(ar); | 3639 | ret = ath10k_pci_setup_resource(ar); |
| 3629 | if (ret) { | 3640 | if (ret) { |
| 3630 | ath10k_err(ar, "failed to setup resource: %d\n", ret); | 3641 | ath10k_err(ar, "failed to setup resource: %d\n", ret); |
| @@ -3705,10 +3716,9 @@ err_unsupported: · 74 unmodified lines | |||
| 3705 | 3716 | ||
| 3706 | err_free_irq: | 3717 | err_free_irq: |
| 3707 | ath10k_pci_free_irq(ar); | 3718 | ath10k_pci_free_irq(ar); |
| 3708 | ath10k_pci_rx_retry_sync(ar); | ||
| 3709 | 3719 | ||
| 3710 | err_deinit_irq: | 3720 | err_deinit_irq: |
| 3711 | ath10k_pci_deinit_irq(ar); | 3721 | ath10k_pci_release_resource(ar); |
| 3712 | 3722 | ||
| 3713 | err_sleep: | 3723 | err_sleep: |
| 3714 | ath10k_pci_sleep_sync(ar); | 3724 | ath10k_pci_sleep_sync(ar); |
| @@ -3720,29 +3730,18 @@ err_free_pipes: · 5 unmodified lines | |||
| 3720 | err_core_destroy: | 3730 | err_core_destroy: |
| 3721 | ath10k_core_destroy(ar); | 3731 | ath10k_core_destroy(ar); |
| 3722 | 3732 | ||
| 3723 | err_free: | ||
| 3724 | kfree(ar_pci->attr); | ||
| 3725 | kfree(ar_pci->pipe_config); | ||
| 3726 | kfree(ar_pci->serv_to_pipe); | ||
| 3727 | |||
| 3728 | return ret; | 3733 | return ret; |
| 3729 | } | 3734 | } |
| 3730 | 3735 | ||
| 3731 | static void ath10k_pci_remove(struct pci_dev *pdev) | 3736 | static void ath10k_pci_remove(struct pci_dev *pdev) |
| 3732 | { | 3737 | { |
| 3733 | struct ath10k *ar = pci_get_drvdata(pdev); | 3738 | struct ath10k *ar = pci_get_drvdata(pdev); |
| 3734 | struct ath10k_pci *ar_pci; | ||
| 3735 | 3739 | ||
| 3736 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci remove\n"); | 3740 | ath10k_dbg(ar, ATH10K_DBG_PCI, "pci remove\n"); |
| 3737 | 3741 | ||
| 3738 | if (!ar) | 3742 | if (!ar) |
| 3739 | return; | 3743 | return; |
| 3740 | 3744 | ||
| 3741 | ar_pci = ath10k_pci_priv(ar); | ||
| 3742 | |||
| 3743 | if (!ar_pci) | ||
| 3744 | return; | ||
| 3745 | |||
| 3746 | ath10k_core_unregister(ar); | 3745 | ath10k_core_unregister(ar); |
| 3747 | ath10k_pci_free_irq(ar); | 3746 | ath10k_pci_free_irq(ar); |
| 3748 | ath10k_pci_deinit_irq(ar); | 3747 | ath10k_pci_deinit_irq(ar); |
| @@ -3750,9 +3749,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev) · 1 unmodified line | |||
| 3750 | ath10k_pci_sleep_sync(ar); | 3749 | ath10k_pci_sleep_sync(ar); |
| 3751 | ath10k_pci_release(ar); | 3750 | ath10k_pci_release(ar); |
| 3752 | ath10k_core_destroy(ar); | 3751 | ath10k_core_destroy(ar); |
| 3753 | kfree(ar_pci->attr); | ||
| 3754 | kfree(ar_pci->pipe_config); | ||
| 3755 | kfree(ar_pci->serv_to_pipe); | ||
| 3756 | } | 3752 | } |
| 3757 | 3753 | ||
| 3758 | MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); | 3754 | MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); |
| @@ -733,11 +733,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) · 732 unmodified lines | |||
| 733 | return; | 733 | return; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| 736 | rx_buf->skb = nskb; | ||
| 737 | |||
| 736 | usb_fill_int_urb(urb, hif_dev->udev, | 738 | usb_fill_int_urb(urb, hif_dev->udev, |
| 737 | usb_rcvintpipe(hif_dev->udev, | 739 | usb_rcvintpipe(hif_dev->udev, |
| 738 | USB_REG_IN_PIPE), | 740 | USB_REG_IN_PIPE), |
| 739 | nskb->data, MAX_REG_IN_BUF_SIZE, | 741 | nskb->data, MAX_REG_IN_BUF_SIZE, |
| 740 | ath9k_hif_usb_reg_in_cb, nskb, 1); | 742 | ath9k_hif_usb_reg_in_cb, rx_buf, 1); |
| 741 | } | 743 | } |
| 742 | 744 | ||
| 743 | resubmit: | 745 | resubmit: |
| @@ -271,6 +271,8 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans, · 270 unmodified lines | |||
| 271 | { | 271 | { |
| 272 | struct iwl_fw_ini_trigger_tlv *trig = (void *)tlv->data; | 272 | struct iwl_fw_ini_trigger_tlv *trig = (void *)tlv->data; |
| 273 | u32 tp = le32_to_cpu(trig->time_point); | 273 | u32 tp = le32_to_cpu(trig->time_point); |
| 274 | struct iwl_ucode_tlv *dup = NULL; | ||
| 275 | int ret; | ||
| 274 | 276 | ||
| 275 | if (le32_to_cpu(tlv->length) < sizeof(*trig)) | 277 | if (le32_to_cpu(tlv->length) < sizeof(*trig)) |
| 276 | return -EINVAL; | 278 | return -EINVAL; |
| @@ -283,10 +285,20 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans, · 6 unmodified lines | |||
| 283 | return -EINVAL; | 285 | return -EINVAL; |
| 284 | } | 286 | } |
| 285 | 287 | ||
| 286 | if (!le32_to_cpu(trig->occurrences)) | 288 | if (!le32_to_cpu(trig->occurrences)) { |
| 289 | dup = kmemdup(tlv, sizeof(*tlv) + le32_to_cpu(tlv->length), | ||
| 290 | GFP_KERNEL); | ||
| 291 | if (!dup) | ||
| 292 | return -ENOMEM; | ||
| 293 | trig = (void *)dup->data; | ||
| 287 | trig->occurrences = cpu_to_le32(-1); | 294 | trig->occurrences = cpu_to_le32(-1); |
| 295 | tlv = dup; | ||
| 296 | } | ||
| 297 | |||
| 298 | ret = iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].trig_list); | ||
| 299 | kfree(dup); | ||
| 288 | 300 | ||
| 289 | return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].trig_list); | 301 | return ret; |
| 290 | } | 302 | } |
| 291 | 303 | ||
| 292 | static int (*dbg_tlv_alloc[])(struct iwl_trans *trans, | 304 | static int (*dbg_tlv_alloc[])(struct iwl_trans *trans, |
| @@ -1189,17 +1189,15 @@ static int iwl_mvm_inactivity_check(struct iwl_mvm *mvm, u8 alloc_for_sta) · 1188 unmodified lines | |||
| 1189 | for_each_set_bit(i, &changetid_queues, IWL_MAX_HW_QUEUES) | 1189 | for_each_set_bit(i, &changetid_queues, IWL_MAX_HW_QUEUES) |
| 1190 | iwl_mvm_change_queue_tid(mvm, i); | 1190 | iwl_mvm_change_queue_tid(mvm, i); |
| 1191 | 1191 | ||
| 1192 | rcu_read_unlock(); | ||
| 1193 | |||
| 1192 | if (free_queue >= 0 && alloc_for_sta != IWL_MVM_INVALID_STA) { | 1194 | if (free_queue >= 0 && alloc_for_sta != IWL_MVM_INVALID_STA) { |
| 1193 | ret = iwl_mvm_free_inactive_queue(mvm, free_queue, queue_owner, | 1195 | ret = iwl_mvm_free_inactive_queue(mvm, free_queue, queue_owner, |
| 1194 | alloc_for_sta); | 1196 | alloc_for_sta); |
| 1195 | if (ret) { | 1197 | if (ret) |
| 1196 | rcu_read_unlock(); | ||
| 1197 | return ret; | 1198 | return ret; |
| 1198 | } | ||
| 1199 | } | 1199 | } |
| 1200 | 1200 | ||
| 1201 | rcu_read_unlock(); | ||
| 1202 | |||
| 1203 | return free_queue; | 1201 | return free_queue; |
| 1204 | } | 1202 | } |
| 1205 | 1203 | ||
| @@ -582,6 +582,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { · 581 unmodified lines | |||
| 582 | IWL_DEV_INFO(0x30DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), | 582 | IWL_DEV_INFO(0x30DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), |
| 583 | IWL_DEV_INFO(0x31DC, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), | 583 | IWL_DEV_INFO(0x31DC, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), |
| 584 | IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), | 584 | IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), |
| 585 | IWL_DEV_INFO(0xA370, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), | ||
| 586 | IWL_DEV_INFO(0xA370, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), | ||
| 585 | 587 | ||
| 586 | IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), | 588 | IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), |
| 587 | 589 | ||
| @@ -301,6 +301,7 @@ struct mt76_hw_cap { · 300 unmodified lines | |||
| 301 | #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) | 301 | #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) |
| 302 | #define MT_DRV_SW_RX_AIRTIME BIT(2) | 302 | #define MT_DRV_SW_RX_AIRTIME BIT(2) |
| 303 | #define MT_DRV_RX_DMA_HDR BIT(3) | 303 | #define MT_DRV_RX_DMA_HDR BIT(3) |
| 304 | #define MT_DRV_HW_MGMT_TXQ BIT(4) | ||
| 304 | 305 | ||
| 305 | struct mt76_driver_ops { | 306 | struct mt76_driver_ops { |
| 306 | u32 drv_flags; | 307 | u32 drv_flags; |
| @@ -642,8 +642,10 @@ mt7603_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) · 641 unmodified lines | |||
| 642 | { | 642 | { |
| 643 | struct mt7603_dev *dev = hw->priv; | 643 | struct mt7603_dev *dev = hw->priv; |
| 644 | 644 | ||
| 645 | mutex_lock(&dev->mt76.mutex); | ||
| 645 | dev->coverage_class = max_t(s16, coverage_class, 0); | 646 | dev->coverage_class = max_t(s16, coverage_class, 0); |
| 646 | mt7603_mac_set_timing(dev); | 647 | mt7603_mac_set_timing(dev); |
| 648 | mutex_unlock(&dev->mt76.mutex); | ||
| 647 | } | 649 | } |
| 648 | 650 | ||
| 649 | static void mt7603_tx(struct ieee80211_hw *hw, | 651 | static void mt7603_tx(struct ieee80211_hw *hw, |
| @@ -234,10 +234,11 @@ mt7615_queues_acq(struct seq_file *s, void *data) · 233 unmodified lines | |||
| 234 | int i; | 234 | int i; |
| 235 | 235 | ||
| 236 | for (i = 0; i < 16; i++) { | 236 | for (i = 0; i < 16; i++) { |
| 237 | int j, acs = i / 4, index = i % 4; | 237 | int j, wmm_idx = i % MT7615_MAX_WMM_SETS; |
| 238 | int acs = i / MT7615_MAX_WMM_SETS; | ||
| 238 | u32 ctrl, val, qlen = 0; | 239 | u32 ctrl, val, qlen = 0; |
| 239 | 240 | ||
| 240 | val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, index)); | 241 | val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx)); |
| 241 | ctrl = BIT(31) | BIT(15) | (acs << 8); | 242 | ctrl = BIT(31) | BIT(15) | (acs << 8); |
| 242 | 243 | ||
| 243 | for (j = 0; j < 32; j++) { | 244 | for (j = 0; j < 32; j++) { |
| @@ -245,11 +246,11 @@ mt7615_queues_acq(struct seq_file *s, void *data) · 1 unmodified line | |||
| 245 | continue; | 246 | continue; |
| 246 | 247 | ||
| 247 | mt76_wr(dev, MT_PLE_FL_Q0_CTRL, | 248 | mt76_wr(dev, MT_PLE_FL_Q0_CTRL, |
| 248 | ctrl | (j + (index << 5))); | 249 | ctrl | (j + (wmm_idx << 5))); |
| 249 | qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, | 250 | qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, |
| 250 | GENMASK(11, 0)); | 251 | GENMASK(11, 0)); |
| 251 | } | 252 | } |
| 252 | seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen); | 253 | seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen); |
| 253 | } | 254 | } |
| 254 | 255 | ||
| 255 | return 0; | 256 | return 0; |
| @@ -36,10 +36,10 @@ static int · 35 unmodified lines | |||
| 36 | mt7622_init_tx_queues_multi(struct mt7615_dev *dev) | 36 | mt7622_init_tx_queues_multi(struct mt7615_dev *dev) |
| 37 | { | 37 | { |
| 38 | static const u8 wmm_queue_map[] = { | 38 | static const u8 wmm_queue_map[] = { |
| 39 | MT7622_TXQ_AC0, | 39 | [IEEE80211_AC_BK] = MT7622_TXQ_AC0, |
| 40 | MT7622_TXQ_AC1, | 40 | [IEEE80211_AC_BE] = MT7622_TXQ_AC1, |
| 41 | MT7622_TXQ_AC2, | 41 | [IEEE80211_AC_VI] = MT7622_TXQ_AC2, |
| 42 | MT7622_TXQ_AC3, | 42 | [IEEE80211_AC_VO] = MT7622_TXQ_AC3, |
| 43 | }; | 43 | }; |
| 44 | int ret; | 44 | int ret; |
| 45 | int i; | 45 | int i; |
| @@ -100,6 +100,7 @@ mt7615_tx_cleanup(struct mt7615_dev *dev) · 54 unmodified lines | |||
| 100 | int i; | 100 | int i; |
| 101 | 101 | ||
| 102 | mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false); | 102 | mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false); |
| 103 | mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false); | ||
| 103 | if (is_mt7615(&dev->mt76)) { | 104 | if (is_mt7615(&dev->mt76)) { |
| 104 | mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false); | 105 | mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false); |
| 105 | } else { | 106 | } else { |
| @@ -72,8 +72,7 @@ static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr) · 71 unmodified lines | |||
| 72 | { | 72 | { |
| 73 | int ret; | 73 | int ret; |
| 74 | 74 | ||
| 75 | ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_SIZE + | 75 | ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_FULL_SIZE); |
| 76 | MT7615_EEPROM_EXTRA_DATA); | ||
| 77 | if (ret < 0) | 76 | if (ret < 0) |
| 78 | return ret; | 77 | return ret; |
| 79 | 78 | ||
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | #define MT7615_EEPROM_TXDPD_SIZE 216 | 17 | #define MT7615_EEPROM_TXDPD_SIZE 216 |
| 18 | #define MT7615_EEPROM_TXDPD_COUNT (44 + 3) | 18 | #define MT7615_EEPROM_TXDPD_COUNT (44 + 3) |
| 19 | 19 | ||
| 20 | #define MT7615_EEPROM_EXTRA_DATA (MT7615_EEPROM_TXDPD_OFFSET + \ | 20 | #define MT7615_EEPROM_FULL_SIZE (MT7615_EEPROM_TXDPD_OFFSET + \ |
| 21 | MT7615_EEPROM_TXDPD_COUNT * \ | 21 | MT7615_EEPROM_TXDPD_COUNT * \ |
| 22 | MT7615_EEPROM_TXDPD_SIZE) | 22 | MT7615_EEPROM_TXDPD_SIZE) |
| 23 | 23 | ||
| @@ -526,22 +526,16 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, · 525 unmodified lines | |||
| 526 | fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; | 526 | fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; |
| 527 | fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; | 527 | fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; |
| 528 | 528 | ||
| 529 | if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) { | 529 | if (beacon) { |
| 530 | q_idx = wmm_idx * MT7615_MAX_WMM_SETS + | ||
| 531 | skb_get_queue_mapping(skb); | ||
| 532 | p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; | ||
| 533 | } else if (beacon) { | ||
| 534 | if (ext_phy) | ||
| 535 | q_idx = MT_LMAC_BCN1; | ||
| 536 | else | ||
| 537 | q_idx = MT_LMAC_BCN0; | ||
| 538 | p_fmt = MT_TX_TYPE_FW; | 530 | p_fmt = MT_TX_TYPE_FW; |
| 531 | q_idx = ext_phy ? MT_LMAC_BCN1 : MT_LMAC_BCN0; | ||
| 532 | } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { | ||
| 533 | p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; | ||
| 534 | q_idx = ext_phy ? MT_LMAC_ALTX1 : MT_LMAC_ALTX0; | ||
| 539 | } else { | 535 | } else { |
| 540 | if (ext_phy) | ||
| 541 | q_idx = MT_LMAC_ALTX1; | ||
| 542 | else | ||
| 543 | q_idx = MT_LMAC_ALTX0; | ||
| 544 | p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; | 536 | p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; |
| 537 | q_idx = wmm_idx * MT7615_MAX_WMM_SETS + | ||
| 538 | mt7615_lmac_mapping(dev, skb_get_queue_mapping(skb)); | ||
| 545 | } | 539 | } |
| 546 | 540 | ||
| 547 | val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | | 541 | val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | |
| @@ -124,21 +124,6 @@ enum tx_pkt_type { · 123 unmodified lines | |||
| 124 | MT_TX_TYPE_FW, | 124 | MT_TX_TYPE_FW, |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | enum tx_pkt_queue_idx { | ||
| 128 | MT_LMAC_AC00, | ||
| 129 | MT_LMAC_AC01, | ||
| 130 | MT_LMAC_AC02, | ||
| 131 | MT_LMAC_AC03, | ||
| 132 | MT_LMAC_ALTX0 = 0x10, | ||
| 133 | MT_LMAC_BMC0, | ||
| 134 | MT_LMAC_BCN0, | ||
| 135 | MT_LMAC_PSMP0, | ||
| 136 | MT_LMAC_ALTX1, | ||
| 137 | MT_LMAC_BMC1, | ||
| 138 | MT_LMAC_BCN1, | ||
| 139 | MT_LMAC_PSMP1, | ||
| 140 | }; | ||
| 141 | |||
| 142 | enum tx_port_idx { | 127 | enum tx_port_idx { |
| 143 | MT_TX_PORT_IDX_LMAC, | 128 | MT_TX_PORT_IDX_LMAC, |
| 144 | MT_TX_PORT_IDX_MCU | 129 | MT_TX_PORT_IDX_MCU |
| @@ -397,6 +397,7 @@ mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, · 396 unmodified lines | |||
| 397 | struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; | 397 | struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; |
| 398 | struct mt7615_dev *dev = mt7615_hw_dev(hw); | 398 | struct mt7615_dev *dev = mt7615_hw_dev(hw); |
| 399 | 399 | ||
| 400 | queue = mt7615_lmac_mapping(dev, queue); | ||
| 400 | queue += mvif->wmm_idx * MT7615_MAX_WMM_SETS; | 401 | queue += mvif->wmm_idx * MT7615_MAX_WMM_SETS; |
| 401 | 402 | ||
| 402 | return mt7615_mcu_set_wmm(dev, queue, params); | 403 | return mt7615_mcu_set_wmm(dev, queue, params); |
| @@ -735,9 +736,12 @@ static void · 332 unmodified lines | |||
| 735 | mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) | 736 | mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) |
| 736 | { | 737 | { |
| 737 | struct mt7615_phy *phy = mt7615_hw_phy(hw); | 738 | struct mt7615_phy *phy = mt7615_hw_phy(hw); |
| 739 | struct mt7615_dev *dev = phy->dev; | ||
| 738 | 740 | ||
| 741 | mutex_lock(&dev->mt76.mutex); | ||
| 739 | phy->coverage_class = max_t(s16, coverage_class, 0); | 742 | phy->coverage_class = max_t(s16, coverage_class, 0); |
| 740 | mt7615_mac_set_timing(phy); | 743 | mt7615_mac_set_timing(phy); |
| 744 | mutex_unlock(&dev->mt76.mutex); | ||
| 741 | } | 745 | } |
| 742 | 746 | ||
| 743 | static int | 747 | static int |
| @@ -146,7 +146,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base, · 145 unmodified lines | |||
| 146 | static const struct mt76_driver_ops drv_ops = { | 146 | static const struct mt76_driver_ops drv_ops = { |
| 147 | /* txwi_size = txd size + txp size */ | 147 | /* txwi_size = txd size + txp size */ |
| 148 | .txwi_size = MT_TXD_SIZE + sizeof(struct mt7615_txp_common), | 148 | .txwi_size = MT_TXD_SIZE + sizeof(struct mt7615_txp_common), |
| 149 | .drv_flags = MT_DRV_TXWI_NO_FREE, | 149 | .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ, |
| 150 | .survey_flags = SURVEY_INFO_TIME_TX | | 150 | .survey_flags = SURVEY_INFO_TIME_TX | |
| 151 | SURVEY_INFO_TIME_RX | | 151 | SURVEY_INFO_TIME_RX | |
| 152 | SURVEY_INFO_TIME_BSS_RX, | 152 | SURVEY_INFO_TIME_BSS_RX, |
| @@ -282,6 +282,21 @@ struct mt7615_dev { · 281 unmodified lines | |||
| 282 | struct list_head wd_head; | 282 | struct list_head wd_head; |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | enum tx_pkt_queue_idx { | ||
| 286 | MT_LMAC_AC00, | ||
| 287 | MT_LMAC_AC01, | ||
| 288 | MT_LMAC_AC02, | ||
| 289 | MT_LMAC_AC03, | ||
| 290 | MT_LMAC_ALTX0 = 0x10, | ||
| 291 | MT_LMAC_BMC0, | ||
| 292 | MT_LMAC_BCN0, | ||
| 293 | MT_LMAC_PSMP0, | ||
| 294 | MT_LMAC_ALTX1, | ||
| 295 | MT_LMAC_BMC1, | ||
| 296 | MT_LMAC_BCN1, | ||
| 297 | MT_LMAC_PSMP1, | ||
| 298 | }; | ||
| 299 | |||
| 285 | enum { | 300 | enum { |
| 286 | HW_BSSID_0 = 0x0, | 301 | HW_BSSID_0 = 0x0, |
| 287 | HW_BSSID_1, | 302 | HW_BSSID_1, |
| @@ -447,6 +462,21 @@ static inline u16 mt7615_wtbl_size(struct mt7615_dev *dev) · 159 unmodified lines | |||
| 447 | return MT7615_WTBL_SIZE; | 462 | return MT7615_WTBL_SIZE; |
| 448 | } | 463 | } |
| 449 | 464 | ||
| 465 | static inline u8 mt7615_lmac_mapping(struct mt7615_dev *dev, u8 ac) | ||
| 466 | { | ||
| 467 | static const u8 lmac_queue_map[] = { | ||
| 468 | [IEEE80211_AC_BK] = MT_LMAC_AC00, | ||
| 469 | [IEEE80211_AC_BE] = MT_LMAC_AC01, | ||
| 470 | [IEEE80211_AC_VI] = MT_LMAC_AC02, | ||
| 471 | [IEEE80211_AC_VO] = MT_LMAC_AC03, | ||
| 472 | }; | ||
| 473 | |||
| 474 | if (WARN_ON_ONCE(ac >= ARRAY_SIZE(lmac_queue_map))) | ||
| 475 | return MT_LMAC_AC01; /* BE */ | ||
| 476 | |||
| 477 | return lmac_queue_map[ac]; | ||
| 478 | } | ||
| 479 | |||
| 450 | void mt7615_dma_reset(struct mt7615_dev *dev); | 480 | void mt7615_dma_reset(struct mt7615_dev *dev); |
| 451 | void mt7615_scan_work(struct work_struct *work); | 481 | void mt7615_scan_work(struct work_struct *work); |
| 452 | void mt7615_roc_work(struct work_struct *work); | 482 | void mt7615_roc_work(struct work_struct *work); |
| @@ -270,7 +270,7 @@ static int mt7663u_probe(struct usb_interface *usb_intf, · 269 unmodified lines | |||
| 270 | { | 270 | { |
| 271 | static const struct mt76_driver_ops drv_ops = { | 271 | static const struct mt76_driver_ops drv_ops = { |
| 272 | .txwi_size = MT_USB_TXD_SIZE, | 272 | .txwi_size = MT_USB_TXD_SIZE, |
| 273 | .drv_flags = MT_DRV_RX_DMA_HDR, | 273 | .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ, |
| 274 | .tx_prepare_skb = mt7663u_tx_prepare_skb, | 274 | .tx_prepare_skb = mt7663u_tx_prepare_skb, |
| 275 | .tx_complete_skb = mt7663u_tx_complete_skb, | 275 | .tx_complete_skb = mt7663u_tx_complete_skb, |
| 276 | .tx_status_data = mt7663u_tx_status_data, | 276 | .tx_status_data = mt7663u_tx_status_data, |
| @@ -329,25 +329,26 @@ static int mt7663u_probe(struct usb_interface *usb_intf, · 52 unmodified lines | |||
| 329 | if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON, | 329 | if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_PWR_ON, |
| 330 | FW_STATE_PWR_ON << 1, 500)) { | 330 | FW_STATE_PWR_ON << 1, 500)) { |
| 331 | dev_err(dev->mt76.dev, "Timeout for power on\n"); | 331 | dev_err(dev->mt76.dev, "Timeout for power on\n"); |
| 332 | return -EIO; | 332 | ret = -EIO; |
| 333 | goto error; | ||
| 333 | } | 334 | } |
| 334 | 335 | ||
| 335 | alloc_queues: | 336 | alloc_queues: |
| 336 | ret = mt76u_alloc_mcu_queue(&dev->mt76); | 337 | ret = mt76u_alloc_mcu_queue(&dev->mt76); |
| 337 | if (ret) | 338 | if (ret) |
| 338 | goto error; | 339 | goto error_free_q; |
| 339 | 340 | ||
| 340 | ret = mt76u_alloc_queues(&dev->mt76); | 341 | ret = mt76u_alloc_queues(&dev->mt76); |
| 341 | if (ret) | 342 | if (ret) |
| 342 | goto error; | 343 | goto error_free_q; |
| 343 | 344 | ||
| 344 | ret = mt7663u_register_device(dev); | 345 | ret = mt7663u_register_device(dev); |
| 345 | if (ret) | 346 | if (ret) |
| 346 | goto error_freeq; | 347 | goto error_free_q; |
| 347 | 348 | ||
| 348 | return 0; | 349 | return 0; |
| 349 | 350 | ||
| 350 | error_freeq: | 351 | error_free_q: |
| 351 | mt76u_queues_deinit(&dev->mt76); | 352 | mt76u_queues_deinit(&dev->mt76); |
| 352 | error: | 353 | error: |
| 353 | mt76u_deinit(&dev->mt76); | 354 | mt76u_deinit(&dev->mt76); |
| @@ -456,8 +456,9 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev) · 455 unmodified lines | |||
| 456 | tasklet_disable(&dev->mt76.tx_tasklet); | 456 | tasklet_disable(&dev->mt76.tx_tasklet); |
| 457 | napi_disable(&dev->mt76.tx_napi); | 457 | napi_disable(&dev->mt76.tx_napi); |
| 458 | 458 | ||
| 459 | for (i = 0; i < ARRAY_SIZE(dev->mt76.napi); i++) | 459 | mt76_for_each_q_rx(&dev->mt76, i) { |
| 460 | napi_disable(&dev->mt76.napi[i]); | 460 | napi_disable(&dev->mt76.napi[i]); |
| 461 | } | ||
| 461 | 462 | ||
| 462 | mutex_lock(&dev->mt76.mutex); | 463 | mutex_lock(&dev->mt76.mutex); |
| 463 | 464 | ||
| @@ -515,7 +516,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev) · 51 unmodified lines | |||
| 515 | 516 | ||
| 516 | tasklet_enable(&dev->mt76.pre_tbtt_tasklet); | 517 | tasklet_enable(&dev->mt76.pre_tbtt_tasklet); |
| 517 | 518 | ||
| 518 | for (i = 0; i < ARRAY_SIZE(dev->mt76.napi); i++) { | 519 | mt76_for_each_q_rx(&dev->mt76, i) { |
| 519 | napi_enable(&dev->mt76.napi[i]); | 520 | napi_enable(&dev->mt76.napi[i]); |
| 520 | napi_schedule(&dev->mt76.napi[i]); | 521 | napi_schedule(&dev->mt76.napi[i]); |
| 521 | } | 522 | } |
| @@ -716,9 +716,12 @@ static void · 715 unmodified lines | |||
| 716 | mt7915_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) | 716 | mt7915_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) |
| 717 | { | 717 | { |
| 718 | struct mt7915_phy *phy = mt7915_hw_phy(hw); | 718 | struct mt7915_phy *phy = mt7915_hw_phy(hw); |
| 719 | struct mt7915_dev *dev = phy->dev; | ||
| 719 | 720 | ||
| 721 | mutex_lock(&dev->mt76.mutex); | ||
| 720 | phy->coverage_class = max_t(s16, coverage_class, 0); | 722 | phy->coverage_class = max_t(s16, coverage_class, 0); |
| 721 | mt7915_mac_set_timing(phy); | 723 | mt7915_mac_set_timing(phy); |
| 724 | mutex_unlock(&dev->mt76.mutex); | ||
| 722 | } | 725 | } |
| 723 | 726 | ||
| 724 | static int | 727 | static int |
| @@ -264,6 +264,13 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, · 263 unmodified lines | |||
| 264 | skb_set_queue_mapping(skb, qid); | 264 | skb_set_queue_mapping(skb, qid); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | if ((dev->drv->drv_flags & MT_DRV_HW_MGMT_TXQ) && | ||
| 268 | !ieee80211_is_data(hdr->frame_control) && | ||
| 269 | !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) { | ||
| 270 | qid = MT_TXQ_PSD; | ||
| 271 | skb_set_queue_mapping(skb, qid); | ||
| 272 | } | ||
| 273 | |||
| 267 | if (!(wcid->tx_info & MT_WCID_TX_INFO_SET)) | 274 | if (!(wcid->tx_info & MT_WCID_TX_INFO_SET)) |
| 268 | ieee80211_get_tx_rates(info->control.vif, sta, skb, | 275 | ieee80211_get_tx_rates(info->control.vif, sta, skb, |
| 269 | info->control.rates, 1); | 276 | info->control.rates, 1); |
| @@ -1010,17 +1010,18 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q) · 1009 unmodified lines | |||
| 1010 | static u8 mt76u_ac_to_hwq(struct mt76_dev *dev, u8 ac) | 1010 | static u8 mt76u_ac_to_hwq(struct mt76_dev *dev, u8 ac) |
| 1011 | { | 1011 | { |
| 1012 | if (mt76_chip(dev) == 0x7663) { | 1012 | if (mt76_chip(dev) == 0x7663) { |
| 1013 | static const u8 wmm_queue_map[] = { | 1013 | static const u8 lmac_queue_map[] = { |
| 1014 | [IEEE80211_AC_VO] = 0, | 1014 | /* ac to lmac mapping */ |
| 1015 | [IEEE80211_AC_VI] = 1, | 1015 | [IEEE80211_AC_BK] = 0, |
| 1016 | [IEEE80211_AC_BE] = 2, | 1016 | [IEEE80211_AC_BE] = 1, |
| 1017 | [IEEE80211_AC_BK] = 4, | 1017 | [IEEE80211_AC_VI] = 2, |
| 1018 | [IEEE80211_AC_VO] = 4, | ||
| 1018 | }; | 1019 | }; |
| 1019 | 1020 | ||
| 1020 | if (WARN_ON(ac >= ARRAY_SIZE(wmm_queue_map))) | 1021 | if (WARN_ON(ac >= ARRAY_SIZE(lmac_queue_map))) |
| 1021 | return 2; /* BE */ | 1022 | return 1; /* BE */ |
| 1022 | 1023 | ||
| 1023 | return wmm_queue_map[ac]; | 1024 | return lmac_queue_map[ac]; |
| 1024 | } | 1025 | } |
| 1025 | 1026 | ||
| 1026 | return mt76_ac_to_hwq(ac); | 1027 | return mt76_ac_to_hwq(ac); |
| @@ -1066,11 +1067,16 @@ static int mt76u_alloc_tx(struct mt76_dev *dev) · 39 unmodified lines | |||
| 1066 | 1067 | ||
| 1067 | static void mt76u_free_tx(struct mt76_dev *dev) | 1068 | static void mt76u_free_tx(struct mt76_dev *dev) |
| 1068 | { | 1069 | { |
| 1069 | struct mt76_queue *q; | 1070 | int i; |
| 1070 | int i, j; | ||
| 1071 | 1071 | ||
| 1072 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 1072 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 1073 | struct mt76_queue *q; | ||
| 1074 | int j; | ||
| 1075 | |||
| 1073 | q = dev->q_tx[i].q; | 1076 | q = dev->q_tx[i].q; |
| 1077 | if (!q) | ||
| 1078 | continue; | ||
| 1079 | |||
| 1074 | for (j = 0; j < q->ndesc; j++) | 1080 | for (j = 0; j < q->ndesc; j++) |
| 1075 | usb_free_urb(q->entry[j].urb); | 1081 | usb_free_urb(q->entry[j].urb); |
| 1076 | } | 1082 | } |
| @@ -1078,17 +1084,22 @@ static void mt76u_free_tx(struct mt76_dev *dev) · 1 unmodified line | |||
| 1078 | 1084 | ||
| 1079 | void mt76u_stop_tx(struct mt76_dev *dev) | 1085 | void mt76u_stop_tx(struct mt76_dev *dev) |
| 1080 | { | 1086 | { |
| 1081 | struct mt76_queue_entry entry; | 1087 | int ret; |
| 1082 | struct mt76_queue *q; | ||
| 1083 | int i, j, ret; | ||
| 1084 | 1088 | ||
| 1085 | ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(&dev->phy), | 1089 | ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(&dev->phy), |
| 1086 | HZ / 5); | 1090 | HZ / 5); |
| 1087 | if (!ret) { | 1091 | if (!ret) { |
| 1092 | struct mt76_queue_entry entry; | ||
| 1093 | struct mt76_queue *q; | ||
| 1094 | int i, j; | ||
| 1095 | |||
| 1088 | dev_err(dev->dev, "timed out waiting for pending tx\n"); | 1096 | dev_err(dev->dev, "timed out waiting for pending tx\n"); |
| 1089 | 1097 | ||
| 1090 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 1098 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 1091 | q = dev->q_tx[i].q; | 1099 | q = dev->q_tx[i].q; |
| 1100 | if (!q) | ||
| 1101 | continue; | ||
| 1102 | |||
| 1092 | for (j = 0; j < q->ndesc; j++) | 1103 | for (j = 0; j < q->ndesc; j++) |
| 1093 | usb_kill_urb(q->entry[j].urb); | 1104 | usb_kill_urb(q->entry[j].urb); |
| 1094 | } | 1105 | } |
| @@ -1100,6 +1111,8 @@ void mt76u_stop_tx(struct mt76_dev *dev) · 5 unmodified lines | |||
| 1100 | */ | 1111 | */ |
| 1101 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 1112 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 1102 | q = dev->q_tx[i].q; | 1113 | q = dev->q_tx[i].q; |
| 1114 | if (!q) | ||
| 1115 | continue; | ||
| 1103 | 1116 | ||
| 1104 | /* Assure we are in sync with killed tasklet. */ | 1117 | /* Assure we are in sync with killed tasklet. */ |
| 1105 | spin_lock_bh(&q->lock); | 1118 | spin_lock_bh(&q->lock); |
| @@ -63,6 +63,8 @@ module_param_named(max_queues, xennet_max_queues, uint, 0644); · 62 unmodified lines | |||
| 63 | MODULE_PARM_DESC(max_queues, | 63 | MODULE_PARM_DESC(max_queues, |
| 64 | "Maximum number of queues per virtual interface"); | 64 | "Maximum number of queues per virtual interface"); |
| 65 | 65 | ||
| 66 | #define XENNET_TIMEOUT (5 * HZ) | ||
| 67 | |||
| 66 | static const struct ethtool_ops xennet_ethtool_ops; | 68 | static const struct ethtool_ops xennet_ethtool_ops; |
| 67 | 69 | ||
| 68 | struct netfront_cb { | 70 | struct netfront_cb { |
| @@ -1334,12 +1336,15 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) · 1265 unmodified lines | |||
| 1334 | 1336 | ||
| 1335 | netif_carrier_off(netdev); | 1337 | netif_carrier_off(netdev); |
| 1336 | 1338 | ||
| 1337 | xenbus_switch_state(dev, XenbusStateInitialising); | 1339 | do { |
| 1338 | wait_event(module_wq, | 1340 | xenbus_switch_state(dev, XenbusStateInitialising); |
| 1339 | xenbus_read_driver_state(dev->otherend) != | 1341 | err = wait_event_timeout(module_wq, |
| 1340 | XenbusStateClosed && | 1342 | xenbus_read_driver_state(dev->otherend) != |
| 1341 | xenbus_read_driver_state(dev->otherend) != | 1343 | XenbusStateClosed && |
| 1342 | XenbusStateUnknown); | 1344 | xenbus_read_driver_state(dev->otherend) != |
| 1345 | XenbusStateUnknown, XENNET_TIMEOUT); | ||
| 1346 | } while (!err); | ||
| 1347 | |||
| 1343 | return netdev; | 1348 | return netdev; |
| 1344 | 1349 | ||
| 1345 | exit: | 1350 | exit: |
| @@ -2139,28 +2144,43 @@ static const struct attribute_group xennet_dev_group = { · 793 unmodified lines | |||
| 2139 | }; | 2144 | }; |
| 2140 | #endif /* CONFIG_SYSFS */ | 2145 | #endif /* CONFIG_SYSFS */ |
| 2141 | 2146 | ||
| 2142 | static int xennet_remove(struct xenbus_device *dev) | 2147 | static void xennet_bus_close(struct xenbus_device *dev) |
| 2143 | { | 2148 | { |
| 2144 | struct netfront_info *info = dev_get_drvdata(&dev->dev); | 2149 | int ret; |
| 2145 | |||
| 2146 | dev_dbg(&dev->dev, "%s\n", dev->nodename); | ||
| 2147 | 2150 | ||
| 2148 | if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { | 2151 | if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) |
| 2152 | return; | ||
| 2153 | do { | ||
| 2149 | xenbus_switch_state(dev, XenbusStateClosing); | 2154 | xenbus_switch_state(dev, XenbusStateClosing); |
| 2150 | wait_event(module_wq, | 2155 | ret = wait_event_timeout(module_wq, |
| 2151 | xenbus_read_driver_state(dev->otherend) == | 2156 | xenbus_read_driver_state(dev->otherend) == |
| 2152 | XenbusStateClosing || | 2157 | XenbusStateClosing || |
| 2153 | xenbus_read_driver_state(dev->otherend) == | 2158 | xenbus_read_driver_state(dev->otherend) == |
| 2154 | XenbusStateUnknown); | 2159 | XenbusStateClosed || |
| 2160 | xenbus_read_driver_state(dev->otherend) == | ||
| 2161 | XenbusStateUnknown, | ||
| 2162 | XENNET_TIMEOUT); | ||
| 2163 | } while (!ret); | ||
| 2164 | |||
| 2165 | if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) | ||
| 2166 | return; | ||
| 2155 | 2167 | ||
| 2168 | do { | ||
| 2156 | xenbus_switch_state(dev, XenbusStateClosed); | 2169 | xenbus_switch_state(dev, XenbusStateClosed); |
| 2157 | wait_event(module_wq, | 2170 | ret = wait_event_timeout(module_wq, |
| 2158 | xenbus_read_driver_state(dev->otherend) == | 2171 | xenbus_read_driver_state(dev->otherend) == |
| 2159 | XenbusStateClosed || | 2172 | XenbusStateClosed || |
| 2160 | xenbus_read_driver_state(dev->otherend) == | 2173 | xenbus_read_driver_state(dev->otherend) == |
| 2161 | XenbusStateUnknown); | 2174 | XenbusStateUnknown, |
| 2162 | } | 2175 | XENNET_TIMEOUT); |
| 2176 | } while (!ret); | ||
| 2177 | } | ||
| 2178 | |||
| 2179 | static int xennet_remove(struct xenbus_device *dev) | ||
| 2180 | { | ||
| 2181 | struct netfront_info *info = dev_get_drvdata(&dev->dev); | ||
| 2163 | 2182 | ||
| 2183 | xennet_bus_close(dev); | ||
| 2164 | xennet_disconnect_backend(info); | 2184 | xennet_disconnect_backend(info); |
| 2165 | 2185 | ||
| 2166 | if (info->netdev->reg_state == NETREG_REGISTERED) | 2186 | if (info->netdev->reg_state == NETREG_REGISTERED) |
| @@ -198,6 +198,7 @@ int s3fwrn5_recv_frame(struct nci_dev *ndev, struct sk_buff *skb, · 197 unmodified lines | |||
| 198 | case S3FWRN5_MODE_FW: | 198 | case S3FWRN5_MODE_FW: |
| 199 | return s3fwrn5_fw_recv_frame(ndev, skb); | 199 | return s3fwrn5_fw_recv_frame(ndev, skb); |
| 200 | default: | 200 | default: |
| 201 | kfree_skb(skb); | ||
| 201 | return -ENODEV; | 202 | return -ENODEV; |
| 202 | } | 203 | } |
| 203 | } | 204 | } |
| @@ -4638,8 +4638,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) · 4637 unmodified lines | |||
| 4638 | * pcie_wait_for_link_delay - Wait until link is active or inactive | 4638 | * pcie_wait_for_link_delay - Wait until link is active or inactive |
| 4639 | * @pdev: Bridge device | 4639 | * @pdev: Bridge device |
| 4640 | * @active: waiting for active or inactive? | 4640 | * @active: waiting for active or inactive? |
| 4641 | * @delay: Delay to wait after link has become active (in ms). Specify %0 | 4641 | * @delay: Delay to wait after link has become active (in ms) |
| 4642 | * for no delay. | ||
| 4643 | * | 4642 | * |
| 4644 | * Use this to wait till link becomes active or inactive. | 4643 | * Use this to wait till link becomes active or inactive. |
| 4645 | */ | 4644 | */ |
| @@ -4680,7 +4679,7 @@ static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, · 34 unmodified lines | |||
| 4680 | msleep(10); | 4679 | msleep(10); |
| 4681 | timeout -= 10; | 4680 | timeout -= 10; |
| 4682 | } | 4681 | } |
| 4683 | if (active && ret && delay) | 4682 | if (active && ret) |
| 4684 | msleep(delay); | 4683 | msleep(delay); |
| 4685 | else if (ret != active) | 4684 | else if (ret != active) |
| 4686 | pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", | 4685 | pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", |
| @@ -4801,28 +4800,17 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev) · 114 unmodified lines | |||
| 4801 | if (!pcie_downstream_port(dev)) | 4800 | if (!pcie_downstream_port(dev)) |
| 4802 | return; | 4801 | return; |
| 4803 | 4802 | ||
| 4804 | /* | 4803 | if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) { |
| 4805 | * Per PCIe r5.0, sec 6.6.1, for downstream ports that support | 4804 | pci_dbg(dev, "waiting %d ms for downstream link\n", delay); |
| 4806 | * speeds > 5 GT/s, we must wait for link training to complete | 4805 | msleep(delay); |
| 4807 | * before the mandatory delay. | 4806 | } else { |
| 4808 | * | 4807 | pci_dbg(dev, "waiting %d ms for downstream link, after activation\n", |
| 4809 | * We can only tell when link training completes via DLL Link | 4808 | delay); |
| 4810 | * Active, which is required for downstream ports that support | 4809 | if (!pcie_wait_for_link_delay(dev, true, delay)) { |
| 4811 | * speeds > 5 GT/s (sec 7.5.3.6). Unfortunately some common | ||
| 4812 | * devices do not implement Link Active reporting even when it's | ||
| 4813 | * required, so we'll check for that directly instead of checking | ||
| 4814 | * the supported link speed. We assume devices without Link Active | ||
| 4815 | * reporting can train in 100 ms regardless of speed. | ||
| 4816 | */ | ||
| 4817 | if (dev->link_active_reporting) { | ||
| 4818 | pci_dbg(dev, "waiting for link to train\n"); | ||
| 4819 | if (!pcie_wait_for_link_delay(dev, true, 0)) { | ||
| 4820 | /* Did not train, no need to wait any further */ | 4810 | /* Did not train, no need to wait any further */ |
| 4821 | return; | 4811 | return; |
| 4822 | } | 4812 | } |
| 4823 | } | 4813 | } |
| 4824 | pci_dbg(child, "waiting %d ms to become accessible\n", delay); | ||
| 4825 | msleep(delay); | ||
| 4826 | 4814 | ||
| 4827 | if (!pci_device_is_present(child)) { | 4815 | if (!pci_device_is_present(child)) { |
| 4828 | pci_dbg(child, "waiting additional %d ms to become accessible\n", delay); | 4816 | pci_dbg(child, "waiting additional %d ms to become accessible\n", delay); |
| @@ -547,6 +547,15 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd) · 546 unmodified lines | |||
| 547 | scsi_uninit_cmd(cmd); | 547 | scsi_uninit_cmd(cmd); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | static void scsi_run_queue_async(struct scsi_device *sdev) | ||
| 551 | { | ||
| 552 | if (scsi_target(sdev)->single_lun || | ||
| 553 | !list_empty(&sdev->host->starved_list)) | ||
| 554 | kblockd_schedule_work(&sdev->requeue_work); | ||
| 555 | else | ||
| 556 | blk_mq_run_hw_queues(sdev->request_queue, true); | ||
| 557 | } | ||
| 558 | |||
| 550 | /* Returns false when no more bytes to process, true if there are more */ | 559 | /* Returns false when no more bytes to process, true if there are more */ |
| 551 | static bool scsi_end_request(struct request *req, blk_status_t error, | 560 | static bool scsi_end_request(struct request *req, blk_status_t error, |
| 552 | unsigned int bytes) | 561 | unsigned int bytes) |
| @@ -591,11 +600,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error, · 38 unmodified lines | |||
| 591 | 600 | ||
| 592 | __blk_mq_end_request(req, error); | 601 | __blk_mq_end_request(req, error); |
| 593 | 602 | ||
| 594 | if (scsi_target(sdev)->single_lun || | 603 | scsi_run_queue_async(sdev); |
| 595 | !list_empty(&sdev->host->starved_list)) | ||
| 596 | kblockd_schedule_work(&sdev->requeue_work); | ||
| 597 | else | ||
| 598 | blk_mq_run_hw_queues(q, true); | ||
| 599 | 604 | ||
| 600 | percpu_ref_put(&q->q_usage_counter); | 605 | percpu_ref_put(&q->q_usage_counter); |
| 601 | return false; | 606 | return false; |
| @@ -1702,6 +1707,7 @@ out_put_budget: · 1100 unmodified lines | |||
| 1702 | */ | 1707 | */ |
| 1703 | if (req->rq_flags & RQF_DONTPREP) | 1708 | if (req->rq_flags & RQF_DONTPREP) |
| 1704 | scsi_mq_uninit_cmd(cmd); | 1709 | scsi_mq_uninit_cmd(cmd); |
| 1710 | scsi_run_queue_async(sdev); | ||
| 1705 | break; | 1711 | break; |
| 1706 | } | 1712 | } |
| 1707 | return ret; | 1713 | return ret; |
| @@ -106,14 +106,22 @@ static int apci1032_cos_insn_config(struct comedi_device *dev, · 105 unmodified lines | |||
| 106 | unsigned int *data) | 106 | unsigned int *data) |
| 107 | { | 107 | { |
| 108 | struct apci1032_private *devpriv = dev->private; | 108 | struct apci1032_private *devpriv = dev->private; |
| 109 | unsigned int shift, oldmask; | 109 | unsigned int shift, oldmask, himask, lomask; |
| 110 | 110 | ||
| 111 | switch (data[0]) { | 111 | switch (data[0]) { |
| 112 | case INSN_CONFIG_DIGITAL_TRIG: | 112 | case INSN_CONFIG_DIGITAL_TRIG: |
| 113 | if (data[1] != 0) | 113 | if (data[1] != 0) |
| 114 | return -EINVAL; | 114 | return -EINVAL; |
| 115 | shift = data[3]; | 115 | shift = data[3]; |
| 116 | oldmask = (1U << shift) - 1; | 116 | if (shift < 32) { |
| 117 | oldmask = (1U << shift) - 1; | ||
| 118 | himask = data[4] << shift; | ||
| 119 | lomask = data[5] << shift; | ||
| 120 | } else { | ||
| 121 | oldmask = 0xffffffffu; | ||
| 122 | himask = 0; | ||
| 123 | lomask = 0; | ||
| 124 | } | ||
| 117 | switch (data[2]) { | 125 | switch (data[2]) { |
| 118 | case COMEDI_DIGITAL_TRIG_DISABLE: | 126 | case COMEDI_DIGITAL_TRIG_DISABLE: |
| 119 | devpriv->ctrl = 0; | 127 | devpriv->ctrl = 0; |
| @@ -136,8 +144,8 @@ static int apci1032_cos_insn_config(struct comedi_device *dev, · 16 unmodified lines | |||
| 136 | devpriv->mode2 &= oldmask; | 144 | devpriv->mode2 &= oldmask; |
| 137 | } | 145 | } |
| 138 | /* configure specified channels */ | 146 | /* configure specified channels */ |
| 139 | devpriv->mode1 |= data[4] << shift; | 147 | devpriv->mode1 |= himask; |
| 140 | devpriv->mode2 |= data[5] << shift; | 148 | devpriv->mode2 |= lomask; |
| 141 | break; | 149 | break; |
| 142 | case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: | 150 | case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: |
| 143 | if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA | | 151 | if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA | |
| @@ -154,8 +162,8 @@ static int apci1032_cos_insn_config(struct comedi_device *dev, · 10 unmodified lines | |||
| 154 | devpriv->mode2 &= oldmask; | 162 | devpriv->mode2 &= oldmask; |
| 155 | } | 163 | } |
| 156 | /* configure specified channels */ | 164 | /* configure specified channels */ |
| 157 | devpriv->mode1 |= data[4] << shift; | 165 | devpriv->mode1 |= himask; |
| 158 | devpriv->mode2 |= data[5] << shift; | 166 | devpriv->mode2 |= lomask; |
| 159 | break; | 167 | break; |
| 160 | default: | 168 | default: |
| 161 | return -EINVAL; | 169 | return -EINVAL; |
| @@ -452,13 +452,14 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev, · 451 unmodified lines | |||
| 452 | struct apci1500_private *devpriv = dev->private; | 452 | struct apci1500_private *devpriv = dev->private; |
| 453 | unsigned int trig = data[1]; | 453 | unsigned int trig = data[1]; |
| 454 | unsigned int shift = data[3]; | 454 | unsigned int shift = data[3]; |
| 455 | unsigned int hi_mask = data[4] << shift; | 455 | unsigned int hi_mask; |
| 456 | unsigned int lo_mask = data[5] << shift; | 456 | unsigned int lo_mask; |
| 457 | unsigned int chan_mask = hi_mask | lo_mask; | 457 | unsigned int chan_mask; |
| 458 | unsigned int old_mask = (1 << shift) - 1; | 458 | unsigned int old_mask; |
| 459 | unsigned int pm; | 459 | unsigned int pm; |
| 460 | unsigned int pt; | 460 | unsigned int pt; |
| 461 | unsigned int pp; | 461 | unsigned int pp; |
| 462 | unsigned int invalid_chan; | ||
| 462 | 463 | ||
| 463 | if (trig > 1) { | 464 | if (trig > 1) { |
| 464 | dev_dbg(dev->class_dev, | 465 | dev_dbg(dev->class_dev, |
| @@ -466,7 +467,20 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev, · 1 unmodified line | |||
| 466 | return -EINVAL; | 467 | return -EINVAL; |
| 467 | } | 468 | } |
| 468 | 469 | ||
| 469 | if (chan_mask > 0xffff) { | 470 | if (shift <= 16) { |
| 471 | hi_mask = data[4] << shift; | ||
| 472 | lo_mask = data[5] << shift; | ||
| 473 | old_mask = (1U << shift) - 1; | ||
| 474 | invalid_chan = (data[4] | data[5]) >> (16 - shift); | ||
| 475 | } else { | ||
| 476 | hi_mask = 0; | ||
| 477 | lo_mask = 0; | ||
| 478 | old_mask = 0xffff; | ||
| 479 | invalid_chan = data[4] | data[5]; | ||
| 480 | } | ||
| 481 | chan_mask = hi_mask | lo_mask; | ||
| 482 | |||
| 483 | if (invalid_chan) { | ||
| 470 | dev_dbg(dev->class_dev, "invalid digital trigger channel\n"); | 484 | dev_dbg(dev->class_dev, "invalid digital trigger channel\n"); |
| 471 | return -EINVAL; | 485 | return -EINVAL; |
| 472 | } | 486 | } |
| @@ -331,14 +331,22 @@ static int apci1564_cos_insn_config(struct comedi_device *dev, · 330 unmodified lines | |||
| 331 | unsigned int *data) | 331 | unsigned int *data) |
| 332 | { | 332 | { |
| 333 | struct apci1564_private *devpriv = dev->private; | 333 | struct apci1564_private *devpriv = dev->private; |
| 334 | unsigned int shift, oldmask; | 334 | unsigned int shift, oldmask, himask, lomask; |
| 335 | 335 | ||
| 336 | switch (data[0]) { | 336 | switch (data[0]) { |
| 337 | case INSN_CONFIG_DIGITAL_TRIG: | 337 | case INSN_CONFIG_DIGITAL_TRIG: |
| 338 | if (data[1] != 0) | 338 | if (data[1] != 0) |
| 339 | return -EINVAL; | 339 | return -EINVAL; |
| 340 | shift = data[3]; | 340 | shift = data[3]; |
| 341 | oldmask = (1U << shift) - 1; | 341 | if (shift < 32) { |
| 342 | oldmask = (1U << shift) - 1; | ||
| 343 | himask = data[4] << shift; | ||
| 344 | lomask = data[5] << shift; | ||
| 345 | } else { | ||
| 346 | oldmask = 0xffffffffu; | ||
| 347 | himask = 0; | ||
| 348 | lomask = 0; | ||
| 349 | } | ||
| 342 | switch (data[2]) { | 350 | switch (data[2]) { |
| 343 | case COMEDI_DIGITAL_TRIG_DISABLE: | 351 | case COMEDI_DIGITAL_TRIG_DISABLE: |
| 344 | devpriv->ctrl = 0; | 352 | devpriv->ctrl = 0; |
| @@ -362,8 +370,8 @@ static int apci1564_cos_insn_config(struct comedi_device *dev, · 17 unmodified lines | |||
| 362 | devpriv->mode2 &= oldmask; | 370 | devpriv->mode2 &= oldmask; |
| 363 | } | 371 | } |
| 364 | /* configure specified channels */ | 372 | /* configure specified channels */ |
| 365 | devpriv->mode1 |= data[4] << shift; | 373 | devpriv->mode1 |= himask; |
| 366 | devpriv->mode2 |= data[5] << shift; | 374 | devpriv->mode2 |= lomask; |
| 367 | break; | 375 | break; |
| 368 | case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: | 376 | case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: |
| 369 | if (devpriv->ctrl != (APCI1564_DI_IRQ_ENA | | 377 | if (devpriv->ctrl != (APCI1564_DI_IRQ_ENA | |
| @@ -380,8 +388,8 @@ static int apci1564_cos_insn_config(struct comedi_device *dev, · 10 unmodified lines | |||
| 380 | devpriv->mode2 &= oldmask; | 388 | devpriv->mode2 &= oldmask; |
| 381 | } | 389 | } |
| 382 | /* configure specified channels */ | 390 | /* configure specified channels */ |
| 383 | devpriv->mode1 |= data[4] << shift; | 391 | devpriv->mode1 |= himask; |
| 384 | devpriv->mode2 |= data[5] << shift; | 392 | devpriv->mode2 |= lomask; |
| 385 | break; | 393 | break; |
| 386 | default: | 394 | default: |
| 387 | return -EINVAL; | 395 | return -EINVAL; |
| @@ -332,7 +332,7 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, · 331 unmodified lines | |||
| 332 | case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: | 332 | case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: |
| 333 | /* check shift amount */ | 333 | /* check shift amount */ |
| 334 | shift = data[3]; | 334 | shift = data[3]; |
| 335 | if (shift >= s->n_chan) { | 335 | if (shift >= 32) { |
| 336 | mask = 0; | 336 | mask = 0; |
| 337 | rising = 0; | 337 | rising = 0; |
| 338 | falling = 0; | 338 | falling = 0; |
| @@ -22,7 +22,7 @@ config VIDEO_ATOMISP · 21 unmodified lines | |||
| 22 | module will be called atomisp | 22 | module will be called atomisp |
| 23 | 23 | ||
| 24 | config VIDEO_ATOMISP_ISP2401 | 24 | config VIDEO_ATOMISP_ISP2401 |
| 25 | bool "VIDEO_ATOMISP_ISP2401" | 25 | bool "Use Intel Atom ISP on Cherrytail/Anniedale (ISP2401)" |
| 26 | depends on VIDEO_ATOMISP | 26 | depends on VIDEO_ATOMISP |
| 27 | help | 27 | help |
| 28 | Enable support for Atom ISP2401-based boards. | 28 | Enable support for Atom ISP2401-based boards. |
| @@ -156,6 +156,7 @@ atomisp-objs += \ · 155 unmodified lines | |||
| 156 | pci/hive_isp_css_common/host/timed_ctrl.o \ | 156 | pci/hive_isp_css_common/host/timed_ctrl.o \ |
| 157 | pci/hive_isp_css_common/host/vmem.o \ | 157 | pci/hive_isp_css_common/host/vmem.o \ |
| 158 | pci/hive_isp_css_shared/host/tag.o \ | 158 | pci/hive_isp_css_shared/host/tag.o \ |
| 159 | pci/system_local.o \ | ||
| 159 | 160 | ||
| 160 | obj-byt = \ | 161 | obj-byt = \ |
| 161 | pci/css_2400_system/hive/ia_css_isp_configs.o \ | 162 | pci/css_2400_system/hive/ia_css_isp_configs.o \ |
| @@ -182,7 +183,6 @@ INCLUDES += \ · 20 unmodified lines | |||
| 182 | -I$(atomisp)/include/hmm/ \ | 183 | -I$(atomisp)/include/hmm/ \ |
| 183 | -I$(atomisp)/include/mmu/ \ | 184 | -I$(atomisp)/include/mmu/ \ |
| 184 | -I$(atomisp)/pci/ \ | 185 | -I$(atomisp)/pci/ \ |
| 185 | -I$(atomisp)/pci/hrt/ \ | ||
| 186 | -I$(atomisp)/pci/base/circbuf/interface/ \ | 186 | -I$(atomisp)/pci/base/circbuf/interface/ \ |
| 187 | -I$(atomisp)/pci/base/refcount/interface/ \ | 187 | -I$(atomisp)/pci/base/refcount/interface/ \ |
| 188 | -I$(atomisp)/pci/camera/pipe/interface/ \ | 188 | -I$(atomisp)/pci/camera/pipe/interface/ \ |
| @@ -192,7 +192,6 @@ INCLUDES += \ · 3 unmodified lines | |||
| 192 | -I$(atomisp)/pci/hive_isp_css_include/ \ | 192 | -I$(atomisp)/pci/hive_isp_css_include/ \ |
| 193 | -I$(atomisp)/pci/hive_isp_css_include/device_access/ \ | 193 | -I$(atomisp)/pci/hive_isp_css_include/device_access/ \ |
| 194 | -I$(atomisp)/pci/hive_isp_css_include/host/ \ | 194 | -I$(atomisp)/pci/hive_isp_css_include/host/ \ |
| 195 | -I$(atomisp)/pci/hive_isp_css_include/memory_access/ \ | ||
| 196 | -I$(atomisp)/pci/hive_isp_css_shared/ \ | 195 | -I$(atomisp)/pci/hive_isp_css_shared/ \ |
| 197 | -I$(atomisp)/pci/hive_isp_css_shared/host/ \ | 196 | -I$(atomisp)/pci/hive_isp_css_shared/host/ \ |
| 198 | -I$(atomisp)/pci/isp/kernels/ \ | 197 | -I$(atomisp)/pci/isp/kernels/ \ |
| @@ -311,9 +310,7 @@ INCLUDES += \ · 112 unmodified lines | |||
| 311 | -I$(atomisp)/pci/runtime/tagger/interface/ | 310 | -I$(atomisp)/pci/runtime/tagger/interface/ |
| 312 | 311 | ||
| 313 | INCLUDES_byt += \ | 312 | INCLUDES_byt += \ |
| 314 | -I$(atomisp)/pci/css_2400_system/ \ | ||
| 315 | -I$(atomisp)/pci/css_2400_system/hive/ \ | 313 | -I$(atomisp)/pci/css_2400_system/hive/ \ |
| 316 | -I$(atomisp)/pci/css_2400_system/hrt/ \ | ||
| 317 | 314 | ||
| 318 | INCLUDES_cht += \ | 315 | INCLUDES_cht += \ |
| 319 | -I$(atomisp)/pci/css_2401_system/ \ | 316 | -I$(atomisp)/pci/css_2401_system/ \ |
| @@ -321,7 +318,6 @@ INCLUDES_cht += \ · 1 unmodified line | |||
| 321 | -I$(atomisp)/pci/css_2401_system/hive/ \ | 318 | -I$(atomisp)/pci/css_2401_system/hive/ \ |
| 322 | -I$(atomisp)/pci/css_2401_system/hrt/ \ | 319 | -I$(atomisp)/pci/css_2401_system/hrt/ \ |
| 323 | 320 | ||
| 324 | # -I$(atomisp)/pci/css_2401_system/hrt/ \ | ||
| 325 | # -I$(atomisp)/pci/css_2401_system/hive_isp_css_2401_system_generated/ \ | 321 | # -I$(atomisp)/pci/css_2401_system/hive_isp_css_2401_system_generated/ \ |
| 326 | 322 | ||
| 327 | DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__ | 323 | DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__ |
| @@ -495,11 +495,11 @@ static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value) · 494 unmodified lines | |||
| 495 | ret = ov2680_read_reg(client, 1, OV2680_MIRROR_REG, &val); | 495 | ret = ov2680_read_reg(client, 1, OV2680_MIRROR_REG, &val); |
| 496 | if (ret) | 496 | if (ret) |
| 497 | return ret; | 497 | return ret; |
| 498 | if (value) { | 498 | if (value) |
| 499 | val |= OV2680_FLIP_MIRROR_BIT_ENABLE; | 499 | val |= OV2680_FLIP_MIRROR_BIT_ENABLE; |
| 500 | } else { | 500 | else |
| 501 | val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE; | 501 | val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE; |
| 502 | } | 502 | |
| 503 | ret = ov2680_write_reg(client, 1, | 503 | ret = ov2680_write_reg(client, 1, |
| 504 | OV2680_MIRROR_REG, val); | 504 | OV2680_MIRROR_REG, val); |
| 505 | if (ret) | 505 | if (ret) |
| @@ -1899,7 +1899,7 @@ static int ov5693_probe(struct i2c_client *client) · 1898 unmodified lines | |||
| 1899 | { | 1899 | { |
| 1900 | struct ov5693_device *dev; | 1900 | struct ov5693_device *dev; |
| 1901 | int i2c; | 1901 | int i2c; |
| 1902 | int ret = 0; | 1902 | int ret; |
| 1903 | void *pdata; | 1903 | void *pdata; |
| 1904 | unsigned int i; | 1904 | unsigned int i; |
| 1905 | 1905 | ||
| @@ -1929,8 +1929,10 @@ static int ov5693_probe(struct i2c_client *client) · 23 unmodified lines | |||
| 1929 | pdata = gmin_camera_platform_data(&dev->sd, | 1929 | pdata = gmin_camera_platform_data(&dev->sd, |
| 1930 | ATOMISP_INPUT_FORMAT_RAW_10, | 1930 | ATOMISP_INPUT_FORMAT_RAW_10, |
| 1931 | atomisp_bayer_order_bggr); | 1931 | atomisp_bayer_order_bggr); |
| 1932 | if (!pdata) | 1932 | if (!pdata) { |
| 1933 | ret = -EINVAL; | ||
| 1933 | goto out_free; | 1934 | goto out_free; |
| 1935 | } | ||
| 1934 | 1936 | ||
| 1935 | ret = ov5693_s_config(&dev->sd, client->irq, pdata); | 1937 | ret = ov5693_s_config(&dev->sd, client->irq, pdata); |
| 1936 | if (ret) | 1938 | if (ret) |
| @@ -250,6 +250,7 @@ const struct atomisp_camera_caps *atomisp_get_default_camera_caps(void); · 249 unmodified lines | |||
| 250 | #define IS_MFLD __IS_SOC(INTEL_FAM6_ATOM_SALTWELL_MID) | 250 | #define IS_MFLD __IS_SOC(INTEL_FAM6_ATOM_SALTWELL_MID) |
| 251 | #define IS_BYT __IS_SOC(INTEL_FAM6_ATOM_SILVERMONT) | 251 | #define IS_BYT __IS_SOC(INTEL_FAM6_ATOM_SILVERMONT) |
| 252 | #define IS_CHT __IS_SOC(INTEL_FAM6_ATOM_AIRMONT) | 252 | #define IS_CHT __IS_SOC(INTEL_FAM6_ATOM_AIRMONT) |
| 253 | #define IS_MRFD __IS_SOC(INTEL_FAM6_ATOM_SILVERMONT_MID) | ||
| 253 | #define IS_MOFD __IS_SOC(INTEL_FAM6_ATOM_AIRMONT_MID) | 254 | #define IS_MOFD __IS_SOC(INTEL_FAM6_ATOM_AIRMONT_MID) |
| 254 | 255 | ||
| 255 | /* Both CHT and MOFD come with ISP2401 */ | 256 | /* Both CHT and MOFD come with ISP2401 */ |
| @@ -20,9 +20,6 @@ · 19 unmodified lines | |||
| 20 | #define ATOMISP_REGS_H | 20 | #define ATOMISP_REGS_H |
| 21 | 21 | ||
| 22 | /* common register definitions */ | 22 | /* common register definitions */ |
| 23 | #define PUNIT_PORT 0x04 | ||
| 24 | #define CCK_PORT 0x14 | ||
| 25 | |||
| 26 | #define PCICMDSTS 0x01 | 23 | #define PCICMDSTS 0x01 |
| 27 | #define INTR 0x0f | 24 | #define INTR 0x0f |
| 28 | #define MSI_CAPID 0x24 | 25 | #define MSI_CAPID 0x24 |
| @@ -355,11 +355,11 @@ int atomisp_acc_map(struct atomisp_sub_device *asd, struct atomisp_acc_map *map) · 354 unmodified lines | |||
| 355 | 355 | ||
| 356 | pgnr = DIV_ROUND_UP(map->length, PAGE_SIZE); | 356 | pgnr = DIV_ROUND_UP(map->length, PAGE_SIZE); |
| 357 | if (pgnr < ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) { | 357 | if (pgnr < ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) { |
| 358 | dev_err(atomisp_dev, | 358 | dev_err(asd->isp->dev, |
| 359 | "user space memory size is less than the expected size..\n"); | 359 | "user space memory size is less than the expected size..\n"); |
| 360 | return -ENOMEM; | 360 | return -ENOMEM; |
| 361 | } else if (pgnr > ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) { | 361 | } else if (pgnr > ((PAGE_ALIGN(map->length)) >> PAGE_SHIFT)) { |
| 362 | dev_err(atomisp_dev, | 362 | dev_err(asd->isp->dev, |
| 363 | "user space memory size is large than the expected size..\n"); | 363 | "user space memory size is large than the expected size..\n"); |
| 364 | return -ENOMEM; | 364 | return -ENOMEM; |
| 365 | } | 365 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
| 22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/io.h> | ||
| 24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 25 | #include <linux/kfifo.h> | 26 | #include <linux/kfifo.h> |
| 26 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
| @@ -109,7 +110,7 @@ struct atomisp_acc_pipe *atomisp_to_acc_pipe(struct video_device *dev) · 82 unmodified lines | |||
| 109 | 110 | ||
| 110 | static unsigned short atomisp_get_sensor_fps(struct atomisp_sub_device *asd) | 111 | static unsigned short atomisp_get_sensor_fps(struct atomisp_sub_device *asd) |
| 111 | { | 112 | { |
| 112 | struct v4l2_subdev_frame_interval fi; | 113 | struct v4l2_subdev_frame_interval fi = { 0 }; |
| 113 | struct atomisp_device *isp = asd->isp; | 114 | struct atomisp_device *isp = asd->isp; |
| 114 | 115 | ||
| 115 | unsigned short fps = 0; | 116 | unsigned short fps = 0; |
| @@ -206,6 +207,7 @@ int atomisp_freq_scaling(struct atomisp_device *isp, · 90 unmodified lines | |||
| 206 | enum atomisp_dfs_mode mode, | 207 | enum atomisp_dfs_mode mode, |
| 207 | bool force) | 208 | bool force) |
| 208 | { | 209 | { |
| 210 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 209 | /* FIXME! Only use subdev[0] status yet */ | 211 | /* FIXME! Only use subdev[0] status yet */ |
| 210 | struct atomisp_sub_device *asd = &isp->asd[0]; | 212 | struct atomisp_sub_device *asd = &isp->asd[0]; |
| 211 | const struct atomisp_dfs_config *dfs; | 213 | const struct atomisp_dfs_config *dfs; |
| @@ -219,7 +221,7 @@ int atomisp_freq_scaling(struct atomisp_device *isp, · 7 unmodified lines | |||
| 219 | return -EINVAL; | 221 | return -EINVAL; |
| 220 | } | 222 | } |
| 221 | 223 | ||
| 222 | if ((isp->pdev->device & ATOMISP_PCI_DEVICE_SOC_MASK) == | 224 | if ((pdev->device & ATOMISP_PCI_DEVICE_SOC_MASK) == |
| 223 | ATOMISP_PCI_DEVICE_SOC_CHT && ATOMISP_USE_YUVPP(asd)) | 225 | ATOMISP_PCI_DEVICE_SOC_CHT && ATOMISP_USE_YUVPP(asd)) |
| 224 | isp->dfs = &dfs_config_cht_soc; | 226 | isp->dfs = &dfs_config_cht_soc; |
| 225 | 227 | ||
| @@ -357,39 +359,41 @@ static void clear_isp_irq(enum hrt_isp_css_irq irq) · 131 unmodified lines | |||
| 357 | irq_clear_all(IRQ0_ID); | 359 | irq_clear_all(IRQ0_ID); |
| 358 | } | 360 | } |
| 359 | 361 | ||
| 360 | void atomisp_msi_irq_init(struct atomisp_device *isp, struct pci_dev *dev) | 362 | void atomisp_msi_irq_init(struct atomisp_device *isp) |
| 361 | { | 363 | { |
| 364 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 362 | u32 msg32; | 365 | u32 msg32; |
| 363 | u16 msg16; | 366 | u16 msg16; |
| 364 | 367 | ||
| 365 | pci_read_config_dword(dev, PCI_MSI_CAPID, &msg32); | 368 | pci_read_config_dword(pdev, PCI_MSI_CAPID, &msg32); |
| 366 | msg32 |= 1 << MSI_ENABLE_BIT; | 369 | msg32 |= 1 << MSI_ENABLE_BIT; |
| 367 | pci_write_config_dword(dev, PCI_MSI_CAPID, msg32); | 370 | pci_write_config_dword(pdev, PCI_MSI_CAPID, msg32); |
| 368 | 371 | ||
| 369 | msg32 = (1 << INTR_IER) | (1 << INTR_IIR); | 372 | msg32 = (1 << INTR_IER) | (1 << INTR_IIR); |
| 370 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, msg32); | 373 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg32); |
| 371 | 374 | ||
| 372 | pci_read_config_word(dev, PCI_COMMAND, &msg16); | 375 | pci_read_config_word(pdev, PCI_COMMAND, &msg16); |
| 373 | msg16 |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | | 376 | msg16 |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | |
| 374 | PCI_COMMAND_INTX_DISABLE); | 377 | PCI_COMMAND_INTX_DISABLE); |
| 375 | pci_write_config_word(dev, PCI_COMMAND, msg16); | 378 | pci_write_config_word(pdev, PCI_COMMAND, msg16); |
| 376 | } | 379 | } |
| 377 | 380 | ||
| 378 | void atomisp_msi_irq_uninit(struct atomisp_device *isp, struct pci_dev *dev) | 381 | void atomisp_msi_irq_uninit(struct atomisp_device *isp) |
| 379 | { | 382 | { |
| 383 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 380 | u32 msg32; | 384 | u32 msg32; |
| 381 | u16 msg16; | 385 | u16 msg16; |
| 382 | 386 | ||
| 383 | pci_read_config_dword(dev, PCI_MSI_CAPID, &msg32); | 387 | pci_read_config_dword(pdev, PCI_MSI_CAPID, &msg32); |
| 384 | msg32 &= ~(1 << MSI_ENABLE_BIT); | 388 | msg32 &= ~(1 << MSI_ENABLE_BIT); |
| 385 | pci_write_config_dword(dev, PCI_MSI_CAPID, msg32); | 389 | pci_write_config_dword(pdev, PCI_MSI_CAPID, msg32); |
| 386 | 390 | ||
| 387 | msg32 = 0x0; | 391 | msg32 = 0x0; |
| 388 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, msg32); | 392 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg32); |
| 389 | 393 | ||
| 390 | pci_read_config_word(dev, PCI_COMMAND, &msg16); | 394 | pci_read_config_word(pdev, PCI_COMMAND, &msg16); |
| 391 | msg16 &= ~(PCI_COMMAND_MASTER); | 395 | msg16 &= ~(PCI_COMMAND_MASTER); |
| 392 | pci_write_config_word(dev, PCI_COMMAND, msg16); | 396 | pci_write_config_word(pdev, PCI_COMMAND, msg16); |
| 393 | } | 397 | } |
| 394 | 398 | ||
| 395 | static void atomisp_sof_event(struct atomisp_sub_device *asd) | 399 | static void atomisp_sof_event(struct atomisp_sub_device *asd) |
| @@ -480,11 +484,12 @@ static void print_csi_rx_errors(enum mipi_port_id port, · 84 unmodified lines | |||
| 480 | /* Clear irq reg */ | 484 | /* Clear irq reg */ |
| 481 | static void clear_irq_reg(struct atomisp_device *isp) | 485 | static void clear_irq_reg(struct atomisp_device *isp) |
| 482 | { | 486 | { |
| 487 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 483 | u32 msg_ret; | 488 | u32 msg_ret; |
| 484 | 489 | ||
| 485 | pci_read_config_dword(isp->pdev, PCI_INTERRUPT_CTRL, &msg_ret); | 490 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &msg_ret); |
| 486 | msg_ret |= 1 << INTR_IIR; | 491 | msg_ret |= 1 << INTR_IIR; |
| 487 | pci_write_config_dword(isp->pdev, PCI_INTERRUPT_CTRL, msg_ret); | 492 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, msg_ret); |
| 488 | } | 493 | } |
| 489 | 494 | ||
| 490 | static struct atomisp_sub_device * | 495 | static struct atomisp_sub_device * |
| @@ -665,11 +670,10 @@ bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe) · 174 unmodified lines | |||
| 665 | void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr, | 670 | void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr, |
| 666 | unsigned int size) | 671 | unsigned int size) |
| 667 | { | 672 | { |
| 668 | u32 __iomem *io_virt_addr; | ||
| 669 | unsigned int data = 0; | 673 | unsigned int data = 0; |
| 670 | unsigned int size32 = DIV_ROUND_UP(size, sizeof(u32)); | 674 | unsigned int size32 = DIV_ROUND_UP(size, sizeof(u32)); |
| 671 | 675 | ||
| 672 | dev_dbg(isp->dev, "atomisp_io_base:%p\n", atomisp_io_base); | 676 | dev_dbg(isp->dev, "atomisp mmio base: %p\n", isp->base); |
| 673 | dev_dbg(isp->dev, "%s, addr:0x%x, size: %d, size32: %d\n", __func__, | 677 | dev_dbg(isp->dev, "%s, addr:0x%x, size: %d, size32: %d\n", __func__, |
| 674 | addr, size, size32); | 678 | addr, size, size32); |
| 675 | if (size32 * 4 + addr > 0x4000) { | 679 | if (size32 * 4 + addr > 0x4000) { |
| @@ -678,13 +682,12 @@ void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr, · 2 unmodified lines | |||
| 678 | return; | 682 | return; |
| 679 | } | 683 | } |
| 680 | addr += SP_DMEM_BASE; | 684 | addr += SP_DMEM_BASE; |
| 681 | io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 685 | addr &= 0x003FFFFF; |
| 682 | do { | 686 | do { |
| 683 | data = *io_virt_addr; | 687 | data = readl(isp->base + addr); |
| 684 | dev_dbg(isp->dev, "%s, \t [0x%x]:0x%x\n", __func__, addr, data); | 688 | dev_dbg(isp->dev, "%s, \t [0x%x]:0x%x\n", __func__, addr, data); |
| 685 | io_virt_addr += sizeof(u32); | 689 | addr += sizeof(u32); |
| 686 | size32 -= 1; | 690 | } while (--size32); |
| 687 | } while (size32 > 0); | ||
| 688 | } | 691 | } |
| 689 | 692 | ||
| 690 | static struct videobuf_buffer *atomisp_css_frame_to_vbuf( | 693 | static struct videobuf_buffer *atomisp_css_frame_to_vbuf( |
| @@ -1289,6 +1292,7 @@ void atomisp_delayed_init_work(struct work_struct *work) · 598 unmodified lines | |||
| 1289 | 1292 | ||
| 1290 | static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) | 1293 | static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) |
| 1291 | { | 1294 | { |
| 1295 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 1292 | enum ia_css_pipe_id css_pipe_id; | 1296 | enum ia_css_pipe_id css_pipe_id; |
| 1293 | bool stream_restart[MAX_STREAM_NUM] = {0}; | 1297 | bool stream_restart[MAX_STREAM_NUM] = {0}; |
| 1294 | bool depth_mode = false; | 1298 | bool depth_mode = false; |
| @@ -1372,8 +1376,8 @@ static void __atomisp_css_recover(struct atomisp_device *isp, bool isp_timeout) · 77 unmodified lines | |||
| 1372 | clear_isp_irq(hrt_isp_css_irq_sp); | 1376 | clear_isp_irq(hrt_isp_css_irq_sp); |
| 1373 | 1377 | ||
| 1374 | /* Set the SRSE to 3 before resetting */ | 1378 | /* Set the SRSE to 3 before resetting */ |
| 1375 | pci_write_config_dword(isp->pdev, PCI_I_CONTROL, isp->saved_regs.i_control | | 1379 | pci_write_config_dword(pdev, PCI_I_CONTROL, |
| 1376 | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); | 1380 | isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); |
| 1377 | 1381 | ||
| 1378 | /* reset ISP and restore its state */ | 1382 | /* reset ISP and restore its state */ |
| 1379 | isp->isp_timeout = true; | 1383 | isp->isp_timeout = true; |
| @@ -6158,6 +6162,7 @@ out: · 4778 unmodified lines | |||
| 6158 | /*Turn off ISP dphy */ | 6162 | /*Turn off ISP dphy */ |
| 6159 | int atomisp_ospm_dphy_down(struct atomisp_device *isp) | 6163 | int atomisp_ospm_dphy_down(struct atomisp_device *isp) |
| 6160 | { | 6164 | { |
| 6165 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 6161 | unsigned long flags; | 6166 | unsigned long flags; |
| 6162 | u32 reg; | 6167 | u32 reg; |
| 6163 | 6168 | ||
| @@ -6179,9 +6184,9 @@ done: · 15 unmodified lines | |||
| 6179 | * MRFLD HW design need all CSI ports are disabled before | 6184 | * MRFLD HW design need all CSI ports are disabled before |
| 6180 | * powering down the IUNIT. | 6185 | * powering down the IUNIT. |
| 6181 | */ | 6186 | */ |
| 6182 | pci_read_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, ®); | 6187 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, ®); |
| 6183 | reg |= MRFLD_ALL_CSI_PORTS_OFF_MASK; | 6188 | reg |= MRFLD_ALL_CSI_PORTS_OFF_MASK; |
| 6184 | pci_write_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, reg); | 6189 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, reg); |
| 6185 | return 0; | 6190 | return 0; |
| 6186 | } | 6191 | } |
| 6187 | 6192 | ||
| @@ -68,8 +68,8 @@ bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe); · 67 unmodified lines | |||
| 68 | /* | 68 | /* |
| 69 | * Interrupt functions | 69 | * Interrupt functions |
| 70 | */ | 70 | */ |
| 71 | void atomisp_msi_irq_init(struct atomisp_device *isp, struct pci_dev *dev); | 71 | void atomisp_msi_irq_init(struct atomisp_device *isp); |
| 72 | void atomisp_msi_irq_uninit(struct atomisp_device *isp, struct pci_dev *dev); | 72 | void atomisp_msi_irq_uninit(struct atomisp_device *isp); |
| 73 | void atomisp_wdt_work(struct work_struct *work); | 73 | void atomisp_wdt_work(struct work_struct *work); |
| 74 | void atomisp_wdt(struct timer_list *t); | 74 | void atomisp_wdt(struct timer_list *t); |
| 75 | void atomisp_setup_flash(struct atomisp_sub_device *asd); | 75 | void atomisp_setup_flash(struct atomisp_sub_device *asd); |
| @@ -29,8 +29,6 @@ struct atomisp_sub_device; · 28 unmodified lines | |||
| 29 | struct video_device; | 29 | struct video_device; |
| 30 | enum atomisp_input_stream_id; | 30 | enum atomisp_input_stream_id; |
| 31 | 31 | ||
| 32 | extern void __iomem *atomisp_io_base; | ||
| 33 | |||
| 34 | struct atomisp_metadata_buf { | 32 | struct atomisp_metadata_buf { |
| 35 | struct ia_css_metadata *metadata; | 33 | struct ia_css_metadata *metadata; |
| 36 | void *md_vptr; | 34 | void *md_vptr; |
| @@ -33,13 +33,12 @@ · 32 unmodified lines | |||
| 33 | #include "atomisp_ioctl.h" | 33 | #include "atomisp_ioctl.h" |
| 34 | #include "atomisp_acc.h" | 34 | #include "atomisp_acc.h" |
| 35 | 35 | ||
| 36 | #include <asm/intel-mid.h> | ||
| 37 | |||
| 38 | #include "ia_css_debug.h" | 36 | #include "ia_css_debug.h" |
| 39 | #include "ia_css_isp_param.h" | 37 | #include "ia_css_isp_param.h" |
| 40 | #include "sh_css_hrt.h" | 38 | #include "sh_css_hrt.h" |
| 41 | #include "ia_css_isys.h" | 39 | #include "ia_css_isys.h" |
| 42 | 40 | ||
| 41 | #include <linux/io.h> | ||
| 43 | #include <linux/pm_runtime.h> | 42 | #include <linux/pm_runtime.h> |
| 44 | 43 | ||
| 45 | /* Assume max number of ACC stages */ | 44 | /* Assume max number of ACC stages */ |
| @@ -69,92 +68,94 @@ struct bayer_ds_factor { · 23 unmodified lines | |||
| 69 | 68 | ||
| 70 | static void atomisp_css2_hw_store_8(hrt_address addr, uint8_t data) | 69 | static void atomisp_css2_hw_store_8(hrt_address addr, uint8_t data) |
| 71 | { | 70 | { |
| 72 | s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 71 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 73 | unsigned long flags; | 72 | unsigned long flags; |
| 74 | 73 | ||
| 75 | spin_lock_irqsave(&mmio_lock, flags); | 74 | spin_lock_irqsave(&mmio_lock, flags); |
| 76 | *io_virt_addr = data; | 75 | writeb(data, isp->base + (addr & 0x003FFFFF)); |
| 77 | spin_unlock_irqrestore(&mmio_lock, flags); | 76 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | static void atomisp_css2_hw_store_16(hrt_address addr, uint16_t data) | 79 | static void atomisp_css2_hw_store_16(hrt_address addr, uint16_t data) |
| 81 | { | 80 | { |
| 82 | s16 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 81 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 83 | unsigned long flags; | 82 | unsigned long flags; |
| 84 | 83 | ||
| 85 | spin_lock_irqsave(&mmio_lock, flags); | 84 | spin_lock_irqsave(&mmio_lock, flags); |
| 86 | *io_virt_addr = data; | 85 | writew(data, isp->base + (addr & 0x003FFFFF)); |
| 87 | spin_unlock_irqrestore(&mmio_lock, flags); | 86 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data) | 89 | void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data) |
| 91 | { | 90 | { |
| 92 | s32 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 91 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 93 | unsigned long flags; | 92 | unsigned long flags; |
| 94 | 93 | ||
| 95 | spin_lock_irqsave(&mmio_lock, flags); | 94 | spin_lock_irqsave(&mmio_lock, flags); |
| 96 | *io_virt_addr = data; | 95 | writel(data, isp->base + (addr & 0x003FFFFF)); |
| 97 | spin_unlock_irqrestore(&mmio_lock, flags); | 96 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 98 | } | 97 | } |
| 99 | 98 | ||
| 100 | static uint8_t atomisp_css2_hw_load_8(hrt_address addr) | 99 | static uint8_t atomisp_css2_hw_load_8(hrt_address addr) |
| 101 | { | 100 | { |
| 102 | s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 101 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 103 | unsigned long flags; | 102 | unsigned long flags; |
| 104 | u8 ret; | 103 | u8 ret; |
| 105 | 104 | ||
| 106 | spin_lock_irqsave(&mmio_lock, flags); | 105 | spin_lock_irqsave(&mmio_lock, flags); |
| 107 | ret = *io_virt_addr; | 106 | ret = readb(isp->base + (addr & 0x003FFFFF)); |
| 108 | spin_unlock_irqrestore(&mmio_lock, flags); | 107 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 109 | return ret; | 108 | return ret; |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | static uint16_t atomisp_css2_hw_load_16(hrt_address addr) | 111 | static uint16_t atomisp_css2_hw_load_16(hrt_address addr) |
| 113 | { | 112 | { |
| 114 | s16 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 113 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 115 | unsigned long flags; | 114 | unsigned long flags; |
| 116 | u16 ret; | 115 | u16 ret; |
| 117 | 116 | ||
| 118 | spin_lock_irqsave(&mmio_lock, flags); | 117 | spin_lock_irqsave(&mmio_lock, flags); |
| 119 | ret = *io_virt_addr; | 118 | ret = readw(isp->base + (addr & 0x003FFFFF)); |
| 120 | spin_unlock_irqrestore(&mmio_lock, flags); | 119 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 121 | return ret; | 120 | return ret; |
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | static uint32_t atomisp_css2_hw_load_32(hrt_address addr) | 123 | static uint32_t atomisp_css2_hw_load_32(hrt_address addr) |
| 125 | { | 124 | { |
| 126 | s32 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 125 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 127 | unsigned long flags; | 126 | unsigned long flags; |
| 128 | u32 ret; | 127 | u32 ret; |
| 129 | 128 | ||
| 130 | spin_lock_irqsave(&mmio_lock, flags); | 129 | spin_lock_irqsave(&mmio_lock, flags); |
| 131 | ret = *io_virt_addr; | 130 | ret = readl(isp->base + (addr & 0x003FFFFF)); |
| 132 | spin_unlock_irqrestore(&mmio_lock, flags); | 131 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 133 | return ret; | 132 | return ret; |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | static void atomisp_css2_hw_store(hrt_address addr, | 135 | static void atomisp_css2_hw_store(hrt_address addr, const void *from, uint32_t n) |
| 137 | const void *from, uint32_t n) | ||
| 138 | { | 136 | { |
| 139 | s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 137 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 140 | unsigned long flags; | 138 | unsigned long flags; |
| 141 | unsigned int i; | 139 | unsigned int i; |
| 142 | 140 | ||
| 141 | addr &= 0x003FFFFF; | ||
| 143 | spin_lock_irqsave(&mmio_lock, flags); | 142 | spin_lock_irqsave(&mmio_lock, flags); |
| 144 | for (i = 0; i < n; i++, io_virt_addr++, from++) | 143 | for (i = 0; i < n; i++, from++) |
| 145 | *io_virt_addr = *(s8 *)from; | 144 | writeb(*(s8 *)from, isp->base + addr + i); |
| 145 | |||
| 146 | spin_unlock_irqrestore(&mmio_lock, flags); | 146 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static void atomisp_css2_hw_load(hrt_address addr, void *to, uint32_t n) | 149 | static void atomisp_css2_hw_load(hrt_address addr, void *to, uint32_t n) |
| 150 | { | 150 | { |
| 151 | s8 __iomem *io_virt_addr = atomisp_io_base + (addr & 0x003FFFFF); | 151 | struct atomisp_device *isp = dev_get_drvdata(atomisp_dev); |
| 152 | unsigned long flags; | 152 | unsigned long flags; |
| 153 | unsigned int i; | 153 | unsigned int i; |
| 154 | 154 | ||
| 155 | addr &= 0x003FFFFF; | ||
| 155 | spin_lock_irqsave(&mmio_lock, flags); | 156 | spin_lock_irqsave(&mmio_lock, flags); |
| 156 | for (i = 0; i < n; i++, to++, io_virt_addr++) | 157 | for (i = 0; i < n; i++, to++) |
| 157 | *(s8 *)to = *io_virt_addr; | 158 | *(s8 *)to = readb(isp->base + addr + i); |
| 158 | spin_unlock_irqrestore(&mmio_lock, flags); | 159 | spin_unlock_irqrestore(&mmio_lock, flags); |
| 159 | } | 160 | } |
| 160 | 161 | ||
| @@ -181,10 +182,10 @@ void atomisp_load_uint32(hrt_address addr, uint32_t *data) · 20 unmodified lines | |||
| 181 | *data = atomisp_css2_hw_load_32(addr); | 182 | *data = atomisp_css2_hw_load_32(addr); |
| 182 | } | 183 | } |
| 183 | 184 | ||
| 184 | static int hmm_get_mmu_base_addr(unsigned int *mmu_base_addr) | 185 | static int hmm_get_mmu_base_addr(struct device *dev, unsigned int *mmu_base_addr) |
| 185 | { | 186 | { |
| 186 | if (!sh_mmu_mrfld.get_pd_base) { | 187 | if (!sh_mmu_mrfld.get_pd_base) { |
| 187 | dev_err(atomisp_dev, "get mmu base address failed.\n"); | 188 | dev_err(dev, "get mmu base address failed.\n"); |
| 188 | return -EINVAL; | 189 | return -EINVAL; |
| 189 | } | 190 | } |
| 190 | 191 | ||
| @@ -839,7 +840,7 @@ int atomisp_css_init(struct atomisp_device *isp) · 648 unmodified lines | |||
| 839 | int ret; | 840 | int ret; |
| 840 | int err; | 841 | int err; |
| 841 | 842 | ||
| 842 | ret = hmm_get_mmu_base_addr(&mmu_base_addr); | 843 | ret = hmm_get_mmu_base_addr(isp->dev, &mmu_base_addr); |
| 843 | if (ret) | 844 | if (ret) |
| 844 | return ret; | 845 | return ret; |
| 845 | 846 | ||
| @@ -941,7 +942,7 @@ int atomisp_css_resume(struct atomisp_device *isp) · 95 unmodified lines | |||
| 941 | unsigned int mmu_base_addr; | 942 | unsigned int mmu_base_addr; |
| 942 | int ret; | 943 | int ret; |
| 943 | 944 | ||
| 944 | ret = hmm_get_mmu_base_addr(&mmu_base_addr); | 945 | ret = hmm_get_mmu_base_addr(isp->dev, &mmu_base_addr); |
| 945 | if (ret) { | 946 | if (ret) { |
| 946 | dev_err(isp->dev, "get base address error.\n"); | 947 | dev_err(isp->dev, "get base address error.\n"); |
| 947 | return -EINVAL; | 948 | return -EINVAL; |
| @@ -1966,8 +1967,7 @@ void atomisp_css_input_set_mode(struct atomisp_sub_device *asd, · 1018 unmodified lines | |||
| 1966 | true, | 1967 | true, |
| 1967 | 0x13000, | 1968 | 0x13000, |
| 1968 | &size_mem_words) != 0) { | 1969 | &size_mem_words) != 0) { |
| 1969 | if (intel_mid_identify_cpu() == | 1970 | if (IS_MRFD) |
| 1970 | INTEL_MID_CPU_CHIP_TANGIER) | ||
| 1971 | size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_2; | 1971 | size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_2; |
| 1972 | else | 1972 | else |
| 1973 | size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_1; | 1973 | size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_1; |
| @@ -2414,13 +2414,13 @@ static void __configure_preview_pp_input(struct atomisp_sub_device *asd, · 440 unmodified lines | |||
| 2414 | struct ia_css_resolution *effective_res = | 2414 | struct ia_css_resolution *effective_res = |
| 2415 | &stream_config->input_config.effective_res; | 2415 | &stream_config->input_config.effective_res; |
| 2416 | 2416 | ||
| 2417 | const struct bayer_ds_factor bds_fct[] = {{2, 1}, {3, 2}, {5, 4} }; | 2417 | static const struct bayer_ds_factor bds_fct[] = {{2, 1}, {3, 2}, {5, 4} }; |
| 2418 | /* | 2418 | /* |
| 2419 | * BZ201033: YUV decimation factor of 4 causes couple of rightmost | 2419 | * BZ201033: YUV decimation factor of 4 causes couple of rightmost |
| 2420 | * columns to be shaded. Remove this factor to work around the CSS bug. | 2420 | * columns to be shaded. Remove this factor to work around the CSS bug. |
| 2421 | * const unsigned int yuv_dec_fct[] = {4, 2}; | 2421 | * const unsigned int yuv_dec_fct[] = {4, 2}; |
| 2422 | */ | 2422 | */ |
| 2423 | const unsigned int yuv_dec_fct[] = { 2 }; | 2423 | static const unsigned int yuv_dec_fct[] = { 2 }; |
| 2424 | unsigned int i; | 2424 | unsigned int i; |
| 2425 | 2425 | ||
| 2426 | if (width == 0 && height == 0) | 2426 | if (width == 0 && height == 0) |
| @@ -2540,7 +2540,7 @@ static void __configure_video_pp_input(struct atomisp_sub_device *asd, · 113 unmodified lines | |||
| 2540 | struct ia_css_resolution *effective_res = | 2540 | struct ia_css_resolution *effective_res = |
| 2541 | &stream_config->input_config.effective_res; | 2541 | &stream_config->input_config.effective_res; |
| 2542 | 2542 | ||
| 2543 | const struct bayer_ds_factor bds_factors[] = { | 2543 | static const struct bayer_ds_factor bds_factors[] = { |
| 2544 | {8, 1}, {6, 1}, {4, 1}, {3, 1}, {2, 1}, {3, 2} | 2544 | {8, 1}, {6, 1}, {4, 1}, {3, 1}, {2, 1}, {3, 2} |
| 2545 | }; | 2545 | }; |
| 2546 | unsigned int i; | 2546 | unsigned int i; |
| @@ -4337,7 +4337,7 @@ static const char * const fw_acc_type_name[] = { · 1790 unmodified lines | |||
| 4337 | [IA_CSS_ACC_STANDALONE] = "Stand-alone acceleration", | 4337 | [IA_CSS_ACC_STANDALONE] = "Stand-alone acceleration", |
| 4338 | }; | 4338 | }; |
| 4339 | 4339 | ||
| 4340 | int atomisp_css_dump_blob_infor(void) | 4340 | int atomisp_css_dump_blob_infor(struct atomisp_device *isp) |
| 4341 | { | 4341 | { |
| 4342 | struct ia_css_blob_descr *bd = sh_css_blob_info; | 4342 | struct ia_css_blob_descr *bd = sh_css_blob_info; |
| 4343 | unsigned int i, nm = sh_css_num_binaries; | 4343 | unsigned int i, nm = sh_css_num_binaries; |
| @@ -4354,8 +4354,7 @@ int atomisp_css_dump_blob_infor(void) · 10 unmodified lines | |||
| 4354 | for (i = 0; i < sh_css_num_binaries - NUM_OF_SPS; i++) { | 4354 | for (i = 0; i < sh_css_num_binaries - NUM_OF_SPS; i++) { |
| 4355 | switch (bd[i].header.type) { | 4355 | switch (bd[i].header.type) { |
| 4356 | case ia_css_isp_firmware: | 4356 | case ia_css_isp_firmware: |
| 4357 | dev_dbg(atomisp_dev, | 4357 | dev_dbg(isp->dev, "Num%2d type %s (%s), binary id is %2d, name is %s\n", |
| 4358 | "Num%2d type %s (%s), binary id is %2d, name is %s\n", | ||
| 4359 | i + NUM_OF_SPS, | 4358 | i + NUM_OF_SPS, |
| 4360 | fw_type_name[bd[i].header.type], | 4359 | fw_type_name[bd[i].header.type], |
| 4361 | fw_acc_type_name[bd[i].header.info.isp.type], | 4360 | fw_acc_type_name[bd[i].header.info.isp.type], |
| @@ -4363,8 +4362,7 @@ int atomisp_css_dump_blob_infor(void) · 1 unmodified line | |||
| 4363 | bd[i].name); | 4362 | bd[i].name); |
| 4364 | break; | 4363 | break; |
| 4365 | default: | 4364 | default: |
| 4366 | dev_dbg(atomisp_dev, | 4365 | dev_dbg(isp->dev, "Num%2d type %s, name is %s\n", |
| 4367 | "Num%2d type %s, name is %s\n", | ||
| 4368 | i + NUM_OF_SPS, fw_type_name[bd[i].header.type], | 4366 | i + NUM_OF_SPS, fw_type_name[bd[i].header.type], |
| 4369 | bd[i].name); | 4367 | bd[i].name); |
| 4370 | } | 4368 | } |
| @@ -153,7 +153,7 @@ int atomisp_css_debug_dump_isp_binary(void); · 152 unmodified lines | |||
| 153 | 153 | ||
| 154 | int atomisp_css_dump_sp_raw_copy_linecount(bool reduced); | 154 | int atomisp_css_dump_sp_raw_copy_linecount(bool reduced); |
| 155 | 155 | ||
| 156 | int atomisp_css_dump_blob_infor(void); | 156 | int atomisp_css_dump_blob_infor(struct atomisp_device *isp); |
| 157 | 157 | ||
| 158 | void atomisp_css_set_isp_config_id(struct atomisp_sub_device *asd, | 158 | void atomisp_css_set_isp_config_id(struct atomisp_sub_device *asd, |
| 159 | uint32_t isp_config_id); | 159 | uint32_t isp_config_id); |
| @@ -62,9 +62,9 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp, · 61 unmodified lines | |||
| 62 | 62 | ||
| 63 | if (opt & OPTION_VALID) { | 63 | if (opt & OPTION_VALID) { |
| 64 | if (opt & OPTION_BIN_LIST) { | 64 | if (opt & OPTION_BIN_LIST) { |
| 65 | ret = atomisp_css_dump_blob_infor(); | 65 | ret = atomisp_css_dump_blob_infor(isp); |
| 66 | if (ret) { | 66 | if (ret) { |
| 67 | dev_err(atomisp_dev, "%s dump blob infor err[ret:%d]\n", | 67 | dev_err(isp->dev, "%s dump blob infor err[ret:%d]\n", |
| 68 | __func__, ret); | 68 | __func__, ret); |
| 69 | goto opt_err; | 69 | goto opt_err; |
| 70 | } | 70 | } |
| @@ -76,7 +76,7 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp, · 5 unmodified lines | |||
| 76 | atomisp_css_debug_dump_isp_binary(); | 76 | atomisp_css_debug_dump_isp_binary(); |
| 77 | } else { | 77 | } else { |
| 78 | ret = -EPERM; | 78 | ret = -EPERM; |
| 79 | dev_err(atomisp_dev, "%s dump running bin err[ret:%d]\n", | 79 | dev_err(isp->dev, "%s dump running bin err[ret:%d]\n", |
| 80 | __func__, ret); | 80 | __func__, ret); |
| 81 | goto opt_err; | 81 | goto opt_err; |
| 82 | } | 82 | } |
| @@ -86,8 +86,7 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp, · 3 unmodified lines | |||
| 86 | hmm_show_mem_stat(__func__, __LINE__); | 86 | hmm_show_mem_stat(__func__, __LINE__); |
| 87 | } else { | 87 | } else { |
| 88 | ret = -EINVAL; | 88 | ret = -EINVAL; |
| 89 | dev_err(atomisp_dev, "%s dump nothing[ret=%d]\n", __func__, | 89 | dev_err(isp->dev, "%s dump nothing[ret=%d]\n", __func__, ret); |
| 90 | ret); | ||
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | opt_err: | 92 | opt_err: |
| @@ -185,8 +184,9 @@ static void iunit_drvfs_remove_files(struct device_driver *drv) · 91 unmodified lines | |||
| 185 | driver_remove_file(drv, &iunit_drvfs_attrs[i]); | 184 | driver_remove_file(drv, &iunit_drvfs_attrs[i]); |
| 186 | } | 185 | } |
| 187 | 186 | ||
| 188 | int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp) | 187 | int atomisp_drvfs_init(struct atomisp_device *isp) |
| 189 | { | 188 | { |
| 189 | struct device_driver *drv = isp->dev->driver; | ||
| 190 | int ret; | 190 | int ret; |
| 191 | 191 | ||
| 192 | iunit_debug.isp = isp; | 192 | iunit_debug.isp = isp; |
| @@ -194,7 +194,7 @@ int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp) · 1 unmodified line | |||
| 194 | 194 | ||
| 195 | ret = iunit_drvfs_create_files(iunit_debug.drv); | 195 | ret = iunit_drvfs_create_files(iunit_debug.drv); |
| 196 | if (ret) { | 196 | if (ret) { |
| 197 | dev_err(atomisp_dev, "drvfs_create_files error: %d\n", ret); | 197 | dev_err(isp->dev, "drvfs_create_files error: %d\n", ret); |
| 198 | iunit_drvfs_remove_files(iunit_debug.drv); | 198 | iunit_drvfs_remove_files(iunit_debug.drv); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 19 | #ifndef __ATOMISP_DRVFS_H__ | 19 | #ifndef __ATOMISP_DRVFS_H__ |
| 20 | #define __ATOMISP_DRVFS_H__ | 20 | #define __ATOMISP_DRVFS_H__ |
| 21 | 21 | ||
| 22 | int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp); | 22 | int atomisp_drvfs_init(struct atomisp_device *isp); |
| 23 | void atomisp_drvfs_exit(void); | 23 | void atomisp_drvfs_exit(void); |
| 24 | 24 | ||
| 25 | #endif /* __ATOMISP_DRVFS_H__ */ | 25 | #endif /* __ATOMISP_DRVFS_H__ */ |
| @@ -26,6 +26,9 @@ enum clock_rate { · 25 unmodified lines | |||
| 26 | #define CLK_RATE_19_2MHZ 19200000 | 26 | #define CLK_RATE_19_2MHZ 19200000 |
| 27 | #define CLK_RATE_25_0MHZ 25000000 | 27 | #define CLK_RATE_25_0MHZ 25000000 |
| 28 | 28 | ||
| 29 | /* Valid clock number range from 0 to 5 */ | ||
| 30 | #define MAX_CLK_COUNT 5 | ||
| 31 | |||
| 29 | /* X-Powers AXP288 register set */ | 32 | /* X-Powers AXP288 register set */ |
| 30 | #define ALDO1_SEL_REG 0x28 | 33 | #define ALDO1_SEL_REG 0x28 |
| 31 | #define ALDO1_CTRL3_REG 0x13 | 34 | #define ALDO1_CTRL3_REG 0x13 |
| @@ -61,9 +64,7 @@ enum clock_rate { · 29 unmodified lines | |||
| 61 | 64 | ||
| 62 | struct gmin_subdev { | 65 | struct gmin_subdev { |
| 63 | struct v4l2_subdev *subdev; | 66 | struct v4l2_subdev *subdev; |
| 64 | int clock_num; | ||
| 65 | enum clock_rate clock_src; | 67 | enum clock_rate clock_src; |
| 66 | bool clock_on; | ||
| 67 | struct clk *pmc_clk; | 68 | struct clk *pmc_clk; |
| 68 | struct gpio_desc *gpio0; | 69 | struct gpio_desc *gpio0; |
| 69 | struct gpio_desc *gpio1; | 70 | struct gpio_desc *gpio1; |
| @@ -75,11 +76,16 @@ struct gmin_subdev { · 5 unmodified lines | |||
| 75 | unsigned int csi_lanes; | 76 | unsigned int csi_lanes; |
| 76 | enum atomisp_input_format csi_fmt; | 77 | enum atomisp_input_format csi_fmt; |
| 77 | enum atomisp_bayer_order csi_bayer; | 78 | enum atomisp_bayer_order csi_bayer; |
| 79 | |||
| 80 | bool clock_on; | ||
| 78 | bool v1p8_on; | 81 | bool v1p8_on; |
| 79 | bool v2p8_on; | 82 | bool v2p8_on; |
| 80 | bool v1p2_on; | 83 | bool v1p2_on; |
| 81 | bool v2p8_vcm_on; | 84 | bool v2p8_vcm_on; |
| 82 | 85 | ||
| 86 | int v1p8_gpio; | ||
| 87 | int v2p8_gpio; | ||
| 88 | |||
| 83 | u8 pwm_i2c_addr; | 89 | u8 pwm_i2c_addr; |
| 84 | 90 | ||
| 85 | /* For PMIC AXP */ | 91 | /* For PMIC AXP */ |
| @@ -90,9 +96,9 @@ struct gmin_subdev { · 4 unmodified lines | |||
| 90 | static struct gmin_subdev gmin_subdevs[MAX_SUBDEVS]; | 96 | static struct gmin_subdev gmin_subdevs[MAX_SUBDEVS]; |
| 91 | 97 | ||
| 92 | /* ACPI HIDs for the PMICs that could be used by this driver */ | 98 | /* ACPI HIDs for the PMICs that could be used by this driver */ |
| 93 | #define PMIC_ACPI_AXP "INT33F4:00" /* XPower AXP288 PMIC */ | 99 | #define PMIC_ACPI_AXP "INT33F4" /* XPower AXP288 PMIC */ |
| 94 | #define PMIC_ACPI_TI "INT33F5:00" /* Dollar Cove TI PMIC */ | 100 | #define PMIC_ACPI_TI "INT33F5" /* Dollar Cove TI PMIC */ |
| 95 | #define PMIC_ACPI_CRYSTALCOVE "INT33FD:00" /* Crystal Cove PMIC */ | 101 | #define PMIC_ACPI_CRYSTALCOVE "INT33FD" /* Crystal Cove PMIC */ |
| 96 | 102 | ||
| 97 | #define PMIC_PLATFORM_TI "intel_soc_pmic_chtdc_ti" | 103 | #define PMIC_PLATFORM_TI "intel_soc_pmic_chtdc_ti" |
| 98 | 104 | ||
| @@ -105,7 +111,7 @@ static enum { · 6 unmodified lines | |||
| 105 | } pmic_id; | 111 | } pmic_id; |
| 106 | 112 | ||
| 107 | static const char *pmic_name[] = { | 113 | static const char *pmic_name[] = { |
| 108 | [PMIC_UNSET] = "unset", | 114 | [PMIC_UNSET] = "ACPI device PM", |
| 109 | [PMIC_REGULATOR] = "regulator driver", | 115 | [PMIC_REGULATOR] = "regulator driver", |
| 110 | [PMIC_AXP] = "XPower AXP288 PMIC", | 116 | [PMIC_AXP] = "XPower AXP288 PMIC", |
| 111 | [PMIC_TI] = "Dollar Cove TI PMIC", | 117 | [PMIC_TI] = "Dollar Cove TI PMIC", |
| @@ -119,24 +125,6 @@ static const struct atomisp_platform_data pdata = { · 7 unmodified lines | |||
| 119 | .subdevs = pdata_subdevs, | 125 | .subdevs = pdata_subdevs, |
| 120 | }; | 126 | }; |
| 121 | 127 | ||
| 122 | /* | ||
| 123 | * Something of a hack. The ECS E7 board drives camera 2.8v from an | ||
| 124 | * external regulator instead of the PMIC. There's a gmin_CamV2P8 | ||
| 125 | * config variable that specifies the GPIO to handle this particular | ||
| 126 | * case, but this needs a broader architecture for handling camera | ||
| 127 | * power. | ||
| 128 | */ | ||
| 129 | enum { V2P8_GPIO_UNSET = -2, V2P8_GPIO_NONE = -1 }; | ||
| 130 | static int v2p8_gpio = V2P8_GPIO_UNSET; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Something of a hack. The CHT RVP board drives camera 1.8v from an | ||
| 134 | * external regulator instead of the PMIC just like ECS E7 board, see the | ||
| 135 | * comments above. | ||
| 136 | */ | ||
| 137 | enum { V1P8_GPIO_UNSET = -2, V1P8_GPIO_NONE = -1 }; | ||
| 138 | static int v1p8_gpio = V1P8_GPIO_UNSET; | ||
| 139 | |||
| 140 | static LIST_HEAD(vcm_devices); | 128 | static LIST_HEAD(vcm_devices); |
| 141 | static DEFINE_MUTEX(vcm_lock); | 129 | static DEFINE_MUTEX(vcm_lock); |
| 142 | 130 | ||
| @@ -199,6 +187,8 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev, · 56 unmodified lines | |||
| 199 | * gmin_subdev struct is already initialized for us. | 187 | * gmin_subdev struct is already initialized for us. |
| 200 | */ | 188 | */ |
| 201 | gs = find_gmin_subdev(subdev); | 189 | gs = find_gmin_subdev(subdev); |
| 190 | if (!gs) | ||
| 191 | return -ENODEV; | ||
| 202 | 192 | ||
| 203 | pdata.subdevs[i].type = type; | 193 | pdata.subdevs[i].type = type; |
| 204 | pdata.subdevs[i].port = gs->csi_port; | 194 | pdata.subdevs[i].port = gs->csi_port; |
| @@ -294,6 +284,7 @@ static struct gmin_cfg_var mrd7_vars[] = { · 89 unmodified lines | |||
| 294 | {"INT33F8:00_CsiFmt", "13"}, | 284 | {"INT33F8:00_CsiFmt", "13"}, |
| 295 | {"INT33F8:00_CsiBayer", "0"}, | 285 | {"INT33F8:00_CsiBayer", "0"}, |
| 296 | {"INT33F8:00_CamClk", "0"}, | 286 | {"INT33F8:00_CamClk", "0"}, |
| 287 | |||
| 297 | {"INT33F9:00_CamType", "1"}, | 288 | {"INT33F9:00_CamType", "1"}, |
| 298 | {"INT33F9:00_CsiPort", "0"}, | 289 | {"INT33F9:00_CsiPort", "0"}, |
| 299 | {"INT33F9:00_CsiLanes", "1"}, | 290 | {"INT33F9:00_CsiLanes", "1"}, |
| @@ -309,6 +300,7 @@ static struct gmin_cfg_var ecs7_vars[] = { · 9 unmodified lines | |||
| 309 | {"INT33BE:00_CsiFmt", "13"}, | 300 | {"INT33BE:00_CsiFmt", "13"}, |
| 310 | {"INT33BE:00_CsiBayer", "2"}, | 301 | {"INT33BE:00_CsiBayer", "2"}, |
| 311 | {"INT33BE:00_CamClk", "0"}, | 302 | {"INT33BE:00_CamClk", "0"}, |
| 303 | |||
| 312 | {"INT33F0:00_CsiPort", "0"}, | 304 | {"INT33F0:00_CsiPort", "0"}, |
| 313 | {"INT33F0:00_CsiLanes", "1"}, | 305 | {"INT33F0:00_CsiLanes", "1"}, |
| 314 | {"INT33F0:00_CsiFmt", "13"}, | 306 | {"INT33F0:00_CsiFmt", "13"}, |
| @@ -322,6 +314,7 @@ static struct gmin_cfg_var i8880_vars[] = { · 7 unmodified lines | |||
| 322 | {"XXOV2680:00_CsiPort", "1"}, | 314 | {"XXOV2680:00_CsiPort", "1"}, |
| 323 | {"XXOV2680:00_CsiLanes", "1"}, | 315 | {"XXOV2680:00_CsiLanes", "1"}, |
| 324 | {"XXOV2680:00_CamClk", "0"}, | 316 | {"XXOV2680:00_CamClk", "0"}, |
| 317 | |||
| 325 | {"XXGC0310:00_CsiPort", "0"}, | 318 | {"XXGC0310:00_CsiPort", "0"}, |
| 326 | {"XXGC0310:00_CsiLanes", "1"}, | 319 | {"XXGC0310:00_CsiLanes", "1"}, |
| 327 | {"XXGC0310:00_CamClk", "1"}, | 320 | {"XXGC0310:00_CamClk", "1"}, |
| @@ -381,34 +374,27 @@ static const guid_t atomisp_dsm_guid = GUID_INIT(0xdc2f6c4f, 0x045b, 0x4f1d, · 53 unmodified lines | |||
| 381 | #define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */ | 374 | #define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */ |
| 382 | static char gmin_pmc_clk_name[GMIN_PMC_CLK_NAME]; | 375 | static char gmin_pmc_clk_name[GMIN_PMC_CLK_NAME]; |
| 383 | 376 | ||
| 384 | static int gmin_i2c_match_one(struct device *dev, const void *data) | ||
| 385 | { | ||
| 386 | const char *name = data; | ||
| 387 | struct i2c_client *client; | ||
| 388 | |||
| 389 | if (dev->type != &i2c_client_type) | ||
| 390 | return 0; | ||
| 391 | |||
| 392 | client = to_i2c_client(dev); | ||
| 393 | |||
| 394 | return (!strcmp(name, client->name)); | ||
| 395 | } | ||
| 396 | |||
| 397 | static struct i2c_client *gmin_i2c_dev_exists(struct device *dev, char *name, | 377 | static struct i2c_client *gmin_i2c_dev_exists(struct device *dev, char *name, |
| 398 | struct i2c_client **client) | 378 | struct i2c_client **client) |
| 399 | { | 379 | { |
| 380 | struct acpi_device *adev; | ||
| 400 | struct device *d; | 381 | struct device *d; |
| 401 | 382 | ||
| 402 | while ((d = bus_find_device(&i2c_bus_type, NULL, name, | 383 | adev = acpi_dev_get_first_match_dev(name, NULL, -1); |
| 403 | gmin_i2c_match_one))) { | 384 | if (!adev) |
| 404 | *client = to_i2c_client(d); | 385 | return NULL; |
| 405 | dev_dbg(dev, "found '%s' at address 0x%02x, adapter %d\n", | ||
| 406 | (*client)->name, (*client)->addr, | ||
| 407 | (*client)->adapter->nr); | ||
| 408 | return *client; | ||
| 409 | } | ||
| 410 | 386 | ||
| 411 | return NULL; | 387 | d = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); |
| 388 | acpi_dev_put(adev); | ||
| 389 | if (!d) | ||
| 390 | return NULL; | ||
| 391 | |||
| 392 | *client = i2c_verify_client(d); | ||
| 393 | put_device(d); | ||
| 394 | |||
| 395 | dev_dbg(dev, "found '%s' at address 0x%02x, adapter %d\n", | ||
| 396 | (*client)->name, (*client)->addr, (*client)->adapter->nr); | ||
| 397 | return *client; | ||
| 412 | } | 398 | } |
| 413 | 399 | ||
| 414 | static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg, | 400 | static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg, |
| @@ -427,94 +413,222 @@ static int gmin_i2c_write(struct device *dev, u16 i2c_addr, u8 reg, · 12 unmodified lines | |||
| 427 | "I2C write, addr: 0x%02x, reg: 0x%02x, value: 0x%02x, mask: 0x%02x\n", | 413 | "I2C write, addr: 0x%02x, reg: 0x%02x, value: 0x%02x, mask: 0x%02x\n", |
| 428 | i2c_addr, reg, value, mask); | 414 | i2c_addr, reg, value, mask); |
| 429 | 415 | ||
| 430 | ret = intel_soc_pmic_exec_mipi_pmic_seq_element(i2c_addr, reg, | 416 | ret = intel_soc_pmic_exec_mipi_pmic_seq_element(i2c_addr, reg, value, mask); |
| 431 | value, mask); | 417 | if (ret == -EOPNOTSUPP) |
| 432 | |||
| 433 | if (ret == -EOPNOTSUPP) { | ||
| 434 | dev_err(dev, | 418 | dev_err(dev, |
| 435 | "ACPI didn't mapped the OpRegion needed to access I2C address 0x%02x.\n" | 419 | "ACPI didn't mapped the OpRegion needed to access I2C address 0x%02x.\n" |
| 436 | "Need to compile the Kernel using CONFIG_*_PMIC_OPREGION settings\n", | 420 | "Need to compile the kernel using CONFIG_*_PMIC_OPREGION settings\n", |
| 437 | i2c_addr); | 421 | i2c_addr); |
| 438 | return ret; | ||
| 439 | } | ||
| 440 | 422 | ||
| 441 | return ret; | 423 | return ret; |
| 442 | } | 424 | } |
| 443 | 425 | ||
| 444 | static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev) | 426 | static int atomisp_get_acpi_power(struct device *dev) |
| 445 | { | 427 | { |
| 446 | struct i2c_client *power = NULL, *client = v4l2_get_subdevdata(subdev); | 428 | char name[5]; |
| 447 | struct acpi_device *adev; | 429 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 448 | acpi_handle handle; | 430 | struct acpi_buffer b_name = { sizeof(name), name }; |
| 449 | struct device *dev; | 431 | union acpi_object *package, *element; |
| 450 | int i, ret; | 432 | acpi_handle handle = ACPI_HANDLE(dev); |
| 433 | acpi_handle rhandle; | ||
| 434 | acpi_status status; | ||
| 435 | int clock_num = -1; | ||
| 436 | int i; | ||
| 451 | 437 | ||
| 452 | if (!client) | 438 | status = acpi_evaluate_object(handle, "_PR0", NULL, &buffer); |
| 453 | return NULL; | 439 | if (!ACPI_SUCCESS(status)) |
| 440 | return -1; | ||
| 454 | 441 | ||
| 455 | dev = &client->dev; | 442 | package = buffer.pointer; |
| 456 | 443 | ||
| 457 | handle = ACPI_HANDLE(dev); | 444 | if (!buffer.length || !package |
| 445 | || package->type != ACPI_TYPE_PACKAGE | ||
| 446 | || !package->package.count) | ||
| 447 | goto fail; | ||
| 458 | 448 | ||
| 459 | // FIXME: may need to release resources allocated by acpi_bus_get_device() | 449 | for (i = 0; i < package->package.count; i++) { |
| 460 | if (!handle || acpi_bus_get_device(handle, &adev)) { | 450 | element = &package->package.elements[i]; |
| 461 | dev_err(dev, "Error could not get ACPI device\n"); | ||
| 462 | return NULL; | ||
| 463 | } | ||
| 464 | 451 | ||
| 465 | dev_info(&client->dev, "%s: ACPI detected it on bus ID=%s, HID=%s\n", | 452 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) |
| 466 | __func__, acpi_device_bid(adev), acpi_device_hid(adev)); | 453 | continue; |
| 467 | 454 | ||
| 468 | if (!pmic_id) { | 455 | rhandle = element->reference.handle; |
| 469 | if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power)) | 456 | if (!rhandle) |
| 470 | pmic_id = PMIC_TI; | 457 | goto fail; |
| 471 | else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_AXP, &power)) | 458 | |
| 472 | pmic_id = PMIC_AXP; | 459 | acpi_get_name(rhandle, ACPI_SINGLE_NAME, &b_name); |
| 473 | else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_CRYSTALCOVE, &power)) | 460 | |
| 474 | pmic_id = PMIC_CRYSTALCOVE; | 461 | dev_dbg(dev, "Found PM resource '%s'\n", name); |
| 475 | else | 462 | if (strlen(name) == 4 && !strncmp(name, "CLK", 3)) { |
| 476 | pmic_id = PMIC_REGULATOR; | 463 | if (name[3] >= '0' && name[3] <= '4') |
| 464 | clock_num = name[3] - '0'; | ||
| 465 | #if 0 | ||
| 466 | /* | ||
| 467 | * We could abort here, but let's parse all resources, | ||
| 468 | * as this is helpful for debugging purposes | ||
| 469 | */ | ||
| 470 | if (clock_num >= 0) | ||
| 471 | break; | ||
| 472 | #endif | ||
| 473 | } | ||
| 477 | } | 474 | } |
| 478 | 475 | ||
| 479 | for (i = 0; i < MAX_SUBDEVS && gmin_subdevs[i].subdev; i++) | 476 | fail: |
| 480 | ; | 477 | ACPI_FREE(buffer.pointer); |
| 481 | if (i >= MAX_SUBDEVS) | 478 | |
| 482 | return NULL; | 479 | return clock_num; |
| 480 | } | ||
| 481 | |||
| 482 | static u8 gmin_get_pmic_id_and_addr(struct device *dev) | ||
| 483 | { | ||
| 484 | struct i2c_client *power; | ||
| 485 | static u8 pmic_i2c_addr; | ||
| 486 | |||
| 487 | if (pmic_id) | ||
| 488 | return pmic_i2c_addr; | ||
| 489 | |||
| 490 | if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power)) | ||
| 491 | pmic_id = PMIC_TI; | ||
| 492 | else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_AXP, &power)) | ||
| 493 | pmic_id = PMIC_AXP; | ||
| 494 | else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_CRYSTALCOVE, &power)) | ||
| 495 | pmic_id = PMIC_CRYSTALCOVE; | ||
| 496 | else | ||
| 497 | pmic_id = PMIC_REGULATOR; | ||
| 498 | |||
| 499 | pmic_i2c_addr = power ? power->addr : 0; | ||
| 500 | return pmic_i2c_addr; | ||
| 501 | } | ||
| 502 | |||
| 503 | static int gmin_detect_pmic(struct v4l2_subdev *subdev) | ||
| 504 | { | ||
| 505 | struct i2c_client *client = v4l2_get_subdevdata(subdev); | ||
| 506 | struct device *dev = &client->dev; | ||
| 507 | u8 pmic_i2c_addr; | ||
| 508 | |||
| 509 | pmic_i2c_addr = gmin_get_pmic_id_and_addr(dev); | ||
| 510 | dev_info(dev, "gmin: power management provided via %s (i2c addr 0x%02x)\n", | ||
| 511 | pmic_name[pmic_id], pmic_i2c_addr); | ||
| 512 | return pmic_i2c_addr; | ||
| 513 | } | ||
| 514 | |||
| 515 | static int gmin_subdev_add(struct gmin_subdev *gs) | ||
| 516 | { | ||
| 517 | struct i2c_client *client = v4l2_get_subdevdata(gs->subdev); | ||
| 518 | struct device *dev = &client->dev; | ||
| 519 | struct acpi_device *adev = ACPI_COMPANION(dev); | ||
| 520 | int ret, clock_num = -1; | ||
| 521 | |||
| 522 | dev_info(dev, "%s: ACPI path is %pfw\n", __func__, dev_fwnode(dev)); | ||
| 523 | |||
| 524 | /*WA:CHT requires XTAL clock as PLL is not stable.*/ | ||
| 525 | gs->clock_src = gmin_get_var_int(dev, false, "ClkSrc", | ||
| 526 | VLV2_CLK_PLL_19P2MHZ); | ||
| 527 | |||
| 528 | gs->csi_port = gmin_get_var_int(dev, false, "CsiPort", 0); | ||
| 529 | gs->csi_lanes = gmin_get_var_int(dev, false, "CsiLanes", 1); | ||
| 530 | |||
| 531 | gs->gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW); | ||
| 532 | if (IS_ERR(gs->gpio0)) | ||
| 533 | gs->gpio0 = NULL; | ||
| 534 | else | ||
| 535 | dev_info(dev, "will handle gpio0 via ACPI\n"); | ||
| 536 | |||
| 537 | gs->gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW); | ||
| 538 | if (IS_ERR(gs->gpio1)) | ||
| 539 | gs->gpio1 = NULL; | ||
| 540 | else | ||
| 541 | dev_info(dev, "will handle gpio1 via ACPI\n"); | ||
| 542 | |||
| 543 | /* | ||
| 544 | * Those are used only when there is an external regulator apart | ||
| 545 | * from the PMIC that would be providing power supply, like on the | ||
| 546 | * two cases below: | ||
| 547 | * | ||
| 548 | * The ECS E7 board drives camera 2.8v from an external regulator | ||
| 549 | * instead of the PMIC. There's a gmin_CamV2P8 config variable | ||
| 550 | * that specifies the GPIO to handle this particular case, | ||
| 551 | * but this needs a broader architecture for handling camera power. | ||
| 552 | * | ||
| 553 | * The CHT RVP board drives camera 1.8v from an* external regulator | ||
| 554 | * instead of the PMIC just like ECS E7 board. | ||
| 555 | */ | ||
| 483 | 556 | ||
| 484 | if (power) { | 557 | gs->v1p8_gpio = gmin_get_var_int(dev, true, "V1P8GPIO", -1); |
| 485 | gmin_subdevs[i].pwm_i2c_addr = power->addr; | 558 | gs->v2p8_gpio = gmin_get_var_int(dev, true, "V2P8GPIO", -1); |
| 559 | |||
| 560 | /* | ||
| 561 | * FIXME: | ||
| 562 | * | ||
| 563 | * The ACPI handling code checks for the _PR? tables in order to | ||
| 564 | * know what is required to switch the device from power state | ||
| 565 | * D0 (_PR0) up to D3COLD (_PR3). | ||
| 566 | * | ||
| 567 | * The adev->flags.power_manageable is set to true if the device | ||
| 568 | * has a _PR0 table, which can be checked by calling | ||
| 569 | * acpi_device_power_manageable(adev). | ||
| 570 | * | ||
| 571 | * However, this only says that the device can be set to power off | ||
| 572 | * mode. | ||
| 573 | * | ||
| 574 | * At least on the DSDT tables we've seen so far, there's no _PR3, | ||
| 575 | * nor _PS3 (which would have a somewhat similar effect). | ||
| 576 | * So, using ACPI for power management won't work, except if adding | ||
| 577 | * an ACPI override logic somewhere. | ||
| 578 | * | ||
| 579 | * So, at least for the existing devices we know, the check below | ||
| 580 | * will always be false. | ||
| 581 | */ | ||
| 582 | if (acpi_device_can_wakeup(adev) && | ||
| 583 | acpi_device_can_poweroff(adev)) { | ||
| 486 | dev_info(dev, | 584 | dev_info(dev, |
| 487 | "gmin: power management provided via %s (i2c addr 0x%02x)\n", | 585 | "gmin: power management provided via device PM\n"); |
| 488 | pmic_name[pmic_id], power->addr); | 586 | return 0; |
| 489 | } else { | ||
| 490 | dev_info(dev, "gmin: power management provided via %s\n", | ||
| 491 | pmic_name[pmic_id]); | ||
| 492 | } | 587 | } |
| 493 | 588 | ||
| 494 | gmin_subdevs[i].subdev = subdev; | 589 | /* |
| 495 | gmin_subdevs[i].clock_num = gmin_get_var_int(dev, false, "CamClk", 0); | 590 | * The code below is here due to backward compatibility with devices |
| 496 | /*WA:CHT requires XTAL clock as PLL is not stable.*/ | 591 | * whose ACPI BIOS may not contain everything that would be needed |
| 497 | gmin_subdevs[i].clock_src = gmin_get_var_int(dev, false, "ClkSrc", | 592 | * in order to set clocks and do power management. |
| 498 | VLV2_CLK_PLL_19P2MHZ); | 593 | */ |
| 499 | gmin_subdevs[i].csi_port = gmin_get_var_int(dev, false, "CsiPort", 0); | 594 | |
| 500 | gmin_subdevs[i].csi_lanes = gmin_get_var_int(dev, false, "CsiLanes", 1); | 595 | /* |
| 596 | * According with : | ||
| 597 | * https://github.com/projectceladon/hardware-intel-kernelflinger/blob/master/doc/fastboot.md | ||
| 598 | * | ||
| 599 | * The "CamClk" EFI var is set via fastboot on some Android devices, | ||
| 600 | * and seems to contain the number of the clock used to feed the | ||
| 601 | * sensor. | ||
| 602 | * | ||
| 603 | * On systems with a proper ACPI table, this is given via the _PR0 | ||
| 604 | * power resource table. The logic below should first check if there | ||
| 605 | * is a power resource already, falling back to the EFI vars detection | ||
| 606 | * otherwise. | ||
| 607 | */ | ||
| 501 | 608 | ||
| 502 | /* get PMC clock with clock framework */ | 609 | /* Try first to use ACPI to get the clock resource */ |
| 503 | snprintf(gmin_pmc_clk_name, | 610 | if (acpi_device_power_manageable(adev)) |
| 504 | sizeof(gmin_pmc_clk_name), | 611 | clock_num = atomisp_get_acpi_power(dev); |
| 505 | "%s_%d", "pmc_plt_clk", gmin_subdevs[i].clock_num); | ||
| 506 | 612 | ||
| 507 | gmin_subdevs[i].pmc_clk = devm_clk_get(dev, gmin_pmc_clk_name); | 613 | /* Fall-back use EFI and/or DMI match */ |
| 508 | if (IS_ERR(gmin_subdevs[i].pmc_clk)) { | 614 | if (clock_num < 0) |
| 509 | ret = PTR_ERR(gmin_subdevs[i].pmc_clk); | 615 | clock_num = gmin_get_var_int(dev, false, "CamClk", 0); |
| 510 | 616 | ||
| 511 | dev_err(dev, | 617 | if (clock_num < 0 || clock_num > MAX_CLK_COUNT) { |
| 512 | "Failed to get clk from %s : %d\n", | 618 | dev_err(dev, "Invalid clock number\n"); |
| 513 | gmin_pmc_clk_name, | 619 | return -EINVAL; |
| 514 | ret); | 620 | } |
| 515 | 621 | ||
| 516 | return NULL; | 622 | snprintf(gmin_pmc_clk_name, sizeof(gmin_pmc_clk_name), |
| 623 | "%s_%d", "pmc_plt_clk", clock_num); | ||
| 624 | |||
| 625 | gs->pmc_clk = devm_clk_get(dev, gmin_pmc_clk_name); | ||
| 626 | if (IS_ERR(gs->pmc_clk)) { | ||
| 627 | ret = PTR_ERR(gs->pmc_clk); | ||
| 628 | dev_err(dev, "Failed to get clk from %s: %d\n", gmin_pmc_clk_name, ret); | ||
| 629 | return ret; | ||
| 517 | } | 630 | } |
| 631 | dev_info(dev, "Will use CLK%d (%s)\n", clock_num, gmin_pmc_clk_name); | ||
| 518 | 632 | ||
| 519 | /* | 633 | /* |
| 520 | * The firmware might enable the clock at | 634 | * The firmware might enable the clock at |
| @@ -526,25 +640,17 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev) · 5 unmodified lines | |||
| 526 | * to disable a clock that has not been enabled, | 640 | * to disable a clock that has not been enabled, |
| 527 | * we need to enable the clock first. | 641 | * we need to enable the clock first. |
| 528 | */ | 642 | */ |
| 529 | ret = clk_prepare_enable(gmin_subdevs[i].pmc_clk); | 643 | ret = clk_prepare_enable(gs->pmc_clk); |
| 530 | if (!ret) | 644 | if (!ret) |
| 531 | clk_disable_unprepare(gmin_subdevs[i].pmc_clk); | 645 | clk_disable_unprepare(gs->pmc_clk); |
| 532 | |||
| 533 | gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW); | ||
| 534 | if (IS_ERR(gmin_subdevs[i].gpio0)) | ||
| 535 | gmin_subdevs[i].gpio0 = NULL; | ||
| 536 | |||
| 537 | gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW); | ||
| 538 | if (IS_ERR(gmin_subdevs[i].gpio1)) | ||
| 539 | gmin_subdevs[i].gpio1 = NULL; | ||
| 540 | 646 | ||
| 541 | switch (pmic_id) { | 647 | switch (pmic_id) { |
| 542 | case PMIC_REGULATOR: | 648 | case PMIC_REGULATOR: |
| 543 | gmin_subdevs[i].v1p8_reg = regulator_get(dev, "V1P8SX"); | 649 | gs->v1p8_reg = regulator_get(dev, "V1P8SX"); |
| 544 | gmin_subdevs[i].v2p8_reg = regulator_get(dev, "V2P8SX"); | 650 | gs->v2p8_reg = regulator_get(dev, "V2P8SX"); |
| 545 | 651 | ||
| 546 | gmin_subdevs[i].v1p2_reg = regulator_get(dev, "V1P2A"); | 652 | gs->v1p2_reg = regulator_get(dev, "V1P2A"); |
| 547 | gmin_subdevs[i].v2p8_vcm_reg = regulator_get(dev, "VPROG4B"); | 653 | gs->v2p8_vcm_reg = regulator_get(dev, "VPROG4B"); |
| 548 | 654 | ||
| 549 | /* Note: ideally we would initialize v[12]p8_on to the | 655 | /* Note: ideally we would initialize v[12]p8_on to the |
| 550 | * output of regulator_is_enabled(), but sadly that | 656 | * output of regulator_is_enabled(), but sadly that |
| @@ -556,32 +662,31 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev) · 5 unmodified lines | |||
| 556 | break; | 662 | break; |
| 557 | 663 | ||
| 558 | case PMIC_AXP: | 664 | case PMIC_AXP: |
| 559 | gmin_subdevs[i].eldo1_1p8v = gmin_get_var_int(dev, false, | 665 | gs->eldo1_1p8v = gmin_get_var_int(dev, false, |
| 560 | "eldo1_1p8v", | 666 | "eldo1_1p8v", |
| 561 | ELDO1_1P8V); | 667 | ELDO1_1P8V); |
| 562 | gmin_subdevs[i].eldo1_sel_reg = gmin_get_var_int(dev, false, | 668 | gs->eldo1_sel_reg = gmin_get_var_int(dev, false, |
| 563 | "eldo1_sel_reg", | 669 | "eldo1_sel_reg", |
| 564 | ELDO1_SEL_REG); | 670 | ELDO1_SEL_REG); |
| 565 | gmin_subdevs[i].eldo1_ctrl_shift = gmin_get_var_int(dev, false, | 671 | gs->eldo1_ctrl_shift = gmin_get_var_int(dev, false, |
| 566 | "eldo1_ctrl_shift", | 672 | "eldo1_ctrl_shift", |
| 567 | ELDO1_CTRL_SHIFT); | 673 | ELDO1_CTRL_SHIFT); |
| 568 | gmin_subdevs[i].eldo2_1p8v = gmin_get_var_int(dev, false, | 674 | gs->eldo2_1p8v = gmin_get_var_int(dev, false, |
| 569 | "eldo2_1p8v", | 675 | "eldo2_1p8v", |
| 570 | ELDO2_1P8V); | 676 | ELDO2_1P8V); |
| 571 | gmin_subdevs[i].eldo2_sel_reg = gmin_get_var_int(dev, false, | 677 | gs->eldo2_sel_reg = gmin_get_var_int(dev, false, |
| 572 | "eldo2_sel_reg", | 678 | "eldo2_sel_reg", |
| 573 | ELDO2_SEL_REG); | 679 | ELDO2_SEL_REG); |
| 574 | gmin_subdevs[i].eldo2_ctrl_shift = gmin_get_var_int(dev, false, | 680 | gs->eldo2_ctrl_shift = gmin_get_var_int(dev, false, |
| 575 | "eldo2_ctrl_shift", | 681 | "eldo2_ctrl_shift", |
| 576 | ELDO2_CTRL_SHIFT); | 682 | ELDO2_CTRL_SHIFT); |
| 577 | gmin_subdevs[i].pwm_i2c_addr = power->addr; | ||
| 578 | break; | 683 | break; |
| 579 | 684 | ||
| 580 | default: | 685 | default: |
| 581 | break; | 686 | break; |
| 582 | } | 687 | } |
| 583 | 688 | ||
| 584 | return &gmin_subdevs[i]; | 689 | return 0; |
| 585 | } | 690 | } |
| 586 | 691 | ||
| 587 | static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev) | 692 | static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev) |
| @@ -591,7 +696,17 @@ static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev) · 3 unmodified lines | |||
| 591 | for (i = 0; i < MAX_SUBDEVS; i++) | 696 | for (i = 0; i < MAX_SUBDEVS; i++) |
| 592 | if (gmin_subdevs[i].subdev == subdev) | 697 | if (gmin_subdevs[i].subdev == subdev) |
| 593 | return &gmin_subdevs[i]; | 698 | return &gmin_subdevs[i]; |
| 594 | return gmin_subdev_add(subdev); | 699 | return NULL; |
| 700 | } | ||
| 701 | |||
| 702 | static struct gmin_subdev *find_free_gmin_subdev_slot(void) | ||
| 703 | { | ||
| 704 | unsigned int i; | ||
| 705 | |||
| 706 | for (i = 0; i < MAX_SUBDEVS; i++) | ||
| 707 | if (gmin_subdevs[i].subdev == NULL) | ||
| 708 | return &gmin_subdevs[i]; | ||
| 709 | return NULL; | ||
| 595 | } | 710 | } |
| 596 | 711 | ||
| 597 | static int axp_regulator_set(struct device *dev, struct gmin_subdev *gs, | 712 | static int axp_regulator_set(struct device *dev, struct gmin_subdev *gs, |
| @@ -700,32 +815,24 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on) · 102 unmodified lines | |||
| 700 | { | 815 | { |
| 701 | struct gmin_subdev *gs = find_gmin_subdev(subdev); | 816 | struct gmin_subdev *gs = find_gmin_subdev(subdev); |
| 702 | int ret; | 817 | int ret; |
| 703 | struct device *dev; | ||
| 704 | struct i2c_client *client = v4l2_get_subdevdata(subdev); | ||
| 705 | int value; | 818 | int value; |
| 706 | 819 | ||
| 707 | dev = &client->dev; | 820 | if (gs->v1p8_gpio >= 0) { |
| 708 | 821 | pr_info("atomisp_gmin_platform: 1.8v power on GPIO %d\n", | |
| 709 | if (v1p8_gpio == V1P8_GPIO_UNSET) { | 822 | gs->v1p8_gpio); |
| 710 | v1p8_gpio = gmin_get_var_int(dev, true, | 823 | ret = gpio_request(gs->v1p8_gpio, "camera_v1p8_en"); |
| 711 | "V1P8GPIO", V1P8_GPIO_NONE); | 824 | if (!ret) |
| 712 | if (v1p8_gpio != V1P8_GPIO_NONE) { | 825 | ret = gpio_direction_output(gs->v1p8_gpio, 0); |
| 713 | pr_info("atomisp_gmin_platform: 1.8v power on GPIO %d\n", | 826 | if (ret) |
| 714 | v1p8_gpio); | 827 | pr_err("V1P8 GPIO initialization failed\n"); |
| 715 | ret = gpio_request(v1p8_gpio, "camera_v1p8_en"); | ||
| 716 | if (!ret) | ||
| 717 | ret = gpio_direction_output(v1p8_gpio, 0); | ||
| 718 | if (ret) | ||
| 719 | pr_err("V1P8 GPIO initialization failed\n"); | ||
| 720 | } | ||
| 721 | } | 828 | } |
| 722 | 829 | ||
| 723 | if (!gs || gs->v1p8_on == on) | 830 | if (!gs || gs->v1p8_on == on) |
| 724 | return 0; | 831 | return 0; |
| 725 | gs->v1p8_on = on; | 832 | gs->v1p8_on = on; |
| 726 | 833 | ||
| 727 | if (v1p8_gpio >= 0) | 834 | if (gs->v1p8_gpio >= 0) |
| 728 | gpio_set_value(v1p8_gpio, on); | 835 | gpio_set_value(gs->v1p8_gpio, on); |
| 729 | 836 | ||
| 730 | if (gs->v1p8_reg) { | 837 | if (gs->v1p8_reg) { |
| 731 | regulator_set_voltage(gs->v1p8_reg, 1800000, 1800000); | 838 | regulator_set_voltage(gs->v1p8_reg, 1800000, 1800000); |
| @@ -762,32 +869,24 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on) · 30 unmodified lines | |||
| 762 | { | 869 | { |
| 763 | struct gmin_subdev *gs = find_gmin_subdev(subdev); | 870 | struct gmin_subdev *gs = find_gmin_subdev(subdev); |
| 764 | int ret; | 871 | int ret; |
| 765 | struct device *dev; | ||
| 766 | struct i2c_client *client = v4l2_get_subdevdata(subdev); | ||
| 767 | int value; | 872 | int value; |
| 768 | 873 | ||
| 769 | dev = &client->dev; | 874 | if (gs->v2p8_gpio >= 0) { |
| 770 | 875 | pr_info("atomisp_gmin_platform: 2.8v power on GPIO %d\n", | |
| 771 | if (v2p8_gpio == V2P8_GPIO_UNSET) { | 876 | gs->v2p8_gpio); |
| 772 | v2p8_gpio = gmin_get_var_int(dev, true, | 877 | ret = gpio_request(gs->v2p8_gpio, "camera_v2p8"); |
| 773 | "V2P8GPIO", V2P8_GPIO_NONE); | 878 | if (!ret) |
| 774 | if (v2p8_gpio != V2P8_GPIO_NONE) { | 879 | ret = gpio_direction_output(gs->v2p8_gpio, 0); |
| 775 | pr_info("atomisp_gmin_platform: 2.8v power on GPIO %d\n", | 880 | if (ret) |
| 776 | v2p8_gpio); | 881 | pr_err("V2P8 GPIO initialization failed\n"); |
| 777 | ret = gpio_request(v2p8_gpio, "camera_v2p8"); | ||
| 778 | if (!ret) | ||
| 779 | ret = gpio_direction_output(v2p8_gpio, 0); | ||
| 780 | if (ret) | ||
| 781 | pr_err("V2P8 GPIO initialization failed\n"); | ||
| 782 | } | ||
| 783 | } | 882 | } |
| 784 | 883 | ||
| 785 | if (!gs || gs->v2p8_on == on) | 884 | if (!gs || gs->v2p8_on == on) |
| 786 | return 0; | 885 | return 0; |
| 787 | gs->v2p8_on = on; | 886 | gs->v2p8_on = on; |
| 788 | 887 | ||
| 789 | if (v2p8_gpio >= 0) | 888 | if (gs->v2p8_gpio >= 0) |
| 790 | gpio_set_value(v2p8_gpio, on); | 889 | gpio_set_value(gs->v2p8_gpio, on); |
| 791 | 890 | ||
| 792 | if (gs->v2p8_reg) { | 891 | if (gs->v2p8_reg) { |
| 793 | regulator_set_voltage(gs->v2p8_reg, 2900000, 2900000); | 892 | regulator_set_voltage(gs->v2p8_reg, 2900000, 2900000); |
| @@ -819,6 +918,37 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on) · 25 unmodified lines | |||
| 819 | return -EINVAL; | 918 | return -EINVAL; |
| 820 | } | 919 | } |
| 821 | 920 | ||
| 921 | static int gmin_acpi_pm_ctrl(struct v4l2_subdev *subdev, int on) | ||
| 922 | { | ||
| 923 | int ret = 0; | ||
| 924 | struct gmin_subdev *gs = find_gmin_subdev(subdev); | ||
| 925 | struct i2c_client *client = v4l2_get_subdevdata(subdev); | ||
| 926 | struct acpi_device *adev = ACPI_COMPANION(&client->dev); | ||
| 927 | |||
| 928 | /* Use the ACPI power management to control it */ | ||
| 929 | on = !!on; | ||
| 930 | if (gs->clock_on == on) | ||
| 931 | return 0; | ||
| 932 | |||
| 933 | dev_dbg(subdev->dev, "Setting power state to %s\n", | ||
| 934 | on ? "on" : "off"); | ||
| 935 | |||
| 936 | if (on) | ||
| 937 | ret = acpi_device_set_power(adev, | ||
| 938 | ACPI_STATE_D0); | ||
| 939 | else | ||
| 940 | ret = acpi_device_set_power(adev, | ||
| 941 | ACPI_STATE_D3_COLD); | ||
| 942 | |||
| 943 | if (!ret) | ||
| 944 | gs->clock_on = on; | ||
| 945 | else | ||
| 946 | dev_err(subdev->dev, "Couldn't set power state to %s\n", | ||
| 947 | on ? "on" : "off"); | ||
| 948 | |||
| 949 | return ret; | ||
| 950 | } | ||
| 951 | |||
| 822 | static int gmin_flisclk_ctrl(struct v4l2_subdev *subdev, int on) | 952 | static int gmin_flisclk_ctrl(struct v4l2_subdev *subdev, int on) |
| 823 | { | 953 | { |
| 824 | int ret = 0; | 954 | int ret = 0; |
| @@ -884,7 +1014,7 @@ static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev, · 59 unmodified lines | |||
| 884 | return NULL; | 1014 | return NULL; |
| 885 | } | 1015 | } |
| 886 | 1016 | ||
| 887 | static struct camera_sensor_platform_data gmin_plat = { | 1017 | static struct camera_sensor_platform_data pmic_gmin_plat = { |
| 888 | .gpio0_ctrl = gmin_gpio0_ctrl, | 1018 | .gpio0_ctrl = gmin_gpio0_ctrl, |
| 889 | .gpio1_ctrl = gmin_gpio1_ctrl, | 1019 | .gpio1_ctrl = gmin_gpio1_ctrl, |
| 890 | .v1p8_ctrl = gmin_v1p8_ctrl, | 1020 | .v1p8_ctrl = gmin_v1p8_ctrl, |
| @@ -895,17 +1025,36 @@ static struct camera_sensor_platform_data gmin_plat = { · 4 unmodified lines | |||
| 895 | .get_vcm_ctrl = gmin_get_vcm_ctrl, | 1025 | .get_vcm_ctrl = gmin_get_vcm_ctrl, |
| 896 | }; | 1026 | }; |
| 897 | 1027 | ||
| 1028 | static struct camera_sensor_platform_data acpi_gmin_plat = { | ||
| 1029 | .gpio0_ctrl = gmin_gpio0_ctrl, | ||
| 1030 | .gpio1_ctrl = gmin_gpio1_ctrl, | ||
| 1031 | .v1p8_ctrl = gmin_acpi_pm_ctrl, | ||
| 1032 | .v2p8_ctrl = gmin_acpi_pm_ctrl, | ||
| 1033 | .v1p2_ctrl = gmin_acpi_pm_ctrl, | ||
| 1034 | .flisclk_ctrl = gmin_acpi_pm_ctrl, | ||
| 1035 | .csi_cfg = gmin_csi_cfg, | ||
| 1036 | .get_vcm_ctrl = gmin_get_vcm_ctrl, | ||
| 1037 | }; | ||
| 1038 | |||
| 898 | struct camera_sensor_platform_data *gmin_camera_platform_data( | 1039 | struct camera_sensor_platform_data *gmin_camera_platform_data( |
| 899 | struct v4l2_subdev *subdev, | 1040 | struct v4l2_subdev *subdev, |
| 900 | enum atomisp_input_format csi_format, | 1041 | enum atomisp_input_format csi_format, |
| 901 | enum atomisp_bayer_order csi_bayer) | 1042 | enum atomisp_bayer_order csi_bayer) |
| 902 | { | 1043 | { |
| 903 | struct gmin_subdev *gs = find_gmin_subdev(subdev); | 1044 | u8 pmic_i2c_addr = gmin_detect_pmic(subdev); |
| 1045 | struct gmin_subdev *gs; | ||
| 904 | 1046 | ||
| 1047 | gs = find_free_gmin_subdev_slot(); | ||
| 1048 | gs->subdev = subdev; | ||
| 905 | gs->csi_fmt = csi_format; | 1049 | gs->csi_fmt = csi_format; |
| 906 | gs->csi_bayer = csi_bayer; | 1050 | gs->csi_bayer = csi_bayer; |
| 1051 | gs->pwm_i2c_addr = pmic_i2c_addr; | ||
| 907 | 1052 | ||
| 908 | return &gmin_plat; | 1053 | gmin_subdev_add(gs); |
| 1054 | if (gs->pmc_clk) | ||
| 1055 | return &pmic_gmin_plat; | ||
| 1056 | else | ||
| 1057 | return &acpi_gmin_plat; | ||
| 909 | } | 1058 | } |
| 910 | EXPORT_SYMBOL_GPL(gmin_camera_platform_data); | 1059 | EXPORT_SYMBOL_GPL(gmin_camera_platform_data); |
| 911 | 1060 | ||
| @@ -957,12 +1106,28 @@ static int gmin_get_config_dsm_var(struct device *dev, · 45 unmodified lines | |||
| 957 | union acpi_object *obj, *cur = NULL; | 1106 | union acpi_object *obj, *cur = NULL; |
| 958 | int i; | 1107 | int i; |
| 959 | 1108 | ||
| 1109 | /* | ||
| 1110 | * The data reported by "CamClk" seems to be either 0 or 1 at the | ||
| 1111 | * _DSM table. | ||
| 1112 | * | ||
| 1113 | * At the ACPI tables we looked so far, this is not related to the | ||
| 1114 | * actual clock source for the sensor, which is given by the | ||
| 1115 | * _PR0 ACPI table. So, ignore it, as otherwise this will be | ||
| 1116 | * set to a wrong value. | ||
| 1117 | */ | ||
| 1118 | if (!strcmp(var, "CamClk")) | ||
| 1119 | return -EINVAL; | ||
| 1120 | |||
| 960 | obj = acpi_evaluate_dsm(handle, &atomisp_dsm_guid, 0, 0, NULL); | 1121 | obj = acpi_evaluate_dsm(handle, &atomisp_dsm_guid, 0, 0, NULL); |
| 961 | if (!obj) { | 1122 | if (!obj) { |
| 962 | dev_info_once(dev, "Didn't find ACPI _DSM table.\n"); | 1123 | dev_info_once(dev, "Didn't find ACPI _DSM table.\n"); |
| 963 | return -EINVAL; | 1124 | return -EINVAL; |
| 964 | } | 1125 | } |
| 965 | 1126 | ||
| 1127 | /* Return on unexpected object type */ | ||
| 1128 | if (obj->type != ACPI_TYPE_PACKAGE) | ||
| 1129 | return -EINVAL; | ||
| 1130 | |||
| 966 | #if 0 /* Just for debugging purposes */ | 1131 | #if 0 /* Just for debugging purposes */ |
| 967 | for (i = 0; i < obj->package.count; i++) { | 1132 | for (i = 0; i < obj->package.count; i++) { |
| 968 | union acpi_object *cur = &obj->package.elements[i]; | 1133 | union acpi_object *cur = &obj->package.elements[i]; |
| @@ -1155,10 +1320,10 @@ EXPORT_SYMBOL_GPL(camera_sensor_csi); · 186 unmodified lines | |||
| 1155 | * trying. The driver itself does direct calls to the PUNIT to manage | 1320 | * trying. The driver itself does direct calls to the PUNIT to manage |
| 1156 | * ISP power. | 1321 | * ISP power. |
| 1157 | */ | 1322 | */ |
| 1158 | static void isp_pm_cap_fixup(struct pci_dev *dev) | 1323 | static void isp_pm_cap_fixup(struct pci_dev *pdev) |
| 1159 | { | 1324 | { |
| 1160 | dev_info(&dev->dev, "Disabling PCI power management on camera ISP\n"); | 1325 | dev_info(&pdev->dev, "Disabling PCI power management on camera ISP\n"); |
| 1161 | dev->pm_cap = 0; | 1326 | pdev->pm_cap = 0; |
| 1162 | } | 1327 | } |
| 1163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0f38, isp_pm_cap_fixup); | 1328 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0f38, isp_pm_cap_fixup); |
| 1164 | 1329 | ||
| @@ -216,12 +216,12 @@ struct atomisp_sw_contex { · 215 unmodified lines | |||
| 216 | * ci device struct | 216 | * ci device struct |
| 217 | */ | 217 | */ |
| 218 | struct atomisp_device { | 218 | struct atomisp_device { |
| 219 | struct pci_dev *pdev; | ||
| 220 | struct device *dev; | 219 | struct device *dev; |
| 221 | struct v4l2_device v4l2_dev; | 220 | struct v4l2_device v4l2_dev; |
| 222 | struct media_device media_dev; | 221 | struct media_device media_dev; |
| 223 | struct atomisp_platform_data *pdata; | 222 | struct atomisp_platform_data *pdata; |
| 224 | void *mmu_l1_base; | 223 | void *mmu_l1_base; |
| 224 | void __iomem *base; | ||
| 225 | const struct firmware *firmware; | 225 | const struct firmware *firmware; |
| 226 | 226 | ||
| 227 | struct pm_qos_request pm_qos; | 227 | struct pm_qos_request pm_qos; |
| @@ -549,8 +549,7 @@ static int atomisp_querycap(struct file *file, void *fh, · 548 unmodified lines | |||
| 549 | 549 | ||
| 550 | strscpy(cap->driver, DRIVER, sizeof(cap->driver)); | 550 | strscpy(cap->driver, DRIVER, sizeof(cap->driver)); |
| 551 | strscpy(cap->card, CARD, sizeof(cap->card)); | 551 | strscpy(cap->card, CARD, sizeof(cap->card)); |
| 552 | snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", | 552 | snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(isp->dev)); |
| 553 | pci_name(isp->pdev)); | ||
| 554 | 553 | ||
| 555 | return 0; | 554 | return 0; |
| 556 | } | 555 | } |
| @@ -1635,6 +1634,7 @@ static int atomisp_streamon(struct file *file, void *fh, · 1078 unmodified lines | |||
| 1635 | struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); | 1634 | struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); |
| 1636 | struct atomisp_sub_device *asd = pipe->asd; | 1635 | struct atomisp_sub_device *asd = pipe->asd; |
| 1637 | struct atomisp_device *isp = video_get_drvdata(vdev); | 1636 | struct atomisp_device *isp = video_get_drvdata(vdev); |
| 1637 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 1638 | enum ia_css_pipe_id css_pipe_id; | 1638 | enum ia_css_pipe_id css_pipe_id; |
| 1639 | unsigned int sensor_start_stream; | 1639 | unsigned int sensor_start_stream; |
| 1640 | unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION; | 1640 | unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION; |
| @@ -1844,9 +1844,8 @@ start_sensor: · 203 unmodified lines | |||
| 1844 | /* Enable the CSI interface on ANN B0/K0 */ | 1844 | /* Enable the CSI interface on ANN B0/K0 */ |
| 1845 | if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << | 1845 | if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << |
| 1846 | ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { | 1846 | ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { |
| 1847 | pci_write_config_word(isp->pdev, MRFLD_PCI_CSI_CONTROL, | 1847 | pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, |
| 1848 | isp->saved_regs.csi_control | | 1848 | isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY); |
| 1849 | MRFLD_PCI_CSI_CONTROL_CSI_READY); | ||
| 1850 | } | 1849 | } |
| 1851 | 1850 | ||
| 1852 | /* stream on the sensor */ | 1851 | /* stream on the sensor */ |
| @@ -1891,6 +1890,7 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) · 38 unmodified lines | |||
| 1891 | { | 1890 | { |
| 1892 | struct video_device *vdev = video_devdata(file); | 1891 | struct video_device *vdev = video_devdata(file); |
| 1893 | struct atomisp_device *isp = video_get_drvdata(vdev); | 1892 | struct atomisp_device *isp = video_get_drvdata(vdev); |
| 1893 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 1894 | struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); | 1894 | struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); |
| 1895 | struct atomisp_sub_device *asd = pipe->asd; | 1895 | struct atomisp_sub_device *asd = pipe->asd; |
| 1896 | struct atomisp_video_pipe *capture_pipe = NULL; | 1896 | struct atomisp_video_pipe *capture_pipe = NULL; |
| @@ -2076,9 +2076,8 @@ stopsensor: · 179 unmodified lines | |||
| 2076 | /* Disable the CSI interface on ANN B0/K0 */ | 2076 | /* Disable the CSI interface on ANN B0/K0 */ |
| 2077 | if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << | 2077 | if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << |
| 2078 | ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { | 2078 | ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { |
| 2079 | pci_write_config_word(isp->pdev, MRFLD_PCI_CSI_CONTROL, | 2079 | pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, |
| 2080 | isp->saved_regs.csi_control & | 2080 | isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY); |
| 2081 | ~MRFLD_PCI_CSI_CONTROL_CSI_READY); | ||
| 2082 | } | 2081 | } |
| 2083 | 2082 | ||
| 2084 | if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false)) | 2083 | if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false)) |
| @@ -2111,8 +2110,8 @@ stopsensor: · 26 unmodified lines | |||
| 2111 | } | 2110 | } |
| 2112 | 2111 | ||
| 2113 | /* disable PUNIT/ISP acknowlede/handshake - SRSE=3 */ | 2112 | /* disable PUNIT/ISP acknowlede/handshake - SRSE=3 */ |
| 2114 | pci_write_config_dword(isp->pdev, PCI_I_CONTROL, isp->saved_regs.i_control | | 2113 | pci_write_config_dword(pdev, PCI_I_CONTROL, |
| 2115 | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); | 2114 | isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); |
| 2116 | dev_err(isp->dev, "atomisp_reset"); | 2115 | dev_err(isp->dev, "atomisp_reset"); |
| 2117 | atomisp_reset(isp); | 2116 | atomisp_reset(isp); |
| 2118 | for (i = 0; i < isp->num_of_streams; i++) { | 2117 | for (i = 0; i < isp->num_of_streams; i++) { |
| @@ -127,8 +127,6 @@ MODULE_PARM_DESC(pad_h, "extra data for ISP processing"); · 126 unmodified lines | |||
| 127 | 127 | ||
| 128 | struct device *atomisp_dev; | 128 | struct device *atomisp_dev; |
| 129 | 129 | ||
| 130 | void __iomem *atomisp_io_base; | ||
| 131 | |||
| 132 | static const struct atomisp_freq_scaling_rule dfs_rules_merr[] = { | 130 | static const struct atomisp_freq_scaling_rule dfs_rules_merr[] = { |
| 133 | { | 131 | { |
| 134 | .width = ISP_FREQ_RULE_ANY, | 132 | .width = ISP_FREQ_RULE_ANY, |
| @@ -512,30 +510,27 @@ void atomisp_acc_unregister(struct atomisp_acc_pipe *video) · 377 unmodified lines | |||
| 512 | 510 | ||
| 513 | static int atomisp_save_iunit_reg(struct atomisp_device *isp) | 511 | static int atomisp_save_iunit_reg(struct atomisp_device *isp) |
| 514 | { | 512 | { |
| 515 | struct pci_dev *dev = isp->pdev; | 513 | struct pci_dev *pdev = to_pci_dev(isp->dev); |
| 516 | 514 | ||
| 517 | dev_dbg(isp->dev, "%s\n", __func__); | 515 | dev_dbg(isp->dev, "%s\n", __func__); |
| 518 | 516 | ||
| 519 | pci_read_config_word(dev, PCI_COMMAND, &isp->saved_regs.pcicmdsts); | 517 | pci_read_config_word(pdev, PCI_COMMAND, &isp->saved_regs.pcicmdsts); |
| 520 | /* isp->saved_regs.ispmmadr is set from the atomisp_pci_probe() */ | 518 | /* isp->saved_regs.ispmmadr is set from the atomisp_pci_probe() */ |
| 521 | pci_read_config_dword(dev, PCI_MSI_CAPID, &isp->saved_regs.msicap); | 519 | pci_read_config_dword(pdev, PCI_MSI_CAPID, &isp->saved_regs.msicap); |
| 522 | pci_read_config_dword(dev, PCI_MSI_ADDR, &isp->saved_regs.msi_addr); | 520 | pci_read_config_dword(pdev, PCI_MSI_ADDR, &isp->saved_regs.msi_addr); |
| 523 | pci_read_config_word(dev, PCI_MSI_DATA, &isp->saved_regs.msi_data); | 521 | pci_read_config_word(pdev, PCI_MSI_DATA, &isp->saved_regs.msi_data); |
| 524 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &isp->saved_regs.intr); | 522 | pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &isp->saved_regs.intr); |
| 525 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, | 523 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &isp->saved_regs.interrupt_control); |
| 526 | &isp->saved_regs.interrupt_control); | 524 | |
| 527 | 525 | pci_read_config_dword(pdev, MRFLD_PCI_PMCS, &isp->saved_regs.pmcs); | |
| 528 | pci_read_config_dword(dev, MRFLD_PCI_PMCS, | ||
| 529 | &isp->saved_regs.pmcs); | ||
| 530 | /* Ensure read/write combining is enabled. */ | 526 | /* Ensure read/write combining is enabled. */ |
| 531 | pci_read_config_dword(dev, PCI_I_CONTROL, | 527 | pci_read_config_dword(pdev, PCI_I_CONTROL, &isp->saved_regs.i_control); |
| 532 | &isp->saved_regs.i_control); | ||
| 533 | isp->saved_regs.i_control |= | 528 | isp->saved_regs.i_control |= |
| 534 | MRFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING | | 529 | MRFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING | |
| 535 | MRFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING; | 530 | MRFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING; |
| 536 | pci_read_config_dword(dev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL, | 531 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL, |
| 537 | &isp->saved_regs.csi_access_viol); | 532 | &isp->saved_regs.csi_access_viol); |
| 538 | pci_read_config_dword(dev, MRFLD_PCI_CSI_RCOMP_CONTROL, | 533 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_RCOMP_CONTROL, |
| 539 | &isp->saved_regs.csi_rcomp_config); | 534 | &isp->saved_regs.csi_rcomp_config); |
| 540 | /* | 535 | /* |
| 541 | * Hardware bugs require setting CSI_HS_OVR_CLK_GATE_ON_UPDATE. | 536 | * Hardware bugs require setting CSI_HS_OVR_CLK_GATE_ON_UPDATE. |
| @@ -545,65 +540,58 @@ static int atomisp_save_iunit_reg(struct atomisp_device *isp) · 3 unmodified lines | |||
| 545 | * is missed, and IUNIT can hang. | 540 | * is missed, and IUNIT can hang. |
| 546 | * For both issues, setting this bit is a workaround. | 541 | * For both issues, setting this bit is a workaround. |
| 547 | */ | 542 | */ |
| 548 | isp->saved_regs.csi_rcomp_config |= | 543 | isp->saved_regs.csi_rcomp_config |= MRFLD_PCI_CSI_HS_OVR_CLK_GATE_ON_UPDATE; |
| 549 | MRFLD_PCI_CSI_HS_OVR_CLK_GATE_ON_UPDATE; | 544 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, |
| 550 | pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, | ||
| 551 | &isp->saved_regs.csi_afe_dly); | 545 | &isp->saved_regs.csi_afe_dly); |
| 552 | pci_read_config_dword(dev, MRFLD_PCI_CSI_CONTROL, | 546 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, |
| 553 | &isp->saved_regs.csi_control); | 547 | &isp->saved_regs.csi_control); |
| 554 | if (isp->media_dev.hw_revision >= | 548 | if (isp->media_dev.hw_revision >= |
| 555 | (ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT)) | 549 | (ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT)) |
| 556 | isp->saved_regs.csi_control |= | 550 | isp->saved_regs.csi_control |= MRFLD_PCI_CSI_CONTROL_PARPATHEN; |
| 557 | MRFLD_PCI_CSI_CONTROL_PARPATHEN; | ||
| 558 | /* | 551 | /* |
| 559 | * On CHT CSI_READY bit should be enabled before stream on | 552 | * On CHT CSI_READY bit should be enabled before stream on |
| 560 | */ | 553 | */ |
| 561 | if (IS_CHT && (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << | 554 | if (IS_CHT && (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << |
| 562 | ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0))) | 555 | ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0))) |
| 563 | isp->saved_regs.csi_control |= | 556 | isp->saved_regs.csi_control |= MRFLD_PCI_CSI_CONTROL_CSI_READY; |
| 564 | MRFLD_PCI_CSI_CONTROL_CSI_READY; | 557 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL, |
| 565 | pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL, | ||
| 566 | &isp->saved_regs.csi_afe_rcomp_config); | 558 | &isp->saved_regs.csi_afe_rcomp_config); |
| 567 | pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_HS_CONTROL, | 559 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_HS_CONTROL, |
| 568 | &isp->saved_regs.csi_afe_hs_control); | 560 | &isp->saved_regs.csi_afe_hs_control); |
| 569 | pci_read_config_dword(dev, MRFLD_PCI_CSI_DEADLINE_CONTROL, | 561 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_DEADLINE_CONTROL, |
| 570 | &isp->saved_regs.csi_deadline_control); | 562 | &isp->saved_regs.csi_deadline_control); |
| 571 | return 0; | 563 | return 0; |
| 572 | } | 564 | } |
| 573 | 565 | ||
| 574 | static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp) | 566 | static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp) |
| 575 | { | 567 | { |
| 576 | struct pci_dev *dev = isp->pdev; | 568 | struct pci_dev *pdev = to_pci_dev(isp->dev); |
| 577 | 569 | ||
| 578 | dev_dbg(isp->dev, "%s\n", __func__); | 570 | dev_dbg(isp->dev, "%s\n", __func__); |
| 579 | 571 | ||
| 580 | pci_write_config_word(dev, PCI_COMMAND, isp->saved_regs.pcicmdsts); | 572 | pci_write_config_word(pdev, PCI_COMMAND, isp->saved_regs.pcicmdsts); |
| 581 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, | 573 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, isp->saved_regs.ispmmadr); |
| 582 | isp->saved_regs.ispmmadr); | 574 | pci_write_config_dword(pdev, PCI_MSI_CAPID, isp->saved_regs.msicap); |
| 583 | pci_write_config_dword(dev, PCI_MSI_CAPID, isp->saved_regs.msicap); | 575 | pci_write_config_dword(pdev, PCI_MSI_ADDR, isp->saved_regs.msi_addr); |
| 584 | pci_write_config_dword(dev, PCI_MSI_ADDR, isp->saved_regs.msi_addr); | 576 | pci_write_config_word(pdev, PCI_MSI_DATA, isp->saved_regs.msi_data); |
| 585 | pci_write_config_word(dev, PCI_MSI_DATA, isp->saved_regs.msi_data); | 577 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, isp->saved_regs.intr); |
| 586 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, isp->saved_regs.intr); | 578 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, isp->saved_regs.interrupt_control); |
| 587 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, | 579 | pci_write_config_dword(pdev, PCI_I_CONTROL, isp->saved_regs.i_control); |
| 588 | isp->saved_regs.interrupt_control); | 580 | |
| 589 | pci_write_config_dword(dev, PCI_I_CONTROL, | 581 | pci_write_config_dword(pdev, MRFLD_PCI_PMCS, isp->saved_regs.pmcs); |
| 590 | isp->saved_regs.i_control); | 582 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL, |
| 591 | |||
| 592 | pci_write_config_dword(dev, MRFLD_PCI_PMCS, | ||
| 593 | isp->saved_regs.pmcs); | ||
| 594 | pci_write_config_dword(dev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL, | ||
| 595 | isp->saved_regs.csi_access_viol); | 583 | isp->saved_regs.csi_access_viol); |
| 596 | pci_write_config_dword(dev, MRFLD_PCI_CSI_RCOMP_CONTROL, | 584 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_RCOMP_CONTROL, |
| 597 | isp->saved_regs.csi_rcomp_config); | 585 | isp->saved_regs.csi_rcomp_config); |
| 598 | pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, | 586 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, |
| 599 | isp->saved_regs.csi_afe_dly); | 587 | isp->saved_regs.csi_afe_dly); |
| 600 | pci_write_config_dword(dev, MRFLD_PCI_CSI_CONTROL, | 588 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, |
| 601 | isp->saved_regs.csi_control); | 589 | isp->saved_regs.csi_control); |
| 602 | pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL, | 590 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL, |
| 603 | isp->saved_regs.csi_afe_rcomp_config); | 591 | isp->saved_regs.csi_afe_rcomp_config); |
| 604 | pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_HS_CONTROL, | 592 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_HS_CONTROL, |
| 605 | isp->saved_regs.csi_afe_hs_control); | 593 | isp->saved_regs.csi_afe_hs_control); |
| 606 | pci_write_config_dword(dev, MRFLD_PCI_CSI_DEADLINE_CONTROL, | 594 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_DEADLINE_CONTROL, |
| 607 | isp->saved_regs.csi_deadline_control); | 595 | isp->saved_regs.csi_deadline_control); |
| 608 | 596 | ||
| 609 | /* | 597 | /* |
| @@ -619,7 +607,7 @@ static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp) · 9 unmodified lines | |||
| 619 | 607 | ||
| 620 | static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp) | 608 | static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp) |
| 621 | { | 609 | { |
| 622 | struct pci_dev *dev = isp->pdev; | 610 | struct pci_dev *pdev = to_pci_dev(isp->dev); |
| 623 | u32 irq; | 611 | u32 irq; |
| 624 | unsigned long flags; | 612 | unsigned long flags; |
| 625 | 613 | ||
| @@ -635,11 +623,11 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp) · 9 unmodified lines | |||
| 635 | * So, here we need to check if there is any pending | 623 | * So, here we need to check if there is any pending |
| 636 | * IRQ, if so, waiting for it to be served | 624 | * IRQ, if so, waiting for it to be served |
| 637 | */ | 625 | */ |
| 638 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 626 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 639 | irq = irq & 1 << INTR_IIR; | 627 | irq = irq & 1 << INTR_IIR; |
| 640 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq); | 628 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); |
| 641 | 629 | ||
| 642 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 630 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 643 | if (!(irq & (1 << INTR_IIR))) | 631 | if (!(irq & (1 << INTR_IIR))) |
| 644 | goto done; | 632 | goto done; |
| 645 | 633 | ||
| @@ -652,11 +640,11 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp) · 6 unmodified lines | |||
| 652 | spin_unlock_irqrestore(&isp->lock, flags); | 640 | spin_unlock_irqrestore(&isp->lock, flags); |
| 653 | return -EAGAIN; | 641 | return -EAGAIN; |
| 654 | } else { | 642 | } else { |
| 655 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 643 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 656 | irq = irq & 1 << INTR_IIR; | 644 | irq = irq & 1 << INTR_IIR; |
| 657 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq); | 645 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); |
| 658 | 646 | ||
| 659 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 647 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 660 | if (!(irq & (1 << INTR_IIR))) { | 648 | if (!(irq & (1 << INTR_IIR))) { |
| 661 | atomisp_css2_hw_store_32(MRFLD_INTR_ENABLE_REG, 0x0); | 649 | atomisp_css2_hw_store_32(MRFLD_INTR_ENABLE_REG, 0x0); |
| 662 | goto done; | 650 | goto done; |
| @@ -675,11 +663,11 @@ done: · 12 unmodified lines | |||
| 675 | * to IIR. It could block subsequent interrupt messages. | 663 | * to IIR. It could block subsequent interrupt messages. |
| 676 | * HW sighting:4568410. | 664 | * HW sighting:4568410. |
| 677 | */ | 665 | */ |
| 678 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 666 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 679 | irq &= ~(1 << INTR_IER); | 667 | irq &= ~(1 << INTR_IER); |
| 680 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq); | 668 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); |
| 681 | 669 | ||
| 682 | atomisp_msi_irq_uninit(isp, dev); | 670 | atomisp_msi_irq_uninit(isp); |
| 683 | atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, true); | 671 | atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, true); |
| 684 | spin_unlock_irqrestore(&isp->lock, flags); | 672 | spin_unlock_irqrestore(&isp->lock, flags); |
| 685 | 673 | ||
| @@ -755,7 +743,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) · 69 unmodified lines | |||
| 755 | 743 | ||
| 756 | /* Wait until ISPSSPM0 bit[25:24] shows the right value */ | 744 | /* Wait until ISPSSPM0 bit[25:24] shows the right value */ |
| 757 | iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, &tmp); | 745 | iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, &tmp); |
| 758 | tmp = (tmp & MRFLD_ISPSSPM0_ISPSSC_MASK) >> MRFLD_ISPSSPM0_ISPSSS_OFFSET; | 746 | tmp = (tmp >> MRFLD_ISPSSPM0_ISPSSS_OFFSET) & MRFLD_ISPSSPM0_ISPSSC_MASK; |
| 759 | if (tmp == val) { | 747 | if (tmp == val) { |
| 760 | trace_ipu_cstate(enable); | 748 | trace_ipu_cstate(enable); |
| 761 | return 0; | 749 | return 0; |
| @@ -778,15 +766,13 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) · 16 unmodified lines | |||
| 778 | /* Workaround for pmu_nc_set_power_state not ready in MRFLD */ | 766 | /* Workaround for pmu_nc_set_power_state not ready in MRFLD */ |
| 779 | int atomisp_mrfld_power_down(struct atomisp_device *isp) | 767 | int atomisp_mrfld_power_down(struct atomisp_device *isp) |
| 780 | { | 768 | { |
| 781 | // FIXME: at least with ISP2401, enabling this code causes the driver to break | 769 | return atomisp_mrfld_power(isp, false); |
| 782 | return 0 && atomisp_mrfld_power(isp, false); | ||
| 783 | } | 770 | } |
| 784 | 771 | ||
| 785 | /* Workaround for pmu_nc_set_power_state not ready in MRFLD */ | 772 | /* Workaround for pmu_nc_set_power_state not ready in MRFLD */ |
| 786 | int atomisp_mrfld_power_up(struct atomisp_device *isp) | 773 | int atomisp_mrfld_power_up(struct atomisp_device *isp) |
| 787 | { | 774 | { |
| 788 | // FIXME: at least with ISP2401, enabling this code causes the driver to break | 775 | return atomisp_mrfld_power(isp, true); |
| 789 | return 0 && atomisp_mrfld_power(isp, true); | ||
| 790 | } | 776 | } |
| 791 | 777 | ||
| 792 | int atomisp_runtime_suspend(struct device *dev) | 778 | int atomisp_runtime_suspend(struct device *dev) |
| @@ -902,6 +888,7 @@ static int __maybe_unused atomisp_resume(struct device *dev) · 109 unmodified lines | |||
| 902 | 888 | ||
| 903 | int atomisp_csi_lane_config(struct atomisp_device *isp) | 889 | int atomisp_csi_lane_config(struct atomisp_device *isp) |
| 904 | { | 890 | { |
| 891 | struct pci_dev *pdev = to_pci_dev(isp->dev); | ||
| 905 | static const struct { | 892 | static const struct { |
| 906 | u8 code; | 893 | u8 code; |
| 907 | u8 lanes[MRFLD_PORT_NUM]; | 894 | u8 lanes[MRFLD_PORT_NUM]; |
| @@ -1003,7 +990,7 @@ int atomisp_csi_lane_config(struct atomisp_device *isp) · 95 unmodified lines | |||
| 1003 | return -EINVAL; | 990 | return -EINVAL; |
| 1004 | } | 991 | } |
| 1005 | 992 | ||
| 1006 | pci_read_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, &csi_control); | 993 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, &csi_control); |
| 1007 | csi_control &= ~port_config_mask; | 994 | csi_control &= ~port_config_mask; |
| 1008 | csi_control |= (portconfigs[i].code << MRFLD_PORT_CONFIGCODE_SHIFT) | 995 | csi_control |= (portconfigs[i].code << MRFLD_PORT_CONFIGCODE_SHIFT) |
| 1009 | | (portconfigs[i].lanes[0] ? 0 : (1 << MRFLD_PORT1_ENABLE_SHIFT)) | 996 | | (portconfigs[i].lanes[0] ? 0 : (1 << MRFLD_PORT1_ENABLE_SHIFT)) |
| @@ -1013,7 +1000,7 @@ int atomisp_csi_lane_config(struct atomisp_device *isp) · 3 unmodified lines | |||
| 1013 | | (((1 << portconfigs[i].lanes[1]) - 1) << MRFLD_PORT2_LANES_SHIFT) | 1000 | | (((1 << portconfigs[i].lanes[1]) - 1) << MRFLD_PORT2_LANES_SHIFT) |
| 1014 | | (((1 << portconfigs[i].lanes[2]) - 1) << port3_lanes_shift); | 1001 | | (((1 << portconfigs[i].lanes[2]) - 1) << port3_lanes_shift); |
| 1015 | 1002 | ||
| 1016 | pci_write_config_dword(isp->pdev, MRFLD_PCI_CSI_CONTROL, csi_control); | 1003 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, csi_control); |
| 1017 | 1004 | ||
| 1018 | dev_dbg(isp->dev, | 1005 | dev_dbg(isp->dev, |
| 1019 | "%s: the portconfig is %d-%d-%d, CSI_CONTROL is 0x%08X\n", | 1006 | "%s: the portconfig is %d-%d-%d, CSI_CONTROL is 0x%08X\n", |
| @@ -1440,8 +1427,7 @@ atomisp_load_firmware(struct atomisp_device *isp) · 420 unmodified lines | |||
| 1440 | * Check for flags the driver was compiled with against the PCI | 1427 | * Check for flags the driver was compiled with against the PCI |
| 1441 | * device. Always returns true on other than ISP 2400. | 1428 | * device. Always returns true on other than ISP 2400. |
| 1442 | */ | 1429 | */ |
| 1443 | static bool is_valid_device(struct pci_dev *dev, | 1430 | static bool is_valid_device(struct pci_dev *pdev, const struct pci_device_id *id) |
| 1444 | const struct pci_device_id *id) | ||
| 1445 | { | 1431 | { |
| 1446 | unsigned int a0_max_id = 0; | 1432 | unsigned int a0_max_id = 0; |
| 1447 | const char *name; | 1433 | const char *name; |
| @@ -1465,14 +1451,14 @@ static bool is_valid_device(struct pci_dev *dev, · 17 unmodified lines | |||
| 1465 | name = "Cherrytrail"; | 1451 | name = "Cherrytrail"; |
| 1466 | break; | 1452 | break; |
| 1467 | default: | 1453 | default: |
| 1468 | dev_err(&dev->dev, "%s: unknown device ID %x04:%x04\n", | 1454 | dev_err(&pdev->dev, "%s: unknown device ID %x04:%x04\n", |
| 1469 | product, id->vendor, id->device); | 1455 | product, id->vendor, id->device); |
| 1470 | return false; | 1456 | return false; |
| 1471 | } | 1457 | } |
| 1472 | 1458 | ||
| 1473 | if (dev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) { | 1459 | if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) { |
| 1474 | dev_err(&dev->dev, "%s revision %d is not unsupported\n", | 1460 | dev_err(&pdev->dev, "%s revision %d is not unsupported\n", |
| 1475 | name, dev->revision); | 1461 | name, pdev->revision); |
| 1476 | return false; | 1462 | return false; |
| 1477 | } | 1463 | } |
| 1478 | 1464 | ||
| @@ -1483,22 +1469,20 @@ static bool is_valid_device(struct pci_dev *dev, · 4 unmodified lines | |||
| 1483 | 1469 | ||
| 1484 | #if defined(ISP2400) | 1470 | #if defined(ISP2400) |
| 1485 | if (IS_ISP2401) { | 1471 | if (IS_ISP2401) { |
| 1486 | dev_err(&dev->dev, "Support for %s (ISP2401) was disabled at compile time\n", | 1472 | dev_err(&pdev->dev, "Support for %s (ISP2401) was disabled at compile time\n", |
| 1487 | name); | 1473 | name); |
| 1488 | return false; | 1474 | return false; |
| 1489 | } | 1475 | } |
| 1490 | #else | 1476 | #else |
| 1491 | if (!IS_ISP2401) { | 1477 | if (!IS_ISP2401) { |
| 1492 | dev_err(&dev->dev, "Support for %s (ISP2400) was disabled at compile time\n", | 1478 | dev_err(&pdev->dev, "Support for %s (ISP2400) was disabled at compile time\n", |
| 1493 | name); | 1479 | name); |
| 1494 | return false; | 1480 | return false; |
| 1495 | } | 1481 | } |
| 1496 | #endif | 1482 | #endif |
| 1497 | 1483 | ||
| 1498 | dev_info(&dev->dev, "Detected %s version %d (ISP240%c) on %s\n", | 1484 | dev_info(&pdev->dev, "Detected %s version %d (ISP240%c) on %s\n", |
| 1499 | name, dev->revision, | 1485 | name, pdev->revision, IS_ISP2401 ? '1' : '0', product); |
| 1500 | IS_ISP2401 ? '1' : '0', | ||
| 1501 | product); | ||
| 1502 | 1486 | ||
| 1503 | return true; | 1487 | return true; |
| 1504 | } | 1488 | } |
| @@ -1538,66 +1522,60 @@ alloc_fail: · 33 unmodified lines | |||
| 1538 | 1522 | ||
| 1539 | #define ATOM_ISP_PCI_BAR 0 | 1523 | #define ATOM_ISP_PCI_BAR 0 |
| 1540 | 1524 | ||
| 1541 | static int atomisp_pci_probe(struct pci_dev *dev, | 1525 | static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
| 1542 | const struct pci_device_id *id) | ||
| 1543 | { | 1526 | { |
| 1544 | const struct atomisp_platform_data *pdata; | 1527 | const struct atomisp_platform_data *pdata; |
| 1545 | struct atomisp_device *isp; | 1528 | struct atomisp_device *isp; |
| 1546 | unsigned int start; | 1529 | unsigned int start; |
| 1547 | void __iomem *base; | ||
| 1548 | int err, val; | 1530 | int err, val; |
| 1549 | u32 irq; | 1531 | u32 irq; |
| 1550 | 1532 | ||
| 1551 | if (!is_valid_device(dev, id)) | 1533 | if (!is_valid_device(pdev, id)) |
| 1552 | return -ENODEV; | 1534 | return -ENODEV; |
| 1553 | 1535 | ||
| 1554 | /* Pointer to struct device. */ | 1536 | /* Pointer to struct device. */ |
| 1555 | atomisp_dev = &dev->dev; | 1537 | atomisp_dev = &pdev->dev; |
| 1556 | 1538 | ||
| 1557 | pdata = atomisp_get_platform_data(); | 1539 | pdata = atomisp_get_platform_data(); |
| 1558 | if (!pdata) | 1540 | if (!pdata) |
| 1559 | dev_warn(&dev->dev, "no platform data available\n"); | 1541 | dev_warn(&pdev->dev, "no platform data available\n"); |
| 1560 | 1542 | ||
| 1561 | err = pcim_enable_device(dev); | 1543 | err = pcim_enable_device(pdev); |
| 1562 | if (err) { | 1544 | if (err) { |
| 1563 | dev_err(&dev->dev, "Failed to enable CI ISP device (%d)\n", | 1545 | dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n", err); |
| 1564 | err); | ||
| 1565 | return err; | 1546 | return err; |
| 1566 | } | 1547 | } |
| 1567 | 1548 | ||
| 1568 | start = pci_resource_start(dev, ATOM_ISP_PCI_BAR); | 1549 | start = pci_resource_start(pdev, ATOM_ISP_PCI_BAR); |
| 1569 | dev_dbg(&dev->dev, "start: 0x%x\n", start); | 1550 | dev_dbg(&pdev->dev, "start: 0x%x\n", start); |
| 1570 | 1551 | ||
| 1571 | err = pcim_iomap_regions(dev, 1 << ATOM_ISP_PCI_BAR, pci_name(dev)); | 1552 | err = pcim_iomap_regions(pdev, 1 << ATOM_ISP_PCI_BAR, pci_name(pdev)); |
| 1572 | if (err) { | 1553 | if (err) { |
| 1573 | dev_err(&dev->dev, "Failed to I/O memory remapping (%d)\n", | 1554 | dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err); |
| 1574 | err); | ||
| 1575 | goto ioremap_fail; | 1555 | goto ioremap_fail; |
| 1576 | } | 1556 | } |
| 1577 | 1557 | ||
| 1578 | base = pcim_iomap_table(dev)[ATOM_ISP_PCI_BAR]; | 1558 | isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); |
| 1579 | dev_dbg(&dev->dev, "base: %p\n", base); | ||
| 1580 | |||
| 1581 | atomisp_io_base = base; | ||
| 1582 | |||
| 1583 | dev_dbg(&dev->dev, "atomisp_io_base: %p\n", atomisp_io_base); | ||
| 1584 | |||
| 1585 | isp = devm_kzalloc(&dev->dev, sizeof(struct atomisp_device), GFP_KERNEL); | ||
| 1586 | if (!isp) { | 1559 | if (!isp) { |
| 1587 | err = -ENOMEM; | 1560 | err = -ENOMEM; |
| 1588 | goto atomisp_dev_alloc_fail; | 1561 | goto atomisp_dev_alloc_fail; |
| 1589 | } | 1562 | } |
| 1590 | isp->pdev = dev; | 1563 | |
| 1591 | isp->dev = &dev->dev; | 1564 | isp->dev = &pdev->dev; |
| 1565 | isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR]; | ||
| 1592 | isp->sw_contex.power_state = ATOM_ISP_POWER_UP; | 1566 | isp->sw_contex.power_state = ATOM_ISP_POWER_UP; |
| 1593 | isp->saved_regs.ispmmadr = start; | 1567 | isp->saved_regs.ispmmadr = start; |
| 1594 | 1568 | ||
| 1569 | dev_dbg(&pdev->dev, "atomisp mmio base: %p\n", isp->base); | ||
| 1570 | |||
| 1595 | rt_mutex_init(&isp->mutex); | 1571 | rt_mutex_init(&isp->mutex); |
| 1596 | mutex_init(&isp->streamoff_mutex); | 1572 | mutex_init(&isp->streamoff_mutex); |
| 1597 | spin_lock_init(&isp->lock); | 1573 | spin_lock_init(&isp->lock); |
| 1598 | 1574 | ||
| 1599 | /* This is not a true PCI device on SoC, so the delay is not needed. */ | 1575 | /* This is not a true PCI device on SoC, so the delay is not needed. */ |
| 1600 | isp->pdev->d3_delay = 0; | 1576 | pdev->d3_delay = 0; |
| 1577 | |||
| 1578 | pci_set_drvdata(pdev, isp); | ||
| 1601 | 1579 | ||
| 1602 | switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { | 1580 | switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { |
| 1603 | case ATOMISP_PCI_DEVICE_SOC_MRFLD: | 1581 | case ATOMISP_PCI_DEVICE_SOC_MRFLD: |
| @@ -1648,15 +1626,14 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 44 unmodified lines | |||
| 1648 | * have specs yet for exactly how it varies. Default to | 1626 | * have specs yet for exactly how it varies. Default to |
| 1649 | * BYT-CR but let provisioning set it via EFI variable | 1627 | * BYT-CR but let provisioning set it via EFI variable |
| 1650 | */ | 1628 | */ |
| 1651 | isp->hpll_freq = gmin_get_var_int(&dev->dev, false, "HpllFreq", | 1629 | isp->hpll_freq = gmin_get_var_int(&pdev->dev, false, "HpllFreq", HPLL_FREQ_2000MHZ); |
| 1652 | HPLL_FREQ_2000MHZ); | ||
| 1653 | 1630 | ||
| 1654 | /* | 1631 | /* |
| 1655 | * for BYT/CHT we are put isp into D3cold to avoid pci registers access | 1632 | * for BYT/CHT we are put isp into D3cold to avoid pci registers access |
| 1656 | * in power off. Set d3cold_delay to 0 since default 100ms is not | 1633 | * in power off. Set d3cold_delay to 0 since default 100ms is not |
| 1657 | * necessary. | 1634 | * necessary. |
| 1658 | */ | 1635 | */ |
| 1659 | isp->pdev->d3cold_delay = 0; | 1636 | pdev->d3cold_delay = 0; |
| 1660 | break; | 1637 | break; |
| 1661 | case ATOMISP_PCI_DEVICE_SOC_ANN: | 1638 | case ATOMISP_PCI_DEVICE_SOC_ANN: |
| 1662 | isp->media_dev.hw_revision = ( | 1639 | isp->media_dev.hw_revision = ( |
| @@ -1666,7 +1643,7 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 3 unmodified lines | |||
| 1666 | ATOMISP_HW_REVISION_ISP2401_LEGACY | 1643 | ATOMISP_HW_REVISION_ISP2401_LEGACY |
| 1667 | #endif | 1644 | #endif |
| 1668 | << ATOMISP_HW_REVISION_SHIFT); | 1645 | << ATOMISP_HW_REVISION_SHIFT); |
| 1669 | isp->media_dev.hw_revision |= isp->pdev->revision < 2 ? | 1646 | isp->media_dev.hw_revision |= pdev->revision < 2 ? |
| 1670 | ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0; | 1647 | ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0; |
| 1671 | isp->dfs = &dfs_config_merr; | 1648 | isp->dfs = &dfs_config_merr; |
| 1672 | isp->hpll_freq = HPLL_FREQ_1600MHZ; | 1649 | isp->hpll_freq = HPLL_FREQ_1600MHZ; |
| @@ -1679,13 +1656,13 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 6 unmodified lines | |||
| 1679 | ATOMISP_HW_REVISION_ISP2401_LEGACY | 1656 | ATOMISP_HW_REVISION_ISP2401_LEGACY |
| 1680 | #endif | 1657 | #endif |
| 1681 | << ATOMISP_HW_REVISION_SHIFT); | 1658 | << ATOMISP_HW_REVISION_SHIFT); |
| 1682 | isp->media_dev.hw_revision |= isp->pdev->revision < 2 ? | 1659 | isp->media_dev.hw_revision |= pdev->revision < 2 ? |
| 1683 | ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0; | 1660 | ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0; |
| 1684 | 1661 | ||
| 1685 | isp->dfs = &dfs_config_cht; | 1662 | isp->dfs = &dfs_config_cht; |
| 1686 | isp->pdev->d3cold_delay = 0; | 1663 | pdev->d3cold_delay = 0; |
| 1687 | 1664 | ||
| 1688 | iosf_mbi_read(CCK_PORT, MBI_REG_READ, CCK_FUSE_REG_0, &val); | 1665 | iosf_mbi_read(BT_MBI_UNIT_CCK, MBI_REG_READ, CCK_FUSE_REG_0, &val); |
| 1689 | switch (val & CCK_FUSE_HPLL_FREQ_MASK) { | 1666 | switch (val & CCK_FUSE_HPLL_FREQ_MASK) { |
| 1690 | case 0x00: | 1667 | case 0x00: |
| 1691 | isp->hpll_freq = HPLL_FREQ_800MHZ; | 1668 | isp->hpll_freq = HPLL_FREQ_800MHZ; |
| @@ -1698,18 +1675,16 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 6 unmodified lines | |||
| 1698 | break; | 1675 | break; |
| 1699 | default: | 1676 | default: |
| 1700 | isp->hpll_freq = HPLL_FREQ_1600MHZ; | 1677 | isp->hpll_freq = HPLL_FREQ_1600MHZ; |
| 1701 | dev_warn(isp->dev, | 1678 | dev_warn(&pdev->dev, "read HPLL from cck failed. Default to 1600 MHz.\n"); |
| 1702 | "read HPLL from cck failed. Default to 1600 MHz.\n"); | ||
| 1703 | } | 1679 | } |
| 1704 | break; | 1680 | break; |
| 1705 | default: | 1681 | default: |
| 1706 | dev_err(&dev->dev, "un-supported IUNIT device\n"); | 1682 | dev_err(&pdev->dev, "un-supported IUNIT device\n"); |
| 1707 | err = -ENODEV; | 1683 | err = -ENODEV; |
| 1708 | goto atomisp_dev_alloc_fail; | 1684 | goto atomisp_dev_alloc_fail; |
| 1709 | } | 1685 | } |
| 1710 | 1686 | ||
| 1711 | dev_info(&dev->dev, "ISP HPLL frequency base = %d MHz\n", | 1687 | dev_info(&pdev->dev, "ISP HPLL frequency base = %d MHz\n", isp->hpll_freq); |
| 1712 | isp->hpll_freq); | ||
| 1713 | 1688 | ||
| 1714 | isp->max_isr_latency = ATOMISP_MAX_ISR_LATENCY; | 1689 | isp->max_isr_latency = ATOMISP_MAX_ISR_LATENCY; |
| 1715 | 1690 | ||
| @@ -1718,30 +1693,28 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 2 unmodified lines | |||
| 1718 | isp->firmware = atomisp_load_firmware(isp); | 1693 | isp->firmware = atomisp_load_firmware(isp); |
| 1719 | if (!isp->firmware) { | 1694 | if (!isp->firmware) { |
| 1720 | err = -ENOENT; | 1695 | err = -ENOENT; |
| 1721 | dev_dbg(&dev->dev, "Firmware load failed\n"); | 1696 | dev_dbg(&pdev->dev, "Firmware load failed\n"); |
| 1722 | goto load_fw_fail; | 1697 | goto load_fw_fail; |
| 1723 | } | 1698 | } |
| 1724 | 1699 | ||
| 1725 | err = sh_css_check_firmware_version(isp->dev, | 1700 | err = sh_css_check_firmware_version(isp->dev, isp->firmware->data); |
| 1726 | isp->firmware->data); | ||
| 1727 | if (err) { | 1701 | if (err) { |
| 1728 | dev_dbg(&dev->dev, "Firmware version check failed\n"); | 1702 | dev_dbg(&pdev->dev, "Firmware version check failed\n"); |
| 1729 | goto fw_validation_fail; | 1703 | goto fw_validation_fail; |
| 1730 | } | 1704 | } |
| 1731 | } else { | 1705 | } else { |
| 1732 | dev_info(&dev->dev, "Firmware load will be deferred\n"); | 1706 | dev_info(&pdev->dev, "Firmware load will be deferred\n"); |
| 1733 | } | 1707 | } |
| 1734 | 1708 | ||
| 1735 | pci_set_master(dev); | 1709 | pci_set_master(pdev); |
| 1736 | pci_set_drvdata(dev, isp); | ||
| 1737 | 1710 | ||
| 1738 | err = pci_enable_msi(dev); | 1711 | err = pci_enable_msi(pdev); |
| 1739 | if (err) { | 1712 | if (err) { |
| 1740 | dev_err(&dev->dev, "Failed to enable msi (%d)\n", err); | 1713 | dev_err(&pdev->dev, "Failed to enable msi (%d)\n", err); |
| 1741 | goto enable_msi_fail; | 1714 | goto enable_msi_fail; |
| 1742 | } | 1715 | } |
| 1743 | 1716 | ||
| 1744 | atomisp_msi_irq_init(isp, dev); | 1717 | atomisp_msi_irq_init(isp); |
| 1745 | 1718 | ||
| 1746 | cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); | 1719 | cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); |
| 1747 | 1720 | ||
| @@ -1762,8 +1735,7 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 14 unmodified lines | |||
| 1762 | * Workaround for imbalance data eye issue which is observed | 1735 | * Workaround for imbalance data eye issue which is observed |
| 1763 | * on TNG B0. | 1736 | * on TNG B0. |
| 1764 | */ | 1737 | */ |
| 1765 | pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, | 1738 | pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, &csi_afe_trim); |
| 1766 | &csi_afe_trim); | ||
| 1767 | csi_afe_trim &= ~((MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << | 1739 | csi_afe_trim &= ~((MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << |
| 1768 | MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) | | 1740 | MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) | |
| 1769 | (MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << | 1741 | (MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << |
| @@ -1776,20 +1748,18 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 6 unmodified lines | |||
| 1776 | MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) | | 1748 | MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) | |
| 1777 | (MRFLD_PCI_CSI3_HSRXCLKTRIM << | 1749 | (MRFLD_PCI_CSI3_HSRXCLKTRIM << |
| 1778 | MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT); | 1750 | MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT); |
| 1779 | pci_write_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, | 1751 | pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, csi_afe_trim); |
| 1780 | csi_afe_trim); | ||
| 1781 | } | 1752 | } |
| 1782 | 1753 | ||
| 1783 | err = atomisp_initialize_modules(isp); | 1754 | err = atomisp_initialize_modules(isp); |
| 1784 | if (err < 0) { | 1755 | if (err < 0) { |
| 1785 | dev_err(&dev->dev, "atomisp_initialize_modules (%d)\n", err); | 1756 | dev_err(&pdev->dev, "atomisp_initialize_modules (%d)\n", err); |
| 1786 | goto initialize_modules_fail; | 1757 | goto initialize_modules_fail; |
| 1787 | } | 1758 | } |
| 1788 | 1759 | ||
| 1789 | err = atomisp_register_entities(isp); | 1760 | err = atomisp_register_entities(isp); |
| 1790 | if (err < 0) { | 1761 | if (err < 0) { |
| 1791 | dev_err(&dev->dev, "atomisp_register_entities failed (%d)\n", | 1762 | dev_err(&pdev->dev, "atomisp_register_entities failed (%d)\n", err); |
| 1792 | err); | ||
| 1793 | goto register_entities_fail; | 1763 | goto register_entities_fail; |
| 1794 | } | 1764 | } |
| 1795 | err = atomisp_create_pads_links(isp); | 1765 | err = atomisp_create_pads_links(isp); |
| @@ -1802,24 +1772,24 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 6 unmodified lines | |||
| 1802 | /* save the iunit context only once after all the values are init'ed. */ | 1772 | /* save the iunit context only once after all the values are init'ed. */ |
| 1803 | atomisp_save_iunit_reg(isp); | 1773 | atomisp_save_iunit_reg(isp); |
| 1804 | 1774 | ||
| 1805 | pm_runtime_put_noidle(&dev->dev); | 1775 | pm_runtime_put_noidle(&pdev->dev); |
| 1806 | pm_runtime_allow(&dev->dev); | 1776 | pm_runtime_allow(&pdev->dev); |
| 1807 | 1777 | ||
| 1808 | hmm_init_mem_stat(repool_pgnr, dypool_enable, dypool_pgnr); | 1778 | hmm_init_mem_stat(repool_pgnr, dypool_enable, dypool_pgnr); |
| 1809 | err = hmm_pool_register(repool_pgnr, HMM_POOL_TYPE_RESERVED); | 1779 | err = hmm_pool_register(repool_pgnr, HMM_POOL_TYPE_RESERVED); |
| 1810 | if (err) { | 1780 | if (err) { |
| 1811 | dev_err(&dev->dev, "Failed to register reserved memory pool.\n"); | 1781 | dev_err(&pdev->dev, "Failed to register reserved memory pool.\n"); |
| 1812 | goto hmm_pool_fail; | 1782 | goto hmm_pool_fail; |
| 1813 | } | 1783 | } |
| 1814 | 1784 | ||
| 1815 | /* Init ISP memory management */ | 1785 | /* Init ISP memory management */ |
| 1816 | hmm_init(); | 1786 | hmm_init(); |
| 1817 | 1787 | ||
| 1818 | err = devm_request_threaded_irq(&dev->dev, dev->irq, | 1788 | err = devm_request_threaded_irq(&pdev->dev, pdev->irq, |
| 1819 | atomisp_isr, atomisp_isr_thread, | 1789 | atomisp_isr, atomisp_isr_thread, |
| 1820 | IRQF_SHARED, "isp_irq", isp); | 1790 | IRQF_SHARED, "isp_irq", isp); |
| 1821 | if (err) { | 1791 | if (err) { |
| 1822 | dev_err(&dev->dev, "Failed to request irq (%d)\n", err); | 1792 | dev_err(&pdev->dev, "Failed to request irq (%d)\n", err); |
| 1823 | goto request_irq_fail; | 1793 | goto request_irq_fail; |
| 1824 | } | 1794 | } |
| 1825 | 1795 | ||
| @@ -1827,23 +1797,23 @@ static int atomisp_pci_probe(struct pci_dev *dev, · 1 unmodified line | |||
| 1827 | if (!defer_fw_load) { | 1797 | if (!defer_fw_load) { |
| 1828 | err = atomisp_css_load_firmware(isp); | 1798 | err = atomisp_css_load_firmware(isp); |
| 1829 | if (err) { | 1799 | if (err) { |
| 1830 | dev_err(&dev->dev, "Failed to init css.\n"); | 1800 | dev_err(&pdev->dev, "Failed to init css.\n"); |
| 1831 | goto css_init_fail; | 1801 | goto css_init_fail; |
| 1832 | } | 1802 | } |
| 1833 | } else { | 1803 | } else { |
| 1834 | dev_dbg(&dev->dev, "Skip css init.\n"); | 1804 | dev_dbg(&pdev->dev, "Skip css init.\n"); |
| 1835 | } | 1805 | } |
| 1836 | /* Clear FW image from memory */ | 1806 | /* Clear FW image from memory */ |
| 1837 | release_firmware(isp->firmware); | 1807 | release_firmware(isp->firmware); |
| 1838 | isp->firmware = NULL; | 1808 | isp->firmware = NULL; |
| 1839 | isp->css_env.isp_css_fw.data = NULL; | 1809 | isp->css_env.isp_css_fw.data = NULL; |
| 1840 | 1810 | ||
| 1841 | atomisp_drvfs_init(&dev->driver->driver, isp); | 1811 | atomisp_drvfs_init(isp); |
| 1842 | 1812 | ||
| 1843 | return 0; | 1813 | return 0; |
| 1844 | 1814 | ||
| 1845 | css_init_fail: | 1815 | css_init_fail: |
| 1846 | devm_free_irq(&dev->dev, dev->irq, isp); | 1816 | devm_free_irq(&pdev->dev, pdev->irq, isp); |
| 1847 | request_irq_fail: | 1817 | request_irq_fail: |
| 1848 | hmm_cleanup(); | 1818 | hmm_cleanup(); |
| 1849 | hmm_pool_unregister(HMM_POOL_TYPE_RESERVED); | 1819 | hmm_pool_unregister(HMM_POOL_TYPE_RESERVED); |
| @@ -1856,8 +1826,8 @@ register_entities_fail: · 6 unmodified lines | |||
| 1856 | atomisp_uninitialize_modules(isp); | 1826 | atomisp_uninitialize_modules(isp); |
| 1857 | initialize_modules_fail: | 1827 | initialize_modules_fail: |
| 1858 | cpu_latency_qos_remove_request(&isp->pm_qos); | 1828 | cpu_latency_qos_remove_request(&isp->pm_qos); |
| 1859 | atomisp_msi_irq_uninit(isp, dev); | 1829 | atomisp_msi_irq_uninit(isp); |
| 1860 | pci_disable_msi(dev); | 1830 | pci_disable_msi(pdev); |
| 1861 | enable_msi_fail: | 1831 | enable_msi_fail: |
| 1862 | fw_validation_fail: | 1832 | fw_validation_fail: |
| 1863 | release_firmware(isp->firmware); | 1833 | release_firmware(isp->firmware); |
| @@ -1869,35 +1839,34 @@ load_fw_fail: · 5 unmodified lines | |||
| 1869 | * The following lines have been copied from atomisp suspend path | 1839 | * The following lines have been copied from atomisp suspend path |
| 1870 | */ | 1840 | */ |
| 1871 | 1841 | ||
| 1872 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 1842 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 1873 | irq = irq & 1 << INTR_IIR; | 1843 | irq = irq & 1 << INTR_IIR; |
| 1874 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq); | 1844 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); |
| 1875 | 1845 | ||
| 1876 | pci_read_config_dword(dev, PCI_INTERRUPT_CTRL, &irq); | 1846 | pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); |
| 1877 | irq &= ~(1 << INTR_IER); | 1847 | irq &= ~(1 << INTR_IER); |
| 1878 | pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, irq); | 1848 | pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); |
| 1879 | 1849 | ||
| 1880 | atomisp_msi_irq_uninit(isp, dev); | 1850 | atomisp_msi_irq_uninit(isp); |
| 1881 | 1851 | ||
| 1882 | atomisp_ospm_dphy_down(isp); | 1852 | atomisp_ospm_dphy_down(isp); |
| 1883 | 1853 | ||
| 1884 | /* Address later when we worry about the ...field chips */ | 1854 | /* Address later when we worry about the ...field chips */ |
| 1885 | if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp)) | 1855 | if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp)) |
| 1886 | dev_err(&dev->dev, "Failed to switch off ISP\n"); | 1856 | dev_err(&pdev->dev, "Failed to switch off ISP\n"); |
| 1887 | 1857 | ||
| 1888 | atomisp_dev_alloc_fail: | 1858 | atomisp_dev_alloc_fail: |
| 1889 | pcim_iounmap_regions(dev, 1 << ATOM_ISP_PCI_BAR); | 1859 | pcim_iounmap_regions(pdev, 1 << ATOM_ISP_PCI_BAR); |
| 1890 | 1860 | ||
| 1891 | ioremap_fail: | 1861 | ioremap_fail: |
| 1892 | return err; | 1862 | return err; |
| 1893 | } | 1863 | } |
| 1894 | 1864 | ||
| 1895 | static void atomisp_pci_remove(struct pci_dev *dev) | 1865 | static void atomisp_pci_remove(struct pci_dev *pdev) |
| 1896 | { | 1866 | { |
| 1897 | struct atomisp_device *isp = (struct atomisp_device *) | 1867 | struct atomisp_device *isp = pci_get_drvdata(pdev); |
| 1898 | pci_get_drvdata(dev); | ||
| 1899 | 1868 | ||
| 1900 | dev_info(&dev->dev, "Removing atomisp driver\n"); | 1869 | dev_info(&pdev->dev, "Removing atomisp driver\n"); |
| 1901 | 1870 | ||
| 1902 | atomisp_drvfs_exit(); | 1871 | atomisp_drvfs_exit(); |
| 1903 | 1872 | ||
| @@ -1906,11 +1875,11 @@ static void atomisp_pci_remove(struct pci_dev *dev) · 2 unmodified lines | |||
| 1906 | ia_css_unload_firmware(); | 1875 | ia_css_unload_firmware(); |
| 1907 | hmm_cleanup(); | 1876 | hmm_cleanup(); |
| 1908 | 1877 | ||
| 1909 | pm_runtime_forbid(&dev->dev); | 1878 | pm_runtime_forbid(&pdev->dev); |
| 1910 | pm_runtime_get_noresume(&dev->dev); | 1879 | pm_runtime_get_noresume(&pdev->dev); |
| 1911 | cpu_latency_qos_remove_request(&isp->pm_qos); | 1880 | cpu_latency_qos_remove_request(&isp->pm_qos); |
| 1912 | 1881 | ||
| 1913 | atomisp_msi_irq_uninit(isp, dev); | 1882 | atomisp_msi_irq_uninit(isp); |
| 1914 | atomisp_unregister_entities(isp); | 1883 | atomisp_unregister_entities(isp); |
| 1915 | 1884 | ||
| 1916 | destroy_workqueue(isp->wdt_work_queue); | 1885 | destroy_workqueue(isp->wdt_work_queue); |
| @@ -48,7 +48,7 @@ static struct ia_css_refcount_entry *refcount_find_entry(ia_css_ptr ptr, · 47 unmodified lines | |||
| 48 | return NULL; | 48 | return NULL; |
| 49 | if (!myrefcount.items) { | 49 | if (!myrefcount.items) { |
| 50 | ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, | 50 | ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, |
| 51 | "refcount_find_entry(): Ref count not initialized!\n"); | 51 | "%s(): Ref count not initialized!\n", __func__); |
| 52 | return NULL; | 52 | return NULL; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| @@ -73,12 +73,12 @@ int ia_css_refcount_init(uint32_t size) · 18 unmodified lines | |||
| 73 | 73 | ||
| 74 | if (size == 0) { | 74 | if (size == 0) { |
| 75 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 75 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 76 | "ia_css_refcount_init(): Size of 0 for Ref count init!\n"); | 76 | "%s(): Size of 0 for Ref count init!\n", __func__); |
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | } | 78 | } |
| 79 | if (myrefcount.items) { | 79 | if (myrefcount.items) { |
| 80 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 80 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 81 | "ia_css_refcount_init(): Ref count is already initialized\n"); | 81 | "%s(): Ref count is already initialized\n", __func__); |
| 82 | return -EINVAL; | 82 | return -EINVAL; |
| 83 | } | 83 | } |
| 84 | myrefcount.items = | 84 | myrefcount.items = |
| @@ -99,7 +99,7 @@ void ia_css_refcount_uninit(void) · 14 unmodified lines | |||
| 99 | u32 i; | 99 | u32 i; |
| 100 | 100 | ||
| 101 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 101 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 102 | "ia_css_refcount_uninit() entry\n"); | 102 | "%s() entry\n", __func__); |
| 103 | for (i = 0; i < myrefcount.size; i++) { | 103 | for (i = 0; i < myrefcount.size; i++) { |
| 104 | /* driver verifier tool has issues with &arr[i] | 104 | /* driver verifier tool has issues with &arr[i] |
| 105 | and prefers arr + i; as these are actually equivalent | 105 | and prefers arr + i; as these are actually equivalent |
| @@ -120,7 +120,7 @@ void ia_css_refcount_uninit(void) · 14 unmodified lines | |||
| 120 | myrefcount.items = NULL; | 120 | myrefcount.items = NULL; |
| 121 | myrefcount.size = 0; | 121 | myrefcount.size = 0; |
| 122 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 122 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 123 | "ia_css_refcount_uninit() leave\n"); | 123 | "%s() leave\n", __func__); |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr) | 126 | ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr) |
| @@ -133,7 +133,7 @@ ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr) · 6 unmodified lines | |||
| 133 | entry = refcount_find_entry(ptr, false); | 133 | entry = refcount_find_entry(ptr, false); |
| 134 | 134 | ||
| 135 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 135 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 136 | "ia_css_refcount_increment(%x) 0x%x\n", id, ptr); | 136 | "%s(%x) 0x%x\n", __func__, id, ptr); |
| 137 | 137 | ||
| 138 | if (!entry) { | 138 | if (!entry) { |
| 139 | entry = refcount_find_entry(ptr, true); | 139 | entry = refcount_find_entry(ptr, true); |
| @@ -145,7 +145,7 @@ ia_css_ptr ia_css_refcount_increment(s32 id, ia_css_ptr ptr) · 5 unmodified lines | |||
| 145 | 145 | ||
| 146 | if (entry->id != id) { | 146 | if (entry->id != id) { |
| 147 | ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, | 147 | ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, |
| 148 | "ia_css_refcount_increment(): Ref count IDS do not match!\n"); | 148 | "%s(): Ref count IDS do not match!\n", __func__); |
| 149 | return mmgr_NULL; | 149 | return mmgr_NULL; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| @@ -165,7 +165,7 @@ bool ia_css_refcount_decrement(s32 id, ia_css_ptr ptr) · 13 unmodified lines | |||
| 165 | struct ia_css_refcount_entry *entry; | 165 | struct ia_css_refcount_entry *entry; |
| 166 | 166 | ||
| 167 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 167 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 168 | "ia_css_refcount_decrement(%x) 0x%x\n", id, ptr); | 168 | "%s(%x) 0x%x\n", __func__, id, ptr); |
| 169 | 169 | ||
| 170 | if (ptr == mmgr_NULL) | 170 | if (ptr == mmgr_NULL) |
| 171 | return false; | 171 | return false; |
| @@ -175,7 +175,7 @@ bool ia_css_refcount_decrement(s32 id, ia_css_ptr ptr) · 3 unmodified lines | |||
| 175 | if (entry) { | 175 | if (entry) { |
| 176 | if (entry->id != id) { | 176 | if (entry->id != id) { |
| 177 | ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, | 177 | ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, |
| 178 | "ia_css_refcount_decrement(): Ref count IDS do not match!\n"); | 178 | "%s(): Ref count IDS do not match!\n", __func__); |
| 179 | return false; | 179 | return false; |
| 180 | } | 180 | } |
| 181 | if (entry->count > 0) { | 181 | if (entry->count > 0) { |
| @@ -225,8 +225,8 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr) · 43 unmodified lines | |||
| 225 | u32 count = 0; | 225 | u32 count = 0; |
| 226 | 226 | ||
| 227 | assert(clear_func_ptr); | 227 | assert(clear_func_ptr); |
| 228 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_refcount_clear(%x)\n", | 228 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s(%x)\n", |
| 229 | id); | 229 | __func__, id); |
| 230 | 230 | ||
| 231 | for (i = 0; i < myrefcount.size; i++) { | 231 | for (i = 0; i < myrefcount.size; i++) { |
| 232 | /* driver verifier tool has issues with &arr[i] | 232 | /* driver verifier tool has issues with &arr[i] |
| @@ -236,14 +236,14 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr) · 3 unmodified lines | |||
| 236 | entry = myrefcount.items + i; | 236 | entry = myrefcount.items + i; |
| 237 | if ((entry->data != mmgr_NULL) && (entry->id == id)) { | 237 | if ((entry->data != mmgr_NULL) && (entry->id == id)) { |
| 238 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 238 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 239 | "ia_css_refcount_clear: %x: 0x%x\n", | 239 | "%s: %x: 0x%x\n", __func__, |
| 240 | id, entry->data); | 240 | id, entry->data); |
| 241 | if (clear_func_ptr) { | 241 | if (clear_func_ptr) { |
| 242 | /* clear using provided function */ | 242 | /* clear using provided function */ |
| 243 | clear_func_ptr(entry->data); | 243 | clear_func_ptr(entry->data); |
| 244 | } else { | 244 | } else { |
| 245 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 245 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 246 | "ia_css_refcount_clear: using hmm_free: no clear_func\n"); | 246 | "%s: using hmm_free: no clear_func\n", __func__); |
| 247 | hmm_free(entry->data); | 247 | hmm_free(entry->data); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| @@ -260,7 +260,7 @@ void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr) · 10 unmodified lines | |||
| 260 | } | 260 | } |
| 261 | } | 261 | } |
| 262 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, | 262 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, |
| 263 | "ia_css_refcount_clear(%x): cleared %d\n", id, | 263 | "%s(%x): cleared %d\n", __func__, id, |
| 264 | count); | 264 | count); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| @@ -52,32 +52,14 @@ typedef unsigned short hive_uint16; · 51 unmodified lines | |||
| 52 | typedef unsigned int hive_uint32; | 52 | typedef unsigned int hive_uint32; |
| 53 | typedef unsigned long long hive_uint64; | 53 | typedef unsigned long long hive_uint64; |
| 54 | 54 | ||
| 55 | /* by default assume 32 bit master port (both data and address) */ | 55 | #define HRT_DATA_WIDTH 32 |
| 56 | #ifndef HRT_DATA_WIDTH | 56 | #define HRT_ADDRESS_WIDTH 64 |
| 57 | #define HRT_DATA_WIDTH 32 | ||
| 58 | #endif | ||
| 59 | #ifndef HRT_ADDRESS_WIDTH | ||
| 60 | #define HRT_ADDRESS_WIDTH 32 | ||
| 61 | #endif | ||
| 62 | |||
| 63 | #define HRT_DATA_BYTES (HRT_DATA_WIDTH / 8) | 57 | #define HRT_DATA_BYTES (HRT_DATA_WIDTH / 8) |
| 64 | #define HRT_ADDRESS_BYTES (HRT_ADDRESS_WIDTH / 8) | 58 | #define HRT_ADDRESS_BYTES (HRT_ADDRESS_WIDTH / 8) |
| 59 | #define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3) | ||
| 65 | 60 | ||
| 66 | #if HRT_DATA_WIDTH == 64 | ||
| 67 | typedef hive_uint64 hrt_data; | ||
| 68 | #elif HRT_DATA_WIDTH == 32 | ||
| 69 | typedef hive_uint32 hrt_data; | 61 | typedef hive_uint32 hrt_data; |
| 70 | #else | ||
| 71 | #error data width not supported | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if HRT_ADDRESS_WIDTH == 64 | ||
| 75 | typedef hive_uint64 hrt_address; | 62 | typedef hive_uint64 hrt_address; |
| 76 | #elif HRT_ADDRESS_WIDTH == 32 | ||
| 77 | typedef hive_uint32 hrt_address; | ||
| 78 | #else | ||
| 79 | #error adddres width not supported | ||
| 80 | #endif | ||
| 81 | 63 | ||
| 82 | /* use 64 bit addresses in simulation, where possible */ | 64 | /* use 64 bit addresses in simulation, where possible */ |
| 83 | typedef hive_uint64 hive_sim_address; | 65 | typedef hive_uint64 hive_sim_address; |
| @@ -735,11 +735,11 @@ ia_css_ptr hmm_host_vaddr_to_hrt_vaddr(const void *ptr) · 734 unmodified lines | |||
| 735 | 735 | ||
| 736 | void hmm_show_mem_stat(const char *func, const int line) | 736 | void hmm_show_mem_stat(const char *func, const int line) |
| 737 | { | 737 | { |
| 738 | trace_printk("tol_cnt=%d usr_size=%d res_size=%d res_cnt=%d sys_size=%d dyc_thr=%d dyc_size=%d.\n", | 738 | pr_info("tol_cnt=%d usr_size=%d res_size=%d res_cnt=%d sys_size=%d dyc_thr=%d dyc_size=%d.\n", |
| 739 | hmm_mem_stat.tol_cnt, | 739 | hmm_mem_stat.tol_cnt, |
| 740 | hmm_mem_stat.usr_size, hmm_mem_stat.res_size, | 740 | hmm_mem_stat.usr_size, hmm_mem_stat.res_size, |
| 741 | hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size, | 741 | hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size, |
| 742 | hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size); | 742 | hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size); |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | void hmm_init_mem_stat(int res_pgnr, int dyc_en, int dyc_pgnr) | 745 | void hmm_init_mem_stat(int res_pgnr, int dyc_en, int dyc_pgnr) |
| @@ -13,306 +13,4 @@ · 12 unmodified lines | |||
| 13 | * more details. | 13 | * more details. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #ifndef __SYSTEM_GLOBAL_H_INCLUDED__ | ||
| 17 | #define __SYSTEM_GLOBAL_H_INCLUDED__ | ||
| 18 | |||
| 19 | #include <hive_isp_css_defs.h> | ||
| 20 | #include <type_support.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * The longest allowed (uninteruptible) bus transfer, does not | ||
| 24 | * take stalling into account | ||
| 25 | */ | ||
| 26 | #define HIVE_ISP_MAX_BURST_LENGTH 1024 | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Maximum allowed burst length in words for the ISP DMA | ||
| 30 | */ | ||
| 31 | #define ISP_DMA_MAX_BURST_LENGTH 128 | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Create a list of HAS and IS properties that defines the system | ||
| 35 | * | ||
| 36 | * The configuration assumes the following | ||
| 37 | * - The system is hetereogeneous; Multiple cells and devices classes | ||
| 38 | * - The cell and device instances are homogeneous, each device type | ||
| 39 | * belongs to the same class | ||
| 40 | * - Device instances supporting a subset of the class capabilities are | ||
| 41 | * allowed | ||
| 42 | * | ||
| 43 | * We could manage different device classes through the enumerated | ||
| 44 | * lists (C) or the use of classes (C++), but that is presently not | ||
| 45 | * fully supported | ||
| 46 | * | ||
| 47 | * N.B. the 3 input formatters are of 2 different classess | ||
| 48 | */ | ||
| 49 | |||
| 50 | #define USE_INPUT_SYSTEM_VERSION_2 | 16 | #define USE_INPUT_SYSTEM_VERSION_2 |
| 51 | |||
| 52 | #define HAS_MMU_VERSION_2 | ||
| 53 | #define HAS_DMA_VERSION_2 | ||
| 54 | #define HAS_GDC_VERSION_2 | ||
| 55 | #define HAS_VAMEM_VERSION_2 | ||
| 56 | #define HAS_HMEM_VERSION_1 | ||
| 57 | #define HAS_BAMEM_VERSION_2 | ||
| 58 | #define HAS_IRQ_VERSION_2 | ||
| 59 | #define HAS_IRQ_MAP_VERSION_2 | ||
| 60 | #define HAS_INPUT_FORMATTER_VERSION_2 | ||
| 61 | /* 2401: HAS_INPUT_SYSTEM_VERSION_2401 */ | ||
| 62 | #define HAS_INPUT_SYSTEM_VERSION_2 | ||
| 63 | #define HAS_BUFFERED_SENSOR | ||
| 64 | #define HAS_FIFO_MONITORS_VERSION_2 | ||
| 65 | /* #define HAS_GP_REGS_VERSION_2 */ | ||
| 66 | #define HAS_GP_DEVICE_VERSION_2 | ||
| 67 | #define HAS_GPIO_VERSION_1 | ||
| 68 | #define HAS_TIMED_CTRL_VERSION_1 | ||
| 69 | #define HAS_RX_VERSION_2 | ||
| 70 | |||
| 71 | #define DMA_DDR_TO_VAMEM_WORKAROUND | ||
| 72 | #define DMA_DDR_TO_HMEM_WORKAROUND | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Semi global. "HRT" is accessible from SP, but the HRT types do not fully apply | ||
| 76 | */ | ||
| 77 | #define HRT_VADDRESS_WIDTH 32 | ||
| 78 | //#define HRT_ADDRESS_WIDTH 64 /* Surprise, this is a local property*/ | ||
| 79 | #define HRT_DATA_WIDTH 32 | ||
| 80 | |||
| 81 | #define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3) | ||
| 82 | #define HIVE_ISP_CTRL_DATA_BYTES (HIVE_ISP_CTRL_DATA_WIDTH / 8) | ||
| 83 | |||
| 84 | /* The main bus connecting all devices */ | ||
| 85 | #define HRT_BUS_WIDTH HIVE_ISP_CTRL_DATA_WIDTH | ||
| 86 | #define HRT_BUS_BYTES HIVE_ISP_CTRL_DATA_BYTES | ||
| 87 | |||
| 88 | /* per-frame parameter handling support */ | ||
| 89 | #define SH_CSS_ENABLE_PER_FRAME_PARAMS | ||
| 90 | |||
| 91 | typedef u32 hrt_bus_align_t; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Enumerate the devices, device access through the API is by ID, through the DLI by address | ||
| 95 | * The enumerator terminators are used to size the wiring arrays and as an exception value. | ||
| 96 | */ | ||
| 97 | typedef enum { | ||
| 98 | DDR0_ID = 0, | ||
| 99 | N_DDR_ID | ||
| 100 | } ddr_ID_t; | ||
| 101 | |||
| 102 | typedef enum { | ||
| 103 | ISP0_ID = 0, | ||
| 104 | N_ISP_ID | ||
| 105 | } isp_ID_t; | ||
| 106 | |||
| 107 | typedef enum { | ||
| 108 | SP0_ID = 0, | ||
| 109 | N_SP_ID | ||
| 110 | } sp_ID_t; | ||
| 111 | |||
| 112 | typedef enum { | ||
| 113 | MMU0_ID = 0, | ||
| 114 | MMU1_ID, | ||
| 115 | N_MMU_ID | ||
| 116 | } mmu_ID_t; | ||
| 117 | |||
| 118 | typedef enum { | ||
| 119 | DMA0_ID = 0, | ||
| 120 | N_DMA_ID | ||
| 121 | } dma_ID_t; | ||
| 122 | |||
| 123 | typedef enum { | ||
| 124 | GDC0_ID = 0, | ||
| 125 | GDC1_ID, | ||
| 126 | N_GDC_ID | ||
| 127 | } gdc_ID_t; | ||
| 128 | |||
| 129 | #define N_GDC_ID_CPP 2 // this extra define is needed because we want to use it also in the preprocessor, and that doesn't work with enums. | ||
| 130 | |||
| 131 | typedef enum { | ||
| 132 | VAMEM0_ID = 0, | ||
| 133 | VAMEM1_ID, | ||
| 134 | VAMEM2_ID, | ||
| 135 | N_VAMEM_ID | ||
| 136 | } vamem_ID_t; | ||
| 137 | |||
| 138 | typedef enum { | ||
| 139 | BAMEM0_ID = 0, | ||
| 140 | N_BAMEM_ID | ||
| 141 | } bamem_ID_t; | ||
| 142 | |||
| 143 | typedef enum { | ||
| 144 | HMEM0_ID = 0, | ||
| 145 | N_HMEM_ID | ||
| 146 | } hmem_ID_t; | ||
| 147 | |||
| 148 | /* | ||
| 149 | typedef enum { | ||
| 150 | IRQ0_ID = 0, | ||
| 151 | N_IRQ_ID | ||
| 152 | } irq_ID_t; | ||
| 153 | */ | ||
| 154 | |||
| 155 | typedef enum { | ||
| 156 | IRQ0_ID = 0, // GP IRQ block | ||
| 157 | IRQ1_ID, // Input formatter | ||
| 158 | IRQ2_ID, // input system | ||
| 159 | IRQ3_ID, // input selector | ||
| 160 | N_IRQ_ID | ||
| 161 | } irq_ID_t; | ||
| 162 | |||
| 163 | typedef enum { | ||
| 164 | FIFO_MONITOR0_ID = 0, | ||
| 165 | N_FIFO_MONITOR_ID | ||
| 166 | } fifo_monitor_ID_t; | ||
| 167 | |||
| 168 | /* | ||
| 169 | * Deprecated: Since all gp_reg instances are different | ||
| 170 | * and put in the address maps of other devices we cannot | ||
| 171 | * enumerate them as that assumes the instrances are the | ||
| 172 | * same. | ||
| 173 | * | ||
| 174 | * We define a single GP_DEVICE containing all gp_regs | ||
| 175 | * w.r.t. a single base address | ||
| 176 | * | ||
| 177 | typedef enum { | ||
| 178 | GP_REGS0_ID = 0, | ||
| 179 | N_GP_REGS_ID | ||
| 180 | } gp_regs_ID_t; | ||
| 181 | */ | ||
| 182 | typedef enum { | ||
| 183 | GP_DEVICE0_ID = 0, | ||
| 184 | N_GP_DEVICE_ID | ||
| 185 | } gp_device_ID_t; | ||
| 186 | |||
| 187 | typedef enum { | ||
| 188 | GP_TIMER0_ID = 0, | ||
| 189 | GP_TIMER1_ID, | ||
| 190 | GP_TIMER2_ID, | ||
| 191 | GP_TIMER3_ID, | ||
| 192 | GP_TIMER4_ID, | ||
| 193 | GP_TIMER5_ID, | ||
| 194 | GP_TIMER6_ID, | ||
| 195 | GP_TIMER7_ID, | ||
| 196 | N_GP_TIMER_ID | ||
| 197 | } gp_timer_ID_t; | ||
| 198 | |||
| 199 | typedef enum { | ||
| 200 | GPIO0_ID = 0, | ||
| 201 | N_GPIO_ID | ||
| 202 | } gpio_ID_t; | ||
| 203 | |||
| 204 | typedef enum { | ||
| 205 | TIMED_CTRL0_ID = 0, | ||
| 206 | N_TIMED_CTRL_ID | ||
| 207 | } timed_ctrl_ID_t; | ||
| 208 | |||
| 209 | typedef enum { | ||
| 210 | INPUT_FORMATTER0_ID = 0, | ||
| 211 | INPUT_FORMATTER1_ID, | ||
| 212 | INPUT_FORMATTER2_ID, | ||
| 213 | INPUT_FORMATTER3_ID, | ||
| 214 | N_INPUT_FORMATTER_ID | ||
| 215 | } input_formatter_ID_t; | ||
| 216 | |||
| 217 | /* The IF RST is outside the IF */ | ||
| 218 | #define INPUT_FORMATTER0_SRST_OFFSET 0x0824 | ||
| 219 | #define INPUT_FORMATTER1_SRST_OFFSET 0x0624 | ||
| 220 | #define INPUT_FORMATTER2_SRST_OFFSET 0x0424 | ||
| 221 | #define INPUT_FORMATTER3_SRST_OFFSET 0x0224 | ||
| 222 | |||
| 223 | #define INPUT_FORMATTER0_SRST_MASK 0x0001 | ||
| 224 | #define INPUT_FORMATTER1_SRST_MASK 0x0002 | ||
| 225 | #define INPUT_FORMATTER2_SRST_MASK 0x0004 | ||
| 226 | #define INPUT_FORMATTER3_SRST_MASK 0x0008 | ||
| 227 | |||
| 228 | typedef enum { | ||
| 229 | INPUT_SYSTEM0_ID = 0, | ||
| 230 | N_INPUT_SYSTEM_ID | ||
| 231 | } input_system_ID_t; | ||
| 232 | |||
| 233 | typedef enum { | ||
| 234 | RX0_ID = 0, | ||
| 235 | N_RX_ID | ||
| 236 | } rx_ID_t; | ||
| 237 | |||
| 238 | enum mipi_port_id { | ||
| 239 | MIPI_PORT0_ID = 0, | ||
| 240 | MIPI_PORT1_ID, | ||
| 241 | MIPI_PORT2_ID, | ||
| 242 | N_MIPI_PORT_ID | ||
| 243 | }; | ||
| 244 | |||
| 245 | #define N_RX_CHANNEL_ID 4 | ||
| 246 | |||
| 247 | /* Generic port enumeration with an internal port type ID */ | ||
| 248 | typedef enum { | ||
| 249 | CSI_PORT0_ID = 0, | ||
| 250 | CSI_PORT1_ID, | ||
| 251 | CSI_PORT2_ID, | ||
| 252 | TPG_PORT0_ID, | ||
| 253 | PRBS_PORT0_ID, | ||
| 254 | FIFO_PORT0_ID, | ||
| 255 | MEMORY_PORT0_ID, | ||
| 256 | N_INPUT_PORT_ID | ||
| 257 | } input_port_ID_t; | ||
| 258 | |||
| 259 | typedef enum { | ||
| 260 | CAPTURE_UNIT0_ID = 0, | ||
| 261 | CAPTURE_UNIT1_ID, | ||
| 262 | CAPTURE_UNIT2_ID, | ||
| 263 | ACQUISITION_UNIT0_ID, | ||
| 264 | DMA_UNIT0_ID, | ||
| 265 | CTRL_UNIT0_ID, | ||
| 266 | GPREGS_UNIT0_ID, | ||
| 267 | FIFO_UNIT0_ID, | ||
| 268 | IRQ_UNIT0_ID, | ||
| 269 | N_SUB_SYSTEM_ID | ||
| 270 | } sub_system_ID_t; | ||
| 271 | |||
| 272 | #define N_CAPTURE_UNIT_ID 3 | ||
| 273 | #define N_ACQUISITION_UNIT_ID 1 | ||
| 274 | #define N_CTRL_UNIT_ID 1 | ||
| 275 | |||
| 276 | enum ia_css_isp_memories { | ||
| 277 | IA_CSS_ISP_PMEM0 = 0, | ||
| 278 | IA_CSS_ISP_DMEM0, | ||
| 279 | IA_CSS_ISP_VMEM0, | ||
| 280 | IA_CSS_ISP_VAMEM0, | ||
| 281 | IA_CSS_ISP_VAMEM1, | ||
| 282 | IA_CSS_ISP_VAMEM2, | ||
| 283 | IA_CSS_ISP_HMEM0, | ||
| 284 | IA_CSS_SP_DMEM0, | ||
| 285 | IA_CSS_DDR, | ||
| 286 | N_IA_CSS_MEMORIES | ||
| 287 | }; | ||
| 288 | |||
| 289 | #define IA_CSS_NUM_MEMORIES 9 | ||
| 290 | /* For driver compatibility */ | ||
| 291 | #define N_IA_CSS_ISP_MEMORIES IA_CSS_NUM_MEMORIES | ||
| 292 | #define IA_CSS_NUM_ISP_MEMORIES IA_CSS_NUM_MEMORIES | ||
| 293 | |||
| 294 | #if 0 | ||
| 295 | typedef enum { | ||
| 296 | dev_chn, /* device channels, external resource */ | ||
| 297 | ext_mem, /* external memories */ | ||
| 298 | int_mem, /* internal memories */ | ||
| 299 | int_chn /* internal channels, user defined */ | ||
| 300 | } resource_type_t; | ||
| 301 | |||
| 302 | /* if this enum is extended with other memory resources, pls also extend the function resource_to_memptr() */ | ||
| 303 | typedef enum { | ||
| 304 | vied_nci_dev_chn_dma_ext0, | ||
| 305 | int_mem_vmem0, | ||
| 306 | int_mem_dmem0 | ||
| 307 | } resource_id_t; | ||
| 308 | |||
| 309 | /* enum listing the different memories within a program group. | ||
| 310 | This enum is used in the mem_ptr_t type */ | ||
| 311 | typedef enum { | ||
| 312 | buf_mem_invalid = 0, | ||
| 313 | buf_mem_vmem_prog0, | ||
| 314 | buf_mem_dmem_prog0 | ||
| 315 | } buf_mem_t; | ||
| 316 | |||
| 317 | #endif | ||
| 318 | #endif /* __SYSTEM_GLOBAL_H_INCLUDED__ */ | ||
| @@ -1,321 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Support for Intel Camera Imaging ISP subsystem. | ||
| 4 | * Copyright (c) 2010-2015, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef __SYSTEM_LOCAL_H_INCLUDED__ | ||
| 17 | #define __SYSTEM_LOCAL_H_INCLUDED__ | ||
| 18 | |||
| 19 | #ifdef HRT_ISP_CSS_CUSTOM_HOST | ||
| 20 | #ifndef HRT_USE_VIR_ADDRS | ||
| 21 | #define HRT_USE_VIR_ADDRS | ||
| 22 | #endif | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #include "system_global.h" | ||
| 26 | |||
| 27 | /* HRT assumes 32 by default (see Linux/include/hive_types.h), overrule it in case it is different */ | ||
| 28 | #undef HRT_ADDRESS_WIDTH | ||
| 29 | #define HRT_ADDRESS_WIDTH 64 /* Surprise, this is a local property */ | ||
| 30 | |||
| 31 | /* This interface is deprecated */ | ||
| 32 | #include "hive_types.h" | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Cell specific address maps | ||
| 36 | */ | ||
| 37 | #if HRT_ADDRESS_WIDTH == 64 | ||
| 38 | |||
| 39 | #define GP_FIFO_BASE ((hrt_address)0x0000000000090104) /* This is NOT a base address */ | ||
| 40 | |||
| 41 | /* DDR */ | ||
| 42 | static const hrt_address DDR_BASE[N_DDR_ID] = { | ||
| 43 | (hrt_address)0x0000000120000000ULL | ||
| 44 | }; | ||
| 45 | |||
| 46 | /* ISP */ | ||
| 47 | static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = { | ||
| 48 | (hrt_address)0x0000000000020000ULL | ||
| 49 | }; | ||
| 50 | |||
| 51 | static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = { | ||
| 52 | (hrt_address)0x0000000000200000ULL | ||
| 53 | }; | ||
| 54 | |||
| 55 | static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = { | ||
| 56 | (hrt_address)0x0000000000100000ULL | ||
| 57 | }; | ||
| 58 | |||
| 59 | static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = { | ||
| 60 | (hrt_address)0x00000000001C0000ULL, | ||
| 61 | (hrt_address)0x00000000001D0000ULL, | ||
| 62 | (hrt_address)0x00000000001E0000ULL | ||
| 63 | }; | ||
| 64 | |||
| 65 | static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = { | ||
| 66 | (hrt_address)0x00000000001F0000ULL | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* SP */ | ||
| 70 | static const hrt_address SP_CTRL_BASE[N_SP_ID] = { | ||
| 71 | (hrt_address)0x0000000000010000ULL | ||
| 72 | }; | ||
| 73 | |||
| 74 | static const hrt_address SP_DMEM_BASE[N_SP_ID] = { | ||
| 75 | (hrt_address)0x0000000000300000ULL | ||
| 76 | }; | ||
| 77 | |||
| 78 | static const hrt_address SP_PMEM_BASE[N_SP_ID] = { | ||
| 79 | (hrt_address)0x00000000000B0000ULL | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* MMU */ | ||
| 83 | /* | ||
| 84 | * MMU0_ID: The data MMU | ||
| 85 | * MMU1_ID: The icache MMU | ||
| 86 | */ | ||
| 87 | static const hrt_address MMU_BASE[N_MMU_ID] = { | ||
| 88 | (hrt_address)0x0000000000070000ULL, | ||
| 89 | (hrt_address)0x00000000000A0000ULL | ||
| 90 | }; | ||
| 91 | |||
| 92 | /* DMA */ | ||
| 93 | static const hrt_address DMA_BASE[N_DMA_ID] = { | ||
| 94 | (hrt_address)0x0000000000040000ULL | ||
| 95 | }; | ||
| 96 | |||
| 97 | /* IRQ */ | ||
| 98 | static const hrt_address IRQ_BASE[N_IRQ_ID] = { | ||
| 99 | (hrt_address)0x0000000000000500ULL, | ||
| 100 | (hrt_address)0x0000000000030A00ULL, | ||
| 101 | (hrt_address)0x000000000008C000ULL, | ||
| 102 | (hrt_address)0x0000000000090200ULL | ||
| 103 | }; | ||
| 104 | |||
| 105 | /* | ||
| 106 | (hrt_address)0x0000000000000500ULL}; | ||
| 107 | */ | ||
| 108 | |||
| 109 | /* GDC */ | ||
| 110 | static const hrt_address GDC_BASE[N_GDC_ID] = { | ||
| 111 | (hrt_address)0x0000000000050000ULL, | ||
| 112 | (hrt_address)0x0000000000060000ULL | ||
| 113 | }; | ||
| 114 | |||
| 115 | /* FIFO_MONITOR (not a subset of GP_DEVICE) */ | ||
| 116 | static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = { | ||
| 117 | (hrt_address)0x0000000000000000ULL | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* | ||
| 121 | static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = { | ||
| 122 | (hrt_address)0x0000000000000000ULL}; | ||
| 123 | |||
| 124 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 125 | (hrt_address)0x0000000000090000ULL}; | ||
| 126 | */ | ||
| 127 | |||
| 128 | /* GP_DEVICE (single base for all separate GP_REG instances) */ | ||
| 129 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 130 | (hrt_address)0x0000000000000000ULL | ||
| 131 | }; | ||
| 132 | |||
| 133 | /*GP TIMER , all timer registers are inter-twined, | ||
| 134 | * so, having multiple base addresses for | ||
| 135 | * different timers does not help*/ | ||
| 136 | static const hrt_address GP_TIMER_BASE = | ||
| 137 | (hrt_address)0x0000000000000600ULL; | ||
| 138 | /* GPIO */ | ||
| 139 | static const hrt_address GPIO_BASE[N_GPIO_ID] = { | ||
| 140 | (hrt_address)0x0000000000000400ULL | ||
| 141 | }; | ||
| 142 | |||
| 143 | /* TIMED_CTRL */ | ||
| 144 | static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = { | ||
| 145 | (hrt_address)0x0000000000000100ULL | ||
| 146 | }; | ||
| 147 | |||
| 148 | /* INPUT_FORMATTER */ | ||
| 149 | static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = { | ||
| 150 | (hrt_address)0x0000000000030000ULL, | ||
| 151 | (hrt_address)0x0000000000030200ULL, | ||
| 152 | (hrt_address)0x0000000000030400ULL, | ||
| 153 | (hrt_address)0x0000000000030600ULL | ||
| 154 | }; /* memcpy() */ | ||
| 155 | |||
| 156 | /* INPUT_SYSTEM */ | ||
| 157 | static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = { | ||
| 158 | (hrt_address)0x0000000000080000ULL | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* (hrt_address)0x0000000000081000ULL, */ /* capture A */ | ||
| 162 | /* (hrt_address)0x0000000000082000ULL, */ /* capture B */ | ||
| 163 | /* (hrt_address)0x0000000000083000ULL, */ /* capture C */ | ||
| 164 | /* (hrt_address)0x0000000000084000ULL, */ /* Acquisition */ | ||
| 165 | /* (hrt_address)0x0000000000085000ULL, */ /* DMA */ | ||
| 166 | /* (hrt_address)0x0000000000089000ULL, */ /* ctrl */ | ||
| 167 | /* (hrt_address)0x000000000008A000ULL, */ /* GP regs */ | ||
| 168 | /* (hrt_address)0x000000000008B000ULL, */ /* FIFO */ | ||
| 169 | /* (hrt_address)0x000000000008C000ULL, */ /* IRQ */ | ||
| 170 | |||
| 171 | /* RX, the MIPI lane control regs start at offset 0 */ | ||
| 172 | static const hrt_address RX_BASE[N_RX_ID] = { | ||
| 173 | (hrt_address)0x0000000000080100ULL | ||
| 174 | }; | ||
| 175 | |||
| 176 | #elif HRT_ADDRESS_WIDTH == 32 | ||
| 177 | |||
| 178 | #define GP_FIFO_BASE ((hrt_address)0x00090104) /* This is NOT a base address */ | ||
| 179 | |||
| 180 | /* DDR : Attention, this value not defined in 32-bit */ | ||
| 181 | static const hrt_address DDR_BASE[N_DDR_ID] = { | ||
| 182 | (hrt_address)0x00000000UL | ||
| 183 | }; | ||
| 184 | |||
| 185 | /* ISP */ | ||
| 186 | static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = { | ||
| 187 | (hrt_address)0x00020000UL | ||
| 188 | }; | ||
| 189 | |||
| 190 | static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = { | ||
| 191 | (hrt_address)0x00200000UL | ||
| 192 | }; | ||
| 193 | |||
| 194 | static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = { | ||
| 195 | (hrt_address)0x100000UL | ||
| 196 | }; | ||
| 197 | |||
| 198 | static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = { | ||
| 199 | (hrt_address)0xffffffffUL, | ||
| 200 | (hrt_address)0xffffffffUL, | ||
| 201 | (hrt_address)0xffffffffUL | ||
| 202 | }; | ||
| 203 | |||
| 204 | static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = { | ||
| 205 | (hrt_address)0xffffffffUL | ||
| 206 | }; | ||
| 207 | |||
| 208 | /* SP */ | ||
| 209 | static const hrt_address SP_CTRL_BASE[N_SP_ID] = { | ||
| 210 | (hrt_address)0x00010000UL | ||
| 211 | }; | ||
| 212 | |||
| 213 | static const hrt_address SP_DMEM_BASE[N_SP_ID] = { | ||
| 214 | (hrt_address)0x00300000UL | ||
| 215 | }; | ||
| 216 | |||
| 217 | static const hrt_address SP_PMEM_BASE[N_SP_ID] = { | ||
| 218 | (hrt_address)0x000B0000UL | ||
| 219 | }; | ||
| 220 | |||
| 221 | /* MMU */ | ||
| 222 | /* | ||
| 223 | * MMU0_ID: The data MMU | ||
| 224 | * MMU1_ID: The icache MMU | ||
| 225 | */ | ||
| 226 | static const hrt_address MMU_BASE[N_MMU_ID] = { | ||
| 227 | (hrt_address)0x00070000UL, | ||
| 228 | (hrt_address)0x000A0000UL | ||
| 229 | }; | ||
| 230 | |||
| 231 | /* DMA */ | ||
| 232 | static const hrt_address DMA_BASE[N_DMA_ID] = { | ||
| 233 | (hrt_address)0x00040000UL | ||
| 234 | }; | ||
| 235 | |||
| 236 | /* IRQ */ | ||
| 237 | static const hrt_address IRQ_BASE[N_IRQ_ID] = { | ||
| 238 | (hrt_address)0x00000500UL, | ||
| 239 | (hrt_address)0x00030A00UL, | ||
| 240 | (hrt_address)0x0008C000UL, | ||
| 241 | (hrt_address)0x00090200UL | ||
| 242 | }; | ||
| 243 | |||
| 244 | /* | ||
| 245 | (hrt_address)0x00000500UL}; | ||
| 246 | */ | ||
| 247 | |||
| 248 | /* GDC */ | ||
| 249 | static const hrt_address GDC_BASE[N_GDC_ID] = { | ||
| 250 | (hrt_address)0x00050000UL, | ||
| 251 | (hrt_address)0x00060000UL | ||
| 252 | }; | ||
| 253 | |||
| 254 | /* FIFO_MONITOR (not a subset of GP_DEVICE) */ | ||
| 255 | static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = { | ||
| 256 | (hrt_address)0x00000000UL | ||
| 257 | }; | ||
| 258 | |||
| 259 | /* | ||
| 260 | static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = { | ||
| 261 | (hrt_address)0x00000000UL}; | ||
| 262 | |||
| 263 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 264 | (hrt_address)0x00090000UL}; | ||
| 265 | */ | ||
| 266 | |||
| 267 | /* GP_DEVICE (single base for all separate GP_REG instances) */ | ||
| 268 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 269 | (hrt_address)0x00000000UL | ||
| 270 | }; | ||
| 271 | |||
| 272 | /*GP TIMER , all timer registers are inter-twined, | ||
| 273 | * so, having multiple base addresses for | ||
| 274 | * different timers does not help*/ | ||
| 275 | static const hrt_address GP_TIMER_BASE = | ||
| 276 | (hrt_address)0x00000600UL; | ||
| 277 | |||
| 278 | /* GPIO */ | ||
| 279 | static const hrt_address GPIO_BASE[N_GPIO_ID] = { | ||
| 280 | (hrt_address)0x00000400UL | ||
| 281 | }; | ||
| 282 | |||
| 283 | /* TIMED_CTRL */ | ||
| 284 | static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = { | ||
| 285 | (hrt_address)0x00000100UL | ||
| 286 | }; | ||
| 287 | |||
| 288 | /* INPUT_FORMATTER */ | ||
| 289 | static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = { | ||
| 290 | (hrt_address)0x00030000UL, | ||
| 291 | (hrt_address)0x00030200UL, | ||
| 292 | (hrt_address)0x00030400UL | ||
| 293 | }; | ||
| 294 | |||
| 295 | /* (hrt_address)0x00030600UL, */ /* memcpy() */ | ||
| 296 | |||
| 297 | /* INPUT_SYSTEM */ | ||
| 298 | static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = { | ||
| 299 | (hrt_address)0x00080000UL | ||
| 300 | }; | ||
| 301 | |||
| 302 | /* (hrt_address)0x00081000UL, */ /* capture A */ | ||
| 303 | /* (hrt_address)0x00082000UL, */ /* capture B */ | ||
| 304 | /* (hrt_address)0x00083000UL, */ /* capture C */ | ||
| 305 | /* (hrt_address)0x00084000UL, */ /* Acquisition */ | ||
| 306 | /* (hrt_address)0x00085000UL, */ /* DMA */ | ||
| 307 | /* (hrt_address)0x00089000UL, */ /* ctrl */ | ||
| 308 | /* (hrt_address)0x0008A000UL, */ /* GP regs */ | ||
| 309 | /* (hrt_address)0x0008B000UL, */ /* FIFO */ | ||
| 310 | /* (hrt_address)0x0008C000UL, */ /* IRQ */ | ||
| 311 | |||
| 312 | /* RX, the MIPI lane control regs start at offset 0 */ | ||
| 313 | static const hrt_address RX_BASE[N_RX_ID] = { | ||
| 314 | (hrt_address)0x00080100UL | ||
| 315 | }; | ||
| 316 | |||
| 317 | #else | ||
| 318 | #error "system_local.h: HRT_ADDRESS_WIDTH must be one of {32,64}" | ||
| 319 | #endif | ||
| 320 | |||
| 321 | #endif /* __SYSTEM_LOCAL_H_INCLUDED__ */ | ||
| @@ -13,415 +13,7 @@ · 12 unmodified lines | |||
| 13 | * more details. | 13 | * more details. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #ifndef __SYSTEM_GLOBAL_H_INCLUDED__ | 16 | #define HAS_NO_INPUT_FORMATTER |
| 17 | #define __SYSTEM_GLOBAL_H_INCLUDED__ | ||
| 18 | |||
| 19 | #include <hive_isp_css_defs.h> | ||
| 20 | #include <type_support.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * The longest allowed (uninteruptible) bus transfer, does not | ||
| 24 | * take stalling into account | ||
| 25 | */ | ||
| 26 | #define HIVE_ISP_MAX_BURST_LENGTH 1024 | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Maximum allowed burst length in words for the ISP DMA | ||
| 30 | * This value is set to 2 to prevent the ISP DMA from blocking | ||
| 31 | * the bus for too long; as the input system can only buffer | ||
| 32 | * 2 lines on Moorefield and Cherrytrail, the input system buffers | ||
| 33 | * may overflow if blocked for too long (BZ 2726). | ||
| 34 | */ | ||
| 35 | #define ISP_DMA_MAX_BURST_LENGTH 2 | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Create a list of HAS and IS properties that defines the system | ||
| 39 | * | ||
| 40 | * The configuration assumes the following | ||
| 41 | * - The system is hetereogeneous; Multiple cells and devices classes | ||
| 42 | * - The cell and device instances are homogeneous, each device type | ||
| 43 | * belongs to the same class | ||
| 44 | * - Device instances supporting a subset of the class capabilities are | ||
| 45 | * allowed | ||
| 46 | * | ||
| 47 | * We could manage different device classes through the enumerated | ||
| 48 | * lists (C) or the use of classes (C++), but that is presently not | ||
| 49 | * fully supported | ||
| 50 | * | ||
| 51 | * N.B. the 3 input formatters are of 2 different classess | ||
| 52 | */ | ||
| 53 | |||
| 54 | #define USE_INPUT_SYSTEM_VERSION_2401 | 17 | #define USE_INPUT_SYSTEM_VERSION_2401 |
| 55 | |||
| 56 | #define HAS_MMU_VERSION_2 | ||
| 57 | #define HAS_DMA_VERSION_2 | ||
| 58 | #define HAS_GDC_VERSION_2 | ||
| 59 | #define HAS_VAMEM_VERSION_2 | ||
| 60 | #define HAS_HMEM_VERSION_1 | ||
| 61 | #define HAS_BAMEM_VERSION_2 | ||
| 62 | #define HAS_IRQ_VERSION_2 | ||
| 63 | #define HAS_IRQ_MAP_VERSION_2 | ||
| 64 | #define HAS_INPUT_FORMATTER_VERSION_2 | ||
| 65 | /* 2401: HAS_INPUT_SYSTEM_VERSION_3 */ | ||
| 66 | /* 2400: HAS_INPUT_SYSTEM_VERSION_2 */ | ||
| 67 | #define HAS_INPUT_SYSTEM_VERSION_2 | ||
| 68 | #define HAS_INPUT_SYSTEM_VERSION_2401 | 18 | #define HAS_INPUT_SYSTEM_VERSION_2401 |
| 69 | #define HAS_BUFFERED_SENSOR | ||
| 70 | #define HAS_FIFO_MONITORS_VERSION_2 | ||
| 71 | /* #define HAS_GP_REGS_VERSION_2 */ | ||
| 72 | #define HAS_GP_DEVICE_VERSION_2 | ||
| 73 | #define HAS_GPIO_VERSION_1 | ||
| 74 | #define HAS_TIMED_CTRL_VERSION_1 | ||
| 75 | #define HAS_RX_VERSION_2 | ||
| 76 | #define HAS_NO_INPUT_FORMATTER | ||
| 77 | /*#define HAS_NO_PACKED_RAW_PIXELS*/ | ||
| 78 | /*#define HAS_NO_DVS_6AXIS_CONFIG_UPDATE*/ | ||
| 79 | |||
| 80 | #define DMA_DDR_TO_VAMEM_WORKAROUND | ||
| 81 | #define DMA_DDR_TO_HMEM_WORKAROUND | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Semi global. "HRT" is accessible from SP, but | ||
| 85 | * the HRT types do not fully apply | ||
| 86 | */ | ||
| 87 | #define HRT_VADDRESS_WIDTH 32 | ||
| 88 | /* Surprise, this is a local property*/ | ||
| 89 | /*#define HRT_ADDRESS_WIDTH 64 */ | ||
| 90 | #define HRT_DATA_WIDTH 32 | ||
| 91 | |||
| 92 | #define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3) | ||
| 93 | #define HIVE_ISP_CTRL_DATA_BYTES (HIVE_ISP_CTRL_DATA_WIDTH / 8) | ||
| 94 | |||
| 95 | /* The main bus connecting all devices */ | ||
| 96 | #define HRT_BUS_WIDTH HIVE_ISP_CTRL_DATA_WIDTH | ||
| 97 | #define HRT_BUS_BYTES HIVE_ISP_CTRL_DATA_BYTES | ||
| 98 | |||
| 99 | #define CSI2P_DISABLE_ISYS2401_ONLINE_MODE | 19 | #define CSI2P_DISABLE_ISYS2401_ONLINE_MODE |
| 100 | |||
| 101 | /* per-frame parameter handling support */ | ||
| 102 | #define SH_CSS_ENABLE_PER_FRAME_PARAMS | ||
| 103 | |||
| 104 | typedef u32 hrt_bus_align_t; | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Enumerate the devices, device access through the API is by ID, | ||
| 108 | * through the DLI by address. The enumerator terminators are used | ||
| 109 | * to size the wiring arrays and as an exception value. | ||
| 110 | */ | ||
| 111 | typedef enum { | ||
| 112 | DDR0_ID = 0, | ||
| 113 | N_DDR_ID | ||
| 114 | } ddr_ID_t; | ||
| 115 | |||
| 116 | typedef enum { | ||
| 117 | ISP0_ID = 0, | ||
| 118 | N_ISP_ID | ||
| 119 | } isp_ID_t; | ||
| 120 | |||
| 121 | typedef enum { | ||
| 122 | SP0_ID = 0, | ||
| 123 | N_SP_ID | ||
| 124 | } sp_ID_t; | ||
| 125 | |||
| 126 | typedef enum { | ||
| 127 | MMU0_ID = 0, | ||
| 128 | MMU1_ID, | ||
| 129 | N_MMU_ID | ||
| 130 | } mmu_ID_t; | ||
| 131 | |||
| 132 | typedef enum { | ||
| 133 | DMA0_ID = 0, | ||
| 134 | N_DMA_ID | ||
| 135 | } dma_ID_t; | ||
| 136 | |||
| 137 | typedef enum { | ||
| 138 | GDC0_ID = 0, | ||
| 139 | GDC1_ID, | ||
| 140 | N_GDC_ID | ||
| 141 | } gdc_ID_t; | ||
| 142 | |||
| 143 | /* this extra define is needed because we want to use it also | ||
| 144 | in the preprocessor, and that doesn't work with enums. | ||
| 145 | */ | ||
| 146 | #define N_GDC_ID_CPP 2 | ||
| 147 | |||
| 148 | typedef enum { | ||
| 149 | VAMEM0_ID = 0, | ||
| 150 | VAMEM1_ID, | ||
| 151 | VAMEM2_ID, | ||
| 152 | N_VAMEM_ID | ||
| 153 | } vamem_ID_t; | ||
| 154 | |||
| 155 | typedef enum { | ||
| 156 | BAMEM0_ID = 0, | ||
| 157 | N_BAMEM_ID | ||
| 158 | } bamem_ID_t; | ||
| 159 | |||
| 160 | typedef enum { | ||
| 161 | HMEM0_ID = 0, | ||
| 162 | N_HMEM_ID | ||
| 163 | } hmem_ID_t; | ||
| 164 | |||
| 165 | typedef enum { | ||
| 166 | ISYS_IRQ0_ID = 0, /* port a */ | ||
| 167 | ISYS_IRQ1_ID, /* port b */ | ||
| 168 | ISYS_IRQ2_ID, /* port c */ | ||
| 169 | N_ISYS_IRQ_ID | ||
| 170 | } isys_irq_ID_t; | ||
| 171 | |||
| 172 | typedef enum { | ||
| 173 | IRQ0_ID = 0, /* GP IRQ block */ | ||
| 174 | IRQ1_ID, /* Input formatter */ | ||
| 175 | IRQ2_ID, /* input system */ | ||
| 176 | IRQ3_ID, /* input selector */ | ||
| 177 | N_IRQ_ID | ||
| 178 | } irq_ID_t; | ||
| 179 | |||
| 180 | typedef enum { | ||
| 181 | FIFO_MONITOR0_ID = 0, | ||
| 182 | N_FIFO_MONITOR_ID | ||
| 183 | } fifo_monitor_ID_t; | ||
| 184 | |||
| 185 | /* | ||
| 186 | * Deprecated: Since all gp_reg instances are different | ||
| 187 | * and put in the address maps of other devices we cannot | ||
| 188 | * enumerate them as that assumes the instrances are the | ||
| 189 | * same. | ||
| 190 | * | ||
| 191 | * We define a single GP_DEVICE containing all gp_regs | ||
| 192 | * w.r.t. a single base address | ||
| 193 | * | ||
| 194 | typedef enum { | ||
| 195 | GP_REGS0_ID = 0, | ||
| 196 | N_GP_REGS_ID | ||
| 197 | } gp_regs_ID_t; | ||
| 198 | */ | ||
| 199 | typedef enum { | ||
| 200 | GP_DEVICE0_ID = 0, | ||
| 201 | N_GP_DEVICE_ID | ||
| 202 | } gp_device_ID_t; | ||
| 203 | |||
| 204 | typedef enum { | ||
| 205 | GP_TIMER0_ID = 0, | ||
| 206 | GP_TIMER1_ID, | ||
| 207 | GP_TIMER2_ID, | ||
| 208 | GP_TIMER3_ID, | ||
| 209 | GP_TIMER4_ID, | ||
| 210 | GP_TIMER5_ID, | ||
| 211 | GP_TIMER6_ID, | ||
| 212 | GP_TIMER7_ID, | ||
| 213 | N_GP_TIMER_ID | ||
| 214 | } gp_timer_ID_t; | ||
| 215 | |||
| 216 | typedef enum { | ||
| 217 | GPIO0_ID = 0, | ||
| 218 | N_GPIO_ID | ||
| 219 | } gpio_ID_t; | ||
| 220 | |||
| 221 | typedef enum { | ||
| 222 | TIMED_CTRL0_ID = 0, | ||
| 223 | N_TIMED_CTRL_ID | ||
| 224 | } timed_ctrl_ID_t; | ||
| 225 | |||
| 226 | typedef enum { | ||
| 227 | INPUT_FORMATTER0_ID = 0, | ||
| 228 | INPUT_FORMATTER1_ID, | ||
| 229 | INPUT_FORMATTER2_ID, | ||
| 230 | INPUT_FORMATTER3_ID, | ||
| 231 | N_INPUT_FORMATTER_ID | ||
| 232 | } input_formatter_ID_t; | ||
| 233 | |||
| 234 | /* The IF RST is outside the IF */ | ||
| 235 | #define INPUT_FORMATTER0_SRST_OFFSET 0x0824 | ||
| 236 | #define INPUT_FORMATTER1_SRST_OFFSET 0x0624 | ||
| 237 | #define INPUT_FORMATTER2_SRST_OFFSET 0x0424 | ||
| 238 | #define INPUT_FORMATTER3_SRST_OFFSET 0x0224 | ||
| 239 | |||
| 240 | #define INPUT_FORMATTER0_SRST_MASK 0x0001 | ||
| 241 | #define INPUT_FORMATTER1_SRST_MASK 0x0002 | ||
| 242 | #define INPUT_FORMATTER2_SRST_MASK 0x0004 | ||
| 243 | #define INPUT_FORMATTER3_SRST_MASK 0x0008 | ||
| 244 | |||
| 245 | typedef enum { | ||
| 246 | INPUT_SYSTEM0_ID = 0, | ||
| 247 | N_INPUT_SYSTEM_ID | ||
| 248 | } input_system_ID_t; | ||
| 249 | |||
| 250 | typedef enum { | ||
| 251 | RX0_ID = 0, | ||
| 252 | N_RX_ID | ||
| 253 | } rx_ID_t; | ||
| 254 | |||
| 255 | enum mipi_port_id { | ||
| 256 | MIPI_PORT0_ID = 0, | ||
| 257 | MIPI_PORT1_ID, | ||
| 258 | MIPI_PORT2_ID, | ||
| 259 | N_MIPI_PORT_ID | ||
| 260 | }; | ||
| 261 | |||
| 262 | #define N_RX_CHANNEL_ID 4 | ||
| 263 | |||
| 264 | /* Generic port enumeration with an internal port type ID */ | ||
| 265 | typedef enum { | ||
| 266 | CSI_PORT0_ID = 0, | ||
| 267 | CSI_PORT1_ID, | ||
| 268 | CSI_PORT2_ID, | ||
| 269 | TPG_PORT0_ID, | ||
| 270 | PRBS_PORT0_ID, | ||
| 271 | FIFO_PORT0_ID, | ||
| 272 | MEMORY_PORT0_ID, | ||
| 273 | N_INPUT_PORT_ID | ||
| 274 | } input_port_ID_t; | ||
| 275 | |||
| 276 | typedef enum { | ||
| 277 | CAPTURE_UNIT0_ID = 0, | ||
| 278 | CAPTURE_UNIT1_ID, | ||
| 279 | CAPTURE_UNIT2_ID, | ||
| 280 | ACQUISITION_UNIT0_ID, | ||
| 281 | DMA_UNIT0_ID, | ||
| 282 | CTRL_UNIT0_ID, | ||
| 283 | GPREGS_UNIT0_ID, | ||
| 284 | FIFO_UNIT0_ID, | ||
| 285 | IRQ_UNIT0_ID, | ||
| 286 | N_SUB_SYSTEM_ID | ||
| 287 | } sub_system_ID_t; | ||
| 288 | |||
| 289 | #define N_CAPTURE_UNIT_ID 3 | ||
| 290 | #define N_ACQUISITION_UNIT_ID 1 | ||
| 291 | #define N_CTRL_UNIT_ID 1 | ||
| 292 | |||
| 293 | /* | ||
| 294 | * Input-buffer Controller. | ||
| 295 | */ | ||
| 296 | typedef enum { | ||
| 297 | IBUF_CTRL0_ID = 0, /* map to ISYS2401_IBUF_CNTRL_A */ | ||
| 298 | IBUF_CTRL1_ID, /* map to ISYS2401_IBUF_CNTRL_B */ | ||
| 299 | IBUF_CTRL2_ID, /* map ISYS2401_IBUF_CNTRL_C */ | ||
| 300 | N_IBUF_CTRL_ID | ||
| 301 | } ibuf_ctrl_ID_t; | ||
| 302 | /* end of Input-buffer Controller */ | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Stream2MMIO. | ||
| 306 | */ | ||
| 307 | typedef enum { | ||
| 308 | STREAM2MMIO0_ID = 0, /* map to ISYS2401_S2M_A */ | ||
| 309 | STREAM2MMIO1_ID, /* map to ISYS2401_S2M_B */ | ||
| 310 | STREAM2MMIO2_ID, /* map to ISYS2401_S2M_C */ | ||
| 311 | N_STREAM2MMIO_ID | ||
| 312 | } stream2mmio_ID_t; | ||
| 313 | |||
| 314 | typedef enum { | ||
| 315 | /* | ||
| 316 | * Stream2MMIO 0 has 8 SIDs that are indexed by | ||
| 317 | * [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID7_ID]. | ||
| 318 | * | ||
| 319 | * Stream2MMIO 1 has 4 SIDs that are indexed by | ||
| 320 | * [STREAM2MMIO_SID0_ID...TREAM2MMIO_SID3_ID]. | ||
| 321 | * | ||
| 322 | * Stream2MMIO 2 has 4 SIDs that are indexed by | ||
| 323 | * [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID3_ID]. | ||
| 324 | */ | ||
| 325 | STREAM2MMIO_SID0_ID = 0, | ||
| 326 | STREAM2MMIO_SID1_ID, | ||
| 327 | STREAM2MMIO_SID2_ID, | ||
| 328 | STREAM2MMIO_SID3_ID, | ||
| 329 | STREAM2MMIO_SID4_ID, | ||
| 330 | STREAM2MMIO_SID5_ID, | ||
| 331 | STREAM2MMIO_SID6_ID, | ||
| 332 | STREAM2MMIO_SID7_ID, | ||
| 333 | N_STREAM2MMIO_SID_ID | ||
| 334 | } stream2mmio_sid_ID_t; | ||
| 335 | /* end of Stream2MMIO */ | ||
| 336 | |||
| 337 | /** | ||
| 338 | * Input System 2401: CSI-MIPI recevier. | ||
| 339 | */ | ||
| 340 | typedef enum { | ||
| 341 | CSI_RX_BACKEND0_ID = 0, /* map to ISYS2401_MIPI_BE_A */ | ||
| 342 | CSI_RX_BACKEND1_ID, /* map to ISYS2401_MIPI_BE_B */ | ||
| 343 | CSI_RX_BACKEND2_ID, /* map to ISYS2401_MIPI_BE_C */ | ||
| 344 | N_CSI_RX_BACKEND_ID | ||
| 345 | } csi_rx_backend_ID_t; | ||
| 346 | |||
| 347 | typedef enum { | ||
| 348 | CSI_RX_FRONTEND0_ID = 0, /* map to ISYS2401_CSI_RX_A */ | ||
| 349 | CSI_RX_FRONTEND1_ID, /* map to ISYS2401_CSI_RX_B */ | ||
| 350 | CSI_RX_FRONTEND2_ID, /* map to ISYS2401_CSI_RX_C */ | ||
| 351 | #define N_CSI_RX_FRONTEND_ID (CSI_RX_FRONTEND2_ID + 1) | ||
| 352 | } csi_rx_frontend_ID_t; | ||
| 353 | |||
| 354 | typedef enum { | ||
| 355 | CSI_RX_DLANE0_ID = 0, /* map to DLANE0 in CSI RX */ | ||
| 356 | CSI_RX_DLANE1_ID, /* map to DLANE1 in CSI RX */ | ||
| 357 | CSI_RX_DLANE2_ID, /* map to DLANE2 in CSI RX */ | ||
| 358 | CSI_RX_DLANE3_ID, /* map to DLANE3 in CSI RX */ | ||
| 359 | N_CSI_RX_DLANE_ID | ||
| 360 | } csi_rx_fe_dlane_ID_t; | ||
| 361 | /* end of CSI-MIPI receiver */ | ||
| 362 | |||
| 363 | typedef enum { | ||
| 364 | ISYS2401_DMA0_ID = 0, | ||
| 365 | N_ISYS2401_DMA_ID | ||
| 366 | } isys2401_dma_ID_t; | ||
| 367 | |||
| 368 | /** | ||
| 369 | * Pixel-generator. ("system_global.h") | ||
| 370 | */ | ||
| 371 | typedef enum { | ||
| 372 | PIXELGEN0_ID = 0, | ||
| 373 | PIXELGEN1_ID, | ||
| 374 | PIXELGEN2_ID, | ||
| 375 | N_PIXELGEN_ID | ||
| 376 | } pixelgen_ID_t; | ||
| 377 | /* end of pixel-generator. ("system_global.h") */ | ||
| 378 | |||
| 379 | typedef enum { | ||
| 380 | INPUT_SYSTEM_CSI_PORT0_ID = 0, | ||
| 381 | INPUT_SYSTEM_CSI_PORT1_ID, | ||
| 382 | INPUT_SYSTEM_CSI_PORT2_ID, | ||
| 383 | |||
| 384 | INPUT_SYSTEM_PIXELGEN_PORT0_ID, | ||
| 385 | INPUT_SYSTEM_PIXELGEN_PORT1_ID, | ||
| 386 | INPUT_SYSTEM_PIXELGEN_PORT2_ID, | ||
| 387 | |||
| 388 | N_INPUT_SYSTEM_INPUT_PORT_ID | ||
| 389 | } input_system_input_port_ID_t; | ||
| 390 | |||
| 391 | #define N_INPUT_SYSTEM_CSI_PORT 3 | ||
| 392 | |||
| 393 | typedef enum { | ||
| 394 | ISYS2401_DMA_CHANNEL_0 = 0, | ||
| 395 | ISYS2401_DMA_CHANNEL_1, | ||
| 396 | ISYS2401_DMA_CHANNEL_2, | ||
| 397 | ISYS2401_DMA_CHANNEL_3, | ||
| 398 | ISYS2401_DMA_CHANNEL_4, | ||
| 399 | ISYS2401_DMA_CHANNEL_5, | ||
| 400 | ISYS2401_DMA_CHANNEL_6, | ||
| 401 | ISYS2401_DMA_CHANNEL_7, | ||
| 402 | ISYS2401_DMA_CHANNEL_8, | ||
| 403 | ISYS2401_DMA_CHANNEL_9, | ||
| 404 | ISYS2401_DMA_CHANNEL_10, | ||
| 405 | ISYS2401_DMA_CHANNEL_11, | ||
| 406 | N_ISYS2401_DMA_CHANNEL | ||
| 407 | } isys2401_dma_channel; | ||
| 408 | |||
| 409 | enum ia_css_isp_memories { | ||
| 410 | IA_CSS_ISP_PMEM0 = 0, | ||
| 411 | IA_CSS_ISP_DMEM0, | ||
| 412 | IA_CSS_ISP_VMEM0, | ||
| 413 | IA_CSS_ISP_VAMEM0, | ||
| 414 | IA_CSS_ISP_VAMEM1, | ||
| 415 | IA_CSS_ISP_VAMEM2, | ||
| 416 | IA_CSS_ISP_HMEM0, | ||
| 417 | IA_CSS_SP_DMEM0, | ||
| 418 | IA_CSS_DDR, | ||
| 419 | N_IA_CSS_MEMORIES | ||
| 420 | }; | ||
| 421 | |||
| 422 | #define IA_CSS_NUM_MEMORIES 9 | ||
| 423 | /* For driver compatibility */ | ||
| 424 | #define N_IA_CSS_ISP_MEMORIES IA_CSS_NUM_MEMORIES | ||
| 425 | #define IA_CSS_NUM_ISP_MEMORIES IA_CSS_NUM_MEMORIES | ||
| 426 | |||
| 427 | #endif /* __SYSTEM_GLOBAL_H_INCLUDED__ */ | ||
| @@ -1,402 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Support for Intel Camera Imaging ISP subsystem. | ||
| 4 | * Copyright (c) 2015, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef __SYSTEM_LOCAL_H_INCLUDED__ | ||
| 17 | #define __SYSTEM_LOCAL_H_INCLUDED__ | ||
| 18 | |||
| 19 | #ifdef HRT_ISP_CSS_CUSTOM_HOST | ||
| 20 | #ifndef HRT_USE_VIR_ADDRS | ||
| 21 | #define HRT_USE_VIR_ADDRS | ||
| 22 | #endif | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #include "system_global.h" | ||
| 26 | |||
| 27 | #define HRT_ADDRESS_WIDTH 64 /* Surprise, this is a local property */ | ||
| 28 | |||
| 29 | /* This interface is deprecated */ | ||
| 30 | #include "hive_types.h" | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Cell specific address maps | ||
| 34 | */ | ||
| 35 | #if HRT_ADDRESS_WIDTH == 64 | ||
| 36 | |||
| 37 | #define GP_FIFO_BASE ((hrt_address)0x0000000000090104) /* This is NOT a base address */ | ||
| 38 | |||
| 39 | /* DDR */ | ||
| 40 | static const hrt_address DDR_BASE[N_DDR_ID] = { | ||
| 41 | 0x0000000120000000ULL | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* ISP */ | ||
| 45 | static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = { | ||
| 46 | 0x0000000000020000ULL | ||
| 47 | }; | ||
| 48 | |||
| 49 | static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = { | ||
| 50 | 0x0000000000200000ULL | ||
| 51 | }; | ||
| 52 | |||
| 53 | static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = { | ||
| 54 | 0x0000000000100000ULL | ||
| 55 | }; | ||
| 56 | |||
| 57 | static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = { | ||
| 58 | 0x00000000001C0000ULL, | ||
| 59 | 0x00000000001D0000ULL, | ||
| 60 | 0x00000000001E0000ULL | ||
| 61 | }; | ||
| 62 | |||
| 63 | static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = { | ||
| 64 | 0x00000000001F0000ULL | ||
| 65 | }; | ||
| 66 | |||
| 67 | /* SP */ | ||
| 68 | static const hrt_address SP_CTRL_BASE[N_SP_ID] = { | ||
| 69 | 0x0000000000010000ULL | ||
| 70 | }; | ||
| 71 | |||
| 72 | static const hrt_address SP_DMEM_BASE[N_SP_ID] = { | ||
| 73 | 0x0000000000300000ULL | ||
| 74 | }; | ||
| 75 | |||
| 76 | /* MMU */ | ||
| 77 | /* | ||
| 78 | * MMU0_ID: The data MMU | ||
| 79 | * MMU1_ID: The icache MMU | ||
| 80 | */ | ||
| 81 | static const hrt_address MMU_BASE[N_MMU_ID] = { | ||
| 82 | 0x0000000000070000ULL, | ||
| 83 | 0x00000000000A0000ULL | ||
| 84 | }; | ||
| 85 | |||
| 86 | /* DMA */ | ||
| 87 | static const hrt_address DMA_BASE[N_DMA_ID] = { | ||
| 88 | 0x0000000000040000ULL | ||
| 89 | }; | ||
| 90 | |||
| 91 | static const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID] = { | ||
| 92 | 0x00000000000CA000ULL | ||
| 93 | }; | ||
| 94 | |||
| 95 | /* IRQ */ | ||
| 96 | static const hrt_address IRQ_BASE[N_IRQ_ID] = { | ||
| 97 | 0x0000000000000500ULL, | ||
| 98 | 0x0000000000030A00ULL, | ||
| 99 | 0x000000000008C000ULL, | ||
| 100 | 0x0000000000090200ULL | ||
| 101 | }; | ||
| 102 | |||
| 103 | /* | ||
| 104 | 0x0000000000000500ULL}; | ||
| 105 | */ | ||
| 106 | |||
| 107 | /* GDC */ | ||
| 108 | static const hrt_address GDC_BASE[N_GDC_ID] = { | ||
| 109 | 0x0000000000050000ULL, | ||
| 110 | 0x0000000000060000ULL | ||
| 111 | }; | ||
| 112 | |||
| 113 | /* FIFO_MONITOR (not a subset of GP_DEVICE) */ | ||
| 114 | static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = { | ||
| 115 | 0x0000000000000000ULL | ||
| 116 | }; | ||
| 117 | |||
| 118 | /* | ||
| 119 | static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = { | ||
| 120 | 0x0000000000000000ULL}; | ||
| 121 | |||
| 122 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 123 | 0x0000000000090000ULL}; | ||
| 124 | */ | ||
| 125 | |||
| 126 | /* GP_DEVICE (single base for all separate GP_REG instances) */ | ||
| 127 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 128 | 0x0000000000000000ULL | ||
| 129 | }; | ||
| 130 | |||
| 131 | /*GP TIMER , all timer registers are inter-twined, | ||
| 132 | * so, having multiple base addresses for | ||
| 133 | * different timers does not help*/ | ||
| 134 | static const hrt_address GP_TIMER_BASE = | ||
| 135 | (hrt_address)0x0000000000000600ULL; | ||
| 136 | |||
| 137 | /* GPIO */ | ||
| 138 | static const hrt_address GPIO_BASE[N_GPIO_ID] = { | ||
| 139 | 0x0000000000000400ULL | ||
| 140 | }; | ||
| 141 | |||
| 142 | /* TIMED_CTRL */ | ||
| 143 | static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = { | ||
| 144 | 0x0000000000000100ULL | ||
| 145 | }; | ||
| 146 | |||
| 147 | /* INPUT_FORMATTER */ | ||
| 148 | static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = { | ||
| 149 | 0x0000000000030000ULL, | ||
| 150 | 0x0000000000030200ULL, | ||
| 151 | 0x0000000000030400ULL, | ||
| 152 | 0x0000000000030600ULL | ||
| 153 | }; /* memcpy() */ | ||
| 154 | |||
| 155 | /* INPUT_SYSTEM */ | ||
| 156 | static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = { | ||
| 157 | 0x0000000000080000ULL | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* 0x0000000000081000ULL, */ /* capture A */ | ||
| 161 | /* 0x0000000000082000ULL, */ /* capture B */ | ||
| 162 | /* 0x0000000000083000ULL, */ /* capture C */ | ||
| 163 | /* 0x0000000000084000ULL, */ /* Acquisition */ | ||
| 164 | /* 0x0000000000085000ULL, */ /* DMA */ | ||
| 165 | /* 0x0000000000089000ULL, */ /* ctrl */ | ||
| 166 | /* 0x000000000008A000ULL, */ /* GP regs */ | ||
| 167 | /* 0x000000000008B000ULL, */ /* FIFO */ | ||
| 168 | /* 0x000000000008C000ULL, */ /* IRQ */ | ||
| 169 | |||
| 170 | /* RX, the MIPI lane control regs start at offset 0 */ | ||
| 171 | static const hrt_address RX_BASE[N_RX_ID] = { | ||
| 172 | 0x0000000000080100ULL | ||
| 173 | }; | ||
| 174 | |||
| 175 | /* IBUF_CTRL, part of the Input System 2401 */ | ||
| 176 | static const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID] = { | ||
| 177 | 0x00000000000C1800ULL, /* ibuf controller A */ | ||
| 178 | 0x00000000000C3800ULL, /* ibuf controller B */ | ||
| 179 | 0x00000000000C5800ULL /* ibuf controller C */ | ||
| 180 | }; | ||
| 181 | |||
| 182 | /* ISYS IRQ Controllers, part of the Input System 2401 */ | ||
| 183 | static const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID] = { | ||
| 184 | 0x00000000000C1400ULL, /* port a */ | ||
| 185 | 0x00000000000C3400ULL, /* port b */ | ||
| 186 | 0x00000000000C5400ULL /* port c */ | ||
| 187 | }; | ||
| 188 | |||
| 189 | /* CSI FE, part of the Input System 2401 */ | ||
| 190 | static const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID] = { | ||
| 191 | 0x00000000000C0400ULL, /* csi fe controller A */ | ||
| 192 | 0x00000000000C2400ULL, /* csi fe controller B */ | ||
| 193 | 0x00000000000C4400ULL /* csi fe controller C */ | ||
| 194 | }; | ||
| 195 | |||
| 196 | /* CSI BE, part of the Input System 2401 */ | ||
| 197 | static const hrt_address CSI_RX_BE_CTRL_BASE[N_CSI_RX_BACKEND_ID] = { | ||
| 198 | 0x00000000000C0800ULL, /* csi be controller A */ | ||
| 199 | 0x00000000000C2800ULL, /* csi be controller B */ | ||
| 200 | 0x00000000000C4800ULL /* csi be controller C */ | ||
| 201 | }; | ||
| 202 | |||
| 203 | /* PIXEL Generator, part of the Input System 2401 */ | ||
| 204 | static const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID] = { | ||
| 205 | 0x00000000000C1000ULL, /* pixel gen controller A */ | ||
| 206 | 0x00000000000C3000ULL, /* pixel gen controller B */ | ||
| 207 | 0x00000000000C5000ULL /* pixel gen controller C */ | ||
| 208 | }; | ||
| 209 | |||
| 210 | /* Stream2MMIO, part of the Input System 2401 */ | ||
| 211 | static const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID] = { | ||
| 212 | 0x00000000000C0C00ULL, /* stream2mmio controller A */ | ||
| 213 | 0x00000000000C2C00ULL, /* stream2mmio controller B */ | ||
| 214 | 0x00000000000C4C00ULL /* stream2mmio controller C */ | ||
| 215 | }; | ||
| 216 | #elif HRT_ADDRESS_WIDTH == 32 | ||
| 217 | |||
| 218 | #define GP_FIFO_BASE ((hrt_address)0x00090104) /* This is NOT a base address */ | ||
| 219 | |||
| 220 | /* DDR : Attention, this value not defined in 32-bit */ | ||
| 221 | static const hrt_address DDR_BASE[N_DDR_ID] = { | ||
| 222 | 0x00000000UL | ||
| 223 | }; | ||
| 224 | |||
| 225 | /* ISP */ | ||
| 226 | static const hrt_address ISP_CTRL_BASE[N_ISP_ID] = { | ||
| 227 | 0x00020000UL | ||
| 228 | }; | ||
| 229 | |||
| 230 | static const hrt_address ISP_DMEM_BASE[N_ISP_ID] = { | ||
| 231 | 0xffffffffUL | ||
| 232 | }; | ||
| 233 | |||
| 234 | static const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = { | ||
| 235 | 0xffffffffUL | ||
| 236 | }; | ||
| 237 | |||
| 238 | static const hrt_address ISP_VAMEM_BASE[N_VAMEM_ID] = { | ||
| 239 | 0xffffffffUL, | ||
| 240 | 0xffffffffUL, | ||
| 241 | 0xffffffffUL | ||
| 242 | }; | ||
| 243 | |||
| 244 | static const hrt_address ISP_HMEM_BASE[N_HMEM_ID] = { | ||
| 245 | 0xffffffffUL | ||
| 246 | }; | ||
| 247 | |||
| 248 | /* SP */ | ||
| 249 | static const hrt_address SP_CTRL_BASE[N_SP_ID] = { | ||
| 250 | 0x00010000UL | ||
| 251 | }; | ||
| 252 | |||
| 253 | static const hrt_address SP_DMEM_BASE[N_SP_ID] = { | ||
| 254 | 0x00300000UL | ||
| 255 | }; | ||
| 256 | |||
| 257 | /* MMU */ | ||
| 258 | /* | ||
| 259 | * MMU0_ID: The data MMU | ||
| 260 | * MMU1_ID: The icache MMU | ||
| 261 | */ | ||
| 262 | static const hrt_address MMU_BASE[N_MMU_ID] = { | ||
| 263 | 0x00070000UL, | ||
| 264 | 0x000A0000UL | ||
| 265 | }; | ||
| 266 | |||
| 267 | /* DMA */ | ||
| 268 | static const hrt_address DMA_BASE[N_DMA_ID] = { | ||
| 269 | 0x00040000UL | ||
| 270 | }; | ||
| 271 | |||
| 272 | static const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID] = { | ||
| 273 | 0x000CA000UL | ||
| 274 | }; | ||
| 275 | |||
| 276 | /* IRQ */ | ||
| 277 | static const hrt_address IRQ_BASE[N_IRQ_ID] = { | ||
| 278 | 0x00000500UL, | ||
| 279 | 0x00030A00UL, | ||
| 280 | 0x0008C000UL, | ||
| 281 | 0x00090200UL | ||
| 282 | }; | ||
| 283 | |||
| 284 | /* | ||
| 285 | 0x00000500UL}; | ||
| 286 | */ | ||
| 287 | |||
| 288 | /* GDC */ | ||
| 289 | static const hrt_address GDC_BASE[N_GDC_ID] = { | ||
| 290 | 0x00050000UL, | ||
| 291 | 0x00060000UL | ||
| 292 | }; | ||
| 293 | |||
| 294 | /* FIFO_MONITOR (not a subset of GP_DEVICE) */ | ||
| 295 | static const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = { | ||
| 296 | 0x00000000UL | ||
| 297 | }; | ||
| 298 | |||
| 299 | /* | ||
| 300 | static const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = { | ||
| 301 | 0x00000000UL}; | ||
| 302 | |||
| 303 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 304 | 0x00090000UL}; | ||
| 305 | */ | ||
| 306 | |||
| 307 | /* GP_DEVICE (single base for all separate GP_REG instances) */ | ||
| 308 | static const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 309 | 0x00000000UL | ||
| 310 | }; | ||
| 311 | |||
| 312 | /*GP TIMER , all timer registers are inter-twined, | ||
| 313 | * so, having multiple base addresses for | ||
| 314 | * different timers does not help*/ | ||
| 315 | static const hrt_address GP_TIMER_BASE = | ||
| 316 | (hrt_address)0x00000600UL; | ||
| 317 | /* GPIO */ | ||
| 318 | static const hrt_address GPIO_BASE[N_GPIO_ID] = { | ||
| 319 | 0x00000400UL | ||
| 320 | }; | ||
| 321 | |||
| 322 | /* TIMED_CTRL */ | ||
| 323 | static const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = { | ||
| 324 | 0x00000100UL | ||
| 325 | }; | ||
| 326 | |||
| 327 | /* INPUT_FORMATTER */ | ||
| 328 | static const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = { | ||
| 329 | 0x00030000UL, | ||
| 330 | 0x00030200UL, | ||
| 331 | 0x00030400UL | ||
| 332 | }; | ||
| 333 | |||
| 334 | /* 0x00030600UL, */ /* memcpy() */ | ||
| 335 | |||
| 336 | /* INPUT_SYSTEM */ | ||
| 337 | static const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = { | ||
| 338 | 0x00080000UL | ||
| 339 | }; | ||
| 340 | |||
| 341 | /* 0x00081000UL, */ /* capture A */ | ||
| 342 | /* 0x00082000UL, */ /* capture B */ | ||
| 343 | /* 0x00083000UL, */ /* capture C */ | ||
| 344 | /* 0x00084000UL, */ /* Acquisition */ | ||
| 345 | /* 0x00085000UL, */ /* DMA */ | ||
| 346 | /* 0x00089000UL, */ /* ctrl */ | ||
| 347 | /* 0x0008A000UL, */ /* GP regs */ | ||
| 348 | /* 0x0008B000UL, */ /* FIFO */ | ||
| 349 | /* 0x0008C000UL, */ /* IRQ */ | ||
| 350 | |||
| 351 | /* RX, the MIPI lane control regs start at offset 0 */ | ||
| 352 | static const hrt_address RX_BASE[N_RX_ID] = { | ||
| 353 | 0x00080100UL | ||
| 354 | }; | ||
| 355 | |||
| 356 | /* IBUF_CTRL, part of the Input System 2401 */ | ||
| 357 | static const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID] = { | ||
| 358 | 0x000C1800UL, /* ibuf controller A */ | ||
| 359 | 0x000C3800UL, /* ibuf controller B */ | ||
| 360 | 0x000C5800UL /* ibuf controller C */ | ||
| 361 | }; | ||
| 362 | |||
| 363 | /* ISYS IRQ Controllers, part of the Input System 2401 */ | ||
| 364 | static const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID] = { | ||
| 365 | 0x000C1400ULL, /* port a */ | ||
| 366 | 0x000C3400ULL, /* port b */ | ||
| 367 | 0x000C5400ULL /* port c */ | ||
| 368 | }; | ||
| 369 | |||
| 370 | /* CSI FE, part of the Input System 2401 */ | ||
| 371 | static const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID] = { | ||
| 372 | 0x000C0400UL, /* csi fe controller A */ | ||
| 373 | 0x000C2400UL, /* csi fe controller B */ | ||
| 374 | 0x000C4400UL /* csi fe controller C */ | ||
| 375 | }; | ||
| 376 | |||
| 377 | /* CSI BE, part of the Input System 2401 */ | ||
| 378 | static const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_BACKEND_ID] = { | ||
| 379 | 0x000C0800UL, /* csi be controller A */ | ||
| 380 | 0x000C2800UL, /* csi be controller B */ | ||
| 381 | 0x000C4800UL /* csi be controller C */ | ||
| 382 | }; | ||
| 383 | |||
| 384 | /* PIXEL Generator, part of the Input System 2401 */ | ||
| 385 | static const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID] = { | ||
| 386 | 0x000C1000UL, /* pixel gen controller A */ | ||
| 387 | 0x000C3000UL, /* pixel gen controller B */ | ||
| 388 | 0x000C5000UL /* pixel gen controller C */ | ||
| 389 | }; | ||
| 390 | |||
| 391 | /* Stream2MMIO, part of the Input System 2401 */ | ||
| 392 | static const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID] = { | ||
| 393 | 0x000C0C00UL, /* stream2mmio controller A */ | ||
| 394 | 0x000C2C00UL, /* stream2mmio controller B */ | ||
| 395 | 0x000C4C00UL /* stream2mmio controller C */ | ||
| 396 | }; | ||
| 397 | |||
| 398 | #else | ||
| 399 | #error "system_local.h: HRT_ADDRESS_WIDTH must be one of {32,64}" | ||
| 400 | #endif | ||
| 401 | |||
| 402 | #endif /* __SYSTEM_LOCAL_H_INCLUDED__ */ | ||
| @@ -1841,8 +1841,13 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, · 1840 unmodified lines | |||
| 1841 | #endif | 1841 | #endif |
| 1842 | 1842 | ||
| 1843 | #if !defined(HAS_NO_INPUT_SYSTEM) | 1843 | #if !defined(HAS_NO_INPUT_SYSTEM) |
| 1844 | dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN, | 1844 | |
| 1845 | ISP_DMA_MAX_BURST_LENGTH); | 1845 | if (!IS_ISP2401) |
| 1846 | dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN, | ||
| 1847 | ISP2400_DMA_MAX_BURST_LENGTH); | ||
| 1848 | else | ||
| 1849 | dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN, | ||
| 1850 | ISP2401_DMA_MAX_BURST_LENGTH); | ||
| 1846 | 1851 | ||
| 1847 | if (ia_css_isys_init() != INPUT_SYSTEM_ERR_NO_ERROR) | 1852 | if (ia_css_isys_init() != INPUT_SYSTEM_ERR_NO_ERROR) |
| 1848 | err = -EINVAL; | 1853 | err = -EINVAL; |
| @@ -4,8 +4,403 @@ · 3 unmodified lines | |||
| 4 | * (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 4 | * (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #ifndef __SYSTEM_GLOBAL_H_INCLUDED__ | ||
| 8 | #define __SYSTEM_GLOBAL_H_INCLUDED__ | ||
| 9 | |||
| 10 | /* | ||
| 11 | * Create a list of HAS and IS properties that defines the system | ||
| 12 | * Those are common for both ISP2400 and ISP2401 | ||
| 13 | * | ||
| 14 | * The configuration assumes the following | ||
| 15 | * - The system is hetereogeneous; Multiple cells and devices classes | ||
| 16 | * - The cell and device instances are homogeneous, each device type | ||
| 17 | * belongs to the same class | ||
| 18 | * - Device instances supporting a subset of the class capabilities are | ||
| 19 | * allowed | ||
| 20 | * | ||
| 21 | * We could manage different device classes through the enumerated | ||
| 22 | * lists (C) or the use of classes (C++), but that is presently not | ||
| 23 | * fully supported | ||
| 24 | * | ||
| 25 | * N.B. the 3 input formatters are of 2 different classess | ||
| 26 | */ | ||
| 27 | |||
| 28 | #define HAS_MMU_VERSION_2 | ||
| 29 | #define HAS_DMA_VERSION_2 | ||
| 30 | #define HAS_GDC_VERSION_2 | ||
| 31 | #define HAS_VAMEM_VERSION_2 | ||
| 32 | #define HAS_HMEM_VERSION_1 | ||
| 33 | #define HAS_BAMEM_VERSION_2 | ||
| 34 | #define HAS_IRQ_VERSION_2 | ||
| 35 | #define HAS_IRQ_MAP_VERSION_2 | ||
| 36 | #define HAS_INPUT_FORMATTER_VERSION_2 | ||
| 37 | #define HAS_INPUT_SYSTEM_VERSION_2 | ||
| 38 | #define HAS_BUFFERED_SENSOR | ||
| 39 | #define HAS_FIFO_MONITORS_VERSION_2 | ||
| 40 | #define HAS_GP_DEVICE_VERSION_2 | ||
| 41 | #define HAS_GPIO_VERSION_1 | ||
| 42 | #define HAS_TIMED_CTRL_VERSION_1 | ||
| 43 | #define HAS_RX_VERSION_2 | ||
| 44 | |||
| 45 | /* per-frame parameter handling support */ | ||
| 46 | #define SH_CSS_ENABLE_PER_FRAME_PARAMS | ||
| 47 | |||
| 48 | #define DMA_DDR_TO_VAMEM_WORKAROUND | ||
| 49 | #define DMA_DDR_TO_HMEM_WORKAROUND | ||
| 50 | |||
| 51 | /* | ||
| 52 | * The longest allowed (uninteruptible) bus transfer, does not | ||
| 53 | * take stalling into account | ||
| 54 | */ | ||
| 55 | #define HIVE_ISP_MAX_BURST_LENGTH 1024 | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Maximum allowed burst length in words for the ISP DMA | ||
| 59 | * This value is set to 2 to prevent the ISP DMA from blocking | ||
| 60 | * the bus for too long; as the input system can only buffer | ||
| 61 | * 2 lines on Moorefield and Cherrytrail, the input system buffers | ||
| 62 | * may overflow if blocked for too long (BZ 2726). | ||
| 63 | */ | ||
| 64 | #define ISP2400_DMA_MAX_BURST_LENGTH 128 | ||
| 65 | #define ISP2401_DMA_MAX_BURST_LENGTH 2 | ||
| 66 | |||
| 7 | #ifdef ISP2401 | 67 | #ifdef ISP2401 |
| 8 | # include "isp2401_system_global.h" | 68 | # include "isp2401_system_global.h" |
| 9 | #else | 69 | #else |
| 10 | # include "isp2400_system_global.h" | 70 | # include "isp2400_system_global.h" |
| 11 | #endif | 71 | #endif |
| 72 | |||
| 73 | #include <hive_isp_css_defs.h> | ||
| 74 | #include <type_support.h> | ||
| 75 | |||
| 76 | /* This interface is deprecated */ | ||
| 77 | #include "hive_types.h" | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Semi global. "HRT" is accessible from SP, but the HRT types do not fully apply | ||
| 81 | */ | ||
| 82 | #define HRT_VADDRESS_WIDTH 32 | ||
| 83 | |||
| 84 | #define SIZEOF_HRT_REG (HRT_DATA_WIDTH >> 3) | ||
| 85 | #define HIVE_ISP_CTRL_DATA_BYTES (HIVE_ISP_CTRL_DATA_WIDTH / 8) | ||
| 86 | |||
| 87 | /* The main bus connecting all devices */ | ||
| 88 | #define HRT_BUS_WIDTH HIVE_ISP_CTRL_DATA_WIDTH | ||
| 89 | #define HRT_BUS_BYTES HIVE_ISP_CTRL_DATA_BYTES | ||
| 90 | |||
| 91 | typedef u32 hrt_bus_align_t; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Enumerate the devices, device access through the API is by ID, | ||
| 95 | * through the DLI by address. The enumerator terminators are used | ||
| 96 | * to size the wiring arrays and as an exception value. | ||
| 97 | */ | ||
| 98 | typedef enum { | ||
| 99 | DDR0_ID = 0, | ||
| 100 | N_DDR_ID | ||
| 101 | } ddr_ID_t; | ||
| 102 | |||
| 103 | typedef enum { | ||
| 104 | ISP0_ID = 0, | ||
| 105 | N_ISP_ID | ||
| 106 | } isp_ID_t; | ||
| 107 | |||
| 108 | typedef enum { | ||
| 109 | SP0_ID = 0, | ||
| 110 | N_SP_ID | ||
| 111 | } sp_ID_t; | ||
| 112 | |||
| 113 | typedef enum { | ||
| 114 | MMU0_ID = 0, | ||
| 115 | MMU1_ID, | ||
| 116 | N_MMU_ID | ||
| 117 | } mmu_ID_t; | ||
| 118 | |||
| 119 | typedef enum { | ||
| 120 | DMA0_ID = 0, | ||
| 121 | N_DMA_ID | ||
| 122 | } dma_ID_t; | ||
| 123 | |||
| 124 | typedef enum { | ||
| 125 | GDC0_ID = 0, | ||
| 126 | GDC1_ID, | ||
| 127 | N_GDC_ID | ||
| 128 | } gdc_ID_t; | ||
| 129 | |||
| 130 | /* this extra define is needed because we want to use it also | ||
| 131 | in the preprocessor, and that doesn't work with enums. | ||
| 132 | */ | ||
| 133 | #define N_GDC_ID_CPP 2 | ||
| 134 | |||
| 135 | typedef enum { | ||
| 136 | VAMEM0_ID = 0, | ||
| 137 | VAMEM1_ID, | ||
| 138 | VAMEM2_ID, | ||
| 139 | N_VAMEM_ID | ||
| 140 | } vamem_ID_t; | ||
| 141 | |||
| 142 | typedef enum { | ||
| 143 | BAMEM0_ID = 0, | ||
| 144 | N_BAMEM_ID | ||
| 145 | } bamem_ID_t; | ||
| 146 | |||
| 147 | typedef enum { | ||
| 148 | HMEM0_ID = 0, | ||
| 149 | N_HMEM_ID | ||
| 150 | } hmem_ID_t; | ||
| 151 | |||
| 152 | typedef enum { | ||
| 153 | IRQ0_ID = 0, /* GP IRQ block */ | ||
| 154 | IRQ1_ID, /* Input formatter */ | ||
| 155 | IRQ2_ID, /* input system */ | ||
| 156 | IRQ3_ID, /* input selector */ | ||
| 157 | N_IRQ_ID | ||
| 158 | } irq_ID_t; | ||
| 159 | |||
| 160 | typedef enum { | ||
| 161 | FIFO_MONITOR0_ID = 0, | ||
| 162 | N_FIFO_MONITOR_ID | ||
| 163 | } fifo_monitor_ID_t; | ||
| 164 | |||
| 165 | typedef enum { | ||
| 166 | GP_DEVICE0_ID = 0, | ||
| 167 | N_GP_DEVICE_ID | ||
| 168 | } gp_device_ID_t; | ||
| 169 | |||
| 170 | typedef enum { | ||
| 171 | GP_TIMER0_ID = 0, | ||
| 172 | GP_TIMER1_ID, | ||
| 173 | GP_TIMER2_ID, | ||
| 174 | GP_TIMER3_ID, | ||
| 175 | GP_TIMER4_ID, | ||
| 176 | GP_TIMER5_ID, | ||
| 177 | GP_TIMER6_ID, | ||
| 178 | GP_TIMER7_ID, | ||
| 179 | N_GP_TIMER_ID | ||
| 180 | } gp_timer_ID_t; | ||
| 181 | |||
| 182 | typedef enum { | ||
| 183 | GPIO0_ID = 0, | ||
| 184 | N_GPIO_ID | ||
| 185 | } gpio_ID_t; | ||
| 186 | |||
| 187 | typedef enum { | ||
| 188 | TIMED_CTRL0_ID = 0, | ||
| 189 | N_TIMED_CTRL_ID | ||
| 190 | } timed_ctrl_ID_t; | ||
| 191 | |||
| 192 | typedef enum { | ||
| 193 | INPUT_FORMATTER0_ID = 0, | ||
| 194 | INPUT_FORMATTER1_ID, | ||
| 195 | INPUT_FORMATTER2_ID, | ||
| 196 | INPUT_FORMATTER3_ID, | ||
| 197 | N_INPUT_FORMATTER_ID | ||
| 198 | } input_formatter_ID_t; | ||
| 199 | |||
| 200 | /* The IF RST is outside the IF */ | ||
| 201 | #define INPUT_FORMATTER0_SRST_OFFSET 0x0824 | ||
| 202 | #define INPUT_FORMATTER1_SRST_OFFSET 0x0624 | ||
| 203 | #define INPUT_FORMATTER2_SRST_OFFSET 0x0424 | ||
| 204 | #define INPUT_FORMATTER3_SRST_OFFSET 0x0224 | ||
| 205 | |||
| 206 | #define INPUT_FORMATTER0_SRST_MASK 0x0001 | ||
| 207 | #define INPUT_FORMATTER1_SRST_MASK 0x0002 | ||
| 208 | #define INPUT_FORMATTER2_SRST_MASK 0x0004 | ||
| 209 | #define INPUT_FORMATTER3_SRST_MASK 0x0008 | ||
| 210 | |||
| 211 | typedef enum { | ||
| 212 | INPUT_SYSTEM0_ID = 0, | ||
| 213 | N_INPUT_SYSTEM_ID | ||
| 214 | } input_system_ID_t; | ||
| 215 | |||
| 216 | typedef enum { | ||
| 217 | RX0_ID = 0, | ||
| 218 | N_RX_ID | ||
| 219 | } rx_ID_t; | ||
| 220 | |||
| 221 | enum mipi_port_id { | ||
| 222 | MIPI_PORT0_ID = 0, | ||
| 223 | MIPI_PORT1_ID, | ||
| 224 | MIPI_PORT2_ID, | ||
| 225 | N_MIPI_PORT_ID | ||
| 226 | }; | ||
| 227 | |||
| 228 | #define N_RX_CHANNEL_ID 4 | ||
| 229 | |||
| 230 | /* Generic port enumeration with an internal port type ID */ | ||
| 231 | typedef enum { | ||
| 232 | CSI_PORT0_ID = 0, | ||
| 233 | CSI_PORT1_ID, | ||
| 234 | CSI_PORT2_ID, | ||
| 235 | TPG_PORT0_ID, | ||
| 236 | PRBS_PORT0_ID, | ||
| 237 | FIFO_PORT0_ID, | ||
| 238 | MEMORY_PORT0_ID, | ||
| 239 | N_INPUT_PORT_ID | ||
| 240 | } input_port_ID_t; | ||
| 241 | |||
| 242 | typedef enum { | ||
| 243 | CAPTURE_UNIT0_ID = 0, | ||
| 244 | CAPTURE_UNIT1_ID, | ||
| 245 | CAPTURE_UNIT2_ID, | ||
| 246 | ACQUISITION_UNIT0_ID, | ||
| 247 | DMA_UNIT0_ID, | ||
| 248 | CTRL_UNIT0_ID, | ||
| 249 | GPREGS_UNIT0_ID, | ||
| 250 | FIFO_UNIT0_ID, | ||
| 251 | IRQ_UNIT0_ID, | ||
| 252 | N_SUB_SYSTEM_ID | ||
| 253 | } sub_system_ID_t; | ||
| 254 | |||
| 255 | #define N_CAPTURE_UNIT_ID 3 | ||
| 256 | #define N_ACQUISITION_UNIT_ID 1 | ||
| 257 | #define N_CTRL_UNIT_ID 1 | ||
| 258 | |||
| 259 | |||
| 260 | enum ia_css_isp_memories { | ||
| 261 | IA_CSS_ISP_PMEM0 = 0, | ||
| 262 | IA_CSS_ISP_DMEM0, | ||
| 263 | IA_CSS_ISP_VMEM0, | ||
| 264 | IA_CSS_ISP_VAMEM0, | ||
| 265 | IA_CSS_ISP_VAMEM1, | ||
| 266 | IA_CSS_ISP_VAMEM2, | ||
| 267 | IA_CSS_ISP_HMEM0, | ||
| 268 | IA_CSS_SP_DMEM0, | ||
| 269 | IA_CSS_DDR, | ||
| 270 | N_IA_CSS_MEMORIES | ||
| 271 | }; | ||
| 272 | |||
| 273 | #define IA_CSS_NUM_MEMORIES 9 | ||
| 274 | /* For driver compatibility */ | ||
| 275 | #define N_IA_CSS_ISP_MEMORIES IA_CSS_NUM_MEMORIES | ||
| 276 | #define IA_CSS_NUM_ISP_MEMORIES IA_CSS_NUM_MEMORIES | ||
| 277 | |||
| 278 | /* | ||
| 279 | * ISP2401 specific enums | ||
| 280 | */ | ||
| 281 | |||
| 282 | typedef enum { | ||
| 283 | ISYS_IRQ0_ID = 0, /* port a */ | ||
| 284 | ISYS_IRQ1_ID, /* port b */ | ||
| 285 | ISYS_IRQ2_ID, /* port c */ | ||
| 286 | N_ISYS_IRQ_ID | ||
| 287 | } isys_irq_ID_t; | ||
| 288 | |||
| 289 | |||
| 290 | /* | ||
| 291 | * Input-buffer Controller. | ||
| 292 | */ | ||
| 293 | typedef enum { | ||
| 294 | IBUF_CTRL0_ID = 0, /* map to ISYS2401_IBUF_CNTRL_A */ | ||
| 295 | IBUF_CTRL1_ID, /* map to ISYS2401_IBUF_CNTRL_B */ | ||
| 296 | IBUF_CTRL2_ID, /* map ISYS2401_IBUF_CNTRL_C */ | ||
| 297 | N_IBUF_CTRL_ID | ||
| 298 | } ibuf_ctrl_ID_t; | ||
| 299 | /* end of Input-buffer Controller */ | ||
| 300 | |||
| 301 | /* | ||
| 302 | * Stream2MMIO. | ||
| 303 | */ | ||
| 304 | typedef enum { | ||
| 305 | STREAM2MMIO0_ID = 0, /* map to ISYS2401_S2M_A */ | ||
| 306 | STREAM2MMIO1_ID, /* map to ISYS2401_S2M_B */ | ||
| 307 | STREAM2MMIO2_ID, /* map to ISYS2401_S2M_C */ | ||
| 308 | N_STREAM2MMIO_ID | ||
| 309 | } stream2mmio_ID_t; | ||
| 310 | |||
| 311 | typedef enum { | ||
| 312 | /* | ||
| 313 | * Stream2MMIO 0 has 8 SIDs that are indexed by | ||
| 314 | * [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID7_ID]. | ||
| 315 | * | ||
| 316 | * Stream2MMIO 1 has 4 SIDs that are indexed by | ||
| 317 | * [STREAM2MMIO_SID0_ID...TREAM2MMIO_SID3_ID]. | ||
| 318 | * | ||
| 319 | * Stream2MMIO 2 has 4 SIDs that are indexed by | ||
| 320 | * [STREAM2MMIO_SID0_ID...STREAM2MMIO_SID3_ID]. | ||
| 321 | */ | ||
| 322 | STREAM2MMIO_SID0_ID = 0, | ||
| 323 | STREAM2MMIO_SID1_ID, | ||
| 324 | STREAM2MMIO_SID2_ID, | ||
| 325 | STREAM2MMIO_SID3_ID, | ||
| 326 | STREAM2MMIO_SID4_ID, | ||
| 327 | STREAM2MMIO_SID5_ID, | ||
| 328 | STREAM2MMIO_SID6_ID, | ||
| 329 | STREAM2MMIO_SID7_ID, | ||
| 330 | N_STREAM2MMIO_SID_ID | ||
| 331 | } stream2mmio_sid_ID_t; | ||
| 332 | /* end of Stream2MMIO */ | ||
| 333 | |||
| 334 | /** | ||
| 335 | * Input System 2401: CSI-MIPI recevier. | ||
| 336 | */ | ||
| 337 | typedef enum { | ||
| 338 | CSI_RX_BACKEND0_ID = 0, /* map to ISYS2401_MIPI_BE_A */ | ||
| 339 | CSI_RX_BACKEND1_ID, /* map to ISYS2401_MIPI_BE_B */ | ||
| 340 | CSI_RX_BACKEND2_ID, /* map to ISYS2401_MIPI_BE_C */ | ||
| 341 | N_CSI_RX_BACKEND_ID | ||
| 342 | } csi_rx_backend_ID_t; | ||
| 343 | |||
| 344 | typedef enum { | ||
| 345 | CSI_RX_FRONTEND0_ID = 0, /* map to ISYS2401_CSI_RX_A */ | ||
| 346 | CSI_RX_FRONTEND1_ID, /* map to ISYS2401_CSI_RX_B */ | ||
| 347 | CSI_RX_FRONTEND2_ID, /* map to ISYS2401_CSI_RX_C */ | ||
| 348 | #define N_CSI_RX_FRONTEND_ID (CSI_RX_FRONTEND2_ID + 1) | ||
| 349 | } csi_rx_frontend_ID_t; | ||
| 350 | |||
| 351 | typedef enum { | ||
| 352 | CSI_RX_DLANE0_ID = 0, /* map to DLANE0 in CSI RX */ | ||
| 353 | CSI_RX_DLANE1_ID, /* map to DLANE1 in CSI RX */ | ||
| 354 | CSI_RX_DLANE2_ID, /* map to DLANE2 in CSI RX */ | ||
| 355 | CSI_RX_DLANE3_ID, /* map to DLANE3 in CSI RX */ | ||
| 356 | N_CSI_RX_DLANE_ID | ||
| 357 | } csi_rx_fe_dlane_ID_t; | ||
| 358 | /* end of CSI-MIPI receiver */ | ||
| 359 | |||
| 360 | typedef enum { | ||
| 361 | ISYS2401_DMA0_ID = 0, | ||
| 362 | N_ISYS2401_DMA_ID | ||
| 363 | } isys2401_dma_ID_t; | ||
| 364 | |||
| 365 | /** | ||
| 366 | * Pixel-generator. ("system_global.h") | ||
| 367 | */ | ||
| 368 | typedef enum { | ||
| 369 | PIXELGEN0_ID = 0, | ||
| 370 | PIXELGEN1_ID, | ||
| 371 | PIXELGEN2_ID, | ||
| 372 | N_PIXELGEN_ID | ||
| 373 | } pixelgen_ID_t; | ||
| 374 | /* end of pixel-generator. ("system_global.h") */ | ||
| 375 | |||
| 376 | typedef enum { | ||
| 377 | INPUT_SYSTEM_CSI_PORT0_ID = 0, | ||
| 378 | INPUT_SYSTEM_CSI_PORT1_ID, | ||
| 379 | INPUT_SYSTEM_CSI_PORT2_ID, | ||
| 380 | |||
| 381 | INPUT_SYSTEM_PIXELGEN_PORT0_ID, | ||
| 382 | INPUT_SYSTEM_PIXELGEN_PORT1_ID, | ||
| 383 | INPUT_SYSTEM_PIXELGEN_PORT2_ID, | ||
| 384 | |||
| 385 | N_INPUT_SYSTEM_INPUT_PORT_ID | ||
| 386 | } input_system_input_port_ID_t; | ||
| 387 | |||
| 388 | #define N_INPUT_SYSTEM_CSI_PORT 3 | ||
| 389 | |||
| 390 | typedef enum { | ||
| 391 | ISYS2401_DMA_CHANNEL_0 = 0, | ||
| 392 | ISYS2401_DMA_CHANNEL_1, | ||
| 393 | ISYS2401_DMA_CHANNEL_2, | ||
| 394 | ISYS2401_DMA_CHANNEL_3, | ||
| 395 | ISYS2401_DMA_CHANNEL_4, | ||
| 396 | ISYS2401_DMA_CHANNEL_5, | ||
| 397 | ISYS2401_DMA_CHANNEL_6, | ||
| 398 | ISYS2401_DMA_CHANNEL_7, | ||
| 399 | ISYS2401_DMA_CHANNEL_8, | ||
| 400 | ISYS2401_DMA_CHANNEL_9, | ||
| 401 | ISYS2401_DMA_CHANNEL_10, | ||
| 402 | ISYS2401_DMA_CHANNEL_11, | ||
| 403 | N_ISYS2401_DMA_CHANNEL | ||
| 404 | } isys2401_dma_channel; | ||
| 405 | |||
| 406 | #endif /* __SYSTEM_GLOBAL_H_INCLUDED__ */ | ||
| @@ -0,0 +1,179 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Support for Intel Camera Imaging ISP subsystem. | ||
| 4 | * Copyright (c) 2015, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include "system_local.h" | ||
| 17 | |||
| 18 | /* ISP */ | ||
| 19 | const hrt_address ISP_CTRL_BASE[N_ISP_ID] = { | ||
| 20 | 0x0000000000020000ULL | ||
| 21 | }; | ||
| 22 | |||
| 23 | const hrt_address ISP_DMEM_BASE[N_ISP_ID] = { | ||
| 24 | 0x0000000000200000ULL | ||
| 25 | }; | ||
| 26 | |||
| 27 | const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID] = { | ||
| 28 | 0x0000000000100000ULL | ||
| 29 | }; | ||
| 30 | |||
| 31 | /* SP */ | ||
| 32 | const hrt_address SP_CTRL_BASE[N_SP_ID] = { | ||
| 33 | 0x0000000000010000ULL | ||
| 34 | }; | ||
| 35 | |||
| 36 | const hrt_address SP_DMEM_BASE[N_SP_ID] = { | ||
| 37 | 0x0000000000300000ULL | ||
| 38 | }; | ||
| 39 | |||
| 40 | /* MMU */ | ||
| 41 | /* | ||
| 42 | * MMU0_ID: The data MMU | ||
| 43 | * MMU1_ID: The icache MMU | ||
| 44 | */ | ||
| 45 | const hrt_address MMU_BASE[N_MMU_ID] = { | ||
| 46 | 0x0000000000070000ULL, | ||
| 47 | 0x00000000000A0000ULL | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* DMA */ | ||
| 51 | const hrt_address DMA_BASE[N_DMA_ID] = { | ||
| 52 | 0x0000000000040000ULL | ||
| 53 | }; | ||
| 54 | |||
| 55 | const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID] = { | ||
| 56 | 0x00000000000CA000ULL | ||
| 57 | }; | ||
| 58 | |||
| 59 | /* IRQ */ | ||
| 60 | const hrt_address IRQ_BASE[N_IRQ_ID] = { | ||
| 61 | 0x0000000000000500ULL, | ||
| 62 | 0x0000000000030A00ULL, | ||
| 63 | 0x000000000008C000ULL, | ||
| 64 | 0x0000000000090200ULL | ||
| 65 | }; | ||
| 66 | |||
| 67 | /* | ||
| 68 | 0x0000000000000500ULL}; | ||
| 69 | */ | ||
| 70 | |||
| 71 | /* GDC */ | ||
| 72 | const hrt_address GDC_BASE[N_GDC_ID] = { | ||
| 73 | 0x0000000000050000ULL, | ||
| 74 | 0x0000000000060000ULL | ||
| 75 | }; | ||
| 76 | |||
| 77 | /* FIFO_MONITOR (not a subset of GP_DEVICE) */ | ||
| 78 | const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID] = { | ||
| 79 | 0x0000000000000000ULL | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* | ||
| 83 | const hrt_address GP_REGS_BASE[N_GP_REGS_ID] = { | ||
| 84 | 0x0000000000000000ULL}; | ||
| 85 | |||
| 86 | const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 87 | 0x0000000000090000ULL}; | ||
| 88 | */ | ||
| 89 | |||
| 90 | /* GP_DEVICE (single base for all separate GP_REG instances) */ | ||
| 91 | const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID] = { | ||
| 92 | 0x0000000000000000ULL | ||
| 93 | }; | ||
| 94 | |||
| 95 | /*GP TIMER , all timer registers are inter-twined, | ||
| 96 | * so, having multiple base addresses for | ||
| 97 | * different timers does not help*/ | ||
| 98 | const hrt_address GP_TIMER_BASE = | ||
| 99 | (hrt_address)0x0000000000000600ULL; | ||
| 100 | |||
| 101 | /* GPIO */ | ||
| 102 | const hrt_address GPIO_BASE[N_GPIO_ID] = { | ||
| 103 | 0x0000000000000400ULL | ||
| 104 | }; | ||
| 105 | |||
| 106 | /* TIMED_CTRL */ | ||
| 107 | const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID] = { | ||
| 108 | 0x0000000000000100ULL | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* INPUT_FORMATTER */ | ||
| 112 | const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID] = { | ||
| 113 | 0x0000000000030000ULL, | ||
| 114 | 0x0000000000030200ULL, | ||
| 115 | 0x0000000000030400ULL, | ||
| 116 | 0x0000000000030600ULL | ||
| 117 | }; /* memcpy() */ | ||
| 118 | |||
| 119 | /* INPUT_SYSTEM */ | ||
| 120 | const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID] = { | ||
| 121 | 0x0000000000080000ULL | ||
| 122 | }; | ||
| 123 | |||
| 124 | /* 0x0000000000081000ULL, */ /* capture A */ | ||
| 125 | /* 0x0000000000082000ULL, */ /* capture B */ | ||
| 126 | /* 0x0000000000083000ULL, */ /* capture C */ | ||
| 127 | /* 0x0000000000084000ULL, */ /* Acquisition */ | ||
| 128 | /* 0x0000000000085000ULL, */ /* DMA */ | ||
| 129 | /* 0x0000000000089000ULL, */ /* ctrl */ | ||
| 130 | /* 0x000000000008A000ULL, */ /* GP regs */ | ||
| 131 | /* 0x000000000008B000ULL, */ /* FIFO */ | ||
| 132 | /* 0x000000000008C000ULL, */ /* IRQ */ | ||
| 133 | |||
| 134 | /* RX, the MIPI lane control regs start at offset 0 */ | ||
| 135 | const hrt_address RX_BASE[N_RX_ID] = { | ||
| 136 | 0x0000000000080100ULL | ||
| 137 | }; | ||
| 138 | |||
| 139 | /* IBUF_CTRL, part of the Input System 2401 */ | ||
| 140 | const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID] = { | ||
| 141 | 0x00000000000C1800ULL, /* ibuf controller A */ | ||
| 142 | 0x00000000000C3800ULL, /* ibuf controller B */ | ||
| 143 | 0x00000000000C5800ULL /* ibuf controller C */ | ||
| 144 | }; | ||
| 145 | |||
| 146 | /* ISYS IRQ Controllers, part of the Input System 2401 */ | ||
| 147 | const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID] = { | ||
| 148 | 0x00000000000C1400ULL, /* port a */ | ||
| 149 | 0x00000000000C3400ULL, /* port b */ | ||
| 150 | 0x00000000000C5400ULL /* port c */ | ||
| 151 | }; | ||
| 152 | |||
| 153 | /* CSI FE, part of the Input System 2401 */ | ||
| 154 | const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID] = { | ||
| 155 | 0x00000000000C0400ULL, /* csi fe controller A */ | ||
| 156 | 0x00000000000C2400ULL, /* csi fe controller B */ | ||
| 157 | 0x00000000000C4400ULL /* csi fe controller C */ | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* CSI BE, part of the Input System 2401 */ | ||
| 161 | const hrt_address CSI_RX_BE_CTRL_BASE[N_CSI_RX_BACKEND_ID] = { | ||
| 162 | 0x00000000000C0800ULL, /* csi be controller A */ | ||
| 163 | 0x00000000000C2800ULL, /* csi be controller B */ | ||
| 164 | 0x00000000000C4800ULL /* csi be controller C */ | ||
| 165 | }; | ||
| 166 | |||
| 167 | /* PIXEL Generator, part of the Input System 2401 */ | ||
| 168 | const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID] = { | ||
| 169 | 0x00000000000C1000ULL, /* pixel gen controller A */ | ||
| 170 | 0x00000000000C3000ULL, /* pixel gen controller B */ | ||
| 171 | 0x00000000000C5000ULL /* pixel gen controller C */ | ||
| 172 | }; | ||
| 173 | |||
| 174 | /* Stream2MMIO, part of the Input System 2401 */ | ||
| 175 | const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID] = { | ||
| 176 | 0x00000000000C0C00ULL, /* stream2mmio controller A */ | ||
| 177 | 0x00000000000C2C00ULL, /* stream2mmio controller B */ | ||
| 178 | 0x00000000000C4C00ULL /* stream2mmio controller C */ | ||
| 179 | }; | ||
| @@ -1,11 +1,103 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | /* | 2 | /* |
| 4 | * (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 3 | * Support for Intel Camera Imaging ISP subsystem. |
| 4 | * Copyright (c) 2015, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 5 | */ | 14 | */ |
| 6 | 15 | ||
| 7 | #ifdef ISP2401 | 16 | #ifndef __SYSTEM_LOCAL_H_INCLUDED__ |
| 8 | # include "isp2401_system_local.h" | 17 | #define __SYSTEM_LOCAL_H_INCLUDED__ |
| 9 | #else | 18 | |
| 10 | # include "isp2400_system_local.h" | 19 | #ifdef HRT_ISP_CSS_CUSTOM_HOST |
| 20 | #ifndef HRT_USE_VIR_ADDRS | ||
| 21 | #define HRT_USE_VIR_ADDRS | ||
| 22 | #endif | ||
| 11 | #endif | 23 | #endif |
| 24 | |||
| 25 | #include "system_global.h" | ||
| 26 | |||
| 27 | /* This interface is deprecated */ | ||
| 28 | #include "hive_types.h" | ||
| 29 | |||
| 30 | /* | ||
| 31 | * Cell specific address maps | ||
| 32 | */ | ||
| 33 | |||
| 34 | #define GP_FIFO_BASE ((hrt_address)0x0000000000090104) /* This is NOT a base address */ | ||
| 35 | |||
| 36 | /* ISP */ | ||
| 37 | extern const hrt_address ISP_CTRL_BASE[N_ISP_ID]; | ||
| 38 | extern const hrt_address ISP_DMEM_BASE[N_ISP_ID]; | ||
| 39 | extern const hrt_address ISP_BAMEM_BASE[N_BAMEM_ID]; | ||
| 40 | |||
| 41 | /* SP */ | ||
| 42 | extern const hrt_address SP_CTRL_BASE[N_SP_ID]; | ||
| 43 | extern const hrt_address SP_DMEM_BASE[N_SP_ID]; | ||
| 44 | |||
| 45 | /* MMU */ | ||
| 46 | |||
| 47 | extern const hrt_address MMU_BASE[N_MMU_ID]; | ||
| 48 | |||
| 49 | /* DMA */ | ||
| 50 | extern const hrt_address DMA_BASE[N_DMA_ID]; | ||
| 51 | extern const hrt_address ISYS2401_DMA_BASE[N_ISYS2401_DMA_ID]; | ||
| 52 | |||
| 53 | /* IRQ */ | ||
| 54 | extern const hrt_address IRQ_BASE[N_IRQ_ID]; | ||
| 55 | |||
| 56 | /* GDC */ | ||
| 57 | extern const hrt_address GDC_BASE[N_GDC_ID]; | ||
| 58 | |||
| 59 | /* FIFO_MONITOR (not a subset of GP_DEVICE) */ | ||
| 60 | extern const hrt_address FIFO_MONITOR_BASE[N_FIFO_MONITOR_ID]; | ||
| 61 | |||
| 62 | /* GP_DEVICE (single base for all separate GP_REG instances) */ | ||
| 63 | extern const hrt_address GP_DEVICE_BASE[N_GP_DEVICE_ID]; | ||
| 64 | |||
| 65 | /*GP TIMER , all timer registers are inter-twined, | ||
| 66 | * so, having multiple base addresses for | ||
| 67 | * different timers does not help*/ | ||
| 68 | extern const hrt_address GP_TIMER_BASE; | ||
| 69 | |||
| 70 | /* GPIO */ | ||
| 71 | extern const hrt_address GPIO_BASE[N_GPIO_ID]; | ||
| 72 | |||
| 73 | /* TIMED_CTRL */ | ||
| 74 | extern const hrt_address TIMED_CTRL_BASE[N_TIMED_CTRL_ID]; | ||
| 75 | |||
| 76 | /* INPUT_FORMATTER */ | ||
| 77 | extern const hrt_address INPUT_FORMATTER_BASE[N_INPUT_FORMATTER_ID]; | ||
| 78 | |||
| 79 | /* INPUT_SYSTEM */ | ||
| 80 | extern const hrt_address INPUT_SYSTEM_BASE[N_INPUT_SYSTEM_ID]; | ||
| 81 | |||
| 82 | /* RX, the MIPI lane control regs start at offset 0 */ | ||
| 83 | extern const hrt_address RX_BASE[N_RX_ID]; | ||
| 84 | |||
| 85 | /* IBUF_CTRL, part of the Input System 2401 */ | ||
| 86 | extern const hrt_address IBUF_CTRL_BASE[N_IBUF_CTRL_ID]; | ||
| 87 | |||
| 88 | /* ISYS IRQ Controllers, part of the Input System 2401 */ | ||
| 89 | extern const hrt_address ISYS_IRQ_BASE[N_ISYS_IRQ_ID]; | ||
| 90 | |||
| 91 | /* CSI FE, part of the Input System 2401 */ | ||
| 92 | extern const hrt_address CSI_RX_FE_CTRL_BASE[N_CSI_RX_FRONTEND_ID]; | ||
| 93 | |||
| 94 | /* CSI BE, part of the Input System 2401 */ | ||
| 95 | extern const hrt_address CSI_RX_BE_CTRL_BASE[N_CSI_RX_BACKEND_ID]; | ||
| 96 | |||
| 97 | /* PIXEL Generator, part of the Input System 2401 */ | ||
| 98 | extern const hrt_address PIXELGEN_CTRL_BASE[N_PIXELGEN_ID]; | ||
| 99 | |||
| 100 | /* Stream2MMIO, part of the Input System 2401 */ | ||
| 101 | extern const hrt_address STREAM2MMIO_CTRL_BASE[N_STREAM2MMIO_ID]; | ||
| 102 | |||
| 103 | #endif /* __SYSTEM_LOCAL_H_INCLUDED__ */ | ||
| @@ -61,11 +61,25 @@ static int prism2sta_probe_usb(struct usb_interface *interface, · 60 unmodified lines | |||
| 61 | const struct usb_device_id *id) | 61 | const struct usb_device_id *id) |
| 62 | { | 62 | { |
| 63 | struct usb_device *dev; | 63 | struct usb_device *dev; |
| 64 | 64 | const struct usb_endpoint_descriptor *epd; | |
| 65 | const struct usb_host_interface *iface_desc = interface->cur_altsetting; | ||
| 65 | struct wlandevice *wlandev = NULL; | 66 | struct wlandevice *wlandev = NULL; |
| 66 | struct hfa384x *hw = NULL; | 67 | struct hfa384x *hw = NULL; |
| 67 | int result = 0; | 68 | int result = 0; |
| 68 | 69 | ||
| 70 | if (iface_desc->desc.bNumEndpoints != 2) { | ||
| 71 | result = -ENODEV; | ||
| 72 | goto failed; | ||
| 73 | } | ||
| 74 | |||
| 75 | result = -EINVAL; | ||
| 76 | epd = &iface_desc->endpoint[1].desc; | ||
| 77 | if (!usb_endpoint_is_bulk_in(epd)) | ||
| 78 | goto failed; | ||
| 79 | epd = &iface_desc->endpoint[2].desc; | ||
| 80 | if (!usb_endpoint_is_bulk_out(epd)) | ||
| 81 | goto failed; | ||
| 82 | |||
| 69 | dev = interface_to_usbdev(interface); | 83 | dev = interface_to_usbdev(interface); |
| 70 | wlandev = create_wlan(); | 84 | wlandev = create_wlan(); |
| 71 | if (!wlandev) { | 85 | if (!wlandev) { |
| @@ -524,6 +524,7 @@ static void __init serial8250_isa_init_ports(void) · 523 unmodified lines | |||
| 524 | */ | 524 | */ |
| 525 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; | 525 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; |
| 526 | up->mcr_force = ALPHA_KLUDGE_MCR; | 526 | up->mcr_force = ALPHA_KLUDGE_MCR; |
| 527 | serial8250_set_defaults(up); | ||
| 527 | } | 528 | } |
| 528 | 529 | ||
| 529 | /* chain base port ops to support Remote Supervisor Adapter */ | 530 | /* chain base port ops to support Remote Supervisor Adapter */ |
| @@ -547,7 +548,6 @@ static void __init serial8250_isa_init_ports(void) · 17 unmodified lines | |||
| 547 | port->membase = old_serial_port[i].iomem_base; | 548 | port->membase = old_serial_port[i].iomem_base; |
| 548 | port->iotype = old_serial_port[i].io_type; | 549 | port->iotype = old_serial_port[i].io_type; |
| 549 | port->regshift = old_serial_port[i].iomem_reg_shift; | 550 | port->regshift = old_serial_port[i].iomem_reg_shift; |
| 550 | serial8250_set_defaults(up); | ||
| 551 | 551 | ||
| 552 | port->irqflags |= irqflag; | 552 | port->irqflags |= irqflag; |
| 553 | if (serial8250_isa_config != NULL) | 553 | if (serial8250_isa_config != NULL) |
| @@ -326,7 +326,17 @@ static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p) · 325 unmodified lines | |||
| 326 | * devices will export them as GPIOs, so we pre-configure them safely | 326 | * devices will export them as GPIOs, so we pre-configure them safely |
| 327 | * as inputs. | 327 | * as inputs. |
| 328 | */ | 328 | */ |
| 329 | u8 dir = pcidev->vendor == PCI_VENDOR_ID_EXAR ? 0xff : 0x00; | 329 | |
| 330 | u8 dir = 0x00; | ||
| 331 | |||
| 332 | if ((pcidev->vendor == PCI_VENDOR_ID_EXAR) && | ||
| 333 | (pcidev->subsystem_vendor != PCI_VENDOR_ID_SEALEVEL)) { | ||
| 334 | // Configure GPIO as inputs for Commtech adapters | ||
| 335 | dir = 0xff; | ||
| 336 | } else { | ||
| 337 | // Configure GPIO as outputs for SeaLevel adapters | ||
| 338 | dir = 0x00; | ||
| 339 | } | ||
| 330 | 340 | ||
| 331 | writeb(0x00, p + UART_EXAR_MPIOINT_7_0); | 341 | writeb(0x00, p + UART_EXAR_MPIOINT_7_0); |
| 332 | writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); | 342 | writeb(0x00, p + UART_EXAR_MPIOLVL_7_0); |
| @@ -306,8 +306,21 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, · 305 unmodified lines | |||
| 306 | } | 306 | } |
| 307 | #endif | 307 | #endif |
| 308 | 308 | ||
| 309 | /* | ||
| 310 | * Store the requested baud rate before calling the generic 8250 | ||
| 311 | * set_termios method. Standard 8250 port expects bauds to be | ||
| 312 | * no higher than (uartclk / 16) so the baud will be clamped if it | ||
| 313 | * gets out of that bound. Mediatek 8250 port supports speed | ||
| 314 | * higher than that, therefore we'll get original baud rate back | ||
| 315 | * after calling the generic set_termios method and recalculate | ||
| 316 | * the speed later in this method. | ||
| 317 | */ | ||
| 318 | baud = tty_termios_baud_rate(termios); | ||
| 319 | |||
| 309 | serial8250_do_set_termios(port, termios, old); | 320 | serial8250_do_set_termios(port, termios, old); |
| 310 | 321 | ||
| 322 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
| 323 | |||
| 311 | /* | 324 | /* |
| 312 | * Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS) | 325 | * Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS) |
| 313 | * | 326 | * |
| @@ -339,6 +352,11 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, · 25 unmodified lines | |||
| 339 | */ | 352 | */ |
| 340 | spin_lock_irqsave(&port->lock, flags); | 353 | spin_lock_irqsave(&port->lock, flags); |
| 341 | 354 | ||
| 355 | /* | ||
| 356 | * Update the per-port timeout. | ||
| 357 | */ | ||
| 358 | uart_update_timeout(port, termios->c_cflag, baud); | ||
| 359 | |||
| 342 | /* set DLAB we have cval saved in up->lcr from the call to the core */ | 360 | /* set DLAB we have cval saved in up->lcr from the call to the core */ |
| 343 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); | 361 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); |
| 344 | serial_dl_write(up, quot); | 362 | serial_dl_write(up, quot); |
| @@ -635,7 +635,7 @@ static void tegra_uart_handle_tx_pio(struct tegra_uart_port *tup) · 634 unmodified lines | |||
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, | 637 | static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, |
| 638 | struct tty_port *tty) | 638 | struct tty_port *port) |
| 639 | { | 639 | { |
| 640 | do { | 640 | do { |
| 641 | char flag = TTY_NORMAL; | 641 | char flag = TTY_NORMAL; |
| @@ -653,16 +653,18 @@ static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, · 11 unmodified lines | |||
| 653 | ch = (unsigned char) tegra_uart_read(tup, UART_RX); | 653 | ch = (unsigned char) tegra_uart_read(tup, UART_RX); |
| 654 | tup->uport.icount.rx++; | 654 | tup->uport.icount.rx++; |
| 655 | 655 | ||
| 656 | if (!uart_handle_sysrq_char(&tup->uport, ch) && tty) | 656 | if (uart_handle_sysrq_char(&tup->uport, ch)) |
| 657 | tty_insert_flip_char(tty, ch, flag); | 657 | continue; |
| 658 | 658 | ||
| 659 | if (tup->uport.ignore_status_mask & UART_LSR_DR) | 659 | if (tup->uport.ignore_status_mask & UART_LSR_DR) |
| 660 | continue; | 660 | continue; |
| 661 | |||
| 662 | tty_insert_flip_char(port, ch, flag); | ||
| 661 | } while (1); | 663 | } while (1); |
| 662 | } | 664 | } |
| 663 | 665 | ||
| 664 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, | 666 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, |
| 665 | struct tty_port *tty, | 667 | struct tty_port *port, |
| 666 | unsigned int count) | 668 | unsigned int count) |
| 667 | { | 669 | { |
| 668 | int copied; | 670 | int copied; |
| @@ -672,17 +674,13 @@ static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, · 3 unmodified lines | |||
| 672 | return; | 674 | return; |
| 673 | 675 | ||
| 674 | tup->uport.icount.rx += count; | 676 | tup->uport.icount.rx += count; |
| 675 | if (!tty) { | ||
| 676 | dev_err(tup->uport.dev, "No tty port\n"); | ||
| 677 | return; | ||
| 678 | } | ||
| 679 | 677 | ||
| 680 | if (tup->uport.ignore_status_mask & UART_LSR_DR) | 678 | if (tup->uport.ignore_status_mask & UART_LSR_DR) |
| 681 | return; | 679 | return; |
| 682 | 680 | ||
| 683 | dma_sync_single_for_cpu(tup->uport.dev, tup->rx_dma_buf_phys, | 681 | dma_sync_single_for_cpu(tup->uport.dev, tup->rx_dma_buf_phys, |
| 684 | count, DMA_FROM_DEVICE); | 682 | count, DMA_FROM_DEVICE); |
| 685 | copied = tty_insert_flip_string(tty, | 683 | copied = tty_insert_flip_string(port, |
| 686 | ((unsigned char *)(tup->rx_dma_buf_virt)), count); | 684 | ((unsigned char *)(tup->rx_dma_buf_virt)), count); |
| 687 | if (copied != count) { | 685 | if (copied != count) { |
| 688 | WARN_ON(1); | 686 | WARN_ON(1); |
| @@ -1580,8 +1580,10 @@ static int cdns_uart_probe(struct platform_device *pdev) · 1579 unmodified lines | |||
| 1580 | * If register_console() don't assign value, then console_port pointer | 1580 | * If register_console() don't assign value, then console_port pointer |
| 1581 | * is cleanup. | 1581 | * is cleanup. |
| 1582 | */ | 1582 | */ |
| 1583 | if (!console_port) | 1583 | if (!console_port) { |
| 1584 | cdns_uart_console.index = id; | ||
| 1584 | console_port = port; | 1585 | console_port = port; |
| 1586 | } | ||
| 1585 | #endif | 1587 | #endif |
| 1586 | 1588 | ||
| 1587 | rc = uart_add_one_port(&cdns_uart_uart_driver, port); | 1589 | rc = uart_add_one_port(&cdns_uart_uart_driver, port); |
| @@ -1594,8 +1596,10 @@ static int cdns_uart_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 1594 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE | 1596 | #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE |
| 1595 | /* This is not port which is used for console that's why clean it up */ | 1597 | /* This is not port which is used for console that's why clean it up */ |
| 1596 | if (console_port == port && | 1598 | if (console_port == port && |
| 1597 | !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) | 1599 | !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) { |
| 1598 | console_port = NULL; | 1600 | console_port = NULL; |
| 1601 | cdns_uart_console.index = -1; | ||
| 1602 | } | ||
| 1599 | #endif | 1603 | #endif |
| 1600 | 1604 | ||
| 1601 | cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node, | 1605 | cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node, |
| @@ -1092,10 +1092,19 @@ static const struct tty_port_operations vc_port_ops = { · 1091 unmodified lines | |||
| 1092 | .destruct = vc_port_destruct, | 1092 | .destruct = vc_port_destruct, |
| 1093 | }; | 1093 | }; |
| 1094 | 1094 | ||
| 1095 | /* | ||
| 1096 | * Change # of rows and columns (0 means unchanged/the size of fg_console) | ||
| 1097 | * [this is to be used together with some user program | ||
| 1098 | * like resize that changes the hardware videomode] | ||
| 1099 | */ | ||
| 1100 | #define VC_MAXCOL (32767) | ||
| 1101 | #define VC_MAXROW (32767) | ||
| 1102 | |||
| 1095 | int vc_allocate(unsigned int currcons) /* return 0 on success */ | 1103 | int vc_allocate(unsigned int currcons) /* return 0 on success */ |
| 1096 | { | 1104 | { |
| 1097 | struct vt_notifier_param param; | 1105 | struct vt_notifier_param param; |
| 1098 | struct vc_data *vc; | 1106 | struct vc_data *vc; |
| 1107 | int err; | ||
| 1099 | 1108 | ||
| 1100 | WARN_CONSOLE_UNLOCKED(); | 1109 | WARN_CONSOLE_UNLOCKED(); |
| 1101 | 1110 | ||
| @@ -1125,6 +1134,11 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ · 23 unmodified lines | |||
| 1125 | if (!*vc->vc_uni_pagedir_loc) | 1134 | if (!*vc->vc_uni_pagedir_loc) |
| 1126 | con_set_default_unimap(vc); | 1135 | con_set_default_unimap(vc); |
| 1127 | 1136 | ||
| 1137 | err = -EINVAL; | ||
| 1138 | if (vc->vc_cols > VC_MAXCOL || vc->vc_rows > VC_MAXROW || | ||
| 1139 | vc->vc_screenbuf_size > KMALLOC_MAX_SIZE || !vc->vc_screenbuf_size) | ||
| 1140 | goto err_free; | ||
| 1141 | err = -ENOMEM; | ||
| 1128 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL); | 1142 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
| 1129 | if (!vc->vc_screenbuf) | 1143 | if (!vc->vc_screenbuf) |
| 1130 | goto err_free; | 1144 | goto err_free; |
| @@ -1143,7 +1157,7 @@ err_free: · 12 unmodified lines | |||
| 1143 | visual_deinit(vc); | 1157 | visual_deinit(vc); |
| 1144 | kfree(vc); | 1158 | kfree(vc); |
| 1145 | vc_cons[currcons].d = NULL; | 1159 | vc_cons[currcons].d = NULL; |
| 1146 | return -ENOMEM; | 1160 | return err; |
| 1147 | } | 1161 | } |
| 1148 | 1162 | ||
| 1149 | static inline int resize_screen(struct vc_data *vc, int width, int height, | 1163 | static inline int resize_screen(struct vc_data *vc, int width, int height, |
| @@ -1158,14 +1172,6 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, · 8 unmodified lines | |||
| 1158 | return err; | 1172 | return err; |
| 1159 | } | 1173 | } |
| 1160 | 1174 | ||
| 1161 | /* | ||
| 1162 | * Change # of rows and columns (0 means unchanged/the size of fg_console) | ||
| 1163 | * [this is to be used together with some user program | ||
| 1164 | * like resize that changes the hardware videomode] | ||
| 1165 | */ | ||
| 1166 | #define VC_RESIZE_MAXCOL (32767) | ||
| 1167 | #define VC_RESIZE_MAXROW (32767) | ||
| 1168 | |||
| 1169 | /** | 1175 | /** |
| 1170 | * vc_do_resize - resizing method for the tty | 1176 | * vc_do_resize - resizing method for the tty |
| 1171 | * @tty: tty being resized | 1177 | * @tty: tty being resized |
| @@ -1201,7 +1207,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, · 29 unmodified lines | |||
| 1201 | user = vc->vc_resize_user; | 1207 | user = vc->vc_resize_user; |
| 1202 | vc->vc_resize_user = 0; | 1208 | vc->vc_resize_user = 0; |
| 1203 | 1209 | ||
| 1204 | if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW) | 1210 | if (cols > VC_MAXCOL || lines > VC_MAXROW) |
| 1205 | return -EINVAL; | 1211 | return -EINVAL; |
| 1206 | 1212 | ||
| 1207 | new_cols = (cols ? cols : vc->vc_cols); | 1213 | new_cols = (cols ? cols : vc->vc_cols); |
| @@ -1212,7 +1218,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, · 4 unmodified lines | |||
| 1212 | if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) | 1218 | if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) |
| 1213 | return 0; | 1219 | return 0; |
| 1214 | 1220 | ||
| 1215 | if (new_screen_size > KMALLOC_MAX_SIZE) | 1221 | if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size) |
| 1216 | return -EINVAL; | 1222 | return -EINVAL; |
| 1217 | newscreen = kzalloc(new_screen_size, GFP_USER); | 1223 | newscreen = kzalloc(new_screen_size, GFP_USER); |
| 1218 | if (!newscreen) | 1224 | if (!newscreen) |
| @@ -3393,6 +3399,7 @@ static int __init con_init(void) · 2174 unmodified lines | |||
| 3393 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 3399 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
| 3394 | tty_port_init(&vc->port); | 3400 | tty_port_init(&vc->port); |
| 3395 | visual_init(vc, currcons, 1); | 3401 | visual_init(vc, currcons, 1); |
| 3402 | /* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */ | ||
| 3396 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); | 3403 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); |
| 3397 | vc_init(vc, vc->vc_rows, vc->vc_cols, | 3404 | vc_init(vc, vc->vc_rows, vc->vc_cols, |
| 3398 | currcons || !vc->vc_sw->con_save_screen); | 3405 | currcons || !vc->vc_sw->con_save_screen); |
| @@ -557,6 +557,10 @@ static bool need_bw_sch(struct usb_host_endpoint *ep, · 556 unmodified lines | |||
| 557 | if (is_fs_or_ls(speed) && !has_tt) | 557 | if (is_fs_or_ls(speed) && !has_tt) |
| 558 | return false; | 558 | return false; |
| 559 | 559 | ||
| 560 | /* skip endpoint with zero maxpkt */ | ||
| 561 | if (usb_endpoint_maxp(&ep->desc) == 0) | ||
| 562 | return false; | ||
| 563 | |||
| 560 | return true; | 564 | return true; |
| 561 | } | 565 | } |
| 562 | 566 | ||
| @@ -265,6 +265,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 264 unmodified lines | |||
| 265 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | 265 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && |
| 266 | pdev->device == 0x1142) | 266 | pdev->device == 0x1142) |
| 267 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | 267 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
| 268 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | ||
| 269 | pdev->device == 0x2142) | ||
| 270 | xhci->quirks |= XHCI_NO_64BIT_SUPPORT; | ||
| 268 | 271 | ||
| 269 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | 272 | if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && |
| 270 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) | 273 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) |
| @@ -856,7 +856,7 @@ static int tegra_xusb_init_context(struct tegra_xusb *tegra) · 855 unmodified lines | |||
| 856 | if (!tegra->context.ipfs) | 856 | if (!tegra->context.ipfs) |
| 857 | return -ENOMEM; | 857 | return -ENOMEM; |
| 858 | 858 | ||
| 859 | tegra->context.fpci = devm_kcalloc(tegra->dev, soc->ipfs.num_offsets, | 859 | tegra->context.fpci = devm_kcalloc(tegra->dev, soc->fpci.num_offsets, |
| 860 | sizeof(u32), GFP_KERNEL); | 860 | sizeof(u32), GFP_KERNEL); |
| 861 | if (!tegra->context.fpci) | 861 | if (!tegra->context.fpci) |
| 862 | return -ENOMEM; | 862 | return -ENOMEM; |
| @@ -521,14 +521,19 @@ static void vfio_pci_release(void *device_data) · 520 unmodified lines | |||
| 521 | vfio_pci_vf_token_user_add(vdev, -1); | 521 | vfio_pci_vf_token_user_add(vdev, -1); |
| 522 | vfio_spapr_pci_eeh_release(vdev->pdev); | 522 | vfio_spapr_pci_eeh_release(vdev->pdev); |
| 523 | vfio_pci_disable(vdev); | 523 | vfio_pci_disable(vdev); |
| 524 | mutex_lock(&vdev->igate); | ||
| 524 | if (vdev->err_trigger) { | 525 | if (vdev->err_trigger) { |
| 525 | eventfd_ctx_put(vdev->err_trigger); | 526 | eventfd_ctx_put(vdev->err_trigger); |
| 526 | vdev->err_trigger = NULL; | 527 | vdev->err_trigger = NULL; |
| 527 | } | 528 | } |
| 529 | mutex_unlock(&vdev->igate); | ||
| 530 | |||
| 531 | mutex_lock(&vdev->igate); | ||
| 528 | if (vdev->req_trigger) { | 532 | if (vdev->req_trigger) { |
| 529 | eventfd_ctx_put(vdev->req_trigger); | 533 | eventfd_ctx_put(vdev->req_trigger); |
| 530 | vdev->req_trigger = NULL; | 534 | vdev->req_trigger = NULL; |
| 531 | } | 535 | } |
| 536 | mutex_unlock(&vdev->igate); | ||
| 532 | } | 537 | } |
| 533 | 538 | ||
| 534 | mutex_unlock(&vdev->reflck->lock); | 539 | mutex_unlock(&vdev->reflck->lock); |
| @@ -216,7 +216,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, · 215 unmodified lines | |||
| 216 | region.color = color; | 216 | region.color = color; |
| 217 | region.rop = ROP_COPY; | 217 | region.rop = ROP_COPY; |
| 218 | 218 | ||
| 219 | if (rw && !bottom_only) { | 219 | if ((int) rw > 0 && !bottom_only) { |
| 220 | region.dx = info->var.xoffset + rs; | 220 | region.dx = info->var.xoffset + rs; |
| 221 | region.dy = 0; | 221 | region.dy = 0; |
| 222 | region.width = rw; | 222 | region.width = rw; |
| @@ -224,7 +224,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, · 1 unmodified line | |||
| 224 | info->fbops->fb_fillrect(info, ®ion); | 224 | info->fbops->fb_fillrect(info, ®ion); |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | if (bh) { | 227 | if ((int) bh > 0) { |
| 228 | region.dx = info->var.xoffset; | 228 | region.dx = info->var.xoffset; |
| 229 | region.dy = info->var.yoffset + bs; | 229 | region.dy = info->var.yoffset + bs; |
| 230 | region.width = rs; | 230 | region.width = rs; |
| @@ -201,7 +201,7 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, · 200 unmodified lines | |||
| 201 | region.color = color; | 201 | region.color = color; |
| 202 | region.rop = ROP_COPY; | 202 | region.rop = ROP_COPY; |
| 203 | 203 | ||
| 204 | if (rw && !bottom_only) { | 204 | if ((int) rw > 0 && !bottom_only) { |
| 205 | region.dx = 0; | 205 | region.dx = 0; |
| 206 | region.dy = info->var.yoffset; | 206 | region.dy = info->var.yoffset; |
| 207 | region.height = rw; | 207 | region.height = rw; |
| @@ -209,7 +209,7 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, · 1 unmodified line | |||
| 209 | info->fbops->fb_fillrect(info, ®ion); | 209 | info->fbops->fb_fillrect(info, ®ion); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | if (bh) { | 212 | if ((int) bh > 0) { |
| 213 | region.dx = info->var.xoffset + bs; | 213 | region.dx = info->var.xoffset + bs; |
| 214 | region.dy = 0; | 214 | region.dy = 0; |
| 215 | region.height = info->var.yres_virtual; | 215 | region.height = info->var.yres_virtual; |
| @@ -184,7 +184,7 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, · 183 unmodified lines | |||
| 184 | region.color = color; | 184 | region.color = color; |
| 185 | region.rop = ROP_COPY; | 185 | region.rop = ROP_COPY; |
| 186 | 186 | ||
| 187 | if (rw && !bottom_only) { | 187 | if ((int) rw > 0 && !bottom_only) { |
| 188 | region.dx = 0; | 188 | region.dx = 0; |
| 189 | region.dy = info->var.yoffset + rs; | 189 | region.dy = info->var.yoffset + rs; |
| 190 | region.height = rw; | 190 | region.height = rw; |
| @@ -192,7 +192,7 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, · 1 unmodified line | |||
| 192 | info->fbops->fb_fillrect(info, ®ion); | 192 | info->fbops->fb_fillrect(info, ®ion); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | if (bh) { | 195 | if ((int) bh > 0) { |
| 196 | region.dx = info->var.xoffset; | 196 | region.dx = info->var.xoffset; |
| 197 | region.dy = info->var.yoffset; | 197 | region.dy = info->var.yoffset; |
| 198 | region.height = info->var.yres; | 198 | region.height = info->var.yres; |
| @@ -231,7 +231,7 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, · 230 unmodified lines | |||
| 231 | region.color = color; | 231 | region.color = color; |
| 232 | region.rop = ROP_COPY; | 232 | region.rop = ROP_COPY; |
| 233 | 233 | ||
| 234 | if (rw && !bottom_only) { | 234 | if ((int) rw > 0 && !bottom_only) { |
| 235 | region.dy = 0; | 235 | region.dy = 0; |
| 236 | region.dx = info->var.xoffset; | 236 | region.dx = info->var.xoffset; |
| 237 | region.width = rw; | 237 | region.width = rw; |
| @@ -239,7 +239,7 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, · 1 unmodified line | |||
| 239 | info->fbops->fb_fillrect(info, ®ion); | 239 | info->fbops->fb_fillrect(info, ®ion); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | if (bh) { | 242 | if ((int) bh > 0) { |
| 243 | region.dy = info->var.yoffset; | 243 | region.dy = info->var.yoffset; |
| 244 | region.dx = info->var.xoffset; | 244 | region.dx = info->var.xoffset; |
| 245 | region.height = bh; | 245 | region.height = bh; |
| @@ -641,11 +641,11 @@ static int vm_cmdline_set(const char *device, · 640 unmodified lines | |||
| 641 | &vm_cmdline_id, &consumed); | 641 | &vm_cmdline_id, &consumed); |
| 642 | 642 | ||
| 643 | /* | 643 | /* |
| 644 | * sscanf() must processes at least 2 chunks; also there | 644 | * sscanf() must process at least 2 chunks; also there |
| 645 | * must be no extra characters after the last chunk, so | 645 | * must be no extra characters after the last chunk, so |
| 646 | * str[consumed] must be '\0' | 646 | * str[consumed] must be '\0' |
| 647 | */ | 647 | */ |
| 648 | if (processed < 2 || str[consumed]) | 648 | if (processed < 2 || str[consumed] || irq == 0) |
| 649 | return -EINVAL; | 649 | return -EINVAL; |
| 650 | 650 | ||
| 651 | resources[0].flags = IORESOURCE_MEM; | 651 | resources[0].flags = IORESOURCE_MEM; |
| @@ -1461,6 +1461,7 @@ static int btrfs_find_all_roots_safe(struct btrfs_trans_handle *trans, · 1460 unmodified lines | |||
| 1461 | if (ret < 0 && ret != -ENOENT) { | 1461 | if (ret < 0 && ret != -ENOENT) { |
| 1462 | ulist_free(tmp); | 1462 | ulist_free(tmp); |
| 1463 | ulist_free(*roots); | 1463 | ulist_free(*roots); |
| 1464 | *roots = NULL; | ||
| 1464 | return ret; | 1465 | return ret; |
| 1465 | } | 1466 | } |
| 1466 | node = ulist_next(tmp, &uiter); | 1467 | node = ulist_next(tmp, &uiter); |
| @@ -1999,7 +1999,8 @@ static int __process_pages_contig(struct address_space *mapping, · 1998 unmodified lines | |||
| 1999 | if (!PageDirty(pages[i]) || | 1999 | if (!PageDirty(pages[i]) || |
| 2000 | pages[i]->mapping != mapping) { | 2000 | pages[i]->mapping != mapping) { |
| 2001 | unlock_page(pages[i]); | 2001 | unlock_page(pages[i]); |
| 2002 | put_page(pages[i]); | 2002 | for (; i < ret; i++) |
| 2003 | put_page(pages[i]); | ||
| 2003 | err = -EAGAIN; | 2004 | err = -EAGAIN; |
| 2004 | goto out; | 2005 | goto out; |
| 2005 | } | 2006 | } |
| @@ -8123,20 +8123,17 @@ again: · 8122 unmodified lines | |||
| 8123 | /* | 8123 | /* |
| 8124 | * Qgroup reserved space handler | 8124 | * Qgroup reserved space handler |
| 8125 | * Page here will be either | 8125 | * Page here will be either |
| 8126 | * 1) Already written to disk | 8126 | * 1) Already written to disk or ordered extent already submitted |
| 8127 | * In this case, its reserved space is released from data rsv map | 8127 | * Then its QGROUP_RESERVED bit in io_tree is already cleaned. |
| 8128 | * and will be freed by delayed_ref handler finally. | 8128 | * Qgroup will be handled by its qgroup_record then. |
| 8129 | * So even we call qgroup_free_data(), it won't decrease reserved | 8129 | * btrfs_qgroup_free_data() call will do nothing here. |
| 8130 | * space. | 8130 | * |
| 8131 | * 2) Not written to disk | 8131 | * 2) Not written to disk yet |
| 8132 | * This means the reserved space should be freed here. However, | 8132 | * Then btrfs_qgroup_free_data() call will clear the QGROUP_RESERVED |
| 8133 | * if a truncate invalidates the page (by clearing PageDirty) | 8133 | * bit of its io_tree, and free the qgroup reserved data space. |
| 8134 | * and the page is accounted for while allocating extent | 8134 | * Since the IO will never happen for this page. |
| 8135 | * in btrfs_check_data_free_space() we let delayed_ref to | ||
| 8136 | * free the entire extent. | ||
| 8137 | */ | 8135 | */ |
| 8138 | if (PageDirty(page)) | 8136 | btrfs_qgroup_free_data(inode, NULL, page_start, PAGE_SIZE); |
| 8139 | btrfs_qgroup_free_data(inode, NULL, page_start, PAGE_SIZE); | ||
| 8140 | if (!inode_evicting) { | 8137 | if (!inode_evicting) { |
| 8141 | clear_extent_bit(tree, page_start, page_end, EXTENT_LOCKED | | 8138 | clear_extent_bit(tree, page_start, page_end, EXTENT_LOCKED | |
| 8142 | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | | 8139 | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | |
| @@ -7051,6 +7051,14 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info) · 7050 unmodified lines | |||
| 7051 | mutex_lock(&uuid_mutex); | 7051 | mutex_lock(&uuid_mutex); |
| 7052 | mutex_lock(&fs_info->chunk_mutex); | 7052 | mutex_lock(&fs_info->chunk_mutex); |
| 7053 | 7053 | ||
| 7054 | /* | ||
| 7055 | * It is possible for mount and umount to race in such a way that | ||
| 7056 | * we execute this code path, but open_fs_devices failed to clear | ||
| 7057 | * total_rw_bytes. We certainly want it cleared before reading the | ||
| 7058 | * device items, so clear it here. | ||
| 7059 | */ | ||
| 7060 | fs_info->fs_devices->total_rw_bytes = 0; | ||
| 7061 | |||
| 7054 | /* | 7062 | /* |
| 7055 | * Read all device items, and then all the chunk items. All | 7063 | * Read all device items, and then all the chunk items. All |
| 7056 | * device items are found before any chunk item (their object id | 7064 | * device items are found before any chunk item (their object id |
| @@ -2044,7 +2044,6 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, · 2043 unmodified lines | |||
| 2044 | FILE_UNIX_BASIC_INFO *info_buf_target; | 2044 | FILE_UNIX_BASIC_INFO *info_buf_target; |
| 2045 | unsigned int xid; | 2045 | unsigned int xid; |
| 2046 | int rc, tmprc; | 2046 | int rc, tmprc; |
| 2047 | bool new_target = d_really_is_negative(target_dentry); | ||
| 2048 | 2047 | ||
| 2049 | if (flags & ~RENAME_NOREPLACE) | 2048 | if (flags & ~RENAME_NOREPLACE) |
| 2050 | return -EINVAL; | 2049 | return -EINVAL; |
| @@ -2121,13 +2120,8 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, · 70 unmodified lines | |||
| 2121 | */ | 2120 | */ |
| 2122 | 2121 | ||
| 2123 | unlink_target: | 2122 | unlink_target: |
| 2124 | /* | 2123 | /* Try unlinking the target dentry if it's not negative */ |
| 2125 | * If the target dentry was created during the rename, try | 2124 | if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) { |
| 2126 | * unlinking it if it's not negative | ||
| 2127 | */ | ||
| 2128 | if (new_target && | ||
| 2129 | d_really_is_positive(target_dentry) && | ||
| 2130 | (rc == -EACCES || rc == -EEXIST)) { | ||
| 2131 | if (d_is_dir(target_dentry)) | 2125 | if (d_is_dir(target_dentry)) |
| 2132 | tmprc = cifs_rmdir(target_dir, target_dentry); | 2126 | tmprc = cifs_rmdir(target_dir, target_dentry); |
| 2133 | else | 2127 | else |
| @@ -201,6 +201,9 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) · 200 unmodified lines | |||
| 201 | sb->s_d_op = &efivarfs_d_ops; | 201 | sb->s_d_op = &efivarfs_d_ops; |
| 202 | sb->s_time_gran = 1; | 202 | sb->s_time_gran = 1; |
| 203 | 203 | ||
| 204 | if (!efivar_supports_writes()) | ||
| 205 | sb->s_flags |= SB_RDONLY; | ||
| 206 | |||
| 204 | inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true); | 207 | inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true); |
| 205 | if (!inode) | 208 | if (!inode) |
| 206 | return -ENOMEM; | 209 | return -ENOMEM; |
| @@ -252,9 +255,6 @@ static struct file_system_type efivarfs_type = { · 45 unmodified lines | |||
| 252 | 255 | ||
| 253 | static __init int efivarfs_init(void) | 256 | static __init int efivarfs_init(void) |
| 254 | { | 257 | { |
| 255 | if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) | ||
| 256 | return -ENODEV; | ||
| 257 | |||
| 258 | if (!efivars_kobject()) | 258 | if (!efivars_kobject()) |
| 259 | return -ENODEV; | 259 | return -ENODEV; |
| 260 | 260 | ||
| @@ -1112,7 +1112,7 @@ found: · 1111 unmodified lines | |||
| 1112 | ret = exfat_get_next_cluster(sb, &clu.dir); | 1112 | ret = exfat_get_next_cluster(sb, &clu.dir); |
| 1113 | } | 1113 | } |
| 1114 | 1114 | ||
| 1115 | if (ret || clu.dir != EXFAT_EOF_CLUSTER) { | 1115 | if (ret || clu.dir == EXFAT_EOF_CLUSTER) { |
| 1116 | /* just initialized hint_stat */ | 1116 | /* just initialized hint_stat */ |
| 1117 | hint_stat->clu = p_dir->dir; | 1117 | hint_stat->clu = p_dir->dir; |
| 1118 | hint_stat->eidx = 0; | 1118 | hint_stat->eidx = 0; |
| @@ -371,7 +371,7 @@ static inline bool exfat_is_last_sector_in_cluster(struct exfat_sb_info *sbi, · 370 unmodified lines | |||
| 371 | static inline sector_t exfat_cluster_to_sector(struct exfat_sb_info *sbi, | 371 | static inline sector_t exfat_cluster_to_sector(struct exfat_sb_info *sbi, |
| 372 | unsigned int clus) | 372 | unsigned int clus) |
| 373 | { | 373 | { |
| 374 | return ((clus - EXFAT_RESERVED_CLUSTERS) << sbi->sect_per_clus_bits) + | 374 | return ((sector_t)(clus - EXFAT_RESERVED_CLUSTERS) << sbi->sect_per_clus_bits) + |
| 375 | sbi->data_start_sector; | 375 | sbi->data_start_sector; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| @@ -176,7 +176,7 @@ int __exfat_truncate(struct inode *inode, loff_t new_size) · 175 unmodified lines | |||
| 176 | ep2->dentry.stream.size = 0; | 176 | ep2->dentry.stream.size = 0; |
| 177 | } else { | 177 | } else { |
| 178 | ep2->dentry.stream.valid_size = cpu_to_le64(new_size); | 178 | ep2->dentry.stream.valid_size = cpu_to_le64(new_size); |
| 179 | ep2->dentry.stream.size = ep->dentry.stream.valid_size; | 179 | ep2->dentry.stream.size = ep2->dentry.stream.valid_size; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | if (new_size == 0) { | 182 | if (new_size == 0) { |
| @@ -495,7 +495,7 @@ static int exfat_utf8_to_utf16(struct super_block *sb, · 494 unmodified lines | |||
| 495 | struct exfat_uni_name *p_uniname, int *p_lossy) | 495 | struct exfat_uni_name *p_uniname, int *p_lossy) |
| 496 | { | 496 | { |
| 497 | int i, unilen, lossy = NLS_NAME_NO_LOSSY; | 497 | int i, unilen, lossy = NLS_NAME_NO_LOSSY; |
| 498 | unsigned short upname[MAX_NAME_LENGTH + 1]; | 498 | __le16 upname[MAX_NAME_LENGTH + 1]; |
| 499 | unsigned short *uniname = p_uniname->name; | 499 | unsigned short *uniname = p_uniname->name; |
| 500 | 500 | ||
| 501 | WARN_ON(!len); | 501 | WARN_ON(!len); |
| @@ -519,7 +519,7 @@ static int exfat_utf8_to_utf16(struct super_block *sb, · 17 unmodified lines | |||
| 519 | exfat_wstrchr(bad_uni_chars, *uniname)) | 519 | exfat_wstrchr(bad_uni_chars, *uniname)) |
| 520 | lossy |= NLS_NAME_LOSSY; | 520 | lossy |= NLS_NAME_LOSSY; |
| 521 | 521 | ||
| 522 | upname[i] = exfat_toupper(sb, *uniname); | 522 | upname[i] = cpu_to_le16(exfat_toupper(sb, *uniname)); |
| 523 | uniname++; | 523 | uniname++; |
| 524 | } | 524 | } |
| 525 | 525 | ||
| @@ -597,7 +597,7 @@ static int exfat_nls_to_ucs2(struct super_block *sb, · 71 unmodified lines | |||
| 597 | struct exfat_uni_name *p_uniname, int *p_lossy) | 597 | struct exfat_uni_name *p_uniname, int *p_lossy) |
| 598 | { | 598 | { |
| 599 | int i = 0, unilen = 0, lossy = NLS_NAME_NO_LOSSY; | 599 | int i = 0, unilen = 0, lossy = NLS_NAME_NO_LOSSY; |
| 600 | unsigned short upname[MAX_NAME_LENGTH + 1]; | 600 | __le16 upname[MAX_NAME_LENGTH + 1]; |
| 601 | unsigned short *uniname = p_uniname->name; | 601 | unsigned short *uniname = p_uniname->name; |
| 602 | struct nls_table *nls = EXFAT_SB(sb)->nls_io; | 602 | struct nls_table *nls = EXFAT_SB(sb)->nls_io; |
| 603 | 603 | ||
| @@ -611,7 +611,7 @@ static int exfat_nls_to_ucs2(struct super_block *sb, · 7 unmodified lines | |||
| 611 | exfat_wstrchr(bad_uni_chars, *uniname)) | 611 | exfat_wstrchr(bad_uni_chars, *uniname)) |
| 612 | lossy |= NLS_NAME_LOSSY; | 612 | lossy |= NLS_NAME_LOSSY; |
| 613 | 613 | ||
| 614 | upname[unilen] = exfat_toupper(sb, *uniname); | 614 | upname[unilen] = cpu_to_le16(exfat_toupper(sb, *uniname)); |
| 615 | uniname++; | 615 | uniname++; |
| 616 | unilen++; | 616 | unilen++; |
| 617 | } | 617 | } |
| @@ -605,6 +605,7 @@ enum { · 604 unmodified lines | |||
| 605 | 605 | ||
| 606 | struct async_poll { | 606 | struct async_poll { |
| 607 | struct io_poll_iocb poll; | 607 | struct io_poll_iocb poll; |
| 608 | struct io_poll_iocb *double_poll; | ||
| 608 | struct io_wq_work work; | 609 | struct io_wq_work work; |
| 609 | }; | 610 | }; |
| 610 | 611 | ||
| @@ -4159,9 +4160,9 @@ static bool io_poll_rewait(struct io_kiocb *req, struct io_poll_iocb *poll) · 3548 unmodified lines | |||
| 4159 | return false; | 4160 | return false; |
| 4160 | } | 4161 | } |
| 4161 | 4162 | ||
| 4162 | static void io_poll_remove_double(struct io_kiocb *req) | 4163 | static void io_poll_remove_double(struct io_kiocb *req, void *data) |
| 4163 | { | 4164 | { |
| 4164 | struct io_poll_iocb *poll = (struct io_poll_iocb *) req->io; | 4165 | struct io_poll_iocb *poll = data; |
| 4165 | 4166 | ||
| 4166 | lockdep_assert_held(&req->ctx->completion_lock); | 4167 | lockdep_assert_held(&req->ctx->completion_lock); |
| 4167 | 4168 | ||
| @@ -4181,7 +4182,7 @@ static void io_poll_complete(struct io_kiocb *req, __poll_t mask, int error) · 13 unmodified lines | |||
| 4181 | { | 4182 | { |
| 4182 | struct io_ring_ctx *ctx = req->ctx; | 4183 | struct io_ring_ctx *ctx = req->ctx; |
| 4183 | 4184 | ||
| 4184 | io_poll_remove_double(req); | 4185 | io_poll_remove_double(req, req->io); |
| 4185 | req->poll.done = true; | 4186 | req->poll.done = true; |
| 4186 | io_cqring_fill_event(req, error ? error : mangle_poll(mask)); | 4187 | io_cqring_fill_event(req, error ? error : mangle_poll(mask)); |
| 4187 | io_commit_cqring(ctx); | 4188 | io_commit_cqring(ctx); |
| @@ -4224,21 +4225,21 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode, · 36 unmodified lines | |||
| 4224 | int sync, void *key) | 4225 | int sync, void *key) |
| 4225 | { | 4226 | { |
| 4226 | struct io_kiocb *req = wait->private; | 4227 | struct io_kiocb *req = wait->private; |
| 4227 | struct io_poll_iocb *poll = (struct io_poll_iocb *) req->io; | 4228 | struct io_poll_iocb *poll = req->apoll->double_poll; |
| 4228 | __poll_t mask = key_to_poll(key); | 4229 | __poll_t mask = key_to_poll(key); |
| 4229 | 4230 | ||
| 4230 | /* for instances that support it check for an event match first: */ | 4231 | /* for instances that support it check for an event match first: */ |
| 4231 | if (mask && !(mask & poll->events)) | 4232 | if (mask && !(mask & poll->events)) |
| 4232 | return 0; | 4233 | return 0; |
| 4233 | 4234 | ||
| 4234 | if (req->poll.head) { | 4235 | if (poll && poll->head) { |
| 4235 | bool done; | 4236 | bool done; |
| 4236 | 4237 | ||
| 4237 | spin_lock(&req->poll.head->lock); | 4238 | spin_lock(&poll->head->lock); |
| 4238 | done = list_empty(&req->poll.wait.entry); | 4239 | done = list_empty(&poll->wait.entry); |
| 4239 | if (!done) | 4240 | if (!done) |
| 4240 | list_del_init(&req->poll.wait.entry); | 4241 | list_del_init(&poll->wait.entry); |
| 4241 | spin_unlock(&req->poll.head->lock); | 4242 | spin_unlock(&poll->head->lock); |
| 4242 | if (!done) | 4243 | if (!done) |
| 4243 | __io_async_wake(req, poll, mask, io_poll_task_func); | 4244 | __io_async_wake(req, poll, mask, io_poll_task_func); |
| 4244 | } | 4245 | } |
| @@ -4258,7 +4259,8 @@ static void io_init_poll_iocb(struct io_poll_iocb *poll, __poll_t events, · 13 unmodified lines | |||
| 4258 | } | 4259 | } |
| 4259 | 4260 | ||
| 4260 | static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, | 4261 | static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, |
| 4261 | struct wait_queue_head *head) | 4262 | struct wait_queue_head *head, |
| 4263 | struct io_poll_iocb **poll_ptr) | ||
| 4262 | { | 4264 | { |
| 4263 | struct io_kiocb *req = pt->req; | 4265 | struct io_kiocb *req = pt->req; |
| 4264 | 4266 | ||
| @@ -4269,7 +4271,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, · 4 unmodified lines | |||
| 4269 | */ | 4271 | */ |
| 4270 | if (unlikely(poll->head)) { | 4272 | if (unlikely(poll->head)) { |
| 4271 | /* already have a 2nd entry, fail a third attempt */ | 4273 | /* already have a 2nd entry, fail a third attempt */ |
| 4272 | if (req->io) { | 4274 | if (*poll_ptr) { |
| 4273 | pt->error = -EINVAL; | 4275 | pt->error = -EINVAL; |
| 4274 | return; | 4276 | return; |
| 4275 | } | 4277 | } |
| @@ -4281,7 +4283,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, · 5 unmodified lines | |||
| 4281 | io_init_poll_iocb(poll, req->poll.events, io_poll_double_wake); | 4283 | io_init_poll_iocb(poll, req->poll.events, io_poll_double_wake); |
| 4282 | refcount_inc(&req->refs); | 4284 | refcount_inc(&req->refs); |
| 4283 | poll->wait.private = req; | 4285 | poll->wait.private = req; |
| 4284 | req->io = (void *) poll; | 4286 | *poll_ptr = poll; |
| 4285 | } | 4287 | } |
| 4286 | 4288 | ||
| 4287 | pt->error = 0; | 4289 | pt->error = 0; |
| @@ -4293,8 +4295,9 @@ static void io_async_queue_proc(struct file *file, struct wait_queue_head *head, · 5 unmodified lines | |||
| 4293 | struct poll_table_struct *p) | 4295 | struct poll_table_struct *p) |
| 4294 | { | 4296 | { |
| 4295 | struct io_poll_table *pt = container_of(p, struct io_poll_table, pt); | 4297 | struct io_poll_table *pt = container_of(p, struct io_poll_table, pt); |
| 4298 | struct async_poll *apoll = pt->req->apoll; | ||
| 4296 | 4299 | ||
| 4297 | __io_queue_proc(&pt->req->apoll->poll, pt, head); | 4300 | __io_queue_proc(&apoll->poll, pt, head, &apoll->double_poll); |
| 4298 | } | 4301 | } |
| 4299 | 4302 | ||
| 4300 | static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx) | 4303 | static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx) |
| @@ -4344,11 +4347,13 @@ static void io_async_task_func(struct callback_head *cb) · 43 unmodified lines | |||
| 4344 | } | 4347 | } |
| 4345 | } | 4348 | } |
| 4346 | 4349 | ||
| 4350 | io_poll_remove_double(req, apoll->double_poll); | ||
| 4347 | spin_unlock_irq(&ctx->completion_lock); | 4351 | spin_unlock_irq(&ctx->completion_lock); |
| 4348 | 4352 | ||
| 4349 | /* restore ->work in case we need to retry again */ | 4353 | /* restore ->work in case we need to retry again */ |
| 4350 | if (req->flags & REQ_F_WORK_INITIALIZED) | 4354 | if (req->flags & REQ_F_WORK_INITIALIZED) |
| 4351 | memcpy(&req->work, &apoll->work, sizeof(req->work)); | 4355 | memcpy(&req->work, &apoll->work, sizeof(req->work)); |
| 4356 | kfree(apoll->double_poll); | ||
| 4352 | kfree(apoll); | 4357 | kfree(apoll); |
| 4353 | 4358 | ||
| 4354 | if (!canceled) { | 4359 | if (!canceled) { |
| @@ -4436,7 +4441,6 @@ static bool io_arm_poll_handler(struct io_kiocb *req) · 81 unmodified lines | |||
| 4436 | struct async_poll *apoll; | 4441 | struct async_poll *apoll; |
| 4437 | struct io_poll_table ipt; | 4442 | struct io_poll_table ipt; |
| 4438 | __poll_t mask, ret; | 4443 | __poll_t mask, ret; |
| 4439 | bool had_io; | ||
| 4440 | 4444 | ||
| 4441 | if (!req->file || !file_can_poll(req->file)) | 4445 | if (!req->file || !file_can_poll(req->file)) |
| 4442 | return false; | 4446 | return false; |
| @@ -4448,11 +4452,11 @@ static bool io_arm_poll_handler(struct io_kiocb *req) · 5 unmodified lines | |||
| 4448 | apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC); | 4452 | apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC); |
| 4449 | if (unlikely(!apoll)) | 4453 | if (unlikely(!apoll)) |
| 4450 | return false; | 4454 | return false; |
| 4455 | apoll->double_poll = NULL; | ||
| 4451 | 4456 | ||
| 4452 | req->flags |= REQ_F_POLLED; | 4457 | req->flags |= REQ_F_POLLED; |
| 4453 | if (req->flags & REQ_F_WORK_INITIALIZED) | 4458 | if (req->flags & REQ_F_WORK_INITIALIZED) |
| 4454 | memcpy(&apoll->work, &req->work, sizeof(req->work)); | 4459 | memcpy(&apoll->work, &req->work, sizeof(req->work)); |
| 4455 | had_io = req->io != NULL; | ||
| 4456 | 4460 | ||
| 4457 | io_get_req_task(req); | 4461 | io_get_req_task(req); |
| 4458 | req->apoll = apoll; | 4462 | req->apoll = apoll; |
| @@ -4470,13 +4474,11 @@ static bool io_arm_poll_handler(struct io_kiocb *req) · 11 unmodified lines | |||
| 4470 | ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, | 4474 | ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, |
| 4471 | io_async_wake); | 4475 | io_async_wake); |
| 4472 | if (ret) { | 4476 | if (ret) { |
| 4473 | ipt.error = 0; | 4477 | io_poll_remove_double(req, apoll->double_poll); |
| 4474 | /* only remove double add if we did it here */ | ||
| 4475 | if (!had_io) | ||
| 4476 | io_poll_remove_double(req); | ||
| 4477 | spin_unlock_irq(&ctx->completion_lock); | 4478 | spin_unlock_irq(&ctx->completion_lock); |
| 4478 | if (req->flags & REQ_F_WORK_INITIALIZED) | 4479 | if (req->flags & REQ_F_WORK_INITIALIZED) |
| 4479 | memcpy(&req->work, &apoll->work, sizeof(req->work)); | 4480 | memcpy(&req->work, &apoll->work, sizeof(req->work)); |
| 4481 | kfree(apoll->double_poll); | ||
| 4480 | kfree(apoll); | 4482 | kfree(apoll); |
| 4481 | return false; | 4483 | return false; |
| 4482 | } | 4484 | } |
| @@ -4507,11 +4509,13 @@ static bool io_poll_remove_one(struct io_kiocb *req) · 24 unmodified lines | |||
| 4507 | bool do_complete; | 4509 | bool do_complete; |
| 4508 | 4510 | ||
| 4509 | if (req->opcode == IORING_OP_POLL_ADD) { | 4511 | if (req->opcode == IORING_OP_POLL_ADD) { |
| 4510 | io_poll_remove_double(req); | 4512 | io_poll_remove_double(req, req->io); |
| 4511 | do_complete = __io_poll_remove_one(req, &req->poll); | 4513 | do_complete = __io_poll_remove_one(req, &req->poll); |
| 4512 | } else { | 4514 | } else { |
| 4513 | struct async_poll *apoll = req->apoll; | 4515 | struct async_poll *apoll = req->apoll; |
| 4514 | 4516 | ||
| 4517 | io_poll_remove_double(req, apoll->double_poll); | ||
| 4518 | |||
| 4515 | /* non-poll requests have submit ref still */ | 4519 | /* non-poll requests have submit ref still */ |
| 4516 | do_complete = __io_poll_remove_one(req, &apoll->poll); | 4520 | do_complete = __io_poll_remove_one(req, &apoll->poll); |
| 4517 | if (do_complete) { | 4521 | if (do_complete) { |
| @@ -4524,6 +4528,7 @@ static bool io_poll_remove_one(struct io_kiocb *req) · 6 unmodified lines | |||
| 4524 | if (req->flags & REQ_F_WORK_INITIALIZED) | 4528 | if (req->flags & REQ_F_WORK_INITIALIZED) |
| 4525 | memcpy(&req->work, &apoll->work, | 4529 | memcpy(&req->work, &apoll->work, |
| 4526 | sizeof(req->work)); | 4530 | sizeof(req->work)); |
| 4531 | kfree(apoll->double_poll); | ||
| 4527 | kfree(apoll); | 4532 | kfree(apoll); |
| 4528 | } | 4533 | } |
| 4529 | } | 4534 | } |
| @@ -4624,7 +4629,7 @@ static void io_poll_queue_proc(struct file *file, struct wait_queue_head *head, · 94 unmodified lines | |||
| 4624 | { | 4629 | { |
| 4625 | struct io_poll_table *pt = container_of(p, struct io_poll_table, pt); | 4630 | struct io_poll_table *pt = container_of(p, struct io_poll_table, pt); |
| 4626 | 4631 | ||
| 4627 | __io_queue_proc(&pt->req->poll, pt, head); | 4632 | __io_queue_proc(&pt->req->poll, pt, head, (struct io_poll_iocb **) &pt->req->io); |
| 4628 | } | 4633 | } |
| 4629 | 4634 | ||
| 4630 | static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) | 4635 | static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| @@ -4732,7 +4737,9 @@ static int io_timeout_remove_prep(struct io_kiocb *req, · 101 unmodified lines | |||
| 4732 | { | 4737 | { |
| 4733 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) | 4738 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 4734 | return -EINVAL; | 4739 | return -EINVAL; |
| 4735 | if (sqe->flags || sqe->ioprio || sqe->buf_index || sqe->len) | 4740 | if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) |
| 4741 | return -EINVAL; | ||
| 4742 | if (sqe->ioprio || sqe->buf_index || sqe->len) | ||
| 4736 | return -EINVAL; | 4743 | return -EINVAL; |
| 4737 | 4744 | ||
| 4738 | req->timeout.addr = READ_ONCE(sqe->addr); | 4745 | req->timeout.addr = READ_ONCE(sqe->addr); |
| @@ -4910,8 +4917,9 @@ static int io_async_cancel_prep(struct io_kiocb *req, · 171 unmodified lines | |||
| 4910 | { | 4917 | { |
| 4911 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) | 4918 | if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) |
| 4912 | return -EINVAL; | 4919 | return -EINVAL; |
| 4913 | if (sqe->flags || sqe->ioprio || sqe->off || sqe->len || | 4920 | if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) |
| 4914 | sqe->cancel_flags) | 4921 | return -EINVAL; |
| 4922 | if (sqe->ioprio || sqe->off || sqe->len || sqe->cancel_flags) | ||
| 4915 | return -EINVAL; | 4923 | return -EINVAL; |
| 4916 | 4924 | ||
| 4917 | req->cancel.addr = READ_ONCE(sqe->addr); | 4925 | req->cancel.addr = READ_ONCE(sqe->addr); |
| @@ -4929,7 +4937,9 @@ static int io_async_cancel(struct io_kiocb *req) · 11 unmodified lines | |||
| 4929 | static int io_files_update_prep(struct io_kiocb *req, | 4937 | static int io_files_update_prep(struct io_kiocb *req, |
| 4930 | const struct io_uring_sqe *sqe) | 4938 | const struct io_uring_sqe *sqe) |
| 4931 | { | 4939 | { |
| 4932 | if (sqe->flags || sqe->ioprio || sqe->rw_flags) | 4940 | if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) |
| 4941 | return -EINVAL; | ||
| 4942 | if (sqe->ioprio || sqe->rw_flags) | ||
| 4933 | return -EINVAL; | 4943 | return -EINVAL; |
| 4934 | 4944 | ||
| 4935 | req->files_update.offset = READ_ONCE(sqe->off); | 4945 | req->files_update.offset = READ_ONCE(sqe->off); |
| @@ -5720,6 +5730,7 @@ fail_req: · 784 unmodified lines | |||
| 5720 | * Never try inline submit of IOSQE_ASYNC is set, go straight | 5730 | * Never try inline submit of IOSQE_ASYNC is set, go straight |
| 5721 | * to async execution. | 5731 | * to async execution. |
| 5722 | */ | 5732 | */ |
| 5733 | io_req_init_async(req); | ||
| 5723 | req->work.flags |= IO_WQ_WORK_CONCURRENT; | 5734 | req->work.flags |= IO_WQ_WORK_CONCURRENT; |
| 5724 | io_queue_async_work(req); | 5735 | io_queue_async_work(req); |
| 5725 | } else { | 5736 | } else { |
| @@ -507,6 +507,17 @@ find_any_file(struct nfs4_file *f) · 506 unmodified lines | |||
| 507 | return ret; | 507 | return ret; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | static struct nfsd_file *find_deleg_file(struct nfs4_file *f) | ||
| 511 | { | ||
| 512 | struct nfsd_file *ret = NULL; | ||
| 513 | |||
| 514 | spin_lock(&f->fi_lock); | ||
| 515 | if (f->fi_deleg_file) | ||
| 516 | ret = nfsd_file_get(f->fi_deleg_file); | ||
| 517 | spin_unlock(&f->fi_lock); | ||
| 518 | return ret; | ||
| 519 | } | ||
| 520 | |||
| 510 | static atomic_long_t num_delegations; | 521 | static atomic_long_t num_delegations; |
| 511 | unsigned long max_delegations; | 522 | unsigned long max_delegations; |
| 512 | 523 | ||
| @@ -2444,6 +2455,8 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st) · 1931 unmodified lines | |||
| 2444 | oo = ols->st_stateowner; | 2455 | oo = ols->st_stateowner; |
| 2445 | nf = st->sc_file; | 2456 | nf = st->sc_file; |
| 2446 | file = find_any_file(nf); | 2457 | file = find_any_file(nf); |
| 2458 | if (!file) | ||
| 2459 | return 0; | ||
| 2447 | 2460 | ||
| 2448 | seq_printf(s, "- "); | 2461 | seq_printf(s, "- "); |
| 2449 | nfs4_show_stateid(s, &st->sc_stateid); | 2462 | nfs4_show_stateid(s, &st->sc_stateid); |
| @@ -2481,6 +2494,8 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st) · 31 unmodified lines | |||
| 2481 | oo = ols->st_stateowner; | 2494 | oo = ols->st_stateowner; |
| 2482 | nf = st->sc_file; | 2495 | nf = st->sc_file; |
| 2483 | file = find_any_file(nf); | 2496 | file = find_any_file(nf); |
| 2497 | if (!file) | ||
| 2498 | return 0; | ||
| 2484 | 2499 | ||
| 2485 | seq_printf(s, "- "); | 2500 | seq_printf(s, "- "); |
| 2486 | nfs4_show_stateid(s, &st->sc_stateid); | 2501 | nfs4_show_stateid(s, &st->sc_stateid); |
| @@ -2513,7 +2528,9 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st) · 26 unmodified lines | |||
| 2513 | 2528 | ||
| 2514 | ds = delegstateid(st); | 2529 | ds = delegstateid(st); |
| 2515 | nf = st->sc_file; | 2530 | nf = st->sc_file; |
| 2516 | file = nf->fi_deleg_file; | 2531 | file = find_deleg_file(nf); |
| 2532 | if (!file) | ||
| 2533 | return 0; | ||
| 2517 | 2534 | ||
| 2518 | seq_printf(s, "- "); | 2535 | seq_printf(s, "- "); |
| 2519 | nfs4_show_stateid(s, &st->sc_stateid); | 2536 | nfs4_show_stateid(s, &st->sc_stateid); |
| @@ -2529,6 +2546,7 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st) · 9 unmodified lines | |||
| 2529 | seq_printf(s, ", "); | 2546 | seq_printf(s, ", "); |
| 2530 | nfs4_show_fname(s, file); | 2547 | nfs4_show_fname(s, file); |
| 2531 | seq_printf(s, " }\n"); | 2548 | seq_printf(s, " }\n"); |
| 2549 | nfsd_file_put(file); | ||
| 2532 | 2550 | ||
| 2533 | return 0; | 2551 | return 0; |
| 2534 | } | 2552 | } |
| @@ -175,7 +175,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, · 174 unmodified lines | |||
| 175 | /* Extract the length of the metadata block */ | 175 | /* Extract the length of the metadata block */ |
| 176 | data = page_address(bvec->bv_page) + bvec->bv_offset; | 176 | data = page_address(bvec->bv_page) + bvec->bv_offset; |
| 177 | length = data[offset]; | 177 | length = data[offset]; |
| 178 | if (offset <= bvec->bv_len - 1) { | 178 | if (offset < bvec->bv_len - 1) { |
| 179 | length |= data[offset + 1] << 8; | 179 | length |= data[offset + 1] << 8; |
| 180 | } else { | 180 | } else { |
| 181 | if (WARN_ON_ONCE(!bio_next_segment(bio, &iter_all))) { | 181 | if (WARN_ON_ONCE(!bio_next_segment(bio, &iter_all))) { |
| @@ -607,14 +607,14 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from) · 606 unmodified lines | |||
| 607 | int nr_pages; | 607 | int nr_pages; |
| 608 | ssize_t ret; | 608 | ssize_t ret; |
| 609 | 609 | ||
| 610 | nr_pages = iov_iter_npages(from, BIO_MAX_PAGES); | ||
| 611 | if (!nr_pages) | ||
| 612 | return 0; | ||
| 613 | |||
| 614 | max = queue_max_zone_append_sectors(bdev_get_queue(bdev)); | 610 | max = queue_max_zone_append_sectors(bdev_get_queue(bdev)); |
| 615 | max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize); | 611 | max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize); |
| 616 | iov_iter_truncate(from, max); | 612 | iov_iter_truncate(from, max); |
| 617 | 613 | ||
| 614 | nr_pages = iov_iter_npages(from, BIO_MAX_PAGES); | ||
| 615 | if (!nr_pages) | ||
| 616 | return 0; | ||
| 617 | |||
| 618 | bio = bio_alloc_bioset(GFP_NOFS, nr_pages, &fs_bio_set); | 618 | bio = bio_alloc_bioset(GFP_NOFS, nr_pages, &fs_bio_set); |
| 619 | if (!bio) | 619 | if (!bio) |
| 620 | return -ENOMEM; | 620 | return -ENOMEM; |
| @@ -1119,7 +1119,7 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd, · 498 unmodified lines | |||
| 1119 | char *file_name; | 1119 | char *file_name; |
| 1120 | struct dentry *dir; | 1120 | struct dentry *dir; |
| 1121 | unsigned int n = 0; | 1121 | unsigned int n = 0; |
| 1122 | int ret = -ENOMEM; | 1122 | int ret; |
| 1123 | 1123 | ||
| 1124 | /* If the group is empty, there is nothing to do */ | 1124 | /* If the group is empty, there is nothing to do */ |
| 1125 | if (!zd->nr_zones[type]) | 1125 | if (!zd->nr_zones[type]) |
| @@ -1135,8 +1135,10 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd, · 9 unmodified lines | |||
| 1135 | zgroup_name = "seq"; | 1135 | zgroup_name = "seq"; |
| 1136 | 1136 | ||
| 1137 | dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type); | 1137 | dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type); |
| 1138 | if (!dir) | 1138 | if (!dir) { |
| 1139 | ret = -ENOMEM; | ||
| 1139 | goto free; | 1140 | goto free; |
| 1141 | } | ||
| 1140 | 1142 | ||
| 1141 | /* | 1143 | /* |
| 1142 | * The first zone contains the super block: skip it. | 1144 | * The first zone contains the super block: skip it. |
| @@ -1174,8 +1176,10 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd, · 31 unmodified lines | |||
| 1174 | * Use the file number within its group as file name. | 1176 | * Use the file number within its group as file name. |
| 1175 | */ | 1177 | */ |
| 1176 | snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n); | 1178 | snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n); |
| 1177 | if (!zonefs_create_inode(dir, file_name, zone, type)) | 1179 | if (!zonefs_create_inode(dir, file_name, zone, type)) { |
| 1180 | ret = -ENOMEM; | ||
| 1178 | goto free; | 1181 | goto free; |
| 1182 | } | ||
| 1179 | 1183 | ||
| 1180 | n++; | 1184 | n++; |
| 1181 | } | 1185 | } |
| @@ -341,7 +341,8 @@ · 340 unmodified lines | |||
| 341 | 341 | ||
| 342 | #define PAGE_ALIGNED_DATA(page_align) \ | 342 | #define PAGE_ALIGNED_DATA(page_align) \ |
| 343 | . = ALIGN(page_align); \ | 343 | . = ALIGN(page_align); \ |
| 344 | *(.data..page_aligned) | 344 | *(.data..page_aligned) \ |
| 345 | . = ALIGN(page_align); | ||
| 345 | 346 | ||
| 346 | #define READ_MOSTLY_DATA(align) \ | 347 | #define READ_MOSTLY_DATA(align) \ |
| 347 | . = ALIGN(align); \ | 348 | . = ALIGN(align); \ |
| @@ -737,7 +738,9 @@ · 389 unmodified lines | |||
| 737 | . = ALIGN(bss_align); \ | 738 | . = ALIGN(bss_align); \ |
| 738 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ | 739 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ |
| 739 | BSS_FIRST_SECTIONS \ | 740 | BSS_FIRST_SECTIONS \ |
| 741 | . = ALIGN(PAGE_SIZE); \ | ||
| 740 | *(.bss..page_aligned) \ | 742 | *(.bss..page_aligned) \ |
| 743 | . = ALIGN(PAGE_SIZE); \ | ||
| 741 | *(.dynbss) \ | 744 | *(.dynbss) \ |
| 742 | *(BSS_MAIN) \ | 745 | *(BSS_MAIN) \ |
| 743 | *(COMMON) \ | 746 | *(COMMON) \ |
| @@ -426,6 +426,7 @@ const char *dm_device_name(struct mapped_device *md); · 425 unmodified lines | |||
| 426 | int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid); | 426 | int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid); |
| 427 | struct gendisk *dm_disk(struct mapped_device *md); | 427 | struct gendisk *dm_disk(struct mapped_device *md); |
| 428 | int dm_suspended(struct dm_target *ti); | 428 | int dm_suspended(struct dm_target *ti); |
| 429 | int dm_post_suspending(struct dm_target *ti); | ||
| 429 | int dm_noflush_suspending(struct dm_target *ti); | 430 | int dm_noflush_suspending(struct dm_target *ti); |
| 430 | void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors); | 431 | void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors); |
| 431 | union map_info *dm_get_rq_mapinfo(struct request *rq); | 432 | union map_info *dm_get_rq_mapinfo(struct request *rq); |
| @@ -994,6 +994,7 @@ int efivars_register(struct efivars *efivars, · 993 unmodified lines | |||
| 994 | int efivars_unregister(struct efivars *efivars); | 994 | int efivars_unregister(struct efivars *efivars); |
| 995 | struct kobject *efivars_kobject(void); | 995 | struct kobject *efivars_kobject(void); |
| 996 | 996 | ||
| 997 | int efivar_supports_writes(void); | ||
| 997 | int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), | 998 | int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), |
| 998 | void *data, bool duplicates, struct list_head *head); | 999 | void *data, bool duplicates, struct list_head *head); |
| 999 | 1000 | ||
| @@ -56,7 +56,7 @@ struct property_entry; · 55 unmodified lines | |||
| 56 | * on a bus (or read from them). Apart from two basic transfer functions to | 56 | * on a bus (or read from them). Apart from two basic transfer functions to |
| 57 | * transmit one message at a time, a more complex version can be used to | 57 | * transmit one message at a time, a more complex version can be used to |
| 58 | * transmit an arbitrary number of messages without interruption. | 58 | * transmit an arbitrary number of messages without interruption. |
| 59 | * @count must be be less than 64k since msg.len is u16. | 59 | * @count must be less than 64k since msg.len is u16. |
| 60 | */ | 60 | */ |
| 61 | int i2c_transfer_buffer_flags(const struct i2c_client *client, | 61 | int i2c_transfer_buffer_flags(const struct i2c_client *client, |
| 62 | char *buf, int count, u16 flags); | 62 | char *buf, int count, u16 flags); |
| @@ -107,9 +107,12 @@ io_mapping_init_wc(struct io_mapping *iomap, · 106 unmodified lines | |||
| 107 | resource_size_t base, | 107 | resource_size_t base, |
| 108 | unsigned long size) | 108 | unsigned long size) |
| 109 | { | 109 | { |
| 110 | iomap->iomem = ioremap_wc(base, size); | ||
| 111 | if (!iomap->iomem) | ||
| 112 | return NULL; | ||
| 113 | |||
| 110 | iomap->base = base; | 114 | iomap->base = base; |
| 111 | iomap->size = size; | 115 | iomap->size = size; |
| 112 | iomap->iomem = ioremap_wc(base, size); | ||
| 113 | #if defined(pgprot_noncached_wc) /* archs can't agree on a name ... */ | 116 | #if defined(pgprot_noncached_wc) /* archs can't agree on a name ... */ |
| 114 | iomap->prot = pgprot_noncached_wc(PAGE_KERNEL); | 117 | iomap->prot = pgprot_noncached_wc(PAGE_KERNEL); |
| 115 | #elif defined(pgprot_writecombine) | 118 | #elif defined(pgprot_writecombine) |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | |||
| 33 | * of two or more hash tables when the rhashtable is being resized. | 33 | * of two or more hash tables when the rhashtable is being resized. |
| 34 | * The end of the chain is marked with a special nulls marks which has | 34 | * The end of the chain is marked with a special nulls marks which has |
| 35 | * the least significant bit set but otherwise stores the address of | 35 | * the least significant bit set but otherwise stores the address of |
| 36 | * the hash bucket. This allows us to be be sure we've found the end | 36 | * the hash bucket. This allows us to be sure we've found the end |
| 37 | * of the right list. | 37 | * of the right list. |
| 38 | * The value stored in the hash bucket has BIT(0) used as a lock bit. | 38 | * The value stored in the hash bucket has BIT(0) used as a lock bit. |
| 39 | * This bit must be atomically set before any changes are made to | 39 | * This bit must be atomically set before any changes are made to |
| @@ -220,7 +220,9 @@ struct tcp_sock { · 219 unmodified lines | |||
| 220 | } rack; | 220 | } rack; |
| 221 | u16 advmss; /* Advertised MSS */ | 221 | u16 advmss; /* Advertised MSS */ |
| 222 | u8 compressed_ack; | 222 | u8 compressed_ack; |
| 223 | u8 dup_ack_counter; | 223 | u8 dup_ack_counter:2, |
| 224 | tlp_retrans:1, /* TLP is a retransmission */ | ||
| 225 | unused:5; | ||
| 224 | u32 chrono_start; /* Start time in jiffies of a TCP chrono */ | 226 | u32 chrono_start; /* Start time in jiffies of a TCP chrono */ |
| 225 | u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */ | 227 | u32 chrono_stat[3]; /* Time in jiffies for chrono_stat stats */ |
| 226 | u8 chrono_type:2, /* current chronograph type */ | 228 | u8 chrono_type:2, /* current chronograph type */ |
| @@ -243,7 +245,7 @@ struct tcp_sock { · 16 unmodified lines | |||
| 243 | save_syn:1, /* Save headers of SYN packet */ | 245 | save_syn:1, /* Save headers of SYN packet */ |
| 244 | is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */ | 246 | is_cwnd_limited:1,/* forward progress limited by snd_cwnd? */ |
| 245 | syn_smc:1; /* SYN includes SMC */ | 247 | syn_smc:1; /* SYN includes SMC */ |
| 246 | u32 tlp_high_seq; /* snd_nxt at the time of TLP retransmit. */ | 248 | u32 tlp_high_seq; /* snd_nxt at the time of TLP */ |
| 247 | 249 | ||
| 248 | u32 tcp_tx_delay; /* delay (in usec) added to TX packets */ | 250 | u32 tcp_tx_delay; /* delay (in usec) added to TX packets */ |
| 249 | u64 tcp_wstamp_ns; /* departure time for next sent data packet */ | 251 | u64 tcp_wstamp_ns; /* departure time for next sent data packet */ |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 18 | #include <linux/mm.h> | ||
| 18 | #include <uapi/linux/xattr.h> | 19 | #include <uapi/linux/xattr.h> |
| 19 | 20 | ||
| 20 | struct inode; | 21 | struct inode; |
| @@ -94,7 +95,7 @@ static inline void simple_xattrs_free(struct simple_xattrs *xattrs) · 73 unmodified lines | |||
| 94 | 95 | ||
| 95 | list_for_each_entry_safe(xattr, node, &xattrs->head, list) { | 96 | list_for_each_entry_safe(xattr, node, &xattrs->head, list) { |
| 96 | kfree(xattr->name); | 97 | kfree(xattr->name); |
| 97 | kfree(xattr); | 98 | kvfree(xattr); |
| 98 | } | 99 | } |
| 99 | } | 100 | } |
| 100 | 101 | ||
| @@ -5,7 +5,6 @@ · 4 unmodified lines | |||
| 5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
| 6 | #include <linux/netlink.h> | 6 | #include <linux/netlink.h> |
| 7 | #include <net/flow_dissector.h> | 7 | #include <net/flow_dissector.h> |
| 8 | #include <linux/rhashtable.h> | ||
| 9 | 8 | ||
| 10 | struct flow_match { | 9 | struct flow_match { |
| 11 | struct flow_dissector *dissector; | 10 | struct flow_dissector *dissector; |
| @@ -12,6 +12,7 @@ struct rt5670_platform_data { · 11 unmodified lines | |||
| 12 | int jd_mode; | 12 | int jd_mode; |
| 13 | bool in2_diff; | 13 | bool in2_diff; |
| 14 | bool dev_gpio; | 14 | bool dev_gpio; |
| 15 | bool gpio1_is_ext_spk_en; | ||
| 15 | 16 | ||
| 16 | bool dmic_en; | 17 | bool dmic_en; |
| 17 | unsigned int dmic1_data_pin; | 18 | unsigned int dmic1_data_pin; |
| @@ -161,6 +161,7 @@ void snd_soc_dai_resume(struct snd_soc_dai *dai); · 160 unmodified lines | |||
| 161 | int snd_soc_dai_compress_new(struct snd_soc_dai *dai, | 161 | int snd_soc_dai_compress_new(struct snd_soc_dai *dai, |
| 162 | struct snd_soc_pcm_runtime *rtd, int num); | 162 | struct snd_soc_pcm_runtime *rtd, int num); |
| 163 | bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream); | 163 | bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream); |
| 164 | void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link); | ||
| 164 | void snd_soc_dai_action(struct snd_soc_dai *dai, | 165 | void snd_soc_dai_action(struct snd_soc_dai *dai, |
| 165 | int stream, int action); | 166 | int stream, int action); |
| 166 | static inline void snd_soc_dai_activate(struct snd_soc_dai *dai, | 167 | static inline void snd_soc_dai_activate(struct snd_soc_dai *dai, |
| @@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev, · 443 unmodified lines | |||
| 444 | const struct snd_soc_component_driver *component_driver, | 444 | const struct snd_soc_component_driver *component_driver, |
| 445 | struct snd_soc_dai_driver *dai_drv, int num_dai); | 445 | struct snd_soc_dai_driver *dai_drv, int num_dai); |
| 446 | void snd_soc_unregister_component(struct device *dev); | 446 | void snd_soc_unregister_component(struct device *dev); |
| 447 | void snd_soc_unregister_component_by_driver(struct device *dev, | ||
| 448 | const struct snd_soc_component_driver *component_driver); | ||
| 447 | struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev, | 449 | struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev, |
| 448 | const char *driver_name); | 450 | const char *driver_name); |
| 449 | struct snd_soc_component *snd_soc_lookup_component(struct device *dev, | 451 | struct snd_soc_component *snd_soc_lookup_component(struct device *dev, |
| @@ -2199,7 +2199,7 @@ static void handle_swbp(struct pt_regs *regs) · 2198 unmodified lines | |||
| 2199 | if (!uprobe) { | 2199 | if (!uprobe) { |
| 2200 | if (is_swbp > 0) { | 2200 | if (is_swbp > 0) { |
| 2201 | /* No matching uprobe; signal SIGTRAP. */ | 2201 | /* No matching uprobe; signal SIGTRAP. */ |
| 2202 | send_sig(SIGTRAP, current, 0); | 2202 | force_sig(SIGTRAP); |
| 2203 | } else { | 2203 | } else { |
| 2204 | /* | 2204 | /* |
| 2205 | * Either we raced with uprobe_unregister() or we can't | 2205 | * Either we raced with uprobe_unregister() or we can't |
| @@ -4119,9 +4119,6 @@ static void __sched notrace __schedule(bool preempt) · 4118 unmodified lines | |||
| 4119 | local_irq_disable(); | 4119 | local_irq_disable(); |
| 4120 | rcu_note_context_switch(preempt); | 4120 | rcu_note_context_switch(preempt); |
| 4121 | 4121 | ||
| 4122 | /* See deactivate_task() below. */ | ||
| 4123 | prev_state = prev->state; | ||
| 4124 | |||
| 4125 | /* | 4122 | /* |
| 4126 | * Make sure that signal_pending_state()->signal_pending() below | 4123 | * Make sure that signal_pending_state()->signal_pending() below |
| 4127 | * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE) | 4124 | * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE) |
| @@ -4145,11 +4142,16 @@ static void __sched notrace __schedule(bool preempt) · 17 unmodified lines | |||
| 4145 | update_rq_clock(rq); | 4142 | update_rq_clock(rq); |
| 4146 | 4143 | ||
| 4147 | switch_count = &prev->nivcsw; | 4144 | switch_count = &prev->nivcsw; |
| 4145 | |||
| 4148 | /* | 4146 | /* |
| 4149 | * We must re-load prev->state in case ttwu_remote() changed it | 4147 | * We must load prev->state once (task_struct::state is volatile), such |
| 4150 | * before we acquired rq->lock. | 4148 | * that: |
| 4149 | * | ||
| 4150 | * - we form a control dependency vs deactivate_task() below. | ||
| 4151 | * - ptrace_{,un}freeze_traced() can change ->state underneath us. | ||
| 4151 | */ | 4152 | */ |
| 4152 | if (!preempt && prev_state && prev_state == prev->state) { | 4153 | prev_state = prev->state; |
| 4154 | if (!preempt && prev_state) { | ||
| 4153 | if (signal_pending_state(prev_state, prev)) { | 4155 | if (signal_pending_state(prev_state, prev)) { |
| 4154 | prev->state = TASK_RUNNING; | 4156 | prev->state = TASK_RUNNING; |
| 4155 | } else { | 4157 | } else { |
| @@ -4163,10 +4165,12 @@ static void __sched notrace __schedule(bool preempt) · 7 unmodified lines | |||
| 4163 | 4165 | ||
| 4164 | /* | 4166 | /* |
| 4165 | * __schedule() ttwu() | 4167 | * __schedule() ttwu() |
| 4166 | * prev_state = prev->state; if (READ_ONCE(p->on_rq) && ...) | 4168 | * prev_state = prev->state; if (p->on_rq && ...) |
| 4167 | * LOCK rq->lock goto out; | 4169 | * if (prev_state) goto out; |
| 4168 | * smp_mb__after_spinlock(); smp_acquire__after_ctrl_dep(); | 4170 | * p->on_rq = 0; smp_acquire__after_ctrl_dep(); |
| 4169 | * p->on_rq = 0; p->state = TASK_WAKING; | 4171 | * p->state = TASK_WAKING |
| 4172 | * | ||
| 4173 | * Where __schedule() and ttwu() have matching control dependencies. | ||
| 4170 | * | 4174 | * |
| 4171 | * After this, schedule() must not care about p->state any more. | 4175 | * After this, schedule() must not care about p->state any more. |
| 4172 | */ | 4176 | */ |
| @@ -4481,6 +4485,7 @@ asmlinkage __visible void __sched preempt_schedule_irq(void) · 308 unmodified lines | |||
| 4481 | int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flags, | 4485 | int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flags, |
| 4482 | void *key) | 4486 | void *key) |
| 4483 | { | 4487 | { |
| 4488 | WARN_ON_ONCE(IS_ENABLED(CONFIG_SCHED_DEBUG) && wake_flags & ~WF_SYNC); | ||
| 4484 | return try_to_wake_up(curr->private, mode, wake_flags); | 4489 | return try_to_wake_up(curr->private, mode, wake_flags); |
| 4485 | } | 4490 | } |
| 4486 | EXPORT_SYMBOL(default_wake_function); | 4491 | EXPORT_SYMBOL(default_wake_function); |
| @@ -45,7 +45,10 @@ int hugetlb_max_hstate __read_mostly; · 44 unmodified lines | |||
| 45 | unsigned int default_hstate_idx; | 45 | unsigned int default_hstate_idx; |
| 46 | struct hstate hstates[HUGE_MAX_HSTATE]; | 46 | struct hstate hstates[HUGE_MAX_HSTATE]; |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_CMA | ||
| 48 | static struct cma *hugetlb_cma[MAX_NUMNODES]; | 49 | static struct cma *hugetlb_cma[MAX_NUMNODES]; |
| 50 | #endif | ||
| 51 | static unsigned long hugetlb_cma_size __initdata; | ||
| 49 | 52 | ||
| 50 | /* | 53 | /* |
| 51 | * Minimum page order among possible hugepage sizes, set to a proper value | 54 | * Minimum page order among possible hugepage sizes, set to a proper value |
| @@ -1235,9 +1238,10 @@ static void free_gigantic_page(struct page *page, unsigned int order) · 1183 unmodified lines | |||
| 1235 | * If the page isn't allocated using the cma allocator, | 1238 | * If the page isn't allocated using the cma allocator, |
| 1236 | * cma_release() returns false. | 1239 | * cma_release() returns false. |
| 1237 | */ | 1240 | */ |
| 1238 | if (IS_ENABLED(CONFIG_CMA) && | 1241 | #ifdef CONFIG_CMA |
| 1239 | cma_release(hugetlb_cma[page_to_nid(page)], page, 1 << order)) | 1242 | if (cma_release(hugetlb_cma[page_to_nid(page)], page, 1 << order)) |
| 1240 | return; | 1243 | return; |
| 1244 | #endif | ||
| 1241 | 1245 | ||
| 1242 | free_contig_range(page_to_pfn(page), 1 << order); | 1246 | free_contig_range(page_to_pfn(page), 1 << order); |
| 1243 | } | 1247 | } |
| @@ -1248,7 +1252,8 @@ static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask, · 4 unmodified lines | |||
| 1248 | { | 1252 | { |
| 1249 | unsigned long nr_pages = 1UL << huge_page_order(h); | 1253 | unsigned long nr_pages = 1UL << huge_page_order(h); |
| 1250 | 1254 | ||
| 1251 | if (IS_ENABLED(CONFIG_CMA)) { | 1255 | #ifdef CONFIG_CMA |
| 1256 | { | ||
| 1252 | struct page *page; | 1257 | struct page *page; |
| 1253 | int node; | 1258 | int node; |
| 1254 | 1259 | ||
| @@ -1262,6 +1267,7 @@ static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask, · 7 unmodified lines | |||
| 1262 | return page; | 1267 | return page; |
| 1263 | } | 1268 | } |
| 1264 | } | 1269 | } |
| 1270 | #endif | ||
| 1265 | 1271 | ||
| 1266 | return alloc_contig_pages(nr_pages, gfp_mask, nid, nodemask); | 1272 | return alloc_contig_pages(nr_pages, gfp_mask, nid, nodemask); |
| 1267 | } | 1273 | } |
| @@ -2571,7 +2577,7 @@ static void __init hugetlb_hstate_alloc_pages(struct hstate *h) · 1303 unmodified lines | |||
| 2571 | 2577 | ||
| 2572 | for (i = 0; i < h->max_huge_pages; ++i) { | 2578 | for (i = 0; i < h->max_huge_pages; ++i) { |
| 2573 | if (hstate_is_gigantic(h)) { | 2579 | if (hstate_is_gigantic(h)) { |
| 2574 | if (IS_ENABLED(CONFIG_CMA) && hugetlb_cma[0]) { | 2580 | if (hugetlb_cma_size) { |
| 2575 | pr_warn_once("HugeTLB: hugetlb_cma is enabled, skip boot time allocation\n"); | 2581 | pr_warn_once("HugeTLB: hugetlb_cma is enabled, skip boot time allocation\n"); |
| 2576 | break; | 2582 | break; |
| 2577 | } | 2583 | } |
| @@ -5654,7 +5660,6 @@ void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason) · 3076 unmodified lines | |||
| 5654 | } | 5660 | } |
| 5655 | 5661 | ||
| 5656 | #ifdef CONFIG_CMA | 5662 | #ifdef CONFIG_CMA |
| 5657 | static unsigned long hugetlb_cma_size __initdata; | ||
| 5658 | static bool cma_reserve_called __initdata; | 5663 | static bool cma_reserve_called __initdata; |
| 5659 | 5664 | ||
| 5660 | static int __init cmdline_parse_hugetlb_cma(char *p) | 5665 | static int __init cmdline_parse_hugetlb_cma(char *p) |
| @@ -958,6 +958,9 @@ static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address, · 957 unmodified lines | |||
| 958 | return SCAN_ADDRESS_RANGE; | 958 | return SCAN_ADDRESS_RANGE; |
| 959 | if (!hugepage_vma_check(vma, vma->vm_flags)) | 959 | if (!hugepage_vma_check(vma, vma->vm_flags)) |
| 960 | return SCAN_VMA_CHECK; | 960 | return SCAN_VMA_CHECK; |
| 961 | /* Anon VMA expected */ | ||
| 962 | if (!vma->anon_vma || vma->vm_ops) | ||
| 963 | return SCAN_VMA_CHECK; | ||
| 961 | return 0; | 964 | return 0; |
| 962 | } | 965 | } |
| 963 | 966 | ||
| @@ -5669,7 +5669,6 @@ static void __mem_cgroup_clear_mc(void) · 5668 unmodified lines | |||
| 5669 | if (!mem_cgroup_is_root(mc.to)) | 5669 | if (!mem_cgroup_is_root(mc.to)) |
| 5670 | page_counter_uncharge(&mc.to->memory, mc.moved_swap); | 5670 | page_counter_uncharge(&mc.to->memory, mc.moved_swap); |
| 5671 | 5671 | ||
| 5672 | mem_cgroup_id_get_many(mc.to, mc.moved_swap); | ||
| 5673 | css_put_many(&mc.to->css, mc.moved_swap); | 5672 | css_put_many(&mc.to->css, mc.moved_swap); |
| 5674 | 5673 | ||
| 5675 | mc.moved_swap = 0; | 5674 | mc.moved_swap = 0; |
| @@ -5860,7 +5859,8 @@ put: /* get_mctgt_type() gets the page */ · 184 unmodified lines | |||
| 5860 | ent = target.ent; | 5859 | ent = target.ent; |
| 5861 | if (!mem_cgroup_move_swap_account(ent, mc.from, mc.to)) { | 5860 | if (!mem_cgroup_move_swap_account(ent, mc.from, mc.to)) { |
| 5862 | mc.precharge--; | 5861 | mc.precharge--; |
| 5863 | /* we fixup refcnts and charges later. */ | 5862 | mem_cgroup_id_get_many(mc.to, 1); |
| 5863 | /* we fixup other refcnts and charges later. */ | ||
| 5864 | mc.moved_swap++; | 5864 | mc.moved_swap++; |
| 5865 | } | 5865 | } |
| 5866 | break; | 5866 | break; |
| @@ -7186,6 +7186,13 @@ static struct cftype memsw_files[] = { · 1319 unmodified lines | |||
| 7186 | { }, /* terminate */ | 7186 | { }, /* terminate */ |
| 7187 | }; | 7187 | }; |
| 7188 | 7188 | ||
| 7189 | /* | ||
| 7190 | * If mem_cgroup_swap_init() is implemented as a subsys_initcall() | ||
| 7191 | * instead of a core_initcall(), this could mean cgroup_memory_noswap still | ||
| 7192 | * remains set to false even when memcg is disabled via "cgroup_disable=memory" | ||
| 7193 | * boot parameter. This may result in premature OOPS inside | ||
| 7194 | * mem_cgroup_get_nr_swap_pages() function in corner cases. | ||
| 7195 | */ | ||
| 7189 | static int __init mem_cgroup_swap_init(void) | 7196 | static int __init mem_cgroup_swap_init(void) |
| 7190 | { | 7197 | { |
| 7191 | /* No memory control -> no swap control */ | 7198 | /* No memory control -> no swap control */ |
| @@ -7200,6 +7207,6 @@ static int __init mem_cgroup_swap_init(void) · 8 unmodified lines | |||
| 7200 | 7207 | ||
| 7201 | return 0; | 7208 | return 0; |
| 7202 | } | 7209 | } |
| 7203 | subsys_initcall(mem_cgroup_swap_init); | 7210 | core_initcall(mem_cgroup_swap_init); |
| 7204 | 7211 | ||
| 7205 | #endif /* CONFIG_MEMCG_SWAP */ | 7212 | #endif /* CONFIG_MEMCG_SWAP */ |
| @@ -1601,7 +1601,7 @@ int vm_insert_pages(struct vm_area_struct *vma, unsigned long addr, · 1600 unmodified lines | |||
| 1601 | return insert_pages(vma, addr, pages, num, vma->vm_page_prot); | 1601 | return insert_pages(vma, addr, pages, num, vma->vm_page_prot); |
| 1602 | #else | 1602 | #else |
| 1603 | unsigned long idx = 0, pgcount = *num; | 1603 | unsigned long idx = 0, pgcount = *num; |
| 1604 | int err; | 1604 | int err = -EINVAL; |
| 1605 | 1605 | ||
| 1606 | for (; idx < pgcount; ++idx) { | 1606 | for (; idx < pgcount; ++idx) { |
| 1607 | err = vm_insert_page(vma, addr + (PAGE_SIZE * idx), pages[idx]); | 1607 | err = vm_insert_page(vma, addr + (PAGE_SIZE * idx), pages[idx]); |
| @@ -2620,7 +2620,7 @@ static void unmap_region(struct mm_struct *mm, · 2619 unmodified lines | |||
| 2620 | * Create a list of vma's touched by the unmap, removing them from the mm's | 2620 | * Create a list of vma's touched by the unmap, removing them from the mm's |
| 2621 | * vma list as we go.. | 2621 | * vma list as we go.. |
| 2622 | */ | 2622 | */ |
| 2623 | static void | 2623 | static bool |
| 2624 | detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, | 2624 | detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, |
| 2625 | struct vm_area_struct *prev, unsigned long end) | 2625 | struct vm_area_struct *prev, unsigned long end) |
| 2626 | { | 2626 | { |
| @@ -2645,6 +2645,17 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, · 18 unmodified lines | |||
| 2645 | 2645 | ||
| 2646 | /* Kill the cache */ | 2646 | /* Kill the cache */ |
| 2647 | vmacache_invalidate(mm); | 2647 | vmacache_invalidate(mm); |
| 2648 | |||
| 2649 | /* | ||
| 2650 | * Do not downgrade mmap_lock if we are next to VM_GROWSDOWN or | ||
| 2651 | * VM_GROWSUP VMA. Such VMAs can change their size under | ||
| 2652 | * down_read(mmap_lock) and collide with the VMA we are about to unmap. | ||
| 2653 | */ | ||
| 2654 | if (vma && (vma->vm_flags & VM_GROWSDOWN)) | ||
| 2655 | return false; | ||
| 2656 | if (prev && (prev->vm_flags & VM_GROWSUP)) | ||
| 2657 | return false; | ||
| 2658 | return true; | ||
| 2648 | } | 2659 | } |
| 2649 | 2660 | ||
| 2650 | /* | 2661 | /* |
| @@ -2825,7 +2836,8 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len, · 174 unmodified lines | |||
| 2825 | } | 2836 | } |
| 2826 | 2837 | ||
| 2827 | /* Detach vmas from rbtree */ | 2838 | /* Detach vmas from rbtree */ |
| 2828 | detach_vmas_to_be_unmapped(mm, vma, prev, end); | 2839 | if (!detach_vmas_to_be_unmapped(mm, vma, prev, end)) |
| 2840 | downgrade = false; | ||
| 2829 | 2841 | ||
| 2830 | if (downgrade) | 2842 | if (downgrade) |
| 2831 | mmap_write_downgrade(mm); | 2843 | mmap_write_downgrade(mm); |
| @@ -3178,7 +3178,7 @@ static int shmem_initxattrs(struct inode *inode, · 3177 unmodified lines | |||
| 3178 | new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len, | 3178 | new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len, |
| 3179 | GFP_KERNEL); | 3179 | GFP_KERNEL); |
| 3180 | if (!new_xattr->name) { | 3180 | if (!new_xattr->name) { |
| 3181 | kfree(new_xattr); | 3181 | kvfree(new_xattr); |
| 3182 | return -ENOMEM; | 3182 | return -ENOMEM; |
| 3183 | } | 3183 | } |
| 3184 | 3184 | ||
| @@ -326,6 +326,14 @@ int slab_unmergeable(struct kmem_cache *s) · 325 unmodified lines | |||
| 326 | if (s->refcount < 0) | 326 | if (s->refcount < 0) |
| 327 | return 1; | 327 | return 1; |
| 328 | 328 | ||
| 329 | #ifdef CONFIG_MEMCG_KMEM | ||
| 330 | /* | ||
| 331 | * Skip the dying kmem_cache. | ||
| 332 | */ | ||
| 333 | if (s->memcg_params.dying) | ||
| 334 | return 1; | ||
| 335 | #endif | ||
| 336 | |||
| 329 | return 0; | 337 | return 0; |
| 330 | } | 338 | } |
| 331 | 339 | ||
| @@ -886,12 +894,15 @@ static int shutdown_memcg_caches(struct kmem_cache *s) · 554 unmodified lines | |||
| 886 | return 0; | 894 | return 0; |
| 887 | } | 895 | } |
| 888 | 896 | ||
| 889 | static void flush_memcg_workqueue(struct kmem_cache *s) | 897 | static void memcg_set_kmem_cache_dying(struct kmem_cache *s) |
| 890 | { | 898 | { |
| 891 | spin_lock_irq(&memcg_kmem_wq_lock); | 899 | spin_lock_irq(&memcg_kmem_wq_lock); |
| 892 | s->memcg_params.dying = true; | 900 | s->memcg_params.dying = true; |
| 893 | spin_unlock_irq(&memcg_kmem_wq_lock); | 901 | spin_unlock_irq(&memcg_kmem_wq_lock); |
| 902 | } | ||
| 894 | 903 | ||
| 904 | static void flush_memcg_workqueue(struct kmem_cache *s) | ||
| 905 | { | ||
| 895 | /* | 906 | /* |
| 896 | * SLAB and SLUB deactivate the kmem_caches through call_rcu. Make | 907 | * SLAB and SLUB deactivate the kmem_caches through call_rcu. Make |
| 897 | * sure all registered rcu callbacks have been invoked. | 908 | * sure all registered rcu callbacks have been invoked. |
| @@ -923,10 +934,6 @@ static inline int shutdown_memcg_caches(struct kmem_cache *s) · 25 unmodified lines | |||
| 923 | { | 934 | { |
| 924 | return 0; | 935 | return 0; |
| 925 | } | 936 | } |
| 926 | |||
| 927 | static inline void flush_memcg_workqueue(struct kmem_cache *s) | ||
| 928 | { | ||
| 929 | } | ||
| 930 | #endif /* CONFIG_MEMCG_KMEM */ | 937 | #endif /* CONFIG_MEMCG_KMEM */ |
| 931 | 938 | ||
| 932 | void slab_kmem_cache_release(struct kmem_cache *s) | 939 | void slab_kmem_cache_release(struct kmem_cache *s) |
| @@ -944,8 +951,6 @@ void kmem_cache_destroy(struct kmem_cache *s) · 11 unmodified lines | |||
| 944 | if (unlikely(!s)) | 951 | if (unlikely(!s)) |
| 945 | return; | 952 | return; |
| 946 | 953 | ||
| 947 | flush_memcg_workqueue(s); | ||
| 948 | |||
| 949 | get_online_cpus(); | 954 | get_online_cpus(); |
| 950 | get_online_mems(); | 955 | get_online_mems(); |
| 951 | 956 | ||
| @@ -955,6 +960,22 @@ void kmem_cache_destroy(struct kmem_cache *s) · 3 unmodified lines | |||
| 955 | if (s->refcount) | 960 | if (s->refcount) |
| 956 | goto out_unlock; | 961 | goto out_unlock; |
| 957 | 962 | ||
| 963 | #ifdef CONFIG_MEMCG_KMEM | ||
| 964 | memcg_set_kmem_cache_dying(s); | ||
| 965 | |||
| 966 | mutex_unlock(&slab_mutex); | ||
| 967 | |||
| 968 | put_online_mems(); | ||
| 969 | put_online_cpus(); | ||
| 970 | |||
| 971 | flush_memcg_workqueue(s); | ||
| 972 | |||
| 973 | get_online_cpus(); | ||
| 974 | get_online_mems(); | ||
| 975 | |||
| 976 | mutex_lock(&slab_mutex); | ||
| 977 | #endif | ||
| 978 | |||
| 958 | err = shutdown_memcg_caches(s); | 979 | err = shutdown_memcg_caches(s); |
| 959 | if (!err) | 980 | if (!err) |
| 960 | err = shutdown_cache(s); | 981 | err = shutdown_cache(s); |
| @@ -1187,7 +1187,10 @@ static int __must_check ax25_connect(struct socket *sock, · 1186 unmodified lines | |||
| 1187 | if (addr_len > sizeof(struct sockaddr_ax25) && | 1187 | if (addr_len > sizeof(struct sockaddr_ax25) && |
| 1188 | fsa->fsa_ax25.sax25_ndigis != 0) { | 1188 | fsa->fsa_ax25.sax25_ndigis != 0) { |
| 1189 | /* Valid number of digipeaters ? */ | 1189 | /* Valid number of digipeaters ? */ |
| 1190 | if (fsa->fsa_ax25.sax25_ndigis < 1 || fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS) { | 1190 | if (fsa->fsa_ax25.sax25_ndigis < 1 || |
| 1191 | fsa->fsa_ax25.sax25_ndigis > AX25_MAX_DIGIS || | ||
| 1192 | addr_len < sizeof(struct sockaddr_ax25) + | ||
| 1193 | sizeof(ax25_address) * fsa->fsa_ax25.sax25_ndigis) { | ||
| 1191 | err = -EINVAL; | 1194 | err = -EINVAL; |
| 1192 | goto out_release; | 1195 | goto out_release; |
| 1193 | } | 1196 | } |
| @@ -1507,7 +1510,10 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) · 313 unmodified lines | |||
| 1507 | struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax; | 1510 | struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)usax; |
| 1508 | 1511 | ||
| 1509 | /* Valid number of digipeaters ? */ | 1512 | /* Valid number of digipeaters ? */ |
| 1510 | if (usax->sax25_ndigis < 1 || usax->sax25_ndigis > AX25_MAX_DIGIS) { | 1513 | if (usax->sax25_ndigis < 1 || |
| 1514 | usax->sax25_ndigis > AX25_MAX_DIGIS || | ||
| 1515 | addr_len < sizeof(struct sockaddr_ax25) + | ||
| 1516 | sizeof(ax25_address) * usax->sax25_ndigis) { | ||
| 1511 | err = -EINVAL; | 1517 | err = -EINVAL; |
| 1512 | goto out; | 1518 | goto out; |
| 1513 | } | 1519 | } |
| @@ -5601,7 +5601,7 @@ static void flush_backlog(struct work_struct *work) · 5600 unmodified lines | |||
| 5601 | skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { | 5601 | skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { |
| 5602 | if (skb->dev->reg_state == NETREG_UNREGISTERING) { | 5602 | if (skb->dev->reg_state == NETREG_UNREGISTERING) { |
| 5603 | __skb_unlink(skb, &sd->input_pkt_queue); | 5603 | __skb_unlink(skb, &sd->input_pkt_queue); |
| 5604 | kfree_skb(skb); | 5604 | dev_kfree_skb_irq(skb); |
| 5605 | input_queue_head_incr(sd); | 5605 | input_queue_head_incr(sd); |
| 5606 | } | 5606 | } |
| 5607 | } | 5607 | } |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | #include <net/flow_offload.h> | 4 | #include <net/flow_offload.h> |
| 5 | #include <linux/rtnetlink.h> | 5 | #include <linux/rtnetlink.h> |
| 6 | #include <linux/mutex.h> | 6 | #include <linux/mutex.h> |
| 7 | #include <linux/rhashtable.h> | ||
| 7 | 8 | ||
| 8 | struct flow_rule *flow_rule_alloc(unsigned int num_actions) | 9 | struct flow_rule *flow_rule_alloc(unsigned int num_actions) |
| 9 | { | 10 | { |
| @@ -1108,7 +1108,7 @@ static ssize_t tx_timeout_show(struct netdev_queue *queue, char *buf) · 1107 unmodified lines | |||
| 1108 | trans_timeout = queue->trans_timeout; | 1108 | trans_timeout = queue->trans_timeout; |
| 1109 | spin_unlock_irq(&queue->_xmit_lock); | 1109 | spin_unlock_irq(&queue->_xmit_lock); |
| 1110 | 1110 | ||
| 1111 | return sprintf(buf, "%lu", trans_timeout); | 1111 | return sprintf(buf, fmt_ulong, trans_timeout); |
| 1112 | } | 1112 | } |
| 1113 | 1113 | ||
| 1114 | static unsigned int get_netdev_queue_index(struct netdev_queue *queue) | 1114 | static unsigned int get_netdev_queue_index(struct netdev_queue *queue) |
| @@ -3343,7 +3343,8 @@ replay: · 3342 unmodified lines | |||
| 3343 | */ | 3343 | */ |
| 3344 | if (err < 0) { | 3344 | if (err < 0) { |
| 3345 | /* If device is not registered at all, free it now */ | 3345 | /* If device is not registered at all, free it now */ |
| 3346 | if (dev->reg_state == NETREG_UNINITIALIZED) | 3346 | if (dev->reg_state == NETREG_UNINITIALIZED || |
| 3347 | dev->reg_state == NETREG_UNREGISTERED) | ||
| 3347 | free_netdev(dev); | 3348 | free_netdev(dev); |
| 3348 | goto out; | 3349 | goto out; |
| 3349 | } | 3350 | } |
| @@ -101,6 +101,7 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse) · 100 unmodified lines | |||
| 101 | more_reuse->prog = reuse->prog; | 101 | more_reuse->prog = reuse->prog; |
| 102 | more_reuse->reuseport_id = reuse->reuseport_id; | 102 | more_reuse->reuseport_id = reuse->reuseport_id; |
| 103 | more_reuse->bind_inany = reuse->bind_inany; | 103 | more_reuse->bind_inany = reuse->bind_inany; |
| 104 | more_reuse->has_conns = reuse->has_conns; | ||
| 104 | 105 | ||
| 105 | memcpy(more_reuse->socks, reuse->socks, | 106 | memcpy(more_reuse->socks, reuse->socks, |
| 106 | reuse->num_socks * sizeof(struct sock *)); | 107 | reuse->num_socks * sizeof(struct sock *)); |
| @@ -120,13 +120,18 @@ static struct sk_buff *frame_get_stripped_skb(struct hsr_frame_info *frame, · 119 unmodified lines | |||
| 120 | return skb_clone(frame->skb_std, GFP_ATOMIC); | 120 | return skb_clone(frame->skb_std, GFP_ATOMIC); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame, | 123 | static struct sk_buff *hsr_fill_tag(struct sk_buff *skb, |
| 124 | struct hsr_port *port, u8 proto_version) | 124 | struct hsr_frame_info *frame, |
| 125 | struct hsr_port *port, u8 proto_version) | ||
| 125 | { | 126 | { |
| 126 | struct hsr_ethhdr *hsr_ethhdr; | 127 | struct hsr_ethhdr *hsr_ethhdr; |
| 127 | int lane_id; | 128 | int lane_id; |
| 128 | int lsdu_size; | 129 | int lsdu_size; |
| 129 | 130 | ||
| 131 | /* pad to minimum packet size which is 60 + 6 (HSR tag) */ | ||
| 132 | if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) | ||
| 133 | return NULL; | ||
| 134 | |||
| 130 | if (port->type == HSR_PT_SLAVE_A) | 135 | if (port->type == HSR_PT_SLAVE_A) |
| 131 | lane_id = 0; | 136 | lane_id = 0; |
| 132 | else | 137 | else |
| @@ -144,6 +149,8 @@ static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame, · 11 unmodified lines | |||
| 144 | hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; | 149 | hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; |
| 145 | hsr_ethhdr->ethhdr.h_proto = htons(proto_version ? | 150 | hsr_ethhdr->ethhdr.h_proto = htons(proto_version ? |
| 146 | ETH_P_HSR : ETH_P_PRP); | 151 | ETH_P_HSR : ETH_P_PRP); |
| 152 | |||
| 153 | return skb; | ||
| 147 | } | 154 | } |
| 148 | 155 | ||
| 149 | static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, | 156 | static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, |
| @@ -172,9 +179,10 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, · 22 unmodified lines | |||
| 172 | memmove(dst, src, movelen); | 179 | memmove(dst, src, movelen); |
| 173 | skb_reset_mac_header(skb); | 180 | skb_reset_mac_header(skb); |
| 174 | 181 | ||
| 175 | hsr_fill_tag(skb, frame, port, port->hsr->prot_version); | 182 | /* skb_put_padto free skb on error and hsr_fill_tag returns NULL in |
| 176 | 183 | * that case | |
| 177 | return skb; | 184 | */ |
| 185 | return hsr_fill_tag(skb, frame, port, port->hsr->prot_version); | ||
| 178 | } | 186 | } |
| 179 | 187 | ||
| 180 | /* If the original frame was an HSR tagged frame, just clone it to be sent | 188 | /* If the original frame was an HSR tagged frame, just clone it to be sent |
| @@ -325,7 +325,8 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb, · 324 unmodified lines | |||
| 325 | if (port->type != node_dst->addr_B_port) | 325 | if (port->type != node_dst->addr_B_port) |
| 326 | return; | 326 | return; |
| 327 | 327 | ||
| 328 | ether_addr_copy(eth_hdr(skb)->h_dest, node_dst->macaddress_B); | 328 | if (is_valid_ether_addr(node_dst->macaddress_B)) |
| 329 | ether_addr_copy(eth_hdr(skb)->h_dest, node_dst->macaddress_B); | ||
| 329 | } | 330 | } |
| 330 | 331 | ||
| 331 | void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port, | 332 | void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port, |
| @@ -3488,10 +3488,8 @@ static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) · 3487 unmodified lines | |||
| 3488 | } | 3488 | } |
| 3489 | } | 3489 | } |
| 3490 | 3490 | ||
| 3491 | /* This routine deals with acks during a TLP episode. | 3491 | /* This routine deals with acks during a TLP episode and ends an episode by |
| 3492 | * We mark the end of a TLP episode on receiving TLP dupack or when | 3492 | * resetting tlp_high_seq. Ref: TLP algorithm in draft-ietf-tcpm-rack |
| 3493 | * ack is after tlp_high_seq. | ||
| 3494 | * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe. | ||
| 3495 | */ | 3493 | */ |
| 3496 | static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) | 3494 | static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) |
| 3497 | { | 3495 | { |
| @@ -3500,7 +3498,10 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) · 2 unmodified lines | |||
| 3500 | if (before(ack, tp->tlp_high_seq)) | 3498 | if (before(ack, tp->tlp_high_seq)) |
| 3501 | return; | 3499 | return; |
| 3502 | 3500 | ||
| 3503 | if (flag & FLAG_DSACKING_ACK) { | 3501 | if (!tp->tlp_retrans) { |
| 3502 | /* TLP of new data has been acknowledged */ | ||
| 3503 | tp->tlp_high_seq = 0; | ||
| 3504 | } else if (flag & FLAG_DSACKING_ACK) { | ||
| 3504 | /* This DSACK means original and TLP probe arrived; no loss */ | 3505 | /* This DSACK means original and TLP probe arrived; no loss */ |
| 3505 | tp->tlp_high_seq = 0; | 3506 | tp->tlp_high_seq = 0; |
| 3506 | } else if (after(ack, tp->tlp_high_seq)) { | 3507 | } else if (after(ack, tp->tlp_high_seq)) { |
| @@ -2624,6 +2624,11 @@ void tcp_send_loss_probe(struct sock *sk) · 2623 unmodified lines | |||
| 2624 | int pcount; | 2624 | int pcount; |
| 2625 | int mss = tcp_current_mss(sk); | 2625 | int mss = tcp_current_mss(sk); |
| 2626 | 2626 | ||
| 2627 | /* At most one outstanding TLP */ | ||
| 2628 | if (tp->tlp_high_seq) | ||
| 2629 | goto rearm_timer; | ||
| 2630 | |||
| 2631 | tp->tlp_retrans = 0; | ||
| 2627 | skb = tcp_send_head(sk); | 2632 | skb = tcp_send_head(sk); |
| 2628 | if (skb && tcp_snd_wnd_test(tp, skb, mss)) { | 2633 | if (skb && tcp_snd_wnd_test(tp, skb, mss)) { |
| 2629 | pcount = tp->packets_out; | 2634 | pcount = tp->packets_out; |
| @@ -2641,10 +2646,6 @@ void tcp_send_loss_probe(struct sock *sk) · 11 unmodified lines | |||
| 2641 | return; | 2646 | return; |
| 2642 | } | 2647 | } |
| 2643 | 2648 | ||
| 2644 | /* At most one outstanding TLP retransmission. */ | ||
| 2645 | if (tp->tlp_high_seq) | ||
| 2646 | goto rearm_timer; | ||
| 2647 | |||
| 2648 | if (skb_still_in_host_queue(sk, skb)) | 2649 | if (skb_still_in_host_queue(sk, skb)) |
| 2649 | goto rearm_timer; | 2650 | goto rearm_timer; |
| 2650 | 2651 | ||
| @@ -2666,10 +2667,12 @@ void tcp_send_loss_probe(struct sock *sk) · 15 unmodified lines | |||
| 2666 | if (__tcp_retransmit_skb(sk, skb, 1)) | 2667 | if (__tcp_retransmit_skb(sk, skb, 1)) |
| 2667 | goto rearm_timer; | 2668 | goto rearm_timer; |
| 2668 | 2669 | ||
| 2670 | tp->tlp_retrans = 1; | ||
| 2671 | |||
| 2672 | probe_sent: | ||
| 2669 | /* Record snd_nxt for loss detection. */ | 2673 | /* Record snd_nxt for loss detection. */ |
| 2670 | tp->tlp_high_seq = tp->snd_nxt; | 2674 | tp->tlp_high_seq = tp->snd_nxt; |
| 2671 | 2675 | ||
| 2672 | probe_sent: | ||
| 2673 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPLOSSPROBES); | 2676 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPLOSSPROBES); |
| 2674 | /* Reset s.t. tcp_rearm_rto will restart timer from now */ | 2677 | /* Reset s.t. tcp_rearm_rto will restart timer from now */ |
| 2675 | inet_csk(sk)->icsk_pending = 0; | 2678 | inet_csk(sk)->icsk_pending = 0; |
| @@ -416,7 +416,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, · 415 unmodified lines | |||
| 416 | struct udp_hslot *hslot2, | 416 | struct udp_hslot *hslot2, |
| 417 | struct sk_buff *skb) | 417 | struct sk_buff *skb) |
| 418 | { | 418 | { |
| 419 | struct sock *sk, *result; | 419 | struct sock *sk, *result, *reuseport_result; |
| 420 | int score, badness; | 420 | int score, badness; |
| 421 | u32 hash = 0; | 421 | u32 hash = 0; |
| 422 | 422 | ||
| @@ -426,17 +426,20 @@ static struct sock *udp4_lib_lookup2(struct net *net, · 3 unmodified lines | |||
| 426 | score = compute_score(sk, net, saddr, sport, | 426 | score = compute_score(sk, net, saddr, sport, |
| 427 | daddr, hnum, dif, sdif); | 427 | daddr, hnum, dif, sdif); |
| 428 | if (score > badness) { | 428 | if (score > badness) { |
| 429 | reuseport_result = NULL; | ||
| 430 | |||
| 429 | if (sk->sk_reuseport && | 431 | if (sk->sk_reuseport && |
| 430 | sk->sk_state != TCP_ESTABLISHED) { | 432 | sk->sk_state != TCP_ESTABLISHED) { |
| 431 | hash = udp_ehashfn(net, daddr, hnum, | 433 | hash = udp_ehashfn(net, daddr, hnum, |
| 432 | saddr, sport); | 434 | saddr, sport); |
| 433 | result = reuseport_select_sock(sk, hash, skb, | 435 | reuseport_result = reuseport_select_sock(sk, hash, skb, |
| 434 | sizeof(struct udphdr)); | 436 | sizeof(struct udphdr)); |
| 435 | if (result && !reuseport_has_conns(sk, false)) | 437 | if (reuseport_result && !reuseport_has_conns(sk, false)) |
| 436 | return result; | 438 | return reuseport_result; |
| 437 | } | 439 | } |
| 440 | |||
| 441 | result = reuseport_result ? : sk; | ||
| 438 | badness = score; | 442 | badness = score; |
| 439 | result = sk; | ||
| 440 | } | 443 | } |
| 441 | } | 444 | } |
| 442 | return result; | 445 | return result; |
| @@ -2051,7 +2054,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) · 1608 unmodified lines | |||
| 2051 | /* | 2054 | /* |
| 2052 | * UDP-Lite specific tests, ignored on UDP sockets | 2055 | * UDP-Lite specific tests, ignored on UDP sockets |
| 2053 | */ | 2056 | */ |
| 2054 | if ((is_udplite & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { | 2057 | if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { |
| 2055 | 2058 | ||
| 2056 | /* | 2059 | /* |
| 2057 | * MIB statistics other than incrementing the error count are | 2060 | * MIB statistics other than incrementing the error count are |
| @@ -1562,17 +1562,18 @@ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head) · 1561 unmodified lines | |||
| 1562 | static int __net_init ip6gre_init_net(struct net *net) | 1562 | static int __net_init ip6gre_init_net(struct net *net) |
| 1563 | { | 1563 | { |
| 1564 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); | 1564 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); |
| 1565 | struct net_device *ndev; | ||
| 1565 | int err; | 1566 | int err; |
| 1566 | 1567 | ||
| 1567 | if (!net_has_fallback_tunnels(net)) | 1568 | if (!net_has_fallback_tunnels(net)) |
| 1568 | return 0; | 1569 | return 0; |
| 1569 | ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", | 1570 | ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0", |
| 1570 | NET_NAME_UNKNOWN, | 1571 | NET_NAME_UNKNOWN, ip6gre_tunnel_setup); |
| 1571 | ip6gre_tunnel_setup); | 1572 | if (!ndev) { |
| 1572 | if (!ign->fb_tunnel_dev) { | ||
| 1573 | err = -ENOMEM; | 1573 | err = -ENOMEM; |
| 1574 | goto err_alloc_dev; | 1574 | goto err_alloc_dev; |
| 1575 | } | 1575 | } |
| 1576 | ign->fb_tunnel_dev = ndev; | ||
| 1576 | dev_net_set(ign->fb_tunnel_dev, net); | 1577 | dev_net_set(ign->fb_tunnel_dev, net); |
| 1577 | /* FB netdevice is special: we have one, and only one per netns. | 1578 | /* FB netdevice is special: we have one, and only one per netns. |
| 1578 | * Allowing to move it to another netns is clearly unsafe. | 1579 | * Allowing to move it to another netns is clearly unsafe. |
| @@ -1592,7 +1593,7 @@ static int __net_init ip6gre_init_net(struct net *net) · 13 unmodified lines | |||
| 1592 | return 0; | 1593 | return 0; |
| 1593 | 1594 | ||
| 1594 | err_reg_dev: | 1595 | err_reg_dev: |
| 1595 | free_netdev(ign->fb_tunnel_dev); | 1596 | free_netdev(ndev); |
| 1596 | err_alloc_dev: | 1597 | err_alloc_dev: |
| 1597 | return err; | 1598 | return err; |
| 1598 | } | 1599 | } |
| @@ -148,7 +148,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, · 147 unmodified lines | |||
| 148 | int dif, int sdif, struct udp_hslot *hslot2, | 148 | int dif, int sdif, struct udp_hslot *hslot2, |
| 149 | struct sk_buff *skb) | 149 | struct sk_buff *skb) |
| 150 | { | 150 | { |
| 151 | struct sock *sk, *result; | 151 | struct sock *sk, *result, *reuseport_result; |
| 152 | int score, badness; | 152 | int score, badness; |
| 153 | u32 hash = 0; | 153 | u32 hash = 0; |
| 154 | 154 | ||
| @@ -158,17 +158,20 @@ static struct sock *udp6_lib_lookup2(struct net *net, · 3 unmodified lines | |||
| 158 | score = compute_score(sk, net, saddr, sport, | 158 | score = compute_score(sk, net, saddr, sport, |
| 159 | daddr, hnum, dif, sdif); | 159 | daddr, hnum, dif, sdif); |
| 160 | if (score > badness) { | 160 | if (score > badness) { |
| 161 | reuseport_result = NULL; | ||
| 162 | |||
| 161 | if (sk->sk_reuseport && | 163 | if (sk->sk_reuseport && |
| 162 | sk->sk_state != TCP_ESTABLISHED) { | 164 | sk->sk_state != TCP_ESTABLISHED) { |
| 163 | hash = udp6_ehashfn(net, daddr, hnum, | 165 | hash = udp6_ehashfn(net, daddr, hnum, |
| 164 | saddr, sport); | 166 | saddr, sport); |
| 165 | 167 | ||
| 166 | result = reuseport_select_sock(sk, hash, skb, | 168 | reuseport_result = reuseport_select_sock(sk, hash, skb, |
| 167 | sizeof(struct udphdr)); | 169 | sizeof(struct udphdr)); |
| 168 | if (result && !reuseport_has_conns(sk, false)) | 170 | if (reuseport_result && !reuseport_has_conns(sk, false)) |
| 169 | return result; | 171 | return reuseport_result; |
| 170 | } | 172 | } |
| 171 | result = sk; | 173 | |
| 174 | result = reuseport_result ? : sk; | ||
| 172 | badness = score; | 175 | badness = score; |
| 173 | } | 176 | } |
| 174 | } | 177 | } |
| @@ -643,7 +646,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) · 468 unmodified lines | |||
| 643 | /* | 646 | /* |
| 644 | * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c). | 647 | * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c). |
| 645 | */ | 648 | */ |
| 646 | if ((is_udplite & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { | 649 | if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) { |
| 647 | 650 | ||
| 648 | if (up->pcrlen == 0) { /* full coverage was set */ | 651 | if (up->pcrlen == 0) { /* full coverage was set */ |
| 649 | net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n", | 652 | net_dbg_ratelimited("UDPLITE6: partial coverage %d while full coverage %d requested\n", |
| @@ -1717,6 +1717,8 @@ static int sync_thread_backup(void *data) · 1716 unmodified lines | |||
| 1717 | { | 1717 | { |
| 1718 | struct ip_vs_sync_thread_data *tinfo = data; | 1718 | struct ip_vs_sync_thread_data *tinfo = data; |
| 1719 | struct netns_ipvs *ipvs = tinfo->ipvs; | 1719 | struct netns_ipvs *ipvs = tinfo->ipvs; |
| 1720 | struct sock *sk = tinfo->sock->sk; | ||
| 1721 | struct udp_sock *up = udp_sk(sk); | ||
| 1720 | int len; | 1722 | int len; |
| 1721 | 1723 | ||
| 1722 | pr_info("sync thread started: state = BACKUP, mcast_ifn = %s, " | 1724 | pr_info("sync thread started: state = BACKUP, mcast_ifn = %s, " |
| @@ -1724,12 +1726,14 @@ static int sync_thread_backup(void *data) · 1 unmodified line | |||
| 1724 | ipvs->bcfg.mcast_ifn, ipvs->bcfg.syncid, tinfo->id); | 1726 | ipvs->bcfg.mcast_ifn, ipvs->bcfg.syncid, tinfo->id); |
| 1725 | 1727 | ||
| 1726 | while (!kthread_should_stop()) { | 1728 | while (!kthread_should_stop()) { |
| 1727 | wait_event_interruptible(*sk_sleep(tinfo->sock->sk), | 1729 | wait_event_interruptible(*sk_sleep(sk), |
| 1728 | !skb_queue_empty(&tinfo->sock->sk->sk_receive_queue) | 1730 | !skb_queue_empty_lockless(&sk->sk_receive_queue) || |
| 1729 | || kthread_should_stop()); | 1731 | !skb_queue_empty_lockless(&up->reader_queue) || |
| 1732 | kthread_should_stop()); | ||
| 1730 | 1733 | ||
| 1731 | /* do we have data now? */ | 1734 | /* do we have data now? */ |
| 1732 | while (!skb_queue_empty(&(tinfo->sock->sk->sk_receive_queue))) { | 1735 | while (!skb_queue_empty_lockless(&sk->sk_receive_queue) || |
| 1736 | !skb_queue_empty_lockless(&up->reader_queue)) { | ||
| 1733 | len = ip_vs_receive(tinfo->sock, tinfo->buf, | 1737 | len = ip_vs_receive(tinfo->sock, tinfo->buf, |
| 1734 | ipvs->bcfg.sync_maxlen); | 1738 | ipvs->bcfg.sync_maxlen); |
| 1735 | if (len <= 0) { | 1739 | if (len <= 0) { |
| @@ -188,24 +188,6 @@ static void nft_netdev_unregister_hooks(struct net *net, · 187 unmodified lines | |||
| 188 | nf_unregister_net_hook(net, &hook->ops); | 188 | nf_unregister_net_hook(net, &hook->ops); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | static int nft_register_basechain_hooks(struct net *net, int family, | ||
| 192 | struct nft_base_chain *basechain) | ||
| 193 | { | ||
| 194 | if (family == NFPROTO_NETDEV) | ||
| 195 | return nft_netdev_register_hooks(net, &basechain->hook_list); | ||
| 196 | |||
| 197 | return nf_register_net_hook(net, &basechain->ops); | ||
| 198 | } | ||
| 199 | |||
| 200 | static void nft_unregister_basechain_hooks(struct net *net, int family, | ||
| 201 | struct nft_base_chain *basechain) | ||
| 202 | { | ||
| 203 | if (family == NFPROTO_NETDEV) | ||
| 204 | nft_netdev_unregister_hooks(net, &basechain->hook_list); | ||
| 205 | else | ||
| 206 | nf_unregister_net_hook(net, &basechain->ops); | ||
| 207 | } | ||
| 208 | |||
| 209 | static int nf_tables_register_hook(struct net *net, | 191 | static int nf_tables_register_hook(struct net *net, |
| 210 | const struct nft_table *table, | 192 | const struct nft_table *table, |
| 211 | struct nft_chain *chain) | 193 | struct nft_chain *chain) |
| @@ -223,7 +205,10 @@ static int nf_tables_register_hook(struct net *net, · 11 unmodified lines | |||
| 223 | if (basechain->type->ops_register) | 205 | if (basechain->type->ops_register) |
| 224 | return basechain->type->ops_register(net, ops); | 206 | return basechain->type->ops_register(net, ops); |
| 225 | 207 | ||
| 226 | return nft_register_basechain_hooks(net, table->family, basechain); | 208 | if (table->family == NFPROTO_NETDEV) |
| 209 | return nft_netdev_register_hooks(net, &basechain->hook_list); | ||
| 210 | |||
| 211 | return nf_register_net_hook(net, &basechain->ops); | ||
| 227 | } | 212 | } |
| 228 | 213 | ||
| 229 | static void nf_tables_unregister_hook(struct net *net, | 214 | static void nf_tables_unregister_hook(struct net *net, |
| @@ -242,7 +227,10 @@ static void nf_tables_unregister_hook(struct net *net, · 12 unmodified lines | |||
| 242 | if (basechain->type->ops_unregister) | 227 | if (basechain->type->ops_unregister) |
| 243 | return basechain->type->ops_unregister(net, ops); | 228 | return basechain->type->ops_unregister(net, ops); |
| 244 | 229 | ||
| 245 | nft_unregister_basechain_hooks(net, table->family, basechain); | 230 | if (table->family == NFPROTO_NETDEV) |
| 231 | nft_netdev_unregister_hooks(net, &basechain->hook_list); | ||
| 232 | else | ||
| 233 | nf_unregister_net_hook(net, &basechain->ops); | ||
| 246 | } | 234 | } |
| 247 | 235 | ||
| 248 | static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) | 236 | static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) |
| @@ -832,8 +820,7 @@ static void nft_table_disable(struct net *net, struct nft_table *table, u32 cnt) · 583 unmodified lines | |||
| 832 | if (cnt && i++ == cnt) | 820 | if (cnt && i++ == cnt) |
| 833 | break; | 821 | break; |
| 834 | 822 | ||
| 835 | nft_unregister_basechain_hooks(net, table->family, | 823 | nf_tables_unregister_hook(net, table, chain); |
| 836 | nft_base_chain(chain)); | ||
| 837 | } | 824 | } |
| 838 | } | 825 | } |
| 839 | 826 | ||
| @@ -848,8 +835,7 @@ static int nf_tables_table_enable(struct net *net, struct nft_table *table) · 8 unmodified lines | |||
| 848 | if (!nft_is_base_chain(chain)) | 835 | if (!nft_is_base_chain(chain)) |
| 849 | continue; | 836 | continue; |
| 850 | 837 | ||
| 851 | err = nft_register_basechain_hooks(net, table->family, | 838 | err = nf_tables_register_hook(net, table, chain); |
| 852 | nft_base_chain(chain)); | ||
| 853 | if (err < 0) | 839 | if (err < 0) |
| 854 | goto err_register_hooks; | 840 | goto err_register_hooks; |
| 855 | 841 | ||
| @@ -894,11 +880,12 @@ static int nf_tables_updtable(struct nft_ctx *ctx) · 38 unmodified lines | |||
| 894 | nft_trans_table_enable(trans) = false; | 880 | nft_trans_table_enable(trans) = false; |
| 895 | } else if (!(flags & NFT_TABLE_F_DORMANT) && | 881 | } else if (!(flags & NFT_TABLE_F_DORMANT) && |
| 896 | ctx->table->flags & NFT_TABLE_F_DORMANT) { | 882 | ctx->table->flags & NFT_TABLE_F_DORMANT) { |
| 883 | ctx->table->flags &= ~NFT_TABLE_F_DORMANT; | ||
| 897 | ret = nf_tables_table_enable(ctx->net, ctx->table); | 884 | ret = nf_tables_table_enable(ctx->net, ctx->table); |
| 898 | if (ret >= 0) { | 885 | if (ret >= 0) |
| 899 | ctx->table->flags &= ~NFT_TABLE_F_DORMANT; | ||
| 900 | nft_trans_table_enable(trans) = true; | 886 | nft_trans_table_enable(trans) = true; |
| 901 | } | 887 | else |
| 888 | ctx->table->flags |= NFT_TABLE_F_DORMANT; | ||
| 902 | } | 889 | } |
| 903 | if (ret < 0) | 890 | if (ret < 0) |
| 904 | goto err; | 891 | goto err; |
| @@ -1228,10 +1228,13 @@ int nci_register_device(struct nci_dev *ndev) · 1227 unmodified lines | |||
| 1228 | 1228 | ||
| 1229 | rc = nfc_register_device(ndev->nfc_dev); | 1229 | rc = nfc_register_device(ndev->nfc_dev); |
| 1230 | if (rc) | 1230 | if (rc) |
| 1231 | goto destroy_rx_wq_exit; | 1231 | goto destroy_tx_wq_exit; |
| 1232 | 1232 | ||
| 1233 | goto exit; | 1233 | goto exit; |
| 1234 | 1234 | ||
| 1235 | destroy_tx_wq_exit: | ||
| 1236 | destroy_workqueue(ndev->tx_wq); | ||
| 1237 | |||
| 1235 | destroy_rx_wq_exit: | 1238 | destroy_rx_wq_exit: |
| 1236 | destroy_workqueue(ndev->rx_wq); | 1239 | destroy_workqueue(ndev->rx_wq); |
| 1237 | 1240 | ||
| @@ -1180,6 +1180,7 @@ static int qrtr_release(struct socket *sock) · 1179 unmodified lines | |||
| 1180 | sk->sk_state_change(sk); | 1180 | sk->sk_state_change(sk); |
| 1181 | 1181 | ||
| 1182 | sock_set_flag(sk, SOCK_DEAD); | 1182 | sock_set_flag(sk, SOCK_DEAD); |
| 1183 | sock_orphan(sk); | ||
| 1183 | sock->sk = NULL; | 1184 | sock->sk = NULL; |
| 1184 | 1185 | ||
| 1185 | if (!sock_flag(sk, SOCK_ZAPPED)) | 1186 | if (!sock_flag(sk, SOCK_ZAPPED)) |
| @@ -543,7 +543,7 @@ try_again: · 542 unmodified lines | |||
| 543 | list_empty(&rx->recvmsg_q) && | 543 | list_empty(&rx->recvmsg_q) && |
| 544 | rx->sk.sk_state != RXRPC_SERVER_LISTENING) { | 544 | rx->sk.sk_state != RXRPC_SERVER_LISTENING) { |
| 545 | release_sock(&rx->sk); | 545 | release_sock(&rx->sk); |
| 546 | return -ENODATA; | 546 | return -EAGAIN; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | if (list_empty(&rx->recvmsg_q)) { | 549 | if (list_empty(&rx->recvmsg_q)) { |
| @@ -304,7 +304,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, · 303 unmodified lines | |||
| 304 | /* this should be in poll */ | 304 | /* this should be in poll */ |
| 305 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); | 305 | sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
| 306 | 306 | ||
| 307 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 307 | if (sk->sk_shutdown & SEND_SHUTDOWN) |
| 308 | return -EPIPE; | 308 | return -EPIPE; |
| 309 | 309 | ||
| 310 | more = msg->msg_flags & MSG_MORE; | 310 | more = msg->msg_flags & MSG_MORE; |
| @@ -673,9 +673,10 @@ static int tcf_ct_ipv6_is_fragment(struct sk_buff *skb, bool *frag) · 672 unmodified lines | |||
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, | 675 | static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, |
| 676 | u8 family, u16 zone) | 676 | u8 family, u16 zone, bool *defrag) |
| 677 | { | 677 | { |
| 678 | enum ip_conntrack_info ctinfo; | 678 | enum ip_conntrack_info ctinfo; |
| 679 | struct qdisc_skb_cb cb; | ||
| 679 | struct nf_conn *ct; | 680 | struct nf_conn *ct; |
| 680 | int err = 0; | 681 | int err = 0; |
| 681 | bool frag; | 682 | bool frag; |
| @@ -693,6 +694,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, · 11 unmodified lines | |||
| 693 | return err; | 694 | return err; |
| 694 | 695 | ||
| 695 | skb_get(skb); | 696 | skb_get(skb); |
| 697 | cb = *qdisc_skb_cb(skb); | ||
| 696 | 698 | ||
| 697 | if (family == NFPROTO_IPV4) { | 699 | if (family == NFPROTO_IPV4) { |
| 698 | enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone; | 700 | enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone; |
| @@ -703,6 +705,9 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, · 4 unmodified lines | |||
| 703 | local_bh_enable(); | 705 | local_bh_enable(); |
| 704 | if (err && err != -EINPROGRESS) | 706 | if (err && err != -EINPROGRESS) |
| 705 | goto out_free; | 707 | goto out_free; |
| 708 | |||
| 709 | if (!err) | ||
| 710 | *defrag = true; | ||
| 706 | } else { /* NFPROTO_IPV6 */ | 711 | } else { /* NFPROTO_IPV6 */ |
| 707 | #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) | 712 | #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) |
| 708 | enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone; | 713 | enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone; |
| @@ -711,12 +716,16 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, · 2 unmodified lines | |||
| 711 | err = nf_ct_frag6_gather(net, skb, user); | 716 | err = nf_ct_frag6_gather(net, skb, user); |
| 712 | if (err && err != -EINPROGRESS) | 717 | if (err && err != -EINPROGRESS) |
| 713 | goto out_free; | 718 | goto out_free; |
| 719 | |||
| 720 | if (!err) | ||
| 721 | *defrag = true; | ||
| 714 | #else | 722 | #else |
| 715 | err = -EOPNOTSUPP; | 723 | err = -EOPNOTSUPP; |
| 716 | goto out_free; | 724 | goto out_free; |
| 717 | #endif | 725 | #endif |
| 718 | } | 726 | } |
| 719 | 727 | ||
| 728 | *qdisc_skb_cb(skb) = cb; | ||
| 720 | skb_clear_hash(skb); | 729 | skb_clear_hash(skb); |
| 721 | skb->ignore_df = 1; | 730 | skb->ignore_df = 1; |
| 722 | return err; | 731 | return err; |
| @@ -914,6 +923,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, · 191 unmodified lines | |||
| 914 | int nh_ofs, err, retval; | 923 | int nh_ofs, err, retval; |
| 915 | struct tcf_ct_params *p; | 924 | struct tcf_ct_params *p; |
| 916 | bool skip_add = false; | 925 | bool skip_add = false; |
| 926 | bool defrag = false; | ||
| 917 | struct nf_conn *ct; | 927 | struct nf_conn *ct; |
| 918 | u8 family; | 928 | u8 family; |
| 919 | 929 | ||
| @@ -946,7 +956,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, · 26 unmodified lines | |||
| 946 | */ | 956 | */ |
| 947 | nh_ofs = skb_network_offset(skb); | 957 | nh_ofs = skb_network_offset(skb); |
| 948 | skb_pull_rcsum(skb, nh_ofs); | 958 | skb_pull_rcsum(skb, nh_ofs); |
| 949 | err = tcf_ct_handle_fragments(net, skb, family, p->zone); | 959 | err = tcf_ct_handle_fragments(net, skb, family, p->zone, &defrag); |
| 950 | if (err == -EINPROGRESS) { | 960 | if (err == -EINPROGRESS) { |
| 951 | retval = TC_ACT_STOLEN; | 961 | retval = TC_ACT_STOLEN; |
| 952 | goto out; | 962 | goto out; |
| @@ -1014,6 +1024,8 @@ out_push: · 61 unmodified lines | |||
| 1014 | 1024 | ||
| 1015 | out: | 1025 | out: |
| 1016 | tcf_action_update_bstats(&c->common, skb); | 1026 | tcf_action_update_bstats(&c->common, skb); |
| 1027 | if (defrag) | ||
| 1028 | qdisc_skb_cb(skb)->pkt_len = skb->len; | ||
| 1017 | return retval; | 1029 | return retval; |
| 1018 | 1030 | ||
| 1019 | drop: | 1031 | drop: |
| @@ -20,7 +20,6 @@ · 19 unmodified lines | |||
| 20 | #include <linux/kmod.h> | 20 | #include <linux/kmod.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/idr.h> | 22 | #include <linux/idr.h> |
| 23 | #include <linux/rhashtable.h> | ||
| 24 | #include <linux/jhash.h> | 23 | #include <linux/jhash.h> |
| 25 | #include <linux/rculist.h> | 24 | #include <linux/rculist.h> |
| 26 | #include <net/net_namespace.h> | 25 | #include <net/net_namespace.h> |
| @@ -22,17 +22,11 @@ · 21 unmodified lines | |||
| 22 | #include <net/sctp/sm.h> | 22 | #include <net/sctp/sm.h> |
| 23 | #include <net/sctp/stream_sched.h> | 23 | #include <net/sctp/stream_sched.h> |
| 24 | 24 | ||
| 25 | /* Migrates chunks from stream queues to new stream queues if needed, | 25 | static void sctp_stream_shrink_out(struct sctp_stream *stream, __u16 outcnt) |
| 26 | * but not across associations. Also, removes those chunks to streams | ||
| 27 | * higher than the new max. | ||
| 28 | */ | ||
| 29 | static void sctp_stream_outq_migrate(struct sctp_stream *stream, | ||
| 30 | struct sctp_stream *new, __u16 outcnt) | ||
| 31 | { | 26 | { |
| 32 | struct sctp_association *asoc; | 27 | struct sctp_association *asoc; |
| 33 | struct sctp_chunk *ch, *temp; | 28 | struct sctp_chunk *ch, *temp; |
| 34 | struct sctp_outq *outq; | 29 | struct sctp_outq *outq; |
| 35 | int i; | ||
| 36 | 30 | ||
| 37 | asoc = container_of(stream, struct sctp_association, stream); | 31 | asoc = container_of(stream, struct sctp_association, stream); |
| 38 | outq = &asoc->outqueue; | 32 | outq = &asoc->outqueue; |
| @@ -56,6 +50,19 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream, · 17 unmodified lines | |||
| 56 | 50 | ||
| 57 | sctp_chunk_free(ch); | 51 | sctp_chunk_free(ch); |
| 58 | } | 52 | } |
| 53 | } | ||
| 54 | |||
| 55 | /* Migrates chunks from stream queues to new stream queues if needed, | ||
| 56 | * but not across associations. Also, removes those chunks to streams | ||
| 57 | * higher than the new max. | ||
| 58 | */ | ||
| 59 | static void sctp_stream_outq_migrate(struct sctp_stream *stream, | ||
| 60 | struct sctp_stream *new, __u16 outcnt) | ||
| 61 | { | ||
| 62 | int i; | ||
| 63 | |||
| 64 | if (stream->outcnt > outcnt) | ||
| 65 | sctp_stream_shrink_out(stream, outcnt); | ||
| 59 | 66 | ||
| 60 | if (new) { | 67 | if (new) { |
| 61 | /* Here we actually move the old ext stuff into the new | 68 | /* Here we actually move the old ext stuff into the new |
| @@ -1037,11 +1044,13 @@ struct sctp_chunk *sctp_process_strreset_resp( · 975 unmodified lines | |||
| 1037 | nums = ntohs(addstrm->number_of_streams); | 1044 | nums = ntohs(addstrm->number_of_streams); |
| 1038 | number = stream->outcnt - nums; | 1045 | number = stream->outcnt - nums; |
| 1039 | 1046 | ||
| 1040 | if (result == SCTP_STRRESET_PERFORMED) | 1047 | if (result == SCTP_STRRESET_PERFORMED) { |
| 1041 | for (i = number; i < stream->outcnt; i++) | 1048 | for (i = number; i < stream->outcnt; i++) |
| 1042 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; | 1049 | SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; |
| 1043 | else | 1050 | } else { |
| 1051 | sctp_stream_shrink_out(stream, number); | ||
| 1044 | stream->outcnt = number; | 1052 | stream->outcnt = number; |
| 1053 | } | ||
| 1045 | 1054 | ||
| 1046 | *evp = sctp_ulpevent_make_stream_change_event(asoc, flags, | 1055 | *evp = sctp_ulpevent_make_stream_change_event(asoc, flags, |
| 1047 | 0, nums, GFP_ATOMIC); | 1056 | 0, nums, GFP_ATOMIC); |
| @@ -126,8 +126,10 @@ EXPORT_SYMBOL_GPL(smc_proto6); · 125 unmodified lines | |||
| 126 | 126 | ||
| 127 | static void smc_restore_fallback_changes(struct smc_sock *smc) | 127 | static void smc_restore_fallback_changes(struct smc_sock *smc) |
| 128 | { | 128 | { |
| 129 | smc->clcsock->file->private_data = smc->sk.sk_socket; | 129 | if (smc->clcsock->file) { /* non-accepted sockets have no file yet */ |
| 130 | smc->clcsock->file = NULL; | 130 | smc->clcsock->file->private_data = smc->sk.sk_socket; |
| 131 | smc->clcsock->file = NULL; | ||
| 132 | } | ||
| 131 | } | 133 | } |
| 132 | 134 | ||
| 133 | static int __smc_release(struct smc_sock *smc) | 135 | static int __smc_release(struct smc_sock *smc) |
| @@ -352,7 +354,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link, · 218 unmodified lines | |||
| 352 | */ | 354 | */ |
| 353 | mutex_lock(&lgr->llc_conf_mutex); | 355 | mutex_lock(&lgr->llc_conf_mutex); |
| 354 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 356 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 355 | if (lgr->lnk[i].state != SMC_LNK_ACTIVE) | 357 | if (!smc_link_active(&lgr->lnk[i])) |
| 356 | continue; | 358 | continue; |
| 357 | rc = smcr_link_reg_rmb(&lgr->lnk[i], rmb_desc); | 359 | rc = smcr_link_reg_rmb(&lgr->lnk[i], rmb_desc); |
| 358 | if (rc) | 360 | if (rc) |
| @@ -632,7 +634,9 @@ static int smc_connect_rdma(struct smc_sock *smc, · 273 unmodified lines | |||
| 632 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 634 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 633 | struct smc_link *l = &smc->conn.lgr->lnk[i]; | 635 | struct smc_link *l = &smc->conn.lgr->lnk[i]; |
| 634 | 636 | ||
| 635 | if (l->peer_qpn == ntoh24(aclc->qpn)) { | 637 | if (l->peer_qpn == ntoh24(aclc->qpn) && |
| 638 | !memcmp(l->peer_gid, &aclc->lcl.gid, SMC_GID_SIZE) && | ||
| 639 | !memcmp(l->peer_mac, &aclc->lcl.mac, sizeof(l->peer_mac))) { | ||
| 636 | link = l; | 640 | link = l; |
| 637 | break; | 641 | break; |
| 638 | } | 642 | } |
| @@ -66,9 +66,13 @@ int smc_cdc_get_free_slot(struct smc_connection *conn, · 65 unmodified lines | |||
| 66 | rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf, | 66 | rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf, |
| 67 | wr_rdma_buf, | 67 | wr_rdma_buf, |
| 68 | (struct smc_wr_tx_pend_priv **)pend); | 68 | (struct smc_wr_tx_pend_priv **)pend); |
| 69 | if (conn->killed) | 69 | if (conn->killed) { |
| 70 | /* abnormal termination */ | 70 | /* abnormal termination */ |
| 71 | if (!rc) | ||
| 72 | smc_wr_tx_put_slot(link, | ||
| 73 | (struct smc_wr_tx_pend_priv *)pend); | ||
| 71 | rc = -EPIPE; | 74 | rc = -EPIPE; |
| 75 | } | ||
| 72 | return rc; | 76 | return rc; |
| 73 | } | 77 | } |
| 74 | 78 | ||
| @@ -45,18 +45,10 @@ static struct smc_lgr_list smc_lgr_list = { /* established link groups */ · 44 unmodified lines | |||
| 45 | static atomic_t lgr_cnt = ATOMIC_INIT(0); /* number of existing link groups */ | 45 | static atomic_t lgr_cnt = ATOMIC_INIT(0); /* number of existing link groups */ |
| 46 | static DECLARE_WAIT_QUEUE_HEAD(lgrs_deleted); | 46 | static DECLARE_WAIT_QUEUE_HEAD(lgrs_deleted); |
| 47 | 47 | ||
| 48 | struct smc_ib_up_work { | ||
| 49 | struct work_struct work; | ||
| 50 | struct smc_link_group *lgr; | ||
| 51 | struct smc_ib_device *smcibdev; | ||
| 52 | u8 ibport; | ||
| 53 | }; | ||
| 54 | |||
| 55 | static void smc_buf_free(struct smc_link_group *lgr, bool is_rmb, | 48 | static void smc_buf_free(struct smc_link_group *lgr, bool is_rmb, |
| 56 | struct smc_buf_desc *buf_desc); | 49 | struct smc_buf_desc *buf_desc); |
| 57 | static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft); | 50 | static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft); |
| 58 | 51 | ||
| 59 | static void smc_link_up_work(struct work_struct *work); | ||
| 60 | static void smc_link_down_work(struct work_struct *work); | 52 | static void smc_link_down_work(struct work_struct *work); |
| 61 | 53 | ||
| 62 | /* return head of link group list and its lock for a given link group */ | 54 | /* return head of link group list and its lock for a given link group */ |
| @@ -326,7 +318,6 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk, · 263 unmodified lines | |||
| 326 | 318 | ||
| 327 | get_device(&ini->ib_dev->ibdev->dev); | 319 | get_device(&ini->ib_dev->ibdev->dev); |
| 328 | atomic_inc(&ini->ib_dev->lnk_cnt); | 320 | atomic_inc(&ini->ib_dev->lnk_cnt); |
| 329 | lnk->state = SMC_LNK_ACTIVATING; | ||
| 330 | lnk->link_id = smcr_next_link_id(lgr); | 321 | lnk->link_id = smcr_next_link_id(lgr); |
| 331 | lnk->lgr = lgr; | 322 | lnk->lgr = lgr; |
| 332 | lnk->link_idx = link_idx; | 323 | lnk->link_idx = link_idx; |
| @@ -362,6 +353,7 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk, · 29 unmodified lines | |||
| 362 | rc = smc_wr_create_link(lnk); | 353 | rc = smc_wr_create_link(lnk); |
| 363 | if (rc) | 354 | if (rc) |
| 364 | goto destroy_qp; | 355 | goto destroy_qp; |
| 356 | lnk->state = SMC_LNK_ACTIVATING; | ||
| 365 | return 0; | 357 | return 0; |
| 366 | 358 | ||
| 367 | destroy_qp: | 359 | destroy_qp: |
| @@ -452,7 +444,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) · 84 unmodified lines | |||
| 452 | } | 444 | } |
| 453 | smc->conn.lgr = lgr; | 445 | smc->conn.lgr = lgr; |
| 454 | spin_lock_bh(lgr_lock); | 446 | spin_lock_bh(lgr_lock); |
| 455 | list_add(&lgr->list, lgr_list); | 447 | list_add_tail(&lgr->list, lgr_list); |
| 456 | spin_unlock_bh(lgr_lock); | 448 | spin_unlock_bh(lgr_lock); |
| 457 | return 0; | 449 | return 0; |
| 458 | 450 | ||
| @@ -550,8 +542,7 @@ struct smc_link *smc_switch_conns(struct smc_link_group *lgr, · 91 unmodified lines | |||
| 550 | smc_wr_wakeup_tx_wait(from_lnk); | 542 | smc_wr_wakeup_tx_wait(from_lnk); |
| 551 | 543 | ||
| 552 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 544 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 553 | if (lgr->lnk[i].state != SMC_LNK_ACTIVE || | 545 | if (!smc_link_active(&lgr->lnk[i]) || i == from_lnk->link_idx) |
| 554 | i == from_lnk->link_idx) | ||
| 555 | continue; | 546 | continue; |
| 556 | if (is_dev_err && from_lnk->smcibdev == lgr->lnk[i].smcibdev && | 547 | if (is_dev_err && from_lnk->smcibdev == lgr->lnk[i].smcibdev && |
| 557 | from_lnk->ibport == lgr->lnk[i].ibport) { | 548 | from_lnk->ibport == lgr->lnk[i].ibport) { |
| @@ -1106,67 +1097,23 @@ static void smc_conn_abort_work(struct work_struct *work) · 548 unmodified lines | |||
| 1106 | sock_put(&smc->sk); /* sock_hold done by schedulers of abort_work */ | 1097 | sock_put(&smc->sk); /* sock_hold done by schedulers of abort_work */ |
| 1107 | } | 1098 | } |
| 1108 | 1099 | ||
| 1109 | /* link is up - establish alternate link if applicable */ | ||
| 1110 | static void smcr_link_up(struct smc_link_group *lgr, | ||
| 1111 | struct smc_ib_device *smcibdev, u8 ibport) | ||
| 1112 | { | ||
| 1113 | struct smc_link *link = NULL; | ||
| 1114 | |||
| 1115 | if (list_empty(&lgr->list) || | ||
| 1116 | lgr->type == SMC_LGR_SYMMETRIC || | ||
| 1117 | lgr->type == SMC_LGR_ASYMMETRIC_PEER) | ||
| 1118 | return; | ||
| 1119 | |||
| 1120 | if (lgr->role == SMC_SERV) { | ||
| 1121 | /* trigger local add link processing */ | ||
| 1122 | link = smc_llc_usable_link(lgr); | ||
| 1123 | if (!link) | ||
| 1124 | return; | ||
| 1125 | smc_llc_srv_add_link_local(link); | ||
| 1126 | } else { | ||
| 1127 | /* invite server to start add link processing */ | ||
| 1128 | u8 gid[SMC_GID_SIZE]; | ||
| 1129 | |||
| 1130 | if (smc_ib_determine_gid(smcibdev, ibport, lgr->vlan_id, gid, | ||
| 1131 | NULL)) | ||
| 1132 | return; | ||
| 1133 | if (lgr->llc_flow_lcl.type != SMC_LLC_FLOW_NONE) { | ||
| 1134 | /* some other llc task is ongoing */ | ||
| 1135 | wait_event_timeout(lgr->llc_flow_waiter, | ||
| 1136 | (list_empty(&lgr->list) || | ||
| 1137 | lgr->llc_flow_lcl.type == SMC_LLC_FLOW_NONE), | ||
| 1138 | SMC_LLC_WAIT_TIME); | ||
| 1139 | } | ||
| 1140 | /* lgr or device no longer active? */ | ||
| 1141 | if (!list_empty(&lgr->list) && | ||
| 1142 | smc_ib_port_active(smcibdev, ibport)) | ||
| 1143 | link = smc_llc_usable_link(lgr); | ||
| 1144 | if (link) | ||
| 1145 | smc_llc_send_add_link(link, smcibdev->mac[ibport - 1], | ||
| 1146 | gid, NULL, SMC_LLC_REQ); | ||
| 1147 | wake_up(&lgr->llc_flow_waiter); /* wake up next waiter */ | ||
| 1148 | } | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport) | 1100 | void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport) |
| 1152 | { | 1101 | { |
| 1153 | struct smc_ib_up_work *ib_work; | ||
| 1154 | struct smc_link_group *lgr, *n; | 1102 | struct smc_link_group *lgr, *n; |
| 1155 | 1103 | ||
| 1156 | list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) { | 1104 | list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) { |
| 1105 | struct smc_link *link; | ||
| 1106 | |||
| 1157 | if (strncmp(smcibdev->pnetid[ibport - 1], lgr->pnet_id, | 1107 | if (strncmp(smcibdev->pnetid[ibport - 1], lgr->pnet_id, |
| 1158 | SMC_MAX_PNETID_LEN) || | 1108 | SMC_MAX_PNETID_LEN) || |
| 1159 | lgr->type == SMC_LGR_SYMMETRIC || | 1109 | lgr->type == SMC_LGR_SYMMETRIC || |
| 1160 | lgr->type == SMC_LGR_ASYMMETRIC_PEER) | 1110 | lgr->type == SMC_LGR_ASYMMETRIC_PEER) |
| 1161 | continue; | 1111 | continue; |
| 1162 | ib_work = kmalloc(sizeof(*ib_work), GFP_KERNEL); | 1112 | |
| 1163 | if (!ib_work) | 1113 | /* trigger local add link processing */ |
| 1164 | continue; | 1114 | link = smc_llc_usable_link(lgr); |
| 1165 | INIT_WORK(&ib_work->work, smc_link_up_work); | 1115 | if (link) |
| 1166 | ib_work->lgr = lgr; | 1116 | smc_llc_add_link_local(link); |
| 1167 | ib_work->smcibdev = smcibdev; | ||
| 1168 | ib_work->ibport = ibport; | ||
| 1169 | schedule_work(&ib_work->work); | ||
| 1170 | } | 1117 | } |
| 1171 | } | 1118 | } |
| 1172 | 1119 | ||
| @@ -1204,10 +1151,12 @@ static void smcr_link_down(struct smc_link *lnk) · 31 unmodified lines | |||
| 1204 | SMC_LLC_WAIT_TIME); | 1151 | SMC_LLC_WAIT_TIME); |
| 1205 | mutex_lock(&lgr->llc_conf_mutex); | 1152 | mutex_lock(&lgr->llc_conf_mutex); |
| 1206 | } | 1153 | } |
| 1207 | if (!list_empty(&lgr->list)) | 1154 | if (!list_empty(&lgr->list)) { |
| 1208 | smc_llc_send_delete_link(to_lnk, del_link_id, | 1155 | smc_llc_send_delete_link(to_lnk, del_link_id, |
| 1209 | SMC_LLC_REQ, true, | 1156 | SMC_LLC_REQ, true, |
| 1210 | SMC_LLC_DEL_LOST_PATH); | 1157 | SMC_LLC_DEL_LOST_PATH); |
| 1158 | smcr_link_clear(lnk, true); | ||
| 1159 | } | ||
| 1211 | wake_up(&lgr->llc_flow_waiter); /* wake up next waiter */ | 1160 | wake_up(&lgr->llc_flow_waiter); /* wake up next waiter */ |
| 1212 | } | 1161 | } |
| 1213 | } | 1162 | } |
| @@ -1247,20 +1196,6 @@ void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport) · 33 unmodified lines | |||
| 1247 | } | 1196 | } |
| 1248 | } | 1197 | } |
| 1249 | 1198 | ||
| 1250 | static void smc_link_up_work(struct work_struct *work) | ||
| 1251 | { | ||
| 1252 | struct smc_ib_up_work *ib_work = container_of(work, | ||
| 1253 | struct smc_ib_up_work, | ||
| 1254 | work); | ||
| 1255 | struct smc_link_group *lgr = ib_work->lgr; | ||
| 1256 | |||
| 1257 | if (list_empty(&lgr->list)) | ||
| 1258 | goto out; | ||
| 1259 | smcr_link_up(lgr, ib_work->smcibdev, ib_work->ibport); | ||
| 1260 | out: | ||
| 1261 | kfree(ib_work); | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | static void smc_link_down_work(struct work_struct *work) | 1199 | static void smc_link_down_work(struct work_struct *work) |
| 1265 | { | 1200 | { |
| 1266 | struct smc_link *link = container_of(work, struct smc_link, | 1201 | struct smc_link *link = container_of(work, struct smc_link, |
| @@ -1333,7 +1268,7 @@ static bool smcr_lgr_match(struct smc_link_group *lgr, · 66 unmodified lines | |||
| 1333 | return false; | 1268 | return false; |
| 1334 | 1269 | ||
| 1335 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 1270 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 1336 | if (lgr->lnk[i].state != SMC_LNK_ACTIVE) | 1271 | if (!smc_link_active(&lgr->lnk[i])) |
| 1337 | continue; | 1272 | continue; |
| 1338 | if ((lgr->role == SMC_SERV || lgr->lnk[i].peer_qpn == clcqpn) && | 1273 | if ((lgr->role == SMC_SERV || lgr->lnk[i].peer_qpn == clcqpn) && |
| 1339 | !memcmp(lgr->lnk[i].peer_gid, &lcl->gid, SMC_GID_SIZE) && | 1274 | !memcmp(lgr->lnk[i].peer_gid, &lcl->gid, SMC_GID_SIZE) && |
| @@ -1376,7 +1311,7 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini) · 36 unmodified lines | |||
| 1376 | smcr_lgr_match(lgr, ini->ib_lcl, role, ini->ib_clcqpn)) && | 1311 | smcr_lgr_match(lgr, ini->ib_lcl, role, ini->ib_clcqpn)) && |
| 1377 | !lgr->sync_err && | 1312 | !lgr->sync_err && |
| 1378 | lgr->vlan_id == ini->vlan_id && | 1313 | lgr->vlan_id == ini->vlan_id && |
| 1379 | (role == SMC_CLNT || | 1314 | (role == SMC_CLNT || ini->is_smcd || |
| 1380 | lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) { | 1315 | lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) { |
| 1381 | /* link group found */ | 1316 | /* link group found */ |
| 1382 | ini->cln_first_contact = SMC_REUSE_CONTACT; | 1317 | ini->cln_first_contact = SMC_REUSE_CONTACT; |
| @@ -1781,14 +1716,14 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb) · 398 unmodified lines | |||
| 1781 | 1716 | ||
| 1782 | void smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn) | 1717 | void smc_sndbuf_sync_sg_for_cpu(struct smc_connection *conn) |
| 1783 | { | 1718 | { |
| 1784 | if (!conn->lgr || conn->lgr->is_smcd || !smc_link_usable(conn->lnk)) | 1719 | if (!conn->lgr || conn->lgr->is_smcd || !smc_link_active(conn->lnk)) |
| 1785 | return; | 1720 | return; |
| 1786 | smc_ib_sync_sg_for_cpu(conn->lnk, conn->sndbuf_desc, DMA_TO_DEVICE); | 1721 | smc_ib_sync_sg_for_cpu(conn->lnk, conn->sndbuf_desc, DMA_TO_DEVICE); |
| 1787 | } | 1722 | } |
| 1788 | 1723 | ||
| 1789 | void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn) | 1724 | void smc_sndbuf_sync_sg_for_device(struct smc_connection *conn) |
| 1790 | { | 1725 | { |
| 1791 | if (!conn->lgr || conn->lgr->is_smcd || !smc_link_usable(conn->lnk)) | 1726 | if (!conn->lgr || conn->lgr->is_smcd || !smc_link_active(conn->lnk)) |
| 1792 | return; | 1727 | return; |
| 1793 | smc_ib_sync_sg_for_device(conn->lnk, conn->sndbuf_desc, DMA_TO_DEVICE); | 1728 | smc_ib_sync_sg_for_device(conn->lnk, conn->sndbuf_desc, DMA_TO_DEVICE); |
| 1794 | } | 1729 | } |
| @@ -1800,7 +1735,7 @@ void smc_rmb_sync_sg_for_cpu(struct smc_connection *conn) · 5 unmodified lines | |||
| 1800 | if (!conn->lgr || conn->lgr->is_smcd) | 1735 | if (!conn->lgr || conn->lgr->is_smcd) |
| 1801 | return; | 1736 | return; |
| 1802 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 1737 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 1803 | if (!smc_link_usable(&conn->lgr->lnk[i])) | 1738 | if (!smc_link_active(&conn->lgr->lnk[i])) |
| 1804 | continue; | 1739 | continue; |
| 1805 | smc_ib_sync_sg_for_cpu(&conn->lgr->lnk[i], conn->rmb_desc, | 1740 | smc_ib_sync_sg_for_cpu(&conn->lgr->lnk[i], conn->rmb_desc, |
| 1806 | DMA_FROM_DEVICE); | 1741 | DMA_FROM_DEVICE); |
| @@ -1814,7 +1749,7 @@ void smc_rmb_sync_sg_for_device(struct smc_connection *conn) · 7 unmodified lines | |||
| 1814 | if (!conn->lgr || conn->lgr->is_smcd) | 1749 | if (!conn->lgr || conn->lgr->is_smcd) |
| 1815 | return; | 1750 | return; |
| 1816 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 1751 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 1817 | if (!smc_link_usable(&conn->lgr->lnk[i])) | 1752 | if (!smc_link_active(&conn->lgr->lnk[i])) |
| 1818 | continue; | 1753 | continue; |
| 1819 | smc_ib_sync_sg_for_device(&conn->lgr->lnk[i], conn->rmb_desc, | 1754 | smc_ib_sync_sg_for_device(&conn->lgr->lnk[i], conn->rmb_desc, |
| 1820 | DMA_FROM_DEVICE); | 1755 | DMA_FROM_DEVICE); |
| @@ -1837,8 +1772,12 @@ int smc_buf_create(struct smc_sock *smc, bool is_smcd) · 16 unmodified lines | |||
| 1837 | return rc; | 1772 | return rc; |
| 1838 | /* create rmb */ | 1773 | /* create rmb */ |
| 1839 | rc = __smc_buf_create(smc, is_smcd, true); | 1774 | rc = __smc_buf_create(smc, is_smcd, true); |
| 1840 | if (rc) | 1775 | if (rc) { |
| 1776 | mutex_lock(&smc->conn.lgr->sndbufs_lock); | ||
| 1777 | list_del(&smc->conn.sndbuf_desc->list); | ||
| 1778 | mutex_unlock(&smc->conn.lgr->sndbufs_lock); | ||
| 1841 | smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc); | 1779 | smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc); |
| 1780 | } | ||
| 1842 | return rc; | 1781 | return rc; |
| 1843 | } | 1782 | } |
| 1844 | 1783 | ||
| @@ -349,6 +349,11 @@ static inline bool smc_link_usable(struct smc_link *lnk) · 348 unmodified lines | |||
| 349 | return true; | 349 | return true; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static inline bool smc_link_active(struct smc_link *lnk) | ||
| 353 | { | ||
| 354 | return lnk->state == SMC_LNK_ACTIVE; | ||
| 355 | } | ||
| 356 | |||
| 352 | struct smc_sock; | 357 | struct smc_sock; |
| 353 | struct smc_clc_msg_accept_confirm; | 358 | struct smc_clc_msg_accept_confirm; |
| 354 | struct smc_clc_msg_local; | 359 | struct smc_clc_msg_local; |
| @@ -506,6 +506,10 @@ long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev) · 505 unmodified lines | |||
| 506 | int cqe_size_order, smc_order; | 506 | int cqe_size_order, smc_order; |
| 507 | long rc; | 507 | long rc; |
| 508 | 508 | ||
| 509 | mutex_lock(&smcibdev->mutex); | ||
| 510 | rc = 0; | ||
| 511 | if (smcibdev->initialized) | ||
| 512 | goto out; | ||
| 509 | /* the calculated number of cq entries fits to mlx5 cq allocation */ | 513 | /* the calculated number of cq entries fits to mlx5 cq allocation */ |
| 510 | cqe_size_order = cache_line_size() == 128 ? 7 : 6; | 514 | cqe_size_order = cache_line_size() == 128 ? 7 : 6; |
| 511 | smc_order = MAX_ORDER - cqe_size_order - 1; | 515 | smc_order = MAX_ORDER - cqe_size_order - 1; |
| @@ -517,7 +521,7 @@ long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev) · 5 unmodified lines | |||
| 517 | rc = PTR_ERR_OR_ZERO(smcibdev->roce_cq_send); | 521 | rc = PTR_ERR_OR_ZERO(smcibdev->roce_cq_send); |
| 518 | if (IS_ERR(smcibdev->roce_cq_send)) { | 522 | if (IS_ERR(smcibdev->roce_cq_send)) { |
| 519 | smcibdev->roce_cq_send = NULL; | 523 | smcibdev->roce_cq_send = NULL; |
| 520 | return rc; | 524 | goto out; |
| 521 | } | 525 | } |
| 522 | smcibdev->roce_cq_recv = ib_create_cq(smcibdev->ibdev, | 526 | smcibdev->roce_cq_recv = ib_create_cq(smcibdev->ibdev, |
| 523 | smc_wr_rx_cq_handler, NULL, | 527 | smc_wr_rx_cq_handler, NULL, |
| @@ -529,21 +533,26 @@ long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev) · 5 unmodified lines | |||
| 529 | } | 533 | } |
| 530 | smc_wr_add_dev(smcibdev); | 534 | smc_wr_add_dev(smcibdev); |
| 531 | smcibdev->initialized = 1; | 535 | smcibdev->initialized = 1; |
| 532 | return rc; | 536 | goto out; |
| 533 | 537 | ||
| 534 | err: | 538 | err: |
| 535 | ib_destroy_cq(smcibdev->roce_cq_send); | 539 | ib_destroy_cq(smcibdev->roce_cq_send); |
| 540 | out: | ||
| 541 | mutex_unlock(&smcibdev->mutex); | ||
| 536 | return rc; | 542 | return rc; |
| 537 | } | 543 | } |
| 538 | 544 | ||
| 539 | static void smc_ib_cleanup_per_ibdev(struct smc_ib_device *smcibdev) | 545 | static void smc_ib_cleanup_per_ibdev(struct smc_ib_device *smcibdev) |
| 540 | { | 546 | { |
| 547 | mutex_lock(&smcibdev->mutex); | ||
| 541 | if (!smcibdev->initialized) | 548 | if (!smcibdev->initialized) |
| 542 | return; | 549 | goto out; |
| 543 | smcibdev->initialized = 0; | 550 | smcibdev->initialized = 0; |
| 544 | ib_destroy_cq(smcibdev->roce_cq_recv); | 551 | ib_destroy_cq(smcibdev->roce_cq_recv); |
| 545 | ib_destroy_cq(smcibdev->roce_cq_send); | 552 | ib_destroy_cq(smcibdev->roce_cq_send); |
| 546 | smc_wr_remove_dev(smcibdev); | 553 | smc_wr_remove_dev(smcibdev); |
| 554 | out: | ||
| 555 | mutex_unlock(&smcibdev->mutex); | ||
| 547 | } | 556 | } |
| 548 | 557 | ||
| 549 | static struct ib_client smc_ib_client; | 558 | static struct ib_client smc_ib_client; |
| @@ -566,6 +575,7 @@ static int smc_ib_add_dev(struct ib_device *ibdev) · 16 unmodified lines | |||
| 566 | INIT_WORK(&smcibdev->port_event_work, smc_ib_port_event_work); | 575 | INIT_WORK(&smcibdev->port_event_work, smc_ib_port_event_work); |
| 567 | atomic_set(&smcibdev->lnk_cnt, 0); | 576 | atomic_set(&smcibdev->lnk_cnt, 0); |
| 568 | init_waitqueue_head(&smcibdev->lnks_deleted); | 577 | init_waitqueue_head(&smcibdev->lnks_deleted); |
| 578 | mutex_init(&smcibdev->mutex); | ||
| 569 | mutex_lock(&smc_ib_devices.mutex); | 579 | mutex_lock(&smc_ib_devices.mutex); |
| 570 | list_add_tail(&smcibdev->list, &smc_ib_devices.list); | 580 | list_add_tail(&smcibdev->list, &smc_ib_devices.list); |
| 571 | mutex_unlock(&smc_ib_devices.mutex); | 581 | mutex_unlock(&smc_ib_devices.mutex); |
| @@ -52,6 +52,7 @@ struct smc_ib_device { /* ib-device infos for smc */ · 51 unmodified lines | |||
| 52 | DECLARE_BITMAP(ports_going_away, SMC_MAX_PORTS); | 52 | DECLARE_BITMAP(ports_going_away, SMC_MAX_PORTS); |
| 53 | atomic_t lnk_cnt; /* number of links on ibdev */ | 53 | atomic_t lnk_cnt; /* number of links on ibdev */ |
| 54 | wait_queue_head_t lnks_deleted; /* wait 4 removal of all links*/ | 54 | wait_queue_head_t lnks_deleted; /* wait 4 removal of all links*/ |
| 55 | struct mutex mutex; /* protect dev setup+cleanup */ | ||
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 57 | struct smc_buf_desc; | 58 | struct smc_buf_desc; |
| @@ -428,7 +428,7 @@ static int smc_llc_send_confirm_rkey(struct smc_link *send_link, · 427 unmodified lines | |||
| 428 | rtok_ix = 1; | 428 | rtok_ix = 1; |
| 429 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 429 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 430 | link = &send_link->lgr->lnk[i]; | 430 | link = &send_link->lgr->lnk[i]; |
| 431 | if (link->state == SMC_LNK_ACTIVE && link != send_link) { | 431 | if (smc_link_active(link) && link != send_link) { |
| 432 | rkeyllc->rtoken[rtok_ix].link_id = link->link_id; | 432 | rkeyllc->rtoken[rtok_ix].link_id = link->link_id; |
| 433 | rkeyllc->rtoken[rtok_ix].rmb_key = | 433 | rkeyllc->rtoken[rtok_ix].rmb_key = |
| 434 | htonl(rmb_desc->mr_rx[link->link_idx]->rkey); | 434 | htonl(rmb_desc->mr_rx[link->link_idx]->rkey); |
| @@ -895,6 +895,36 @@ out: · 460 unmodified lines | |||
| 895 | return rc; | 895 | return rc; |
| 896 | } | 896 | } |
| 897 | 897 | ||
| 898 | /* as an SMC client, invite server to start the add_link processing */ | ||
| 899 | static void smc_llc_cli_add_link_invite(struct smc_link *link, | ||
| 900 | struct smc_llc_qentry *qentry) | ||
| 901 | { | ||
| 902 | struct smc_link_group *lgr = smc_get_lgr(link); | ||
| 903 | struct smc_init_info ini; | ||
| 904 | |||
| 905 | if (lgr->type == SMC_LGR_SYMMETRIC || | ||
| 906 | lgr->type == SMC_LGR_ASYMMETRIC_PEER) | ||
| 907 | goto out; | ||
| 908 | |||
| 909 | ini.vlan_id = lgr->vlan_id; | ||
| 910 | smc_pnet_find_alt_roce(lgr, &ini, link->smcibdev); | ||
| 911 | if (!ini.ib_dev) | ||
| 912 | goto out; | ||
| 913 | |||
| 914 | smc_llc_send_add_link(link, ini.ib_dev->mac[ini.ib_port - 1], | ||
| 915 | ini.ib_gid, NULL, SMC_LLC_REQ); | ||
| 916 | out: | ||
| 917 | kfree(qentry); | ||
| 918 | } | ||
| 919 | |||
| 920 | static bool smc_llc_is_local_add_link(union smc_llc_msg *llc) | ||
| 921 | { | ||
| 922 | if (llc->raw.hdr.common.type == SMC_LLC_ADD_LINK && | ||
| 923 | !llc->add_link.qp_mtu && !llc->add_link.link_num) | ||
| 924 | return true; | ||
| 925 | return false; | ||
| 926 | } | ||
| 927 | |||
| 898 | static void smc_llc_process_cli_add_link(struct smc_link_group *lgr) | 928 | static void smc_llc_process_cli_add_link(struct smc_link_group *lgr) |
| 899 | { | 929 | { |
| 900 | struct smc_llc_qentry *qentry; | 930 | struct smc_llc_qentry *qentry; |
| @@ -902,7 +932,10 @@ static void smc_llc_process_cli_add_link(struct smc_link_group *lgr) · 1 unmodified line | |||
| 902 | qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl); | 932 | qentry = smc_llc_flow_qentry_clr(&lgr->llc_flow_lcl); |
| 903 | 933 | ||
| 904 | mutex_lock(&lgr->llc_conf_mutex); | 934 | mutex_lock(&lgr->llc_conf_mutex); |
| 905 | smc_llc_cli_add_link(qentry->link, qentry); | 935 | if (smc_llc_is_local_add_link(&qentry->msg)) |
| 936 | smc_llc_cli_add_link_invite(qentry->link, qentry); | ||
| 937 | else | ||
| 938 | smc_llc_cli_add_link(qentry->link, qentry); | ||
| 906 | mutex_unlock(&lgr->llc_conf_mutex); | 939 | mutex_unlock(&lgr->llc_conf_mutex); |
| 907 | } | 940 | } |
| 908 | 941 | ||
| @@ -911,7 +944,7 @@ static int smc_llc_active_link_count(struct smc_link_group *lgr) · 2 unmodified lines | |||
| 911 | int i, link_count = 0; | 944 | int i, link_count = 0; |
| 912 | 945 | ||
| 913 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { | 946 | for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
| 914 | if (!smc_link_usable(&lgr->lnk[i])) | 947 | if (!smc_link_active(&lgr->lnk[i])) |
| 915 | continue; | 948 | continue; |
| 916 | link_count++; | 949 | link_count++; |
| 917 | } | 950 | } |
| @@ -1051,12 +1084,14 @@ static int smc_llc_srv_conf_link(struct smc_link *link, · 133 unmodified lines | |||
| 1051 | if (rc) | 1084 | if (rc) |
| 1052 | return -ENOLINK; | 1085 | return -ENOLINK; |
| 1053 | /* receive CONFIRM LINK response over the RoCE fabric */ | 1086 | /* receive CONFIRM LINK response over the RoCE fabric */ |
| 1054 | qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_FIRST_TIME, | 1087 | qentry = smc_llc_wait(lgr, link, SMC_LLC_WAIT_FIRST_TIME, 0); |
| 1055 | SMC_LLC_CONFIRM_LINK); | 1088 | if (!qentry || |
| 1056 | if (!qentry) { | 1089 | qentry->msg.raw.hdr.common.type != SMC_LLC_CONFIRM_LINK) { |
| 1057 | /* send DELETE LINK */ | 1090 | /* send DELETE LINK */ |
| 1058 | smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, | 1091 | smc_llc_send_delete_link(link, link_new->link_id, SMC_LLC_REQ, |
| 1059 | false, SMC_LLC_DEL_LOST_PATH); | 1092 | false, SMC_LLC_DEL_LOST_PATH); |
| 1093 | if (qentry) | ||
| 1094 | smc_llc_flow_qentry_del(&lgr->llc_flow_lcl); | ||
| 1060 | return -ENOLINK; | 1095 | return -ENOLINK; |
| 1061 | } | 1096 | } |
| 1062 | smc_llc_save_peer_uid(qentry); | 1097 | smc_llc_save_peer_uid(qentry); |
| @@ -1158,14 +1193,14 @@ static void smc_llc_process_srv_add_link(struct smc_link_group *lgr) · 95 unmodified lines | |||
| 1158 | mutex_unlock(&lgr->llc_conf_mutex); | 1193 | mutex_unlock(&lgr->llc_conf_mutex); |
| 1159 | } | 1194 | } |
| 1160 | 1195 | ||
| 1161 | /* enqueue a local add_link req to trigger a new add_link flow, only as SERV */ | 1196 | /* enqueue a local add_link req to trigger a new add_link flow */ |
| 1162 | void smc_llc_srv_add_link_local(struct smc_link *link) | 1197 | void smc_llc_add_link_local(struct smc_link *link) |
| 1163 | { | 1198 | { |
| 1164 | struct smc_llc_msg_add_link add_llc = {0}; | 1199 | struct smc_llc_msg_add_link add_llc = {0}; |
| 1165 | 1200 | ||
| 1166 | add_llc.hd.length = sizeof(add_llc); | 1201 | add_llc.hd.length = sizeof(add_llc); |
| 1167 | add_llc.hd.common.type = SMC_LLC_ADD_LINK; | 1202 | add_llc.hd.common.type = SMC_LLC_ADD_LINK; |
| 1168 | /* no dev and port needed, we as server ignore client data anyway */ | 1203 | /* no dev and port needed */ |
| 1169 | smc_llc_enqueue(link, (union smc_llc_msg *)&add_llc); | 1204 | smc_llc_enqueue(link, (union smc_llc_msg *)&add_llc); |
| 1170 | } | 1205 | } |
| 1171 | 1206 | ||
| @@ -1345,7 +1380,7 @@ static void smc_llc_process_srv_delete_link(struct smc_link_group *lgr) · 173 unmodified lines | |||
| 1345 | 1380 | ||
| 1346 | if (lgr->type == SMC_LGR_SINGLE && !list_empty(&lgr->list)) { | 1381 | if (lgr->type == SMC_LGR_SINGLE && !list_empty(&lgr->list)) { |
| 1347 | /* trigger setup of asymm alt link */ | 1382 | /* trigger setup of asymm alt link */ |
| 1348 | smc_llc_srv_add_link_local(lnk); | 1383 | smc_llc_add_link_local(lnk); |
| 1349 | } | 1384 | } |
| 1350 | out: | 1385 | out: |
| 1351 | mutex_unlock(&lgr->llc_conf_mutex); | 1386 | mutex_unlock(&lgr->llc_conf_mutex); |
| @@ -1474,7 +1509,18 @@ static void smc_llc_event_handler(struct smc_llc_qentry *qentry) · 122 unmodified lines | |||
| 1474 | if (list_empty(&lgr->list)) | 1509 | if (list_empty(&lgr->list)) |
| 1475 | goto out; /* lgr is terminating */ | 1510 | goto out; /* lgr is terminating */ |
| 1476 | if (lgr->role == SMC_CLNT) { | 1511 | if (lgr->role == SMC_CLNT) { |
| 1477 | if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_ADD_LINK) { | 1512 | if (smc_llc_is_local_add_link(llc)) { |
| 1513 | if (lgr->llc_flow_lcl.type == | ||
| 1514 | SMC_LLC_FLOW_ADD_LINK) | ||
| 1515 | break; /* add_link in progress */ | ||
| 1516 | if (smc_llc_flow_start(&lgr->llc_flow_lcl, | ||
| 1517 | qentry)) { | ||
| 1518 | schedule_work(&lgr->llc_add_link_work); | ||
| 1519 | } | ||
| 1520 | return; | ||
| 1521 | } | ||
| 1522 | if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_ADD_LINK && | ||
| 1523 | !lgr->llc_flow_lcl.qentry) { | ||
| 1478 | /* a flow is waiting for this message */ | 1524 | /* a flow is waiting for this message */ |
| 1479 | smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, | 1525 | smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, |
| 1480 | qentry); | 1526 | qentry); |
| @@ -1498,28 +1544,13 @@ static void smc_llc_event_handler(struct smc_llc_qentry *qentry) · 17 unmodified lines | |||
| 1498 | } | 1544 | } |
| 1499 | break; | 1545 | break; |
| 1500 | case SMC_LLC_DELETE_LINK: | 1546 | case SMC_LLC_DELETE_LINK: |
| 1501 | if (lgr->role == SMC_CLNT) { | 1547 | if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_ADD_LINK && |
| 1502 | /* server requests to delete this link, send response */ | 1548 | !lgr->llc_flow_lcl.qentry) { |
| 1503 | if (lgr->llc_flow_lcl.type != SMC_LLC_FLOW_NONE) { | 1549 | /* DEL LINK REQ during ADD LINK SEQ */ |
| 1504 | /* DEL LINK REQ during ADD LINK SEQ */ | 1550 | smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, qentry); |
| 1505 | smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, | 1551 | wake_up(&lgr->llc_msg_waiter); |
| 1506 | qentry); | 1552 | } else if (smc_llc_flow_start(&lgr->llc_flow_lcl, qentry)) { |
| 1507 | wake_up(&lgr->llc_msg_waiter); | 1553 | schedule_work(&lgr->llc_del_link_work); |
| 1508 | } else if (smc_llc_flow_start(&lgr->llc_flow_lcl, | ||
| 1509 | qentry)) { | ||
| 1510 | schedule_work(&lgr->llc_del_link_work); | ||
| 1511 | } | ||
| 1512 | } else { | ||
| 1513 | if (lgr->llc_flow_lcl.type == SMC_LLC_FLOW_ADD_LINK && | ||
| 1514 | !lgr->llc_flow_lcl.qentry) { | ||
| 1515 | /* DEL LINK REQ during ADD LINK SEQ */ | ||
| 1516 | smc_llc_flow_qentry_set(&lgr->llc_flow_lcl, | ||
| 1517 | qentry); | ||
| 1518 | wake_up(&lgr->llc_msg_waiter); | ||
| 1519 | } else if (smc_llc_flow_start(&lgr->llc_flow_lcl, | ||
| 1520 | qentry)) { | ||
| 1521 | schedule_work(&lgr->llc_del_link_work); | ||
| 1522 | } | ||
| 1523 | } | 1554 | } |
| 1524 | return; | 1555 | return; |
| 1525 | case SMC_LLC_CONFIRM_RKEY: | 1556 | case SMC_LLC_CONFIRM_RKEY: |
| @@ -1585,23 +1616,30 @@ again: · 59 unmodified lines | |||
| 1585 | static void smc_llc_rx_response(struct smc_link *link, | 1616 | static void smc_llc_rx_response(struct smc_link *link, |
| 1586 | struct smc_llc_qentry *qentry) | 1617 | struct smc_llc_qentry *qentry) |
| 1587 | { | 1618 | { |
| 1619 | enum smc_llc_flowtype flowtype = link->lgr->llc_flow_lcl.type; | ||
| 1620 | struct smc_llc_flow *flow = &link->lgr->llc_flow_lcl; | ||
| 1588 | u8 llc_type = qentry->msg.raw.hdr.common.type; | 1621 | u8 llc_type = qentry->msg.raw.hdr.common.type; |
| 1589 | 1622 | ||
| 1590 | switch (llc_type) { | 1623 | switch (llc_type) { |
| 1591 | case SMC_LLC_TEST_LINK: | 1624 | case SMC_LLC_TEST_LINK: |
| 1592 | if (link->state == SMC_LNK_ACTIVE) | 1625 | if (smc_link_active(link)) |
| 1593 | complete(&link->llc_testlink_resp); | 1626 | complete(&link->llc_testlink_resp); |
| 1594 | break; | 1627 | break; |
| 1595 | case SMC_LLC_ADD_LINK: | 1628 | case SMC_LLC_ADD_LINK: |
| 1596 | case SMC_LLC_DELETE_LINK: | ||
| 1597 | case SMC_LLC_CONFIRM_LINK: | ||
| 1598 | case SMC_LLC_ADD_LINK_CONT: | 1629 | case SMC_LLC_ADD_LINK_CONT: |
| 1630 | case SMC_LLC_CONFIRM_LINK: | ||
| 1631 | if (flowtype != SMC_LLC_FLOW_ADD_LINK || flow->qentry) | ||
| 1632 | break; /* drop out-of-flow response */ | ||
| 1633 | goto assign; | ||
| 1634 | case SMC_LLC_DELETE_LINK: | ||
| 1635 | if (flowtype != SMC_LLC_FLOW_DEL_LINK || flow->qentry) | ||
| 1636 | break; /* drop out-of-flow response */ | ||
| 1637 | goto assign; | ||
| 1599 | case SMC_LLC_CONFIRM_RKEY: | 1638 | case SMC_LLC_CONFIRM_RKEY: |
| 1600 | case SMC_LLC_DELETE_RKEY: | 1639 | case SMC_LLC_DELETE_RKEY: |
| 1601 | /* assign responses to the local flow, we requested them */ | 1640 | if (flowtype != SMC_LLC_FLOW_RKEY || flow->qentry) |
| 1602 | smc_llc_flow_qentry_set(&link->lgr->llc_flow_lcl, qentry); | 1641 | break; /* drop out-of-flow response */ |
| 1603 | wake_up(&link->lgr->llc_msg_waiter); | 1642 | goto assign; |
| 1604 | return; | ||
| 1605 | case SMC_LLC_CONFIRM_RKEY_CONT: | 1643 | case SMC_LLC_CONFIRM_RKEY_CONT: |
| 1606 | /* not used because max links is 3 */ | 1644 | /* not used because max links is 3 */ |
| 1607 | break; | 1645 | break; |
| @@ -1610,6 +1648,11 @@ static void smc_llc_rx_response(struct smc_link *link, · 2 unmodified lines | |||
| 1610 | break; | 1648 | break; |
| 1611 | } | 1649 | } |
| 1612 | kfree(qentry); | 1650 | kfree(qentry); |
| 1651 | return; | ||
| 1652 | assign: | ||
| 1653 | /* assign responses to the local flow, we requested them */ | ||
| 1654 | smc_llc_flow_qentry_set(&link->lgr->llc_flow_lcl, qentry); | ||
| 1655 | wake_up(&link->lgr->llc_msg_waiter); | ||
| 1613 | } | 1656 | } |
| 1614 | 1657 | ||
| 1615 | static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc) | 1658 | static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc) |
| @@ -1663,7 +1706,7 @@ static void smc_llc_testlink_work(struct work_struct *work) · 47 unmodified lines | |||
| 1663 | u8 user_data[16] = { 0 }; | 1706 | u8 user_data[16] = { 0 }; |
| 1664 | int rc; | 1707 | int rc; |
| 1665 | 1708 | ||
| 1666 | if (link->state != SMC_LNK_ACTIVE) | 1709 | if (!smc_link_active(link)) |
| 1667 | return; /* don't reschedule worker */ | 1710 | return; /* don't reschedule worker */ |
| 1668 | expire_time = link->wr_rx_tstamp + link->llc_testlink_time; | 1711 | expire_time = link->wr_rx_tstamp + link->llc_testlink_time; |
| 1669 | if (time_is_after_jiffies(expire_time)) { | 1712 | if (time_is_after_jiffies(expire_time)) { |
| @@ -1675,7 +1718,7 @@ static void smc_llc_testlink_work(struct work_struct *work) · 5 unmodified lines | |||
| 1675 | /* receive TEST LINK response over RoCE fabric */ | 1718 | /* receive TEST LINK response over RoCE fabric */ |
| 1676 | rc = wait_for_completion_interruptible_timeout(&link->llc_testlink_resp, | 1719 | rc = wait_for_completion_interruptible_timeout(&link->llc_testlink_resp, |
| 1677 | SMC_LLC_WAIT_TIME); | 1720 | SMC_LLC_WAIT_TIME); |
| 1678 | if (link->state != SMC_LNK_ACTIVE) | 1721 | if (!smc_link_active(link)) |
| 1679 | return; /* link state changed */ | 1722 | return; /* link state changed */ |
| 1680 | if (rc <= 0) { | 1723 | if (rc <= 0) { |
| 1681 | smcr_link_down_cond_sched(link); | 1724 | smcr_link_down_cond_sched(link); |
| @@ -103,7 +103,7 @@ void smc_llc_send_link_delete_all(struct smc_link_group *lgr, bool ord, · 102 unmodified lines | |||
| 103 | u32 rsn); | 103 | u32 rsn); |
| 104 | int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry); | 104 | int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry); |
| 105 | int smc_llc_srv_add_link(struct smc_link *link); | 105 | int smc_llc_srv_add_link(struct smc_link *link); |
| 106 | void smc_llc_srv_add_link_local(struct smc_link *link); | 106 | void smc_llc_add_link_local(struct smc_link *link); |
| 107 | int smc_llc_init(void) __init; | 107 | int smc_llc_init(void) __init; |
| 108 | 108 | ||
| 109 | #endif /* SMC_LLC_H */ | 109 | #endif /* SMC_LLC_H */ |
| @@ -827,11 +827,11 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) · 826 unmodified lines | |||
| 827 | state |= l->bc_rcvlink->rcv_unacked; | 827 | state |= l->bc_rcvlink->rcv_unacked; |
| 828 | state |= l->rcv_unacked; | 828 | state |= l->rcv_unacked; |
| 829 | state |= !skb_queue_empty(&l->transmq); | 829 | state |= !skb_queue_empty(&l->transmq); |
| 830 | state |= !skb_queue_empty(&l->deferdq); | ||
| 831 | probe = mstate->probing; | 830 | probe = mstate->probing; |
| 832 | probe |= l->silent_intv_cnt; | 831 | probe |= l->silent_intv_cnt; |
| 833 | if (probe || mstate->monitoring) | 832 | if (probe || mstate->monitoring) |
| 834 | l->silent_intv_cnt++; | 833 | l->silent_intv_cnt++; |
| 834 | probe |= !skb_queue_empty(&l->deferdq); | ||
| 835 | if (l->snd_nxt == l->checkpoint) { | 835 | if (l->snd_nxt == l->checkpoint) { |
| 836 | tipc_link_update_cwin(l, 0, 0); | 836 | tipc_link_update_cwin(l, 0, 0); |
| 837 | probe = true; | 837 | probe = true; |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | |||
| 22 | #include <net/af_vsock.h> | 22 | #include <net/af_vsock.h> |
| 23 | 23 | ||
| 24 | static struct workqueue_struct *virtio_vsock_workqueue; | 24 | static struct workqueue_struct *virtio_vsock_workqueue; |
| 25 | static struct virtio_vsock *the_virtio_vsock; | 25 | static struct virtio_vsock __rcu *the_virtio_vsock; |
| 26 | static DEFINE_MUTEX(the_virtio_vsock_mutex); /* protects the_virtio_vsock */ | 26 | static DEFINE_MUTEX(the_virtio_vsock_mutex); /* protects the_virtio_vsock */ |
| 27 | 27 | ||
| 28 | struct virtio_vsock { | 28 | struct virtio_vsock { |
| @@ -87,8 +87,8 @@ parse_symbol() { · 86 unmodified lines | |||
| 87 | return | 87 | return |
| 88 | fi | 88 | fi |
| 89 | 89 | ||
| 90 | # Strip out the base of the path | 90 | # Strip out the base of the path on each line |
| 91 | code=${code#$basepath/} | 91 | code=$(while read -r line; do echo "${line#$basepath/}"; done <<< "$code") |
| 92 | 92 | ||
| 93 | # In the case of inlines, move everything to same line | 93 | # In the case of inlines, move everything to same line |
| 94 | code=${code//$'\n'/' '} | 94 | code=${code//$'\n'/' '} |
| @@ -96,7 +96,7 @@ lx-symbols command.""" · 95 unmodified lines | |||
| 96 | return "" | 96 | return "" |
| 97 | attrs = sect_attrs['attrs'] | 97 | attrs = sect_attrs['attrs'] |
| 98 | section_name_to_address = { | 98 | section_name_to_address = { |
| 99 | attrs[n]['name'].string(): attrs[n]['address'] | 99 | attrs[n]['battr']['attr']['name'].string(): attrs[n]['address'] |
| 100 | for n in range(int(sect_attrs['nsections']))} | 100 | for n in range(int(sect_attrs['nsections']))} |
| 101 | args = [] | 101 | args = [] |
| 102 | for section_name in [".data", ".data..read_mostly", ".rodata", ".bss", | 102 | for section_name in [".data", ".data..read_mostly", ".rodata", ".bss", |
| @@ -138,11 +138,19 @@ char *read_text_file(const char *filename) · 137 unmodified lines | |||
| 138 | 138 | ||
| 139 | char *get_line(char **stringp) | 139 | char *get_line(char **stringp) |
| 140 | { | 140 | { |
| 141 | char *orig = *stringp, *next; | ||
| 142 | |||
| 141 | /* do not return the unwanted extra line at EOF */ | 143 | /* do not return the unwanted extra line at EOF */ |
| 142 | if (*stringp && **stringp == '\0') | 144 | if (!orig || *orig == '\0') |
| 143 | return NULL; | 145 | return NULL; |
| 144 | 146 | ||
| 145 | return strsep(stringp, "\n"); | 147 | next = strchr(orig, '\n'); |
| 148 | if (next) | ||
| 149 | *next++ = '\0'; | ||
| 150 | |||
| 151 | *stringp = next; | ||
| 152 | |||
| 153 | return orig; | ||
| 146 | } | 154 | } |
| 147 | 155 | ||
| 148 | /* A list of all modules we processed */ | 156 | /* A list of all modules we processed */ |
| @@ -606,7 +606,9 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) · 605 unmodified lines | |||
| 606 | { | 606 | { |
| 607 | int c; | 607 | int c; |
| 608 | 608 | ||
| 609 | if (snd_BUG_ON(!buffer || !buffer->buffer)) | 609 | if (snd_BUG_ON(!buffer)) |
| 610 | return 1; | ||
| 611 | if (!buffer->buffer) | ||
| 610 | return 1; | 612 | return 1; |
| 611 | if (len <= 0 || buffer->stop || buffer->error) | 613 | if (len <= 0 || buffer->stop || buffer->error) |
| 612 | return 1; | 614 | return 1; |
| @@ -7587,6 +7587,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 7586 unmodified lines | |||
| 7587 | SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), | 7587 | SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), |
| 7588 | SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), | 7588 | SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), |
| 7589 | SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), | 7589 | SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), |
| 7590 | SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), | ||
| 7590 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), | 7591 | SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), |
| 7591 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), | 7592 | SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), |
| 7592 | SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), | 7593 | SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), |
| @@ -232,9 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci, · 231 unmodified lines | |||
| 232 | } | 232 | } |
| 233 | pm_runtime_set_autosuspend_delay(&pci->dev, 2000); | 233 | pm_runtime_set_autosuspend_delay(&pci->dev, 2000); |
| 234 | pm_runtime_use_autosuspend(&pci->dev); | 234 | pm_runtime_use_autosuspend(&pci->dev); |
| 235 | pm_runtime_set_active(&pci->dev); | ||
| 236 | pm_runtime_put_noidle(&pci->dev); | 235 | pm_runtime_put_noidle(&pci->dev); |
| 237 | pm_runtime_enable(&pci->dev); | ||
| 238 | pm_runtime_allow(&pci->dev); | 236 | pm_runtime_allow(&pci->dev); |
| 239 | return 0; | 237 | return 0; |
| 240 | 238 | ||
| @@ -303,7 +301,7 @@ static void snd_acp3x_remove(struct pci_dev *pci) · 62 unmodified lines | |||
| 303 | ret = acp3x_deinit(adata->acp3x_base); | 301 | ret = acp3x_deinit(adata->acp3x_base); |
| 304 | if (ret) | 302 | if (ret) |
| 305 | dev_err(&pci->dev, "ACP de-init failed\n"); | 303 | dev_err(&pci->dev, "ACP de-init failed\n"); |
| 306 | pm_runtime_disable(&pci->dev); | 304 | pm_runtime_forbid(&pci->dev); |
| 307 | pm_runtime_get_noresume(&pci->dev); | 305 | pm_runtime_get_noresume(&pci->dev); |
| 308 | pci_disable_msi(pci); | 306 | pci_disable_msi(pci); |
| 309 | pci_release_regions(pci); | 307 | pci_release_regions(pci); |
| @@ -779,13 +779,6 @@ static int max98373_probe(struct snd_soc_component *component) · 778 unmodified lines | |||
| 779 | regmap_write(max98373->regmap, | 779 | regmap_write(max98373->regmap, |
| 780 | MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, | 780 | MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, |
| 781 | 0x1); | 781 | 0x1); |
| 782 | /* Set inital volume (0dB) */ | ||
| 783 | regmap_write(max98373->regmap, | ||
| 784 | MAX98373_R203D_AMP_DIG_VOL_CTRL, | ||
| 785 | 0x00); | ||
| 786 | regmap_write(max98373->regmap, | ||
| 787 | MAX98373_R203E_AMP_PATH_GAIN, | ||
| 788 | 0x00); | ||
| 789 | /* Enable DC blocker */ | 782 | /* Enable DC blocker */ |
| 790 | regmap_write(max98373->regmap, | 783 | regmap_write(max98373->regmap, |
| 791 | MAX98373_R203F_AMP_DSP_CFG, | 784 | MAX98373_R203F_AMP_DSP_CFG, |
| @@ -869,7 +862,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98373 = { · 77 unmodified lines | |||
| 869 | .num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets), | 862 | .num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets), |
| 870 | .dapm_routes = max98373_audio_map, | 863 | .dapm_routes = max98373_audio_map, |
| 871 | .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), | 864 | .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), |
| 872 | .idle_bias_on = 1, | ||
| 873 | .use_pmdown_time = 1, | 865 | .use_pmdown_time = 1, |
| 874 | .endianness = 1, | 866 | .endianness = 1, |
| 875 | .non_legacy_dai_naming = 1, | 867 | .non_legacy_dai_naming = 1, |
| @@ -272,13 +272,13 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) · 271 unmodified lines | |||
| 272 | regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf); | 272 | regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf); |
| 273 | *mic = buf & 0x80000000; | 273 | *mic = buf & 0x80000000; |
| 274 | } | 274 | } |
| 275 | if (!*mic) { | 275 | |
| 276 | if (!*hp) { | ||
| 276 | snd_soc_dapm_disable_pin(dapm, "HV"); | 277 | snd_soc_dapm_disable_pin(dapm, "HV"); |
| 277 | snd_soc_dapm_disable_pin(dapm, "VREF"); | 278 | snd_soc_dapm_disable_pin(dapm, "VREF"); |
| 278 | } | ||
| 279 | if (!*hp) | ||
| 280 | snd_soc_dapm_disable_pin(dapm, "LDO1"); | 279 | snd_soc_dapm_disable_pin(dapm, "LDO1"); |
| 281 | snd_soc_dapm_sync(dapm); | 280 | snd_soc_dapm_sync(dapm); |
| 281 | } | ||
| 282 | 282 | ||
| 283 | return 0; | 283 | return 0; |
| 284 | } | 284 | } |
| @@ -31,18 +31,19 @@ · 30 unmodified lines | |||
| 31 | #include "rt5670.h" | 31 | #include "rt5670.h" |
| 32 | #include "rt5670-dsp.h" | 32 | #include "rt5670-dsp.h" |
| 33 | 33 | ||
| 34 | #define RT5670_DEV_GPIO BIT(0) | 34 | #define RT5670_DEV_GPIO BIT(0) |
| 35 | #define RT5670_IN2_DIFF BIT(1) | 35 | #define RT5670_IN2_DIFF BIT(1) |
| 36 | #define RT5670_DMIC_EN BIT(2) | 36 | #define RT5670_DMIC_EN BIT(2) |
| 37 | #define RT5670_DMIC1_IN2P BIT(3) | 37 | #define RT5670_DMIC1_IN2P BIT(3) |
| 38 | #define RT5670_DMIC1_GPIO6 BIT(4) | 38 | #define RT5670_DMIC1_GPIO6 BIT(4) |
| 39 | #define RT5670_DMIC1_GPIO7 BIT(5) | 39 | #define RT5670_DMIC1_GPIO7 BIT(5) |
| 40 | #define RT5670_DMIC2_INR BIT(6) | 40 | #define RT5670_DMIC2_INR BIT(6) |
| 41 | #define RT5670_DMIC2_GPIO8 BIT(7) | 41 | #define RT5670_DMIC2_GPIO8 BIT(7) |
| 42 | #define RT5670_DMIC3_GPIO5 BIT(8) | 42 | #define RT5670_DMIC3_GPIO5 BIT(8) |
| 43 | #define RT5670_JD_MODE1 BIT(9) | 43 | #define RT5670_JD_MODE1 BIT(9) |
| 44 | #define RT5670_JD_MODE2 BIT(10) | 44 | #define RT5670_JD_MODE2 BIT(10) |
| 45 | #define RT5670_JD_MODE3 BIT(11) | 45 | #define RT5670_JD_MODE3 BIT(11) |
| 46 | #define RT5670_GPIO1_IS_EXT_SPK_EN BIT(12) | ||
| 46 | 47 | ||
| 47 | static unsigned long rt5670_quirk; | 48 | static unsigned long rt5670_quirk; |
| 48 | static unsigned int quirk_override; | 49 | static unsigned int quirk_override; |
| @@ -602,9 +603,9 @@ int rt5670_set_jack_detect(struct snd_soc_component *component, · 553 unmodified lines | |||
| 602 | EXPORT_SYMBOL_GPL(rt5670_set_jack_detect); | 603 | EXPORT_SYMBOL_GPL(rt5670_set_jack_detect); |
| 603 | 604 | ||
| 604 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); | 605 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); |
| 605 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); | 606 | static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0); |
| 606 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | 607 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); |
| 607 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | 608 | static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000); |
| 608 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | 609 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); |
| 609 | 610 | ||
| 610 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | 611 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ |
| @@ -1447,6 +1448,33 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w, · 836 unmodified lines | |||
| 1447 | return 0; | 1448 | return 0; |
| 1448 | } | 1449 | } |
| 1449 | 1450 | ||
| 1451 | static int rt5670_spk_event(struct snd_soc_dapm_widget *w, | ||
| 1452 | struct snd_kcontrol *kcontrol, int event) | ||
| 1453 | { | ||
| 1454 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); | ||
| 1455 | struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); | ||
| 1456 | |||
| 1457 | if (!rt5670->pdata.gpio1_is_ext_spk_en) | ||
| 1458 | return 0; | ||
| 1459 | |||
| 1460 | switch (event) { | ||
| 1461 | case SND_SOC_DAPM_POST_PMU: | ||
| 1462 | regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, | ||
| 1463 | RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_HI); | ||
| 1464 | break; | ||
| 1465 | |||
| 1466 | case SND_SOC_DAPM_PRE_PMD: | ||
| 1467 | regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, | ||
| 1468 | RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_LO); | ||
| 1469 | break; | ||
| 1470 | |||
| 1471 | default: | ||
| 1472 | return 0; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | return 0; | ||
| 1476 | } | ||
| 1477 | |||
| 1450 | static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, | 1478 | static int rt5670_bst1_event(struct snd_soc_dapm_widget *w, |
| 1451 | struct snd_kcontrol *kcontrol, int event) | 1479 | struct snd_kcontrol *kcontrol, int event) |
| 1452 | { | 1480 | { |
| @@ -1860,7 +1888,9 @@ static const struct snd_soc_dapm_widget rt5670_specific_dapm_widgets[] = { · 407 unmodified lines | |||
| 1860 | }; | 1888 | }; |
| 1861 | 1889 | ||
| 1862 | static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = { | 1890 | static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = { |
| 1863 | SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0), | 1891 | SND_SOC_DAPM_PGA_E("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0, |
| 1892 | rt5670_spk_event, SND_SOC_DAPM_PRE_PMD | | ||
| 1893 | SND_SOC_DAPM_POST_PMU), | ||
| 1864 | SND_SOC_DAPM_OUTPUT("SPOLP"), | 1894 | SND_SOC_DAPM_OUTPUT("SPOLP"), |
| 1865 | SND_SOC_DAPM_OUTPUT("SPOLN"), | 1895 | SND_SOC_DAPM_OUTPUT("SPOLN"), |
| 1866 | SND_SOC_DAPM_OUTPUT("SPORP"), | 1896 | SND_SOC_DAPM_OUTPUT("SPORP"), |
| @@ -2857,14 +2887,14 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { · 990 unmodified lines | |||
| 2857 | }, | 2887 | }, |
| 2858 | { | 2888 | { |
| 2859 | .callback = rt5670_quirk_cb, | 2889 | .callback = rt5670_quirk_cb, |
| 2860 | .ident = "Lenovo Thinkpad Tablet 10", | 2890 | .ident = "Lenovo Miix 2 10", |
| 2861 | .matches = { | 2891 | .matches = { |
| 2862 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 2892 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 2863 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"), | 2893 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"), |
| 2864 | }, | 2894 | }, |
| 2865 | .driver_data = (unsigned long *)(RT5670_DMIC_EN | | 2895 | .driver_data = (unsigned long *)(RT5670_DMIC_EN | |
| 2866 | RT5670_DMIC1_IN2P | | 2896 | RT5670_DMIC1_IN2P | |
| 2867 | RT5670_DEV_GPIO | | 2897 | RT5670_GPIO1_IS_EXT_SPK_EN | |
| 2868 | RT5670_JD_MODE2), | 2898 | RT5670_JD_MODE2), |
| 2869 | }, | 2899 | }, |
| 2870 | { | 2900 | { |
| @@ -2924,6 +2954,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, · 53 unmodified lines | |||
| 2924 | rt5670->pdata.dev_gpio = true; | 2954 | rt5670->pdata.dev_gpio = true; |
| 2925 | dev_info(&i2c->dev, "quirk dev_gpio\n"); | 2955 | dev_info(&i2c->dev, "quirk dev_gpio\n"); |
| 2926 | } | 2956 | } |
| 2957 | if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) { | ||
| 2958 | rt5670->pdata.gpio1_is_ext_spk_en = true; | ||
| 2959 | dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n"); | ||
| 2960 | } | ||
| 2927 | if (rt5670_quirk & RT5670_IN2_DIFF) { | 2961 | if (rt5670_quirk & RT5670_IN2_DIFF) { |
| 2928 | rt5670->pdata.in2_diff = true; | 2962 | rt5670->pdata.in2_diff = true; |
| 2929 | dev_info(&i2c->dev, "quirk IN2_DIFF\n"); | 2963 | dev_info(&i2c->dev, "quirk IN2_DIFF\n"); |
| @@ -3023,6 +3057,13 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, · 93 unmodified lines | |||
| 3023 | RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); | 3057 | RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); |
| 3024 | } | 3058 | } |
| 3025 | 3059 | ||
| 3060 | if (rt5670->pdata.gpio1_is_ext_spk_en) { | ||
| 3061 | regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, | ||
| 3062 | RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1); | ||
| 3063 | regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, | ||
| 3064 | RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); | ||
| 3065 | } | ||
| 3066 | |||
| 3026 | if (rt5670->pdata.jd_mode) { | 3067 | if (rt5670->pdata.jd_mode) { |
| 3027 | regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, | 3068 | regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, |
| 3028 | RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); | 3069 | RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); |
| @@ -757,7 +757,7 @@ · 756 unmodified lines | |||
| 757 | #define RT5670_PWR_VREF2_BIT 4 | 757 | #define RT5670_PWR_VREF2_BIT 4 |
| 758 | #define RT5670_PWR_FV2 (0x1 << 3) | 758 | #define RT5670_PWR_FV2 (0x1 << 3) |
| 759 | #define RT5670_PWR_FV2_BIT 3 | 759 | #define RT5670_PWR_FV2_BIT 3 |
| 760 | #define RT5670_LDO_SEL_MASK (0x3) | 760 | #define RT5670_LDO_SEL_MASK (0x7) |
| 761 | #define RT5670_LDO_SEL_SFT 0 | 761 | #define RT5670_LDO_SEL_SFT 0 |
| 762 | 762 | ||
| 763 | /* Power Management for Analog 2 (0x64) */ | 763 | /* Power Management for Analog 2 (0x64) */ |
| @@ -967,13 +967,12 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) · 966 unmodified lines | |||
| 967 | rt5682_enable_push_button_irq(component, false); | 967 | rt5682_enable_push_button_irq(component, false); |
| 968 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, | 968 | snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, |
| 969 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); | 969 | RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_LOW); |
| 970 | if (snd_soc_dapm_get_pin_status(dapm, "MICBIAS")) | 970 | if (!snd_soc_dapm_get_pin_status(dapm, "MICBIAS")) |
| 971 | snd_soc_component_update_bits(component, | 971 | snd_soc_component_update_bits(component, |
| 972 | RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0); | 972 | RT5682_PWR_ANLG_1, RT5682_PWR_MB, 0); |
| 973 | else | 973 | if (!snd_soc_dapm_get_pin_status(dapm, "Vref2")) |
| 974 | snd_soc_component_update_bits(component, | 974 | snd_soc_component_update_bits(component, |
| 975 | RT5682_PWR_ANLG_1, | 975 | RT5682_PWR_ANLG_1, RT5682_PWR_VREF2, 0); |
| 976 | RT5682_PWR_VREF2 | RT5682_PWR_MB, 0); | ||
| 977 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, | 976 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3, |
| 978 | RT5682_PWR_CBJ, 0); | 977 | RT5682_PWR_CBJ, 0); |
| 979 | 978 | ||
| @@ -992,16 +991,17 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, · 12 unmodified lines | |||
| 992 | 991 | ||
| 993 | rt5682->hs_jack = hs_jack; | 992 | rt5682->hs_jack = hs_jack; |
| 994 | 993 | ||
| 995 | if (!rt5682->is_sdw) { | 994 | if (!hs_jack) { |
| 996 | if (!hs_jack) { | 995 | regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, |
| 997 | regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, | 996 | RT5682_JD1_EN_MASK, RT5682_JD1_DIS); |
| 998 | RT5682_JD1_EN_MASK, RT5682_JD1_DIS); | 997 | regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, |
| 999 | regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, | 998 | RT5682_POW_JDH | RT5682_POW_JDL, 0); |
| 1000 | RT5682_POW_JDH | RT5682_POW_JDL, 0); | 999 | cancel_delayed_work_sync(&rt5682->jack_detect_work); |
| 1001 | cancel_delayed_work_sync(&rt5682->jack_detect_work); | ||
| 1002 | return 0; | ||
| 1003 | } | ||
| 1004 | 1000 | ||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | if (!rt5682->is_sdw) { | ||
| 1005 | switch (rt5682->pdata.jd_src) { | 1005 | switch (rt5682->pdata.jd_src) { |
| 1006 | case RT5682_JD1: | 1006 | case RT5682_JD1: |
| 1007 | snd_soc_component_update_bits(component, | 1007 | snd_soc_component_update_bits(component, |
| @@ -1082,7 +1082,8 @@ void rt5682_jack_detect_handler(struct work_struct *work) · 74 unmodified lines | |||
| 1082 | /* jack was out, report jack type */ | 1082 | /* jack was out, report jack type */ |
| 1083 | rt5682->jack_type = | 1083 | rt5682->jack_type = |
| 1084 | rt5682_headset_detect(rt5682->component, 1); | 1084 | rt5682_headset_detect(rt5682->component, 1); |
| 1085 | } else { | 1085 | } else if ((rt5682->jack_type & SND_JACK_HEADSET) == |
| 1086 | SND_JACK_HEADSET) { | ||
| 1086 | /* jack is already in, report button event */ | 1087 | /* jack is already in, report button event */ |
| 1087 | rt5682->jack_type = SND_JACK_HEADSET; | 1088 | rt5682->jack_type = SND_JACK_HEADSET; |
| 1088 | btn_type = rt5682_button_detect(rt5682->component); | 1089 | btn_type = rt5682_button_detect(rt5682->component); |
| @@ -1608,8 +1609,7 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { · 519 unmodified lines | |||
| 1608 | 0, set_filter_clk, SND_SOC_DAPM_PRE_PMU), | 1609 | 0, set_filter_clk, SND_SOC_DAPM_PRE_PMU), |
| 1609 | SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, | 1610 | SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0, |
| 1610 | rt5682_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | 1611 | rt5682_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
| 1611 | SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0, | 1612 | SND_SOC_DAPM_SUPPLY("Vref2", SND_SOC_NOPM, 0, 0, NULL, 0), |
| 1612 | NULL, 0), | ||
| 1613 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, NULL, 0), | 1613 | SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, NULL, 0), |
| 1614 | 1614 | ||
| 1615 | /* ASRC */ | 1615 | /* ASRC */ |
| @@ -2492,6 +2492,15 @@ static int rt5682_wclk_prepare(struct clk_hw *hw) · 876 unmodified lines | |||
| 2492 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); | 2492 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS"); |
| 2493 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, | 2493 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, |
| 2494 | RT5682_PWR_MB, RT5682_PWR_MB); | 2494 | RT5682_PWR_MB, RT5682_PWR_MB); |
| 2495 | |||
| 2496 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "Vref2"); | ||
| 2497 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, | ||
| 2498 | RT5682_PWR_VREF2 | RT5682_PWR_FV2, | ||
| 2499 | RT5682_PWR_VREF2); | ||
| 2500 | usleep_range(55000, 60000); | ||
| 2501 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, | ||
| 2502 | RT5682_PWR_FV2, RT5682_PWR_FV2); | ||
| 2503 | |||
| 2495 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1"); | 2504 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1"); |
| 2496 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2F"); | 2505 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2F"); |
| 2497 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2B"); | 2506 | snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2B"); |
| @@ -2517,9 +2526,12 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw) · 19 unmodified lines | |||
| 2517 | snd_soc_dapm_mutex_lock(dapm); | 2526 | snd_soc_dapm_mutex_lock(dapm); |
| 2518 | 2527 | ||
| 2519 | snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); | 2528 | snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS"); |
| 2529 | snd_soc_dapm_disable_pin_unlocked(dapm, "Vref2"); | ||
| 2520 | if (!rt5682->jack_type) | 2530 | if (!rt5682->jack_type) |
| 2521 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, | 2531 | snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, |
| 2532 | RT5682_PWR_VREF2 | RT5682_PWR_FV2 | | ||
| 2522 | RT5682_PWR_MB, 0); | 2533 | RT5682_PWR_MB, 0); |
| 2534 | |||
| 2523 | snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1"); | 2535 | snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1"); |
| 2524 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2F"); | 2536 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2F"); |
| 2525 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2B"); | 2537 | snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2B"); |
| @@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0), · 185 unmodified lines | |||
| 186 | 186 | ||
| 187 | /* Boost mixer */ | 187 | /* Boost mixer */ |
| 188 | static const struct snd_kcontrol_new wm8974_boost_mixer[] = { | 188 | static const struct snd_kcontrol_new wm8974_boost_mixer[] = { |
| 189 | SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 0), | 189 | SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1), |
| 190 | }; | 190 | }; |
| 191 | 191 | ||
| 192 | /* Input PGA */ | 192 | /* Input PGA */ |
| @@ -474,6 +474,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, · 281 unmodified lines | |||
| 474 | iface |= 0x0008; | 474 | iface |= 0x0008; |
| 475 | break; | 475 | break; |
| 476 | case SND_SOC_DAIFMT_DSP_A: | 476 | case SND_SOC_DAIFMT_DSP_A: |
| 477 | if ((fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_IB_IF || | ||
| 478 | (fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_NB_IF) { | ||
| 479 | return -EINVAL; | ||
| 480 | } | ||
| 477 | iface |= 0x00018; | 481 | iface |= 0x00018; |
| 478 | break; | 482 | break; |
| 479 | default: | 483 | default: |
| @@ -317,8 +317,8 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 316 unmodified lines | |||
| 317 | if (ret < 0) | 317 | if (ret < 0) |
| 318 | goto out_put_node; | 318 | goto out_put_node; |
| 319 | 319 | ||
| 320 | dai_link->dpcm_playback = 1; | 320 | snd_soc_dai_link_set_capabilities(dai_link); |
| 321 | dai_link->dpcm_capture = 1; | 321 | |
| 322 | dai_link->ops = &graph_ops; | 322 | dai_link->ops = &graph_ops; |
| 323 | dai_link->init = asoc_simple_dai_init; | 323 | dai_link->init = asoc_simple_dai_init; |
| 324 | 324 | ||
| @@ -231,8 +231,8 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 230 unmodified lines | |||
| 231 | if (ret < 0) | 231 | if (ret < 0) |
| 232 | goto out_put_node; | 232 | goto out_put_node; |
| 233 | 233 | ||
| 234 | dai_link->dpcm_playback = 1; | 234 | snd_soc_dai_link_set_capabilities(dai_link); |
| 235 | dai_link->dpcm_capture = 1; | 235 | |
| 236 | dai_link->ops = &simple_ops; | 236 | dai_link->ops = &simple_ops; |
| 237 | dai_link->init = asoc_simple_dai_init; | 237 | dai_link->init = asoc_simple_dai_init; |
| 238 | 238 | ||
| @@ -354,6 +354,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { · 353 unmodified lines | |||
| 354 | { | 354 | { |
| 355 | .name = "Codec DSP", | 355 | .name = "Codec DSP", |
| 356 | .stream_name = "Wake on Voice", | 356 | .stream_name = "Wake on Voice", |
| 357 | .capture_only = 1, | ||
| 357 | .ops = &bdw_rt5677_dsp_ops, | 358 | .ops = &bdw_rt5677_dsp_ops, |
| 358 | SND_SOC_DAILINK_REG(dsp), | 359 | SND_SOC_DAILINK_REG(dsp), |
| 359 | }, | 360 | }, |
| @@ -543,8 +543,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) · 542 unmodified lines | |||
| 543 | 543 | ||
| 544 | if (cnt) { | 544 | if (cnt) { |
| 545 | ret = device_add_properties(codec_dev, props); | 545 | ret = device_add_properties(codec_dev, props); |
| 546 | if (ret) | 546 | if (ret) { |
| 547 | put_device(codec_dev); | ||
| 547 | return ret; | 548 | return ret; |
| 549 | } | ||
| 548 | } | 550 | } |
| 549 | 551 | ||
| 550 | devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios); | 552 | devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios); |
| @@ -253,21 +253,20 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, · 252 unmodified lines | |||
| 253 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); | 253 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); |
| 254 | 254 | ||
| 255 | /* | 255 | /* |
| 256 | * Default mode for SSP configuration is TDM 4 slot | 256 | * Default mode for SSP configuration is TDM 4 slot. One board/design, |
| 257 | * the Lenovo Miix 2 10 uses not 1 but 2 codecs connected to SSP2. The | ||
| 258 | * second piggy-backed, output-only codec is inside the keyboard-dock | ||
| 259 | * (which has extra speakers). Unlike the main rt5672 codec, we cannot | ||
| 260 | * configure this codec, it is hard coded to use 2 channel 24 bit I2S. | ||
| 261 | * Since we only support 2 channels anyways, there is no need for TDM | ||
| 262 | * on any cht-bsw-rt5672 designs. So we simply use I2S 2ch everywhere. | ||
| 257 | */ | 263 | */ |
| 258 | ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), | 264 | ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), |
| 259 | SND_SOC_DAIFMT_DSP_B | | 265 | SND_SOC_DAIFMT_I2S | |
| 260 | SND_SOC_DAIFMT_IB_NF | | 266 | SND_SOC_DAIFMT_NB_NF | |
| 261 | SND_SOC_DAIFMT_CBS_CFS); | 267 | SND_SOC_DAIFMT_CBS_CFS); |
| 262 | if (ret < 0) { | 268 | if (ret < 0) { |
| 263 | dev_err(rtd->dev, "can't set format to TDM %d\n", ret); | 269 | dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); |
| 264 | return ret; | ||
| 265 | } | ||
| 266 | |||
| 267 | /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ | ||
| 268 | ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); | ||
| 269 | if (ret < 0) { | ||
| 270 | dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); | ||
| 271 | return ret; | 270 | return ret; |
| 272 | } | 271 | } |
| 273 | 272 | ||
| @@ -72,7 +72,7 @@ config SND_SOC_QDSP6_ASM_DAI · 71 unmodified lines | |||
| 72 | 72 | ||
| 73 | config SND_SOC_QDSP6 | 73 | config SND_SOC_QDSP6 |
| 74 | tristate "SoC ALSA audio driver for QDSP6" | 74 | tristate "SoC ALSA audio driver for QDSP6" |
| 75 | depends on QCOM_APR && HAS_DMA | 75 | depends on QCOM_APR |
| 76 | select SND_SOC_QDSP6_COMMON | 76 | select SND_SOC_QDSP6_COMMON |
| 77 | select SND_SOC_QDSP6_CORE | 77 | select SND_SOC_QDSP6_CORE |
| 78 | select SND_SOC_QDSP6_AFE | 78 | select SND_SOC_QDSP6_AFE |
| @@ -219,19 +219,32 @@ static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, · 218 unmodified lines | |||
| 219 | return 0; | 219 | return 0; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static int rockchip_sound_startup(struct snd_pcm_substream *substream) | ||
| 223 | { | ||
| 224 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 225 | |||
| 226 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
| 227 | return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, | ||
| 228 | 8000, 96000); | ||
| 229 | } | ||
| 230 | |||
| 222 | static const struct snd_soc_ops rockchip_sound_max98357a_ops = { | 231 | static const struct snd_soc_ops rockchip_sound_max98357a_ops = { |
| 232 | .startup = rockchip_sound_startup, | ||
| 223 | .hw_params = rockchip_sound_max98357a_hw_params, | 233 | .hw_params = rockchip_sound_max98357a_hw_params, |
| 224 | }; | 234 | }; |
| 225 | 235 | ||
| 226 | static const struct snd_soc_ops rockchip_sound_rt5514_ops = { | 236 | static const struct snd_soc_ops rockchip_sound_rt5514_ops = { |
| 237 | .startup = rockchip_sound_startup, | ||
| 227 | .hw_params = rockchip_sound_rt5514_hw_params, | 238 | .hw_params = rockchip_sound_rt5514_hw_params, |
| 228 | }; | 239 | }; |
| 229 | 240 | ||
| 230 | static const struct snd_soc_ops rockchip_sound_da7219_ops = { | 241 | static const struct snd_soc_ops rockchip_sound_da7219_ops = { |
| 242 | .startup = rockchip_sound_startup, | ||
| 231 | .hw_params = rockchip_sound_da7219_hw_params, | 243 | .hw_params = rockchip_sound_da7219_hw_params, |
| 232 | }; | 244 | }; |
| 233 | 245 | ||
| 234 | static const struct snd_soc_ops rockchip_sound_dmic_ops = { | 246 | static const struct snd_soc_ops rockchip_sound_dmic_ops = { |
| 247 | .startup = rockchip_sound_startup, | ||
| 235 | .hw_params = rockchip_sound_dmic_hw_params, | 248 | .hw_params = rockchip_sound_dmic_hw_params, |
| 236 | }; | 249 | }; |
| 237 | 250 | ||
| @@ -2572,6 +2572,33 @@ int snd_soc_register_component(struct device *dev, · 2571 unmodified lines | |||
| 2572 | } | 2572 | } |
| 2573 | EXPORT_SYMBOL_GPL(snd_soc_register_component); | 2573 | EXPORT_SYMBOL_GPL(snd_soc_register_component); |
| 2574 | 2574 | ||
| 2575 | /** | ||
| 2576 | * snd_soc_unregister_component_by_driver - Unregister component using a given driver | ||
| 2577 | * from the ASoC core | ||
| 2578 | * | ||
| 2579 | * @dev: The device to unregister | ||
| 2580 | * @component_driver: The component driver to unregister | ||
| 2581 | */ | ||
| 2582 | void snd_soc_unregister_component_by_driver(struct device *dev, | ||
| 2583 | const struct snd_soc_component_driver *component_driver) | ||
| 2584 | { | ||
| 2585 | struct snd_soc_component *component; | ||
| 2586 | |||
| 2587 | if (!component_driver) | ||
| 2588 | return; | ||
| 2589 | |||
| 2590 | mutex_lock(&client_mutex); | ||
| 2591 | component = snd_soc_lookup_component_nolocked(dev, component_driver->name); | ||
| 2592 | if (!component) | ||
| 2593 | goto out; | ||
| 2594 | |||
| 2595 | snd_soc_del_component_unlocked(component); | ||
| 2596 | |||
| 2597 | out: | ||
| 2598 | mutex_unlock(&client_mutex); | ||
| 2599 | } | ||
| 2600 | EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver); | ||
| 2601 | |||
| 2575 | /** | 2602 | /** |
| 2576 | * snd_soc_unregister_component - Unregister all related component | 2603 | * snd_soc_unregister_component - Unregister all related component |
| 2577 | * from the ASoC core | 2604 | * from the ASoC core |
| @@ -391,6 +391,44 @@ bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir) · 390 unmodified lines | |||
| 391 | return stream->channels_min; | 391 | return stream->channels_min; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | /* | ||
| 395 | * snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs | ||
| 396 | */ | ||
| 397 | void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link) | ||
| 398 | { | ||
| 399 | struct snd_soc_dai_link_component *cpu; | ||
| 400 | struct snd_soc_dai_link_component *codec; | ||
| 401 | struct snd_soc_dai *dai; | ||
| 402 | bool supported[SNDRV_PCM_STREAM_LAST + 1]; | ||
| 403 | int direction; | ||
| 404 | int i; | ||
| 405 | |||
| 406 | for_each_pcm_streams(direction) { | ||
| 407 | supported[direction] = true; | ||
| 408 | |||
| 409 | for_each_link_cpus(dai_link, i, cpu) { | ||
| 410 | dai = snd_soc_find_dai(cpu); | ||
| 411 | if (!dai || !snd_soc_dai_stream_valid(dai, direction)) { | ||
| 412 | supported[direction] = false; | ||
| 413 | break; | ||
| 414 | } | ||
| 415 | } | ||
| 416 | if (!supported[direction]) | ||
| 417 | continue; | ||
| 418 | for_each_link_codecs(dai_link, i, codec) { | ||
| 419 | dai = snd_soc_find_dai(codec); | ||
| 420 | if (!dai || !snd_soc_dai_stream_valid(dai, direction)) { | ||
| 421 | supported[direction] = false; | ||
| 422 | break; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK]; | ||
| 428 | dai_link->dpcm_capture = supported[SNDRV_PCM_STREAM_CAPTURE]; | ||
| 429 | } | ||
| 430 | EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities); | ||
| 431 | |||
| 394 | void snd_soc_dai_action(struct snd_soc_dai *dai, | 432 | void snd_soc_dai_action(struct snd_soc_dai *dai, |
| 395 | int stream, int action) | 433 | int stream, int action) |
| 396 | { | 434 | { |
| @@ -48,7 +48,9 @@ EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai); · 47 unmodified lines | |||
| 48 | 48 | ||
| 49 | static void devm_component_release(struct device *dev, void *res) | 49 | static void devm_component_release(struct device *dev, void *res) |
| 50 | { | 50 | { |
| 51 | snd_soc_unregister_component(*(struct device **)res); | 51 | const struct snd_soc_component_driver **cmpnt_drv = res; |
| 52 | |||
| 53 | snd_soc_unregister_component_by_driver(dev, *cmpnt_drv); | ||
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | /** | 56 | /** |
| @@ -65,7 +67,7 @@ int devm_snd_soc_register_component(struct device *dev, · 10 unmodified lines | |||
| 65 | const struct snd_soc_component_driver *cmpnt_drv, | 67 | const struct snd_soc_component_driver *cmpnt_drv, |
| 66 | struct snd_soc_dai_driver *dai_drv, int num_dai) | 68 | struct snd_soc_dai_driver *dai_drv, int num_dai) |
| 67 | { | 69 | { |
| 68 | struct device **ptr; | 70 | const struct snd_soc_component_driver **ptr; |
| 69 | int ret; | 71 | int ret; |
| 70 | 72 | ||
| 71 | ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); | 73 | ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); |
| @@ -74,7 +76,7 @@ int devm_snd_soc_register_component(struct device *dev, · 2 unmodified lines | |||
| 74 | 76 | ||
| 75 | ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); | 77 | ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); |
| 76 | if (ret == 0) { | 78 | if (ret == 0) { |
| 77 | *ptr = dev; | 79 | *ptr = cmpnt_drv; |
| 78 | devres_add(dev, ptr); | 80 | devres_add(dev, ptr); |
| 79 | } else { | 81 | } else { |
| 80 | devres_free(ptr); | 82 | devres_free(ptr); |
| @@ -478,7 +478,7 @@ void snd_dmaengine_pcm_unregister(struct device *dev) · 477 unmodified lines | |||
| 478 | 478 | ||
| 479 | pcm = soc_component_to_pcm(component); | 479 | pcm = soc_component_to_pcm(component); |
| 480 | 480 | ||
| 481 | snd_soc_unregister_component(dev); | 481 | snd_soc_unregister_component_by_driver(dev, component->driver); |
| 482 | dmaengine_pcm_release_chan(pcm); | 482 | dmaengine_pcm_release_chan(pcm); |
| 483 | kfree(pcm); | 483 | kfree(pcm); |
| 484 | } | 484 | } |
| @@ -1261,17 +1261,29 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, · 1260 unmodified lines | |||
| 1261 | list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list); | 1261 | list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list); |
| 1262 | 1262 | ||
| 1263 | ret = soc_tplg_add_route(tplg, routes[i]); | 1263 | ret = soc_tplg_add_route(tplg, routes[i]); |
| 1264 | if (ret < 0) | 1264 | if (ret < 0) { |
| 1265 | /* | ||
| 1266 | * this route was added to the list, it will | ||
| 1267 | * be freed in remove_route() so increment the | ||
| 1268 | * counter to skip it in the error handling | ||
| 1269 | * below. | ||
| 1270 | */ | ||
| 1271 | i++; | ||
| 1265 | break; | 1272 | break; |
| 1273 | } | ||
| 1266 | 1274 | ||
| 1267 | /* add route, but keep going if some fail */ | 1275 | /* add route, but keep going if some fail */ |
| 1268 | snd_soc_dapm_add_routes(dapm, routes[i], 1); | 1276 | snd_soc_dapm_add_routes(dapm, routes[i], 1); |
| 1269 | } | 1277 | } |
| 1270 | 1278 | ||
| 1271 | /* free memory allocated for all dapm routes in case of error */ | 1279 | /* |
| 1272 | if (ret < 0) | 1280 | * free memory allocated for all dapm routes not added to the |
| 1273 | for (i = 0; i < count ; i++) | 1281 | * list in case of error |
| 1274 | kfree(routes[i]); | 1282 | */ |
| 1283 | if (ret < 0) { | ||
| 1284 | while (i < count) | ||
| 1285 | kfree(routes[i++]); | ||
| 1286 | } | ||
| 1275 | 1287 | ||
| 1276 | /* | 1288 | /* |
| 1277 | * free pointer to array of dapm routes as this is no longer needed. | 1289 | * free pointer to array of dapm routes as this is no longer needed. |
| @@ -1359,7 +1371,6 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( · 81 unmodified lines | |||
| 1359 | if (err < 0) { | 1371 | if (err < 0) { |
| 1360 | dev_err(tplg->dev, "ASoC: failed to init %s\n", | 1372 | dev_err(tplg->dev, "ASoC: failed to init %s\n", |
| 1361 | mc->hdr.name); | 1373 | mc->hdr.name); |
| 1362 | soc_tplg_free_tlv(tplg, &kc[i]); | ||
| 1363 | goto err_sm; | 1374 | goto err_sm; |
| 1364 | } | 1375 | } |
| 1365 | } | 1376 | } |
| @@ -1367,6 +1378,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create( · 1 unmodified line | |||
| 1367 | 1378 | ||
| 1368 | err_sm: | 1379 | err_sm: |
| 1369 | for (; i >= 0; i--) { | 1380 | for (; i >= 0; i--) { |
| 1381 | soc_tplg_free_tlv(tplg, &kc[i]); | ||
| 1370 | sm = (struct soc_mixer_control *)kc[i].private_value; | 1382 | sm = (struct soc_mixer_control *)kc[i].private_value; |
| 1371 | kfree(sm); | 1383 | kfree(sm); |
| 1372 | kfree(kc[i].name); | 1384 | kfree(kc[i].name); |
| @@ -345,15 +345,15 @@ int snd_sof_device_remove(struct device *dev) · 344 unmodified lines | |||
| 345 | struct snd_sof_pdata *pdata = sdev->pdata; | 345 | struct snd_sof_pdata *pdata = sdev->pdata; |
| 346 | int ret; | 346 | int ret; |
| 347 | 347 | ||
| 348 | ret = snd_sof_dsp_power_down_notify(sdev); | ||
| 349 | if (ret < 0) | ||
| 350 | dev_warn(dev, "error: %d failed to prepare DSP for device removal", | ||
| 351 | ret); | ||
| 352 | |||
| 353 | if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) | 348 | if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) |
| 354 | cancel_work_sync(&sdev->probe_work); | 349 | cancel_work_sync(&sdev->probe_work); |
| 355 | 350 | ||
| 356 | if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { | 351 | if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) { |
| 352 | ret = snd_sof_dsp_power_down_notify(sdev); | ||
| 353 | if (ret < 0) | ||
| 354 | dev_warn(dev, "error: %d failed to prepare DSP for device removal", | ||
| 355 | ret); | ||
| 356 | |||
| 357 | snd_sof_fw_unload(sdev); | 357 | snd_sof_fw_unload(sdev); |
| 358 | snd_sof_ipc_free(sdev); | 358 | snd_sof_ipc_free(sdev); |
| 359 | snd_sof_free_debug(sdev); | 359 | snd_sof_free_debug(sdev); |
| @@ -375,6 +375,14 @@ static int imx8_ipc_pcm_params(struct snd_sof_dev *sdev, · 374 unmodified lines | |||
| 375 | static struct snd_soc_dai_driver imx8_dai[] = { | 375 | static struct snd_soc_dai_driver imx8_dai[] = { |
| 376 | { | 376 | { |
| 377 | .name = "esai-port", | 377 | .name = "esai-port", |
| 378 | .playback = { | ||
| 379 | .channels_min = 1, | ||
| 380 | .channels_max = 8, | ||
| 381 | }, | ||
| 382 | .capture = { | ||
| 383 | .channels_min = 1, | ||
| 384 | .channels_max = 8, | ||
| 385 | }, | ||
| 378 | }, | 386 | }, |
| 379 | }; | 387 | }; |
| 380 | 388 | ||
| @@ -240,6 +240,14 @@ static int imx8m_ipc_pcm_params(struct snd_sof_dev *sdev, · 239 unmodified lines | |||
| 240 | static struct snd_soc_dai_driver imx8m_dai[] = { | 240 | static struct snd_soc_dai_driver imx8m_dai[] = { |
| 241 | { | 241 | { |
| 242 | .name = "sai-port", | 242 | .name = "sai-port", |
| 243 | .playback = { | ||
| 244 | .channels_min = 1, | ||
| 245 | .channels_max = 32, | ||
| 246 | }, | ||
| 247 | .capture = { | ||
| 248 | .channels_min = 1, | ||
| 249 | .channels_max = 32, | ||
| 250 | }, | ||
| 243 | }, | 251 | }, |
| 244 | }; | 252 | }; |
| 245 | 253 | ||
| @@ -380,7 +380,7 @@ · 379 unmodified lines | |||
| 380 | { | 380 | { |
| 381 | "Unit": "CPU-M-CF", | 381 | "Unit": "CPU-M-CF", |
| 382 | "EventCode": "265", | 382 | "EventCode": "265", |
| 383 | "EventName": "DFLT_CCERROR", | 383 | "EventName": "DFLT_CCFINISH", |
| 384 | "BriefDescription": "Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2", | 384 | "BriefDescription": "Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2", |
| 385 | "PublicDescription": "Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2" | 385 | "PublicDescription": "Increments by one for every DEFLATE CONVERSION CALL instruction executed that ended in Condition Codes 0, 1 or 2" |
| 386 | }, | 386 | }, |
| @@ -144,7 +144,7 @@ setup() · 143 unmodified lines | |||
| 144 | 144 | ||
| 145 | cleanup() | 145 | cleanup() |
| 146 | { | 146 | { |
| 147 | for n in h1 r1 h2 h3 h4 | 147 | for n in h0 r1 h1 h2 h3 |
| 148 | do | 148 | do |
| 149 | ip netns del ${n} 2>/dev/null | 149 | ip netns del ${n} 2>/dev/null |
| 150 | done | 150 | done |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | set +x | 6 | set +x |
| 7 | set -e | 7 | set -e |
| 8 | 8 | ||
| 9 | modprobe -q nf_defrag_ipv6 | ||
| 10 | |||
| 9 | readonly NETNS="ns-$(mktemp -u XXXXXX)" | 11 | readonly NETNS="ns-$(mktemp -u XXXXXX)" |
| 10 | 12 | ||
| 11 | setup() { | 13 | setup() { |
| @@ -75,7 +75,7 @@ main() { · 74 unmodified lines | |||
| 75 | fi | 75 | fi |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | if [[ "$(ip netns identify)" == "root" ]]; then | 78 | if [[ -z "$(ip netns identify)" ]]; then |
| 79 | ./in_netns.sh $0 $@ | 79 | ./in_netns.sh $0 $@ |
| 80 | else | 80 | else |
| 81 | main $@ | 81 | main $@ |