diff --git a/.gitignore b/.gitignore index 87b9dd8a163b81..d5f4804ed07cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -143,6 +143,9 @@ x509.genkey /allrandom.config /allyes.config +# Kconfig savedefconfig output +/defconfig + # Kdevelop4 *.kdev4 diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 936cf2a59ca4b3..3f7c3a7e8a2b09 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -147,6 +147,14 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Falkor v{1,2} | E1041 | QCOM_FALKOR_ERRATUM_1041 | +----------------+-----------------+-----------------+-----------------------------+ +| Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1463225 | ++----------------+-----------------+-----------------+-----------------------------+ +| Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1418040 | ++----------------+-----------------+-----------------+-----------------------------+ +| Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1530923 | ++----------------+-----------------+-----------------+-----------------------------+ +| Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1024718 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/Documentation/dev-tools/kunit/faq.rst b/Documentation/dev-tools/kunit/faq.rst index ea55b2467653f0..1628862e702451 100644 --- a/Documentation/dev-tools/kunit/faq.rst +++ b/Documentation/dev-tools/kunit/faq.rst @@ -61,3 +61,43 @@ test, or an end-to-end test. kernel by installing a production configuration of the kernel on production hardware with a production userspace and then trying to exercise some behavior that depends on interactions between the hardware, the kernel, and userspace. + +KUnit isn't working, what should I do? +====================================== + +Unfortunately, there are a number of things which can break, but here are some +things to try. + +1. Try running ``./tools/testing/kunit/kunit.py run`` with the ``--raw_output`` + parameter. This might show details or error messages hidden by the kunit_tool + parser. +2. Instead of running ``kunit.py run``, try running ``kunit.py config``, + ``kunit.py build``, and ``kunit.py exec`` independently. This can help track + down where an issue is occurring. (If you think the parser is at fault, you + can run it manually against stdin or a file with ``kunit.py parse``.) +3. Running the UML kernel directly can often reveal issues or error messages + kunit_tool ignores. This should be as simple as running ``./vmlinux`` after + building the UML kernel (e.g., by using ``kunit.py build``). Note that UML + has some unusual requirements (such as the host having a tmpfs filesystem + mounted), and has had issues in the past when built statically and the host + has KASLR enabled. (On older host kernels, you may need to run ``setarch + `uname -m` -R ./vmlinux`` to disable KASLR.) +4. Make sure the kernel .config has ``CONFIG_KUNIT=y`` and at least one test + (e.g. ``CONFIG_KUNIT_EXAMPLE_TEST=y``). kunit_tool will keep its .config + around, so you can see what config was used after running ``kunit.py run``. + It also preserves any config changes you might make, so you can + enable/disable things with ``make ARCH=um menuconfig`` or similar, and then + re-run kunit_tool. +5. Try to run ``make ARCH=um defconfig`` before running ``kunit.py run``. This + may help clean up any residual config items which could be causing problems. +6. Finally, try running KUnit outside UML. KUnit and KUnit tests can run be + built into any kernel, or can be built as a module and loaded at runtime. + Doing so should allow you to determine if UML is causing the issue you're + seeing. When tests are built-in, they will execute when the kernel boots, and + modules will automatically execute associated tests when loaded. Test results + can be collected from ``/sys/kernel/debug/kunit//results``, and + can be parsed with ``kunit.py parse``. For more details, see "KUnit on + non-UML architectures" in :doc:`usage`. + +If none of the above tricks help, you are always welcome to email any issues to +kunit-dev@googlegroups.com. diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile index a63898954068d4..91c4d00e96d3c9 100644 --- a/Documentation/devicetree/bindings/Makefile +++ b/Documentation/devicetree/bindings/Makefile @@ -2,7 +2,6 @@ DT_DOC_CHECKER ?= dt-doc-validate DT_EXTRACT_EX ?= dt-extract-example DT_MK_SCHEMA ?= dt-mk-schema -DT_MK_SCHEMA_USERONLY_FLAG := $(if $(DT_SCHEMA_FILES), -u) DT_SCHEMA_MIN_VERSION = 2020.5 @@ -35,21 +34,40 @@ quiet_cmd_mk_schema = SCHEMA $@ DT_DOCS = $(shell $(find_cmd) | sed -e 's|^$(srctree)/||') -DT_SCHEMA_FILES ?= $(DT_DOCS) - -extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) -extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) -extra-$(CHECK_DT_BINDING) += processed-schema-examples.yaml - override DTC_FLAGS := \ -Wno-avoid_unnecessary_addr_size \ - -Wno-graph_child_address + -Wno-graph_child_address \ + -Wno-interrupt_provider $(obj)/processed-schema-examples.yaml: $(DT_DOCS) check_dtschema_version FORCE $(call if_changed,mk_schema) -$(obj)/processed-schema.yaml: DT_MK_SCHEMA_FLAGS := $(DT_MK_SCHEMA_USERONLY_FLAG) +ifeq ($(DT_SCHEMA_FILES),) + +# Unless DT_SCHEMA_FILES is specified, use the full schema for dtbs_check too. +# Just copy processed-schema-examples.yaml + +$(obj)/processed-schema.yaml: $(obj)/processed-schema-examples.yaml FORCE + $(call if_changed,copy) + +DT_SCHEMA_FILES = $(DT_DOCS) + +else + +# If DT_SCHEMA_FILES is specified, use it for processed-schema.yaml + +$(obj)/processed-schema.yaml: DT_MK_SCHEMA_FLAGS := -u $(obj)/processed-schema.yaml: $(DT_SCHEMA_FILES) check_dtschema_version FORCE $(call if_changed,mk_schema) -extra-y += processed-schema.yaml +endif + +extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) +extra-$(CHECK_DT_BINDING) += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) +extra-$(CHECK_DT_BINDING) += processed-schema-examples.yaml +extra-$(CHECK_DTBS) += processed-schema.yaml + +# Hack: avoid 'Argument list too long' error for 'make clean'. Remove most of +# build artifacts here before they are processed by scripts/Makefile.clean +clean-files = $(shell find $(obj) \( -name '*.example.dts' -o \ + -name '*.example.dt.yaml' \) -delete 2>/dev/null) diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt index 715047444391a8..10b8459e49f8c2 100644 --- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt @@ -47,7 +47,7 @@ Required properties: &lsio_mu1 1 2 &lsio_mu1 1 3 &lsio_mu1 3 3>; - See Documentation/devicetree/bindings/mailbox/fsl,mu.txt + See Documentation/devicetree/bindings/mailbox/fsl,mu.yaml for detailed mailbox binding. Note: Each mu which supports general interrupt should have an alias correctly diff --git a/Documentation/devicetree/bindings/bus/socionext,uniphier-system-bus.yaml b/Documentation/devicetree/bindings/bus/socionext,uniphier-system-bus.yaml index c4c9119e4a2065..a0c6c5d2b70fba 100644 --- a/Documentation/devicetree/bindings/bus/socionext,uniphier-system-bus.yaml +++ b/Documentation/devicetree/bindings/bus/socionext,uniphier-system-bus.yaml @@ -80,14 +80,14 @@ examples: ranges = <1 0x00000000 0x42000000 0x02000000>, <5 0x00000000 0x46000000 0x01000000>; - ethernet@1,01f00000 { + ethernet@1,1f00000 { compatible = "smsc,lan9115"; reg = <1 0x01f00000 0x1000>; interrupts = <0 48 4>; phy-mode = "mii"; }; - uart@5,00200000 { + serial@5,200000 { compatible = "ns16550a"; reg = <5 0x00200000 0x20>; interrupts = <0 49 4>; diff --git a/Documentation/devicetree/bindings/clock/imx27-clock.yaml b/Documentation/devicetree/bindings/clock/imx27-clock.yaml index b5f3ed084ea0ba..a75365453dbce2 100644 --- a/Documentation/devicetree/bindings/clock/imx27-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx27-clock.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Clock bindings for Freescale i.MX27 maintainers: - - Fabio Estevam + - Fabio Estevam description: | The clock consumer should specify the desired clock by having the clock diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.yaml b/Documentation/devicetree/bindings/clock/imx31-clock.yaml index 1b6f75d3928a88..a25a374b3b2aab 100644 --- a/Documentation/devicetree/bindings/clock/imx31-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx31-clock.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Clock bindings for Freescale i.MX31 maintainers: - - Fabio Estevam + - Fabio Estevam description: | The clock consumer should specify the desired clock by having the clock diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.yaml b/Documentation/devicetree/bindings/clock/imx5-clock.yaml index f5c2b3d7a910bc..4d9e7c73dce919 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.yaml +++ b/Documentation/devicetree/bindings/clock/imx5-clock.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Clock bindings for Freescale i.MX5 maintainers: - - Fabio Estevam + - Fabio Estevam description: | The clock consumer should specify the desired clock by having the clock diff --git a/Documentation/devicetree/bindings/display/bridge/sii902x.txt b/Documentation/devicetree/bindings/display/bridge/sii902x.txt index 6e14e087c0d0ad..0d1db3f9da84f1 100644 --- a/Documentation/devicetree/bindings/display/bridge/sii902x.txt +++ b/Documentation/devicetree/bindings/display/bridge/sii902x.txt @@ -37,7 +37,7 @@ Optional properties: simple-card or audio-graph-card binding. See their binding documents on how to describe the way the sii902x device is connected to the rest of the audio system: - Documentation/devicetree/bindings/sound/simple-card.txt + Documentation/devicetree/bindings/sound/simple-card.yaml Documentation/devicetree/bindings/sound/audio-graph-card.txt Note: In case of the audio-graph-card binding the used port index should be 3. diff --git a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt index 5bf77f6dd19db0..5a99490c17b9b5 100644 --- a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt +++ b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt @@ -68,7 +68,7 @@ Required properties: datasheet - clocks : phandle to the PRE axi clock input, as described in Documentation/devicetree/bindings/clock/clock-bindings.txt and - Documentation/devicetree/bindings/clock/imx6q-clock.txt. + Documentation/devicetree/bindings/clock/imx6q-clock.yaml. - clock-names: should be "axi" - interrupts: should contain the PRE interrupt - fsl,iram: phandle pointing to the mmio-sram device node, that should be @@ -94,7 +94,7 @@ Required properties: datasheet - clocks : phandles to the PRG ipg and axi clock inputs, as described in Documentation/devicetree/bindings/clock/clock-bindings.txt and - Documentation/devicetree/bindings/clock/imx6q-clock.txt. + Documentation/devicetree/bindings/clock/imx6q-clock.yaml. - clock-names: should be "ipg" and "axi" - fsl,pres: phandles to the PRE units attached to this PRG, with the fixed PRE as the first entry and the muxable PREs following. diff --git a/Documentation/devicetree/bindings/display/imx/ldb.txt b/Documentation/devicetree/bindings/display/imx/ldb.txt index 38c637fa39ddf4..8e6e7d797943ff 100644 --- a/Documentation/devicetree/bindings/display/imx/ldb.txt +++ b/Documentation/devicetree/bindings/display/imx/ldb.txt @@ -30,8 +30,8 @@ Required properties: "di2_sel" - IPU2 DI0 mux "di3_sel" - IPU2 DI1 mux The needed clock numbers for each are documented in - Documentation/devicetree/bindings/clock/imx5-clock.txt, and in - Documentation/devicetree/bindings/clock/imx6q-clock.txt. + Documentation/devicetree/bindings/clock/imx5-clock.yaml, and in + Documentation/devicetree/bindings/clock/imx6q-clock.yaml. Optional properties: - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q diff --git a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml index 41fd5713c15644..be69e0cc50fcd0 100644 --- a/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml +++ b/Documentation/devicetree/bindings/display/panel/arm,versatile-tft-panel.yaml @@ -33,7 +33,7 @@ additionalProperties: false examples: - | - sysreg { + sysreg@0 { compatible = "arm,versatile-sysreg", "syscon", "simple-mfd"; reg = <0x00000 0x1000>; diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml index ec8ae742d4da2a..7204da5eb4c593 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-drm.yaml @@ -24,7 +24,7 @@ properties: description: | Should contain a list of phandles pointing to display interface port of vop devices. vop definitions as defined in - Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt + Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml required: - compatible diff --git a/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt b/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt index ba455589f86935..e1c49b660d3a3d 100644 --- a/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/mediatek,mt7621-gpio.txt @@ -12,7 +12,7 @@ Required properties for the top level node: Only the GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported. - #interrupt-cells : Specifies the number of cells needed to encode an interrupt. Should be 2. The first cell defines the interrupt number, - the second encodes the triger flags encoded as described in + the second encodes the trigger flags encoded as described in Documentation/devicetree/bindings/interrupt-controller/interrupts.txt - compatible: - "mediatek,mt7621-gpio" for Mediatek controllers diff --git a/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt b/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt index e13405355166dd..e6bbcae4d07fb2 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt @@ -10,7 +10,7 @@ Interrupt number definition: 16-31 : private irq, and we use 16 as the co-processor timer. 31-1024: common irq for soc ip. -Interrupt triger mode: (Defined in dt-bindings/interrupt-controller/irq.h) +Interrupt trigger mode: (Defined in dt-bindings/interrupt-controller/irq.h) IRQ_TYPE_LEVEL_HIGH (default) IRQ_TYPE_LEVEL_LOW IRQ_TYPE_EDGE_RISING diff --git a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt index 4438432bfe9b3d..ad76edccf88166 100644 --- a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt +++ b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt @@ -87,7 +87,7 @@ Example: ranges; /* APU<->RPU0 IPI mailbox controller */ - ipi_mailbox_rpu0: mailbox@ff90400 { + ipi_mailbox_rpu0: mailbox@ff990400 { reg = <0xff990400 0x20>, <0xff990420 0x20>, <0xff990080 0x20>, diff --git a/Documentation/devicetree/bindings/misc/olpc,xo1.75-ec.txt b/Documentation/devicetree/bindings/misc/olpc,xo1.75-ec.txt index 8c4d649cdd8ff4..2d7cdf19a0d0fc 100644 --- a/Documentation/devicetree/bindings/misc/olpc,xo1.75-ec.txt +++ b/Documentation/devicetree/bindings/misc/olpc,xo1.75-ec.txt @@ -8,7 +8,7 @@ The embedded controller requires the SPI controller driver to signal readiness to receive a transfer (that is, when TX FIFO contains the response data) by strobing the ACK pin with the ready signal. See the "ready-gpios" property of the SSP binding as documented in: -. +. Example: &ssp3 { diff --git a/Documentation/devicetree/bindings/net/mediatek-bluetooth.txt b/Documentation/devicetree/bindings/net/mediatek-bluetooth.txt index 219bcbd0d34478..9ef5bacda8c18c 100644 --- a/Documentation/devicetree/bindings/net/mediatek-bluetooth.txt +++ b/Documentation/devicetree/bindings/net/mediatek-bluetooth.txt @@ -3,7 +3,7 @@ MediaTek SoC built-in Bluetooth Devices This device is a serial attached device to BTIF device and thus it must be a child node of the serial node with BTIF. The dt-bindings details for BTIF -device can be known via Documentation/devicetree/bindings/serial/8250.txt. +device can be known via Documentation/devicetree/bindings/serial/8250.yaml. Required properties: diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index b68613188c1916..1b8e8b4a63797d 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -114,7 +114,7 @@ with values derived from the SoC user manual. [flags]> On other mach-shmobile platforms GPIO is handled by the gpio-rcar driver. -Please refer to Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt +Please refer to Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml for documentation of the GPIO device tree bindings on those platforms. diff --git a/Documentation/devicetree/bindings/sound/audio-graph-card.txt b/Documentation/devicetree/bindings/sound/audio-graph-card.txt index 269682619a702d..d5f6919a2d69ec 100644 --- a/Documentation/devicetree/bindings/sound/audio-graph-card.txt +++ b/Documentation/devicetree/bindings/sound/audio-graph-card.txt @@ -5,7 +5,7 @@ It is based on common bindings for device graphs. see ${LINUX}/Documentation/devicetree/bindings/graph.txt Basically, Audio Graph Card property is same as Simple Card. -see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt +see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.yaml Below are same as Simple-Card. diff --git a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml index 175e4fb0c31550..2e0bbc1c868abf 100644 --- a/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/intel,keembay-i2s.yaml @@ -23,7 +23,8 @@ properties: reg: items: - - description: I2S configuration + - description: I2S registers + - description: I2S gen configuration reg-names: items: @@ -60,7 +61,8 @@ examples: i2s3: i2s@20140000 { compatible = "intel,keembay-i2s"; #sound-dai-cells = <0>; - reg = <0x20140000 0x200 0x202a00a4 0x4>; + reg = <0x20140000 0x200>, /* I2S registers */ + <0x202a00a4 0x4>; /* I2S gen configuration */ reg-names = "i2s-regs", "i2s_gen_cfg"; interrupts = ; clock-names = "osc", "apb_clk"; diff --git a/Documentation/devicetree/bindings/sound/mt8183-da7219-max98357.txt b/Documentation/devicetree/bindings/sound/mt8183-da7219-max98357.txt index 92ac86f8382202..f7f3b83da6300c 100644 --- a/Documentation/devicetree/bindings/sound/mt8183-da7219-max98357.txt +++ b/Documentation/devicetree/bindings/sound/mt8183-da7219-max98357.txt @@ -1,7 +1,8 @@ -MT8183 with MT6358, DA7219 and MAX98357 CODECS +MT8183 with MT6358, DA7219, MAX98357, and RT1015 CODECS Required properties: -- compatible : "mediatek,mt8183_da7219_max98357" +- compatible : "mediatek,mt8183_da7219_max98357" for MAX98357A codec + "mediatek,mt8183_da7219_rt1015" for RT1015 codec - mediatek,headset-codec: the phandles of da7219 codecs - mediatek,platform: the phandle of MT8183 ASoC platform diff --git a/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt b/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt index decaa013a07e1d..5afd3d8dab8457 100644 --- a/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt +++ b/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt @@ -1,7 +1,8 @@ -MT8183 with MT6358, TS3A227 and MAX98357 CODECS +MT8183 with MT6358, TS3A227, MAX98357, and RT1015 CODECS Required properties: -- compatible : "mediatek,mt8183_mt6358_ts3a227_max98357" +- compatible : "mediatek,mt8183_mt6358_ts3a227_max98357" for MAX98357A codec + "mediatek,mt8183_mt6358_ts3a227_rt1015" for RT1015 codec - mediatek,platform: the phandle of MT8183 ASoC platform Optional properties: diff --git a/Documentation/devicetree/bindings/sound/simple-card.yaml b/Documentation/devicetree/bindings/sound/simple-card.yaml index 8132d0c0f00a12..35e669020296db 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.yaml +++ b/Documentation/devicetree/bindings/sound/simple-card.yaml @@ -378,6 +378,8 @@ examples: - | sound { compatible = "simple-audio-card"; + #address-cells = <1>; + #size-cells = <0>; simple-audio-card,name = "rsnd-ak4643"; simple-audio-card,format = "left_j"; @@ -391,10 +393,12 @@ examples: "ak4642 Playback", "DAI1 Playback"; dpcmcpu: simple-audio-card,cpu@0 { + reg = <0>; sound-dai = <&rcar_sound 0>; }; simple-audio-card,cpu@1 { + reg = <1>; sound-dai = <&rcar_sound 1>; }; @@ -418,6 +422,8 @@ examples: - | sound { compatible = "simple-audio-card"; + #address-cells = <1>; + #size-cells = <0>; simple-audio-card,routing = "pcm3168a Playback", "DAI1 Playback", @@ -426,6 +432,7 @@ examples: "pcm3168a Playback", "DAI4 Playback"; simple-audio-card,dai-link@0 { + reg = <0>; format = "left_j"; bitclock-master = <&sndcpu0>; frame-master = <&sndcpu0>; @@ -439,22 +446,23 @@ examples: }; simple-audio-card,dai-link@1 { + reg = <1>; format = "i2s"; bitclock-master = <&sndcpu1>; frame-master = <&sndcpu1>; convert-channels = <8>; /* TDM Split */ - sndcpu1: cpu@0 { + sndcpu1: cpu0 { sound-dai = <&rcar_sound 1>; }; - cpu@1 { + cpu1 { sound-dai = <&rcar_sound 2>; }; - cpu@2 { + cpu2 { sound-dai = <&rcar_sound 3>; }; - cpu@3 { + cpu3 { sound-dai = <&rcar_sound 4>; }; codec { @@ -466,6 +474,7 @@ examples: }; simple-audio-card,dai-link@2 { + reg = <2>; format = "i2s"; bitclock-master = <&sndcpu2>; frame-master = <&sndcpu2>; diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt index 4d51f3f5ea98c3..a6ffcdec6f6aee 100644 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt @@ -5,7 +5,7 @@ codec or external codecs. sti sound drivers allows to expose sti SoC audio interface through the generic ASoC simple card. For details about sound card declaration please refer to -Documentation/devicetree/bindings/sound/simple-card.txt. +Documentation/devicetree/bindings/sound/simple-card.yaml. 1) sti-uniperiph-dai: audio dai device. --------------------------------------- diff --git a/Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml b/Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml new file mode 100644 index 00000000000000..6f2be650340160 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml @@ -0,0 +1,95 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,j721e-cpb-audio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments J721e Common Processor Board Audio Support + +maintainers: + - Peter Ujfalusi + +description: | + The audio support on the board is using pcm3168a codec connected to McASP10 + serializers in parallel setup. + The pcm3168a SCKI clock is sourced from j721e AUDIO_REFCLK2 pin. + In order to support 48KHz and 44.1KHz family of sampling rates the parent + clock for AUDIO_REFCLK2 needs to be changed between PLL4 (for 48KHz) and + PLL15 (for 44.1KHz). The same PLLs are used for McASP10's AUXCLK clock via + different HSDIVIDER. + + Clocking setup for 48KHz family: + PLL4 ---> PLL4_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk + |-> PLL4_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI + + Clocking setup for 44.1KHz family: + PLL15 ---> PLL15_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk + |-> PLL15_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI + +properties: + compatible: + items: + - const: ti,j721e-cpb-audio + + model: + $ref: /schemas/types.yaml#/definitions/string + description: User specified audio sound card name + + ti,cpb-mcasp: + description: phandle to McASP used on CPB + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + ti,cpb-codec: + description: phandle to the pcm3168a codec used on the CPB + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + clocks: + items: + - description: AUXCLK clock for McASP used by CPB audio + - description: Parent for CPB_McASP auxclk (for 48KHz) + - description: Parent for CPB_McASP auxclk (for 44.1KHz) + - description: SCKI clock for the pcm3168a codec on CPB + - description: Parent for CPB_SCKI clock (for 48KHz) + - description: Parent for CPB_SCKI clock (for 44.1KHz) + + clock-names: + items: + - const: cpb-mcasp-auxclk + - const: cpb-mcasp-auxclk-48000 + - const: cpb-mcasp-auxclk-44100 + - const: cpb-codec-scki + - const: cpb-codec-scki-48000 + - const: cpb-codec-scki-44100 + +required: + - compatible + - model + - ti,cpb-mcasp + - ti,cpb-codec + - clocks + - clock-names + +additionalProperties: false + +examples: + - |+ + sound { + compatible = "ti,j721e-cpb-audio"; + model = "j721e-cpb"; + + status = "okay"; + + ti,cpb-mcasp = <&mcasp10>; + ti,cpb-codec = <&pcm3168a_1>; + + clocks = <&k3_clks 184 1>, + <&k3_clks 184 2>, <&k3_clks 184 4>, + <&k3_clks 157 371>, + <&k3_clks 157 400>, <&k3_clks 157 401>; + clock-names = "cpb-mcasp-auxclk", + "cpb-mcasp-auxclk-48000", "cpb-mcasp-auxclk-44100", + "cpb-codec-scki", + "cpb-codec-scki-48000", "cpb-codec-scki-44100"; + }; diff --git a/Documentation/devicetree/bindings/sound/ti,j721e-cpb-ivi-audio.yaml b/Documentation/devicetree/bindings/sound/ti,j721e-cpb-ivi-audio.yaml new file mode 100644 index 00000000000000..e0b88470a502fb --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,j721e-cpb-ivi-audio.yaml @@ -0,0 +1,150 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,j721e-cpb-ivi-audio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments J721e Common Processor Board Audio Support + +maintainers: + - Peter Ujfalusi + +description: | + The Infotainment board plugs into the Common Processor Board, the support of the + extension board is extending the CPB audio support, decribed in: + sound/ti,j721e-cpb-audio.txt + + The audio support on the Infotainment Expansion Board consists of McASP0 + connected to two pcm3168a codecs with dedicated set of serializers to each. + The SCKI for pcm3168a is sourced from j721e AUDIO_REFCLK0 pin. + + In order to support 48KHz and 44.1KHz family of sampling rates the parent clock + for AUDIO_REFCLK0 needs to be changed between PLL4 (for 48KHz) and PLL15 (for + 44.1KHz). The same PLLs are used for McASP0's AUXCLK clock via different + HSDIVIDER. + + Note: the same PLL4 and PLL15 is used by the audio support on the CPB! + + Clocking setup for 48KHz family: + PLL4 ---> PLL4_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk + | |-> MCASP0_AUXCLK ---> McASP0.auxclk + | + |-> PLL4_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI + |-> AUDIO_REFCLK0 ---> pcm3168a_a/b.SCKI + + Clocking setup for 44.1KHz family: + PLL15 ---> PLL15_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk + | |-> MCASP0_AUXCLK ---> McASP0.auxclk + | + |-> PLL15_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI + |-> AUDIO_REFCLK0 ---> pcm3168a_a/b.SCKI + +properties: + compatible: + items: + - const: ti,j721e-cpb-ivi-audio + + model: + $ref: /schemas/types.yaml#/definitions/string + description: User specified audio sound card name + + ti,cpb-mcasp: + description: phandle to McASP used on CPB + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + ti,cpb-codec: + description: phandle to the pcm3168a codec used on the CPB + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + ti,ivi-mcasp: + description: phandle to McASP used on IVI + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + ti,ivi-codec-a: + description: phandle to the pcm3168a-A codec on the expansion board + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + ti,ivi-codec-b: + description: phandle to the pcm3168a-B codec on the expansion board + allOf: + - $ref: /schemas/types.yaml#/definitions/phandle + + clocks: + items: + - description: AUXCLK clock for McASP used by CPB audio + - description: Parent for CPB_McASP auxclk (for 48KHz) + - description: Parent for CPB_McASP auxclk (for 44.1KHz) + - description: SCKI clock for the pcm3168a codec on CPB + - description: Parent for CPB_SCKI clock (for 48KHz) + - description: Parent for CPB_SCKI clock (for 44.1KHz) + - description: AUXCLK clock for McASP used by IVI audio + - description: Parent for IVI_McASP auxclk (for 48KHz) + - description: Parent for IVI_McASP auxclk (for 44.1KHz) + - description: SCKI clock for the pcm3168a codec on IVI + - description: Parent for IVI_SCKI clock (for 48KHz) + - description: Parent for IVI_SCKI clock (for 44.1KHz) + + clock-names: + items: + - const: cpb-mcasp-auxclk + - const: cpb-mcasp-auxclk-48000 + - const: cpb-mcasp-auxclk-44100 + - const: cpb-codec-scki + - const: cpb-codec-scki-48000 + - const: cpb-codec-scki-44100 + - const: ivi-mcasp-auxclk + - const: ivi-mcasp-auxclk-48000 + - const: ivi-mcasp-auxclk-44100 + - const: ivi-codec-scki + - const: ivi-codec-scki-48000 + - const: ivi-codec-scki-44100 + +required: + - compatible + - model + - ti,cpb-mcasp + - ti,cpb-codec + - ti,ivi-mcasp + - ti,ivi-codec-a + - ti,ivi-codec-b + - clocks + - clock-names + +additionalProperties: false + +examples: + - |+ + sound { + compatible = "ti,j721e-cpb-ivi-audio"; + model = "j721e-cpb-ivi"; + + status = "okay"; + + ti,cpb-mcasp = <&mcasp10>; + ti,cpb-codec = <&pcm3168a_1>; + + ti,ivi-mcasp = <&mcasp0>; + ti,ivi-codec-a = <&pcm3168a_a>; + ti,ivi-codec-b = <&pcm3168a_b>; + + clocks = <&k3_clks 184 1>, + <&k3_clks 184 2>, <&k3_clks 184 4>, + <&k3_clks 157 371>, + <&k3_clks 157 400>, <&k3_clks 157 401>, + <&k3_clks 174 1>, + <&k3_clks 174 2>, <&k3_clks 174 4>, + <&k3_clks 157 301>, + <&k3_clks 157 330>, <&k3_clks 157 331>; + clock-names = "cpb-mcasp-auxclk", + "cpb-mcasp-auxclk-48000", "cpb-mcasp-auxclk-44100", + "cpb-codec-scki", + "cpb-codec-scki-48000", "cpb-codec-scki-44100", + "ivi-mcasp-auxclk", + "ivi-mcasp-auxclk-48000", "ivi-mcasp-auxclk-44100", + "ivi-codec-scki", + "ivi-codec-scki-48000", "ivi-codec-scki-44100"; + }; diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt index 790311a42bf1ae..c8c1e913f4e787 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt +++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt @@ -19,7 +19,7 @@ Required properties: SPI Controller nodes must be child of GENI based Qualcomm Universal Peripharal. Please refer GENI based QUP wrapper controller node bindings -described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt. +described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml. SPI slave nodes must be children of the SPI master node and conform to SPI bus binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt. diff --git a/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml b/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml index fcd25a0af38c93..727d04550324c1 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-sensor.yaml @@ -41,7 +41,7 @@ examples: #include // Example 1: SDM845 TSENS - soc: soc@0 { + soc: soc { #address-cells = <2>; #size-cells = <2>; diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml index b8515d3eeaa2b4..3ec9cc87ec502e 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml @@ -224,7 +224,7 @@ examples: #include // Example 1: SDM845 TSENS - soc: soc@0 { + soc { #address-cells = <2>; #size-cells = <2>; diff --git a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml index 25b9209c2e5d9f..ea14de80ec759d 100644 --- a/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml +++ b/Documentation/devicetree/bindings/thermal/ti,am654-thermal.yaml @@ -35,7 +35,7 @@ examples: #include vtm: thermal@42050000 { compatible = "ti,am654-vtm"; - reg = <0x0 0x42050000 0x0 0x25c>; + reg = <0x42050000 0x25c>; power-domains = <&k3_pds 80 TI_SCI_PD_EXCLUSIVE>; #thermal-sensor-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/timer/csky,mptimer.txt b/Documentation/devicetree/bindings/timer/csky,mptimer.txt index 15cfec08fbb8e9..f5c7e99cf52bf4 100644 --- a/Documentation/devicetree/bindings/timer/csky,mptimer.txt +++ b/Documentation/devicetree/bindings/timer/csky,mptimer.txt @@ -8,7 +8,7 @@ regs is accessed by cpu co-processor 4 registers with mtcr/mfcr. - PTIM_CTLR "cr<0, 14>" Control reg to start reset timer. - PTIM_TSR "cr<1, 14>" Interrupt cleanup status reg. - PTIM_CCVR "cr<3, 14>" Current counter value reg. - - PTIM_LVR "cr<6, 14>" Window value reg to triger next event. + - PTIM_LVR "cr<6, 14>" Window value reg to trigger next event. ============================== timer node bindings definition diff --git a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml index e4e83d3971ac00..8b019ac05bbe0d 100644 --- a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml +++ b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml @@ -127,8 +127,8 @@ examples: #address-cells = <1>; #size-cells = <0>; - string@0409 { - reg = <0x0409>; + string@409 { + reg = <0x409>; manufacturer = "ASPEED"; product = "USB Virtual Hub"; serial-number = "0000"; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 9aeab66be85fcb..147afcfe81fed8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -20,7 +20,7 @@ patternProperties: "^(keypad|m25p|max8952|max8997|max8998|mpmc),.*": true "^(pinctrl-single|#pinctrl-single|PowerPC),.*": true "^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*": true - "^(simple-audio-card|simple-graph-card|st-plgpio|st-spics|ts),.*": true + "^(simple-audio-card|st-plgpio|st-spics|ts),.*": true # Keep list in alphabetical order. "^abilis,.*": diff --git a/Documentation/devicetree/writing-schema.rst b/Documentation/devicetree/writing-schema.rst index 220cf464ed778b..8c74a99f95e23f 100644 --- a/Documentation/devicetree/writing-schema.rst +++ b/Documentation/devicetree/writing-schema.rst @@ -1,4 +1,4 @@ -:orphan: +.. SPDX-License-Identifier: GPL-2.0 Writing DeviceTree Bindings in json-schema ========================================== @@ -124,9 +124,12 @@ dtc must also be built with YAML output support enabled. This requires that libyaml and its headers be installed on the host system. For some distributions that involves installing the development package, such as: -Debian: +Debian:: + apt-get install libyaml-dev -Fedora: + +Fedora:: + dnf -y install libyaml-devel Running checks diff --git a/Documentation/i2c/slave-eeprom-backend.rst b/Documentation/i2c/slave-eeprom-backend.rst index 0b8cd83698e0f0..38d951f103023a 100644 --- a/Documentation/i2c/slave-eeprom-backend.rst +++ b/Documentation/i2c/slave-eeprom-backend.rst @@ -1,14 +1,26 @@ ============================== -Linux I2C slave eeprom backend +Linux I2C slave EEPROM backend ============================== -by Wolfram Sang in 2014-15 +by Wolfram Sang in 2014-20 -This is a proof-of-concept backend which acts like an EEPROM on the connected -I2C bus. The memory contents can be modified from userspace via this file -located in sysfs:: +This backend simulates an EEPROM on the connected I2C bus. Its memory contents +can be accessed from userspace via this file located in sysfs:: /sys/bus/i2c/devices//slave-eeprom +The following types are available: 24c02, 24c32, 24c64, and 24c512. Read-only +variants are also supported. The name needed for instantiating has the form +'slave-[ro]'. Examples follow: + +24c02, read/write, address 0x64: + # echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-1/new_device + +24c512, read-only, address 0x42: + # echo slave-24c512ro 0x1042 > /sys/bus/i2c/devices/i2c-1/new_device + +You can also preload data during boot if a device-property named +'firmware-name' contains a valid filename (DT or ACPI only). + As of 2015, Linux doesn't support poll on binary sysfs files, so there is no notification when another master changed the content. diff --git a/Documentation/kbuild/modules.rst b/Documentation/kbuild/modules.rst index a45cccff467d8e..85ccc878895e75 100644 --- a/Documentation/kbuild/modules.rst +++ b/Documentation/kbuild/modules.rst @@ -182,7 +182,8 @@ module 8123.ko, which is built from the following files:: 8123_pci.c 8123_bin.o_shipped <= Binary blob ---- 3.1 Shared Makefile +3.1 Shared Makefile +------------------- An external module always includes a wrapper makefile that supports building the module using "make" with no arguments. @@ -470,9 +471,9 @@ build. The syntax of the Module.symvers file is:: - + - 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE + 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE The fields are separated by tabs and values may be empty (e.g. if no namespace is defined for an exported symbol). diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst index 503393854e2e2a..3b25655e441bc7 100644 --- a/Documentation/kbuild/reproducible-builds.rst +++ b/Documentation/kbuild/reproducible-builds.rst @@ -101,7 +101,7 @@ Structure randomisation If you enable ``CONFIG_GCC_PLUGIN_RANDSTRUCT``, you will need to pre-generate the random seed in -``scripts/gcc-plgins/randomize_layout_seed.h`` so the same value +``scripts/gcc-plugins/randomize_layout_seed.h`` so the same value is used in rebuilds. Debug info conflicts diff --git a/Documentation/mips/ingenic-tcu.rst b/Documentation/mips/ingenic-tcu.rst index c5a646b14450c6..2b75760619b43f 100644 --- a/Documentation/mips/ingenic-tcu.rst +++ b/Documentation/mips/ingenic-tcu.rst @@ -68,4 +68,4 @@ and frameworks can be controlled from the same registers, all of these drivers access their registers through the same regmap. For more information regarding the devicetree bindings of the TCU drivers, -have a look at Documentation/devicetree/bindings/timer/ingenic,tcu.txt. +have a look at Documentation/devicetree/bindings/timer/ingenic,tcu.yaml. diff --git a/Documentation/sound/designs/compress-offload.rst b/Documentation/sound/designs/compress-offload.rst index ad4bfbdacc8351..935f325dbc773a 100644 --- a/Documentation/sound/designs/compress-offload.rst +++ b/Documentation/sound/designs/compress-offload.rst @@ -151,6 +151,57 @@ Modifications include: - Addition of encoding options when required (derived from OpenMAX IL) - Addition of rateControlSupported (missing in OpenMAX AL) +State Machine +============= + +The compressed audio stream state machine is described below :: + + +----------+ + | | + | OPEN | + | | + +----------+ + | + | + | compr_set_params() + | + v + compr_free() +----------+ + +------------------------------------| | + | | SETUP | + | +-------------------------| |<-------------------------+ + | | compr_write() +----------+ | + | | ^ | + | | | compr_drain_notify() | + | | | or | + | | | compr_stop() | + | | | | + | | +----------+ | + | | | | | + | | | DRAIN | | + | | | | | + | | +----------+ | + | | ^ | + | | | | + | | | compr_drain() | + | | | | + | v | | + | +----------+ +----------+ | + | | | compr_start() | | compr_stop() | + | | PREPARE |------------------->| RUNNING |--------------------------+ + | | | | | | + | +----------+ +----------+ | + | | | ^ | + | |compr_free() | | | + | | compr_pause() | | compr_resume() | + | | | | | + | v v | | + | +----------+ +----------+ | + | | | | | compr_stop() | + +--->| FREE | | PAUSE |---------------------------+ + | | | | + +----------+ +----------+ + Gapless Playback ================ @@ -199,6 +250,38 @@ Sequence flow for gapless would be: (note: order for partial_drain and write for next track can be reversed as well) +Gapless Playback SM +=================== + +For Gapless, we move from running state to partial drain and back, along +with setting of meta_data and signalling for next track :: + + + +----------+ + compr_drain_notify() | | + +------------------------>| RUNNING | + | | | + | +----------+ + | | + | | + | | compr_next_track() + | | + | V + | +----------+ + | | | + | |NEXT_TRACK| + | | | + | +----------+ + | | + | | + | | compr_partial_drain() + | | + | V + | +----------+ + | | | + +------------------------ | PARTIAL_ | + | DRAIN | + +----------+ Not supported ============= diff --git a/MAINTAINERS b/MAINTAINERS index 496fd4eafb68cc..ad7110789463c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3946,7 +3946,7 @@ L: linux-crypto@vger.kernel.org S: Supported F: drivers/char/hw_random/cctrng.c F: drivers/char/hw_random/cctrng.h -F: Documentation/devicetree/bindings/rng/arm-cctrng.txt +F: Documentation/devicetree/bindings/rng/arm-cctrng.yaml W: https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family CEC FRAMEWORK @@ -5490,7 +5490,7 @@ F: include/uapi/drm/r128_drm.h DRM DRIVER FOR RAYDIUM RM67191 PANELS M: Robert Chiras S: Maintained -F: Documentation/devicetree/bindings/display/panel/raydium,rm67191.txt +F: Documentation/devicetree/bindings/display/panel/raydium,rm67191.yaml F: drivers/gpu/drm/panel/panel-raydium-rm67191.c DRM DRIVER FOR ROCKTECH JH057N00900 PANELS @@ -6956,6 +6956,7 @@ M: Timur Tabi M: Nicolin Chen M: Xiubo Li R: Fabio Estevam +R: Shengjiu Wang L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: linuxppc-dev@lists.ozlabs.org S: Maintained @@ -11333,17 +11334,17 @@ F: drivers/iio/adc/at91-sama5d2_adc.c F: include/dt-bindings/iio/adc/at91-sama5d2_adc.h MICROCHIP SAMA5D2-COMPATIBLE SHUTDOWN CONTROLLER -M: Nicolas Ferre +M: Claudiu Beznea S: Supported F: drivers/power/reset/at91-sama5d2_shdwc.c MICROCHIP SPI DRIVER -M: Nicolas Ferre +M: Tudor Ambarus S: Supported F: drivers/spi/spi-atmel.* MICROCHIP SSC DRIVER -M: Nicolas Ferre +M: Codrin Ciubotariu L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: drivers/misc/atmel-ssc.c @@ -14574,8 +14575,8 @@ RENESAS R-CAR THERMAL DRIVERS M: Niklas Söderlund L: linux-renesas-soc@vger.kernel.org S: Supported -F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt -F: Documentation/devicetree/bindings/thermal/rcar-thermal.txt +F: Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.yaml +F: Documentation/devicetree/bindings/thermal/rcar-thermal.yaml F: drivers/thermal/rcar_gen3_thermal.c F: drivers/thermal/rcar_thermal.c diff --git a/Makefile b/Makefile index a60c98519c37bc..fe0164a654c769 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 8 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Kleptomaniac Octopus # *DOCUMENTATION* @@ -970,8 +970,8 @@ LDFLAGS_vmlinux += --pack-dyn-relocs=relr endif # Align the bit size of userspace programs with the kernel -KBUILD_USERCFLAGS += $(filter -m32 -m64, $(KBUILD_CFLAGS)) -KBUILD_USERLDFLAGS += $(filter -m32 -m64, $(KBUILD_CFLAGS)) +KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) +KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CFLAGS)) # make the checker run with the right architecture CHECKFLAGS += --arch=$(ARCH) diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi index 06fbffa81636b3..1990239cc6af6c 100644 --- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi +++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi @@ -140,13 +140,13 @@ compatible = "audio-graph-card"; label = "Droid 4 Audio"; - simple-graph-card,widgets = + widgets = "Speaker", "Earpiece", "Speaker", "Loudspeaker", "Headphone", "Headphone Jack", "Microphone", "Internal Mic"; - simple-graph-card,routing = + routing = "Earpiece", "EP", "Loudspeaker", "SPKR", "Headphone Jack", "HSL", diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index fd4e1ce1daf96a..e93145d72c26e0 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -241,7 +241,6 @@ static int __init fdt_find_hyper_node(unsigned long node, const char *uname, * see Documentation/devicetree/bindings/arm/xen.txt for the * documentation of the Xen Device Tree format. */ -#define GRANT_TABLE_PHYSADDR 0 void __init xen_early_init(void) { of_scan_flat_dt(fdt_find_hyper_node, NULL); diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h index 5e5dc05d63a064..12f0eb56a1cc30 100644 --- a/arch/arm64/include/asm/alternative.h +++ b/arch/arm64/include/asm/alternative.h @@ -73,11 +73,11 @@ static inline void apply_alternatives_module(void *start, size_t length) { } ".pushsection .altinstructions,\"a\"\n" \ ALTINSTR_ENTRY(feature) \ ".popsection\n" \ - ".pushsection .altinstr_replacement, \"a\"\n" \ + ".subsection 1\n" \ "663:\n\t" \ newinstr "\n" \ "664:\n\t" \ - ".popsection\n\t" \ + ".previous\n\t" \ ".org . - (664b-663b) + (662b-661b)\n\t" \ ".org . - (662b-661b) + (664b-663b)\n" \ ".endif\n" @@ -117,9 +117,9 @@ static inline void apply_alternatives_module(void *start, size_t length) { } 662: .pushsection .altinstructions, "a" altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f .popsection - .pushsection .altinstr_replacement, "ax" + .subsection 1 663: \insn2 -664: .popsection +664: .previous .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) .endif @@ -160,7 +160,7 @@ static inline void apply_alternatives_module(void *start, size_t length) { } .pushsection .altinstructions, "a" altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f .popsection - .pushsection .altinstr_replacement, "ax" + .subsection 1 .align 2 /* So GAS knows label 661 is suitably aligned */ 661: .endm @@ -179,9 +179,9 @@ static inline void apply_alternatives_module(void *start, size_t length) { } .macro alternative_else 662: .if .Lasm_alt_mode==0 - .pushsection .altinstr_replacement, "ax" + .subsection 1 .else - .popsection + .previous .endif 663: .endm @@ -192,7 +192,7 @@ static inline void apply_alternatives_module(void *start, size_t length) { } .macro alternative_endif 664: .if .Lasm_alt_mode==0 - .popsection + .previous .endif .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index a87a93f67671d9..7219cddeba669f 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -86,6 +86,7 @@ #define QCOM_CPU_PART_FALKOR 0xC00 #define QCOM_CPU_PART_KRYO 0x200 #define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803 +#define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804 #define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805 #define NVIDIA_CPU_PART_DENVER 0x003 @@ -114,6 +115,7 @@ #define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER) +#define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD) #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER) #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER) #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index cf50c53e9357ea..8e302dc093d09e 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -472,12 +472,7 @@ static bool has_cortex_a76_erratum_1463225(const struct arm64_cpu_capabilities *entry, int scope) { - u32 midr = read_cpuid_id(); - /* Cortex-A76 r0p0 - r3p1 */ - struct midr_range range = MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1); - - WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); - return is_midr_in_range(midr, &range) && is_kernel_in_hyp_mode(); + return is_affected_midr_range_list(entry, scope) && is_kernel_in_hyp_mode(); } #endif @@ -728,6 +723,8 @@ static const struct midr_range erratum_1418040_list[] = { MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1), /* Neoverse-N1 r0p0 to r3p1 */ MIDR_RANGE(MIDR_NEOVERSE_N1, 0, 0, 3, 1), + /* Kryo4xx Gold (rcpe to rfpf) => (r0p0 to r3p1) */ + MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xf), {}, }; #endif @@ -772,11 +769,22 @@ static const struct midr_range erratum_speculative_at_list[] = { #ifdef CONFIG_ARM64_ERRATUM_1530923 /* Cortex A55 r0p0 to r2p0 */ MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 2, 0), + /* Kryo4xx Silver (rdpe => r1p0) */ + MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe), #endif {}, }; #endif +#ifdef CONFIG_ARM64_ERRATUM_1463225 +static const struct midr_range erratum_1463225[] = { + /* Cortex-A76 r0p0 - r3p1 */ + MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1), + /* Kryo4xx Gold (rcpe to rfpf) => (r0p0 to r3p1) */ + MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xf), +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -916,6 +924,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .capability = ARM64_WORKAROUND_1463225, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = has_cortex_a76_erratum_1463225, + .midr_range_list = erratum_1463225, }, #endif #ifdef CONFIG_CAVIUM_TX2_ERRATUM_219 diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9f63053a63a981..9fae0efc80c176 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1408,6 +1408,8 @@ static bool cpu_has_broken_dbm(void) static const struct midr_range cpus[] = { #ifdef CONFIG_ARM64_ERRATUM_1024718 MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 1, 0), // A55 r0p0 -r1p0 + /* Kryo4xx Silver (rdpe => r1p0) */ + MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe), #endif {}, }; diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index cbe49cd117cfec..5290f17a4d8041 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c @@ -122,7 +122,7 @@ void *alloc_insn_page(void) { return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS, - NUMA_NO_NODE, __func__); + NUMA_NO_NODE, __builtin_return_address(0)); } /* arm kprobe: install breakpoint in text */ diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 6827da7f3aa54c..5423ffe0a98760 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -165,9 +165,6 @@ SECTIONS *(.altinstructions) __alt_instructions_end = .; } - .altinstr_replacement : { - *(.altinstr_replacement) - } . = ALIGN(SEGMENT_ALIGN); __inittext_end = .; diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c index e779b19e01939b..f66f4b1d062ed6 100644 --- a/arch/m68k/kernel/setup_no.c +++ b/arch/m68k/kernel/setup_no.c @@ -138,7 +138,8 @@ void __init setup_arch(char **cmdline_p) pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ", __bss_stop, memory_start, memory_start, memory_end); - memblock_add(memory_start, memory_end - memory_start); + memblock_add(_rambase, memory_end - _rambase); + memblock_reserve(_rambase, memory_start - _rambase); /* Keep a copy of command line */ *cmdline_p = &command_line[0]; diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c index 29f47923aa4629..7d04210d34f026 100644 --- a/arch/m68k/mm/mcfmmu.c +++ b/arch/m68k/mm/mcfmmu.c @@ -174,7 +174,7 @@ void __init cf_bootmem_alloc(void) m68k_memory[0].addr = _rambase; m68k_memory[0].size = _ramend - _rambase; - memblock_add(m68k_memory[0].addr, m68k_memory[0].size); + memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0); /* compute total pages in system */ num_pages = PFN_DOWN(_ramend - _rambase); diff --git a/arch/mips/boot/dts/ingenic/gcw0.dts b/arch/mips/boot/dts/ingenic/gcw0.dts index 8d22828787d8c1..bc72304a2440bf 100644 --- a/arch/mips/boot/dts/ingenic/gcw0.dts +++ b/arch/mips/boot/dts/ingenic/gcw0.dts @@ -92,7 +92,7 @@ "MIC1N", "Built-in Mic"; simple-audio-card,pin-switches = "Speaker", "Headphones"; - simple-audio-card,hp-det-gpio = <&gpf 21 GPIO_ACTIVE_HIGH>; + simple-audio-card,hp-det-gpio = <&gpf 21 GPIO_ACTIVE_LOW>; simple-audio-card,aux-devs = <&speaker_amp>, <&headphones_amp>; simple-audio-card,bitclock-master = <&dai_codec>; diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 7c32c956156a0c..f655af68176c85 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -723,12 +723,14 @@ static int simulate_loongson3_cpucfg(struct pt_regs *regs, perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); /* Do not emulate on unsupported core models. */ - if (!loongson3_cpucfg_emulation_enabled(¤t_cpu_data)) + preempt_disable(); + if (!loongson3_cpucfg_emulation_enabled(¤t_cpu_data)) { + preempt_enable(); return -1; - + } regs->regs[rd] = loongson3_cpucfg_read_synthesized( ¤t_cpu_data, sel); - + preempt_enable(); return 0; } @@ -2169,6 +2171,7 @@ static void configure_status(void) change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, status_set); + back_to_back_c0_hazard(); } unsigned int hwrena; diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index aa37545ebe8f72..b10342018d199a 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -514,8 +514,8 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP | PMU_PPE_TC); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); - clkdev_add_pmu("1e108000.gswip", "gphy0", 0, 0, PMU_GPHY); - clkdev_add_pmu("1e108000.gswip", "gphy1", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); @@ -538,8 +538,8 @@ void __init ltq_soc_init(void) PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | PMU_PPE_QSB | PMU_PPE_TOP); - clkdev_add_pmu("1e108000.gswip", "gphy0", 0, 0, PMU_GPHY); - clkdev_add_pmu("1e108000.gswip", "gphy1", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index 1199fc2bfaec91..ca5fcb4bff3260 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -353,9 +353,6 @@ static bool pkey_access_permitted(int pkey, bool write, bool execute) int pkey_shift; u64 amr; - if (!is_pkey_enabled(pkey)) - return true; - pkey_shift = pkeyshift(pkey); if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift))) return true; diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index bd3f14175193c3..e83b3f14897cc4 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -45,6 +45,32 @@ #define CREATE_TRACE_POINTS #include +/* Check that the stack and regs on entry from user mode are sane. */ +static void check_user_regs(struct pt_regs *regs) +{ + if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) { + /* + * Make sure that the entry code gave us a sensible EFLAGS + * register. Native because we want to check the actual CPU + * state, not the interrupt state as imagined by Xen. + */ + unsigned long flags = native_save_fl(); + WARN_ON_ONCE(flags & (X86_EFLAGS_AC | X86_EFLAGS_DF | + X86_EFLAGS_NT)); + + /* We think we came from user mode. Make sure pt_regs agrees. */ + WARN_ON_ONCE(!user_mode(regs)); + + /* + * All entries from user mode (except #DF) should be on the + * normal thread stack and should have user pt_regs in the + * correct location. + */ + WARN_ON_ONCE(!on_thread_stack()); + WARN_ON_ONCE(regs != task_pt_regs(current)); + } +} + #ifdef CONFIG_CONTEXT_TRACKING /** * enter_from_user_mode - Establish state when coming from user mode @@ -127,9 +153,6 @@ static long syscall_trace_enter(struct pt_regs *regs) unsigned long ret = 0; u32 work; - if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) - BUG_ON(regs != task_pt_regs(current)); - work = READ_ONCE(ti->flags); if (work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) { @@ -346,6 +369,8 @@ __visible noinstr void do_syscall_64(unsigned long nr, struct pt_regs *regs) { struct thread_info *ti; + check_user_regs(regs); + enter_from_user_mode(); instrumentation_begin(); @@ -409,6 +434,8 @@ static void do_syscall_32_irqs_on(struct pt_regs *regs) /* Handles int $0x80 */ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) { + check_user_regs(regs); + enter_from_user_mode(); instrumentation_begin(); @@ -460,6 +487,8 @@ __visible noinstr long do_fast_syscall_32(struct pt_regs *regs) vdso_image_32.sym_int80_landing_pad; bool success; + check_user_regs(regs); + /* * SYSENTER loses EIP, and even SYSCALL32 needs us to skip forward * so that 'regs->ip -= 2' lands back on an int $0x80 instruction. @@ -510,6 +539,18 @@ __visible noinstr long do_fast_syscall_32(struct pt_regs *regs) (regs->flags & (X86_EFLAGS_RF | X86_EFLAGS_TF | X86_EFLAGS_VM)) == 0; #endif } + +/* Returns 0 to return using IRET or 1 to return using SYSEXIT/SYSRETL. */ +__visible noinstr long do_SYSENTER_32(struct pt_regs *regs) +{ + /* SYSENTER loses RSP, but the vDSO saved it in RBP. */ + regs->sp = regs->bp; + + /* SYSENTER clobbers EFLAGS.IF. Assume it was set in usermode. */ + regs->flags |= X86_EFLAGS_IF; + + return do_fast_syscall_32(regs); +} #endif SYSCALL_DEFINE0(ni_syscall) @@ -553,6 +594,7 @@ SYSCALL_DEFINE0(ni_syscall) bool noinstr idtentry_enter_cond_rcu(struct pt_regs *regs) { if (user_mode(regs)) { + check_user_regs(regs); enter_from_user_mode(); return false; } @@ -686,6 +728,7 @@ void noinstr idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit) */ void noinstr idtentry_enter_user(struct pt_regs *regs) { + check_user_regs(regs); enter_from_user_mode(); } diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 024d7d276cd40b..2d0bd5d5f0328d 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -933,9 +933,8 @@ SYM_FUNC_START(entry_SYSENTER_32) .Lsysenter_past_esp: pushl $__USER_DS /* pt_regs->ss */ - pushl %ebp /* pt_regs->sp (stashed in bp) */ + pushl $0 /* pt_regs->sp (placeholder) */ pushfl /* pt_regs->flags (except IF = 0) */ - orl $X86_EFLAGS_IF, (%esp) /* Fix IF */ pushl $__USER_CS /* pt_regs->cs */ pushl $0 /* pt_regs->ip = 0 (placeholder) */ pushl %eax /* pt_regs->orig_ax */ @@ -965,7 +964,7 @@ SYM_FUNC_START(entry_SYSENTER_32) .Lsysenter_flags_fixed: movl %esp, %eax - call do_fast_syscall_32 + call do_SYSENTER_32 /* XEN PV guests always use IRET path */ ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \ "jmp .Lsyscall_32_done", X86_FEATURE_XENPV diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 0f974ae01e62b8..541fdaf6404533 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -57,29 +57,30 @@ SYM_CODE_START(entry_SYSENTER_compat) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp - /* - * User tracing code (ptrace or signal handlers) might assume that - * the saved RAX contains a 32-bit number when we're invoking a 32-bit - * syscall. Just in case the high bits are nonzero, zero-extend - * the syscall number. (This could almost certainly be deleted - * with no ill effects.) - */ - movl %eax, %eax - /* Construct struct pt_regs on stack */ pushq $__USER32_DS /* pt_regs->ss */ - pushq %rbp /* pt_regs->sp (stashed in bp) */ + pushq $0 /* pt_regs->sp = 0 (placeholder) */ /* * Push flags. This is nasty. First, interrupts are currently - * off, but we need pt_regs->flags to have IF set. Second, even - * if TF was set when SYSENTER started, it's clear by now. We fix - * that later using TIF_SINGLESTEP. + * off, but we need pt_regs->flags to have IF set. Second, if TS + * was set in usermode, it's still set, and we're singlestepping + * through this code. do_SYSENTER_32() will fix up IF. */ pushfq /* pt_regs->flags (except IF = 0) */ - orl $X86_EFLAGS_IF, (%rsp) /* Fix saved flags */ pushq $__USER32_CS /* pt_regs->cs */ pushq $0 /* pt_regs->ip = 0 (placeholder) */ +SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL) + + /* + * User tracing code (ptrace or signal handlers) might assume that + * the saved RAX contains a 32-bit number when we're invoking a 32-bit + * syscall. Just in case the high bits are nonzero, zero-extend + * the syscall number. (This could almost certainly be deleted + * with no ill effects.) + */ + movl %eax, %eax + pushq %rax /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -135,7 +136,7 @@ SYM_CODE_START(entry_SYSENTER_compat) .Lsysenter_flags_fixed: movq %rsp, %rdi - call do_fast_syscall_32 + call do_SYSENTER_32 /* XEN PV guests always use IRET path */ ALTERNATIVE "testl %eax, %eax; jz swapgs_restore_regs_and_return_to_usermode", \ "jmp swapgs_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 2bdc72e6890eca..6035df1b49e1a7 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -377,7 +377,8 @@ void __init hyperv_init(void) hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX, - VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, __func__); + VM_FLUSH_RESET_PERMS, NUMA_NO_NODE, + __builtin_return_address(0)); if (hv_hypercall_pg == NULL) { wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); goto remove_cpuhp_state; diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 42159f45bf9c42..845e7481ab776e 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -623,6 +623,11 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) * MXCSR and XCR definitions: */ +static inline void ldmxcsr(u32 mxcsr) +{ + asm volatile("ldmxcsr %0" :: "m" (mxcsr)); +} + extern unsigned int mxcsr_feature_mask; #define XCR_XFEATURE_ENABLED_MASK 0x00000000 diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h index cf51c50eb356dd..eeac6dc2adaa3b 100644 --- a/arch/x86/include/asm/idtentry.h +++ b/arch/x86/include/asm/idtentry.h @@ -353,10 +353,6 @@ static __always_inline void __##func(struct pt_regs *regs) #else /* CONFIG_X86_64 */ -/* Maps to a regular IDTENTRY on 32bit for now */ -# define DECLARE_IDTENTRY_IST DECLARE_IDTENTRY -# define DEFINE_IDTENTRY_IST DEFINE_IDTENTRY - /** * DECLARE_IDTENTRY_DF - Declare functions for double fault 32bit variant * @vector: Vector number (ignored for C) @@ -387,28 +383,18 @@ __visible noinstr void func(struct pt_regs *regs, \ #endif /* !CONFIG_X86_64 */ /* C-Code mapping */ +#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW +#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW + +#ifdef CONFIG_X86_64 #define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST #define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST #define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST -#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW -#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW - #define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST #define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST #define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST - -/** - * DECLARE_IDTENTRY_XEN - Declare functions for XEN redirect IDT entry points - * @vector: Vector number (ignored for C) - * @func: Function name of the entry point - * - * Used for xennmi and xendebug redirections. No DEFINE as this is all ASM - * indirection magic. - */ -#define DECLARE_IDTENTRY_XEN(vector, func) \ - asmlinkage void xen_asm_exc_xen##func(void); \ - asmlinkage void asm_exc_xen##func(void) +#endif #else /* !__ASSEMBLY__ */ @@ -455,9 +441,6 @@ __visible noinstr void func(struct pt_regs *regs, \ # define DECLARE_IDTENTRY_MCE(vector, func) \ DECLARE_IDTENTRY(vector, func) -# define DECLARE_IDTENTRY_DEBUG(vector, func) \ - DECLARE_IDTENTRY(vector, func) - /* No ASM emitted for DF as this goes through a C shim */ # define DECLARE_IDTENTRY_DF(vector, func) @@ -469,10 +452,6 @@ __visible noinstr void func(struct pt_regs *regs, \ /* No ASM code emitted for NMI */ #define DECLARE_IDTENTRY_NMI(vector, func) -/* XEN NMI and DB wrapper */ -#define DECLARE_IDTENTRY_XEN(vector, func) \ - idtentry vector asm_exc_xen##func exc_##func has_error_code=0 - /* * ASM code to emit the common vector entry stubs where each stub is * packed into 8 bytes. @@ -565,16 +544,28 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault); #ifdef CONFIG_X86_MCE +#ifdef CONFIG_X86_64 DECLARE_IDTENTRY_MCE(X86_TRAP_MC, exc_machine_check); +#else +DECLARE_IDTENTRY_RAW(X86_TRAP_MC, exc_machine_check); +#endif #endif /* NMI */ DECLARE_IDTENTRY_NMI(X86_TRAP_NMI, exc_nmi); -DECLARE_IDTENTRY_XEN(X86_TRAP_NMI, nmi); +#ifdef CONFIG_XEN_PV +DECLARE_IDTENTRY_RAW(X86_TRAP_NMI, xenpv_exc_nmi); +#endif /* #DB */ +#ifdef CONFIG_X86_64 DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB, exc_debug); -DECLARE_IDTENTRY_XEN(X86_TRAP_DB, debug); +#else +DECLARE_IDTENTRY_RAW(X86_TRAP_DB, exc_debug); +#endif +#ifdef CONFIG_XEN_PV +DECLARE_IDTENTRY_RAW(X86_TRAP_DB, xenpv_exc_debug); +#endif /* #DF */ DECLARE_IDTENTRY_DF(X86_TRAP_DF, exc_double_fault); diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index c25a67a34bd3d9..0ab48f1cdf848f 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -49,6 +49,13 @@ enum split_lock_detect_state { static enum split_lock_detect_state sld_state __ro_after_init = sld_off; static u64 msr_test_ctrl_cache __ro_after_init; +/* + * With a name like MSR_TEST_CTL it should go without saying, but don't touch + * MSR_TEST_CTL unless the CPU is one of the whitelisted models. Writing it + * on CPUs that do not support SLD can cause fireworks, even when writing '0'. + */ +static bool cpu_model_supports_sld __ro_after_init; + /* * Processors which have self-snooping capability can handle conflicting * memory type across CPUs by snooping its own cache. However, there exists @@ -1071,7 +1078,8 @@ static void sld_update_msr(bool on) static void split_lock_init(void) { - split_lock_verify_msr(sld_state != sld_off); + if (cpu_model_supports_sld) + split_lock_verify_msr(sld_state != sld_off); } static void split_lock_warn(unsigned long ip) @@ -1177,5 +1185,6 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) return; } + cpu_model_supports_sld = true; split_lock_setup(); } diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index fbe89a92ff361d..14e4b4d17ee5bc 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -1901,6 +1901,8 @@ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check; static __always_inline void exc_machine_check_kernel(struct pt_regs *regs) { + WARN_ON_ONCE(user_mode(regs)); + /* * Only required when from kernel mode. See * mce_check_crashing_cpu() for details. @@ -1954,7 +1956,7 @@ DEFINE_IDTENTRY_MCE_USER(exc_machine_check) } #else /* 32bit unified entry point */ -DEFINE_IDTENTRY_MCE(exc_machine_check) +DEFINE_IDTENTRY_RAW(exc_machine_check) { unsigned long dr7; diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 06c818967bb637..15247b96c6eaaa 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -101,6 +101,12 @@ void kernel_fpu_begin(void) copy_fpregs_to_fpstate(¤t->thread.fpu); } __cpu_invalidate_fpregs_state(); + + if (boot_cpu_has(X86_FEATURE_XMM)) + ldmxcsr(MXCSR_DEFAULT); + + if (boot_cpu_has(X86_FEATURE_FPU)) + asm volatile ("fninit"); } EXPORT_SYMBOL_GPL(kernel_fpu_begin); diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 8748321c448674..b8aee71840ae50 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -29,6 +29,8 @@ #include #include +#include + /* This is a multiple of PAGE_SIZE. */ #define LDT_SLOT_STRIDE (LDT_ENTRIES * LDT_ENTRY_SIZE) @@ -543,6 +545,28 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount) return bytecount; } +static bool allow_16bit_segments(void) +{ + if (!IS_ENABLED(CONFIG_X86_16BIT)) + return false; + +#ifdef CONFIG_XEN_PV + /* + * Xen PV does not implement ESPFIX64, which means that 16-bit + * segments will not work correctly. Until either Xen PV implements + * ESPFIX64 and can signal this fact to the guest or unless someone + * provides compelling evidence that allowing broken 16-bit segments + * is worthwhile, disallow 16-bit segments under Xen PV. + */ + if (xen_pv_domain()) { + pr_info_once("Warning: 16-bit segments do not work correctly in a Xen PV guest\n"); + return false; + } +#endif + + return true; +} + static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) { struct mm_struct *mm = current->mm; @@ -574,7 +598,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) /* The user wants to clear the entry. */ memset(&ldt, 0, sizeof(ldt)); } else { - if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) { + if (!ldt_info.seg_32bit && !allow_16bit_segments()) { error = -EINVAL; goto out; } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index f58679e487f6ca..b038695f36c5e4 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -869,6 +869,12 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, instrumentation_begin(); trace_hardirqs_off_finish(); + /* + * If something gets miswired and we end up here for a user mode + * #DB, we will malfunction. + */ + WARN_ON_ONCE(user_mode(regs)); + /* * Catch SYSENTER with TF set and clear DR_STEP. If this hit a * watchpoint at the same time then that will still be handled. @@ -887,6 +893,12 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, static __always_inline void exc_debug_user(struct pt_regs *regs, unsigned long dr6) { + /* + * If something gets miswired and we end up here for a kernel mode + * #DB, we will malfunction. + */ + WARN_ON_ONCE(!user_mode(regs)); + idtentry_enter_user(regs); instrumentation_begin(); @@ -917,7 +929,7 @@ DEFINE_IDTENTRY_DEBUG_USER(exc_debug) } #else /* 32 bit does not have separate entry points. */ -DEFINE_IDTENTRY_DEBUG(exc_debug) +DEFINE_IDTENTRY_RAW(exc_debug) { unsigned long dr6, dr7; diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index acc49fa6a0971d..0d68948c82ad6f 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -598,6 +598,26 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum, } #ifdef CONFIG_X86_64 +void noist_exc_debug(struct pt_regs *regs); + +DEFINE_IDTENTRY_RAW(xenpv_exc_nmi) +{ + /* On Xen PV, NMI doesn't use IST. The C part is the sane as native. */ + exc_nmi(regs); +} + +DEFINE_IDTENTRY_RAW(xenpv_exc_debug) +{ + /* + * There's no IST on Xen PV, but we still need to dispatch + * to the correct handler. + */ + if (user_mode(regs)) + noist_exc_debug(regs); + else + exc_debug(regs); +} + struct trap_array_entry { void (*orig)(void); void (*xen)(void); @@ -609,18 +629,18 @@ struct trap_array_entry { .xen = xen_asm_##func, \ .ist_okay = ist_ok } -#define TRAP_ENTRY_REDIR(func, xenfunc, ist_ok) { \ +#define TRAP_ENTRY_REDIR(func, ist_ok) { \ .orig = asm_##func, \ - .xen = xen_asm_##xenfunc, \ + .xen = xen_asm_xenpv_##func, \ .ist_okay = ist_ok } static struct trap_array_entry trap_array[] = { - TRAP_ENTRY_REDIR(exc_debug, exc_xendebug, true ), + TRAP_ENTRY_REDIR(exc_debug, true ), TRAP_ENTRY(exc_double_fault, true ), #ifdef CONFIG_X86_MCE TRAP_ENTRY(exc_machine_check, true ), #endif - TRAP_ENTRY_REDIR(exc_nmi, exc_xennmi, true ), + TRAP_ENTRY_REDIR(exc_nmi, true ), TRAP_ENTRY(exc_int3, false ), TRAP_ENTRY(exc_overflow, false ), #ifdef CONFIG_IA32_EMULATION diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index 5d252aaeade8b3..aab1d99b2b480b 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S @@ -29,10 +29,9 @@ _ASM_NOKPROBE(xen_\name) .endm xen_pv_trap asm_exc_divide_error -xen_pv_trap asm_exc_debug -xen_pv_trap asm_exc_xendebug +xen_pv_trap asm_xenpv_exc_debug xen_pv_trap asm_exc_int3 -xen_pv_trap asm_exc_xennmi +xen_pv_trap asm_xenpv_exc_nmi xen_pv_trap asm_exc_overflow xen_pv_trap asm_exc_bounds xen_pv_trap asm_exc_invalid_op @@ -161,10 +160,22 @@ SYM_FUNC_END(xen_syscall32_target) /* 32-bit compat sysenter target */ SYM_FUNC_START(xen_sysenter_target) - mov 0*8(%rsp), %rcx - mov 1*8(%rsp), %r11 - mov 5*8(%rsp), %rsp - jmp entry_SYSENTER_compat + /* + * NB: Xen is polite and clears TF from EFLAGS for us. This means + * that we don't need to guard against single step exceptions here. + */ + popq %rcx + popq %r11 + + /* + * Neither Xen nor the kernel really knows what the old SS and + * CS were. The kernel expects __USER32_DS and __USER32_CS, so + * report those values even though Xen will guess its own values. + */ + movq $__USER32_DS, 4*8(%rsp) + movq $__USER32_CS, 1*8(%rsp) + + jmp entry_SYSENTER_compat_after_hwframe SYM_FUNC_END(xen_sysenter_target) #else /* !CONFIG_IA32_EMULATION */ diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 4707e90b8ee55f..9ffd7e28955476 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -24,7 +24,8 @@ void blk_flush_integrity(void) flush_workqueue(kintegrityd_wq); } -void __bio_integrity_free(struct bio_set *bs, struct bio_integrity_payload *bip) +static void __bio_integrity_free(struct bio_set *bs, + struct bio_integrity_payload *bip) { if (bs && mempool_initialized(&bs->bio_integrity_pool)) { if (bip->bip_vec) diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 15df3a36e9fa43..e0b2bc131bf546 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -125,6 +125,9 @@ static const char *const blk_queue_flag_name[] = { QUEUE_FLAG_NAME(REGISTERED), QUEUE_FLAG_NAME(SCSI_PASSTHROUGH), QUEUE_FLAG_NAME(QUIESCED), + QUEUE_FLAG_NAME(PCI_P2PDMA), + QUEUE_FLAG_NAME(ZONE_RESETALL), + QUEUE_FLAG_NAME(RQ_ALLOC_TIME), }; #undef QUEUE_FLAG_NAME diff --git a/block/keyslot-manager.c b/block/keyslot-manager.c index c2ef41b3147ba9..35abcb1ec051d5 100644 --- a/block/keyslot-manager.c +++ b/block/keyslot-manager.c @@ -374,8 +374,7 @@ void blk_ksm_destroy(struct blk_keyslot_manager *ksm) if (!ksm) return; kvfree(ksm->slot_hashtable); - memzero_explicit(ksm->slots, sizeof(ksm->slots[0]) * ksm->num_slots); - kvfree(ksm->slots); + kvfree_sensitive(ksm->slots, sizeof(ksm->slots[0]) * ksm->num_slots); memzero_explicit(ksm, sizeof(*ksm)); } EXPORT_SYMBOL_GPL(blk_ksm_destroy); diff --git a/crypto/af_alg.c b/crypto/af_alg.c index b1cd3535c52560..28fc323e3fe304 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -128,21 +128,15 @@ EXPORT_SYMBOL_GPL(af_alg_release); void af_alg_release_parent(struct sock *sk) { struct alg_sock *ask = alg_sk(sk); - unsigned int nokey = ask->nokey_refcnt; - bool last = nokey && !ask->refcnt; + unsigned int nokey = atomic_read(&ask->nokey_refcnt); sk = ask->parent; ask = alg_sk(sk); - local_bh_disable(); - bh_lock_sock(sk); - ask->nokey_refcnt -= nokey; - if (!last) - last = !--ask->refcnt; - bh_unlock_sock(sk); - local_bh_enable(); + if (nokey) + atomic_dec(&ask->nokey_refcnt); - if (last) + if (atomic_dec_and_test(&ask->refcnt)) sock_put(sk); } EXPORT_SYMBOL_GPL(af_alg_release_parent); @@ -187,7 +181,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = -EBUSY; lock_sock(sk); - if (ask->refcnt | ask->nokey_refcnt) + if (atomic_read(&ask->refcnt)) goto unlock; swap(ask->type, type); @@ -236,7 +230,7 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, int err = -EBUSY; lock_sock(sk); - if (ask->refcnt) + if (atomic_read(&ask->refcnt) != atomic_read(&ask->nokey_refcnt)) goto unlock; type = ask->type; @@ -301,12 +295,14 @@ int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern) if (err) goto unlock; - if (nokey || !ask->refcnt++) + if (atomic_inc_return_relaxed(&ask->refcnt) == 1) sock_hold(sk); - ask->nokey_refcnt += nokey; + if (nokey) { + atomic_inc(&ask->nokey_refcnt); + atomic_set(&alg_sk(sk2)->nokey_refcnt, 1); + } alg_sk(sk2)->parent = sk; alg_sk(sk2)->type = type; - alg_sk(sk2)->nokey_refcnt = nokey; newsock->ops = type->ops; newsock->state = SS_CONNECTED; diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index eb1910b6d434c8..0ae000a61c7f5b 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -384,7 +384,7 @@ static int aead_check_key(struct socket *sock) struct alg_sock *ask = alg_sk(sk); lock_sock(sk); - if (ask->refcnt) + if (!atomic_read(&ask->nokey_refcnt)) goto unlock_child; psk = ask->parent; @@ -396,11 +396,8 @@ static int aead_check_key(struct socket *sock) if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY) goto unlock; - if (!pask->refcnt++) - sock_hold(psk); - - ask->refcnt = 1; - sock_put(psk); + atomic_dec(&pask->nokey_refcnt); + atomic_set(&ask->nokey_refcnt, 0); err = 0; diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index da1ffa4f7f8daf..e71727c25a7db7 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -301,7 +301,7 @@ static int hash_check_key(struct socket *sock) struct alg_sock *ask = alg_sk(sk); lock_sock(sk); - if (ask->refcnt) + if (!atomic_read(&ask->nokey_refcnt)) goto unlock_child; psk = ask->parent; @@ -313,11 +313,8 @@ static int hash_check_key(struct socket *sock) if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) goto unlock; - if (!pask->refcnt++) - sock_hold(psk); - - ask->refcnt = 1; - sock_put(psk); + atomic_dec(&pask->nokey_refcnt); + atomic_set(&ask->nokey_refcnt, 0); err = 0; diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 4c3bdffe0c3a57..ec5567c87a6df4 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -211,7 +211,7 @@ static int skcipher_check_key(struct socket *sock) struct alg_sock *ask = alg_sk(sk); lock_sock(sk); - if (ask->refcnt) + if (!atomic_read(&ask->nokey_refcnt)) goto unlock_child; psk = ask->parent; @@ -223,11 +223,8 @@ static int skcipher_check_key(struct socket *sock) if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) goto unlock; - if (!pask->refcnt++) - sock_hold(psk); - - ask->refcnt = 1; - sock_put(psk); + atomic_dec(&pask->nokey_refcnt); + atomic_set(&ask->nokey_refcnt, 0); err = 0; diff --git a/drivers/acpi/dptf/dptf_power.c b/drivers/acpi/dptf/dptf_power.c index 5fab7e350db877..92b996a564d0f9 100644 --- a/drivers/acpi/dptf/dptf_power.c +++ b/drivers/acpi/dptf/dptf_power.c @@ -228,6 +228,7 @@ static const struct acpi_device_id int3407_device_ids[] = { {"INT3407", 0}, {"INT3532", 0}, {"INTC1047", 0}, + {"INTC1050", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, int3407_device_ids); diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 873e039ad4b705..62873388b24f7d 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -25,8 +25,8 @@ static int acpi_fan_remove(struct platform_device *pdev); static const struct acpi_device_id fan_device_ids[] = { {"PNP0C0B", 0}, - {"INT1044", 0}, {"INT3404", 0}, + {"INTC1044", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, fan_device_ids); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 9d21bf0f155eed..980df853ee4970 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -878,6 +878,7 @@ static int virtblk_probe(struct virtio_device *vdev) put_disk(vblk->disk); out_free_vq: vdev->config->del_vqs(vdev); + kfree(vblk->vqs); out_free_vblk: kfree(vblk); out_free_index: diff --git a/drivers/char/tpm/st33zp24/i2c.c b/drivers/char/tpm/st33zp24/i2c.c index 35333b65acd1a6..7c617edff4ca29 100644 --- a/drivers/char/tpm/st33zp24/i2c.c +++ b/drivers/char/tpm/st33zp24/i2c.c @@ -210,7 +210,7 @@ static int st33zp24_i2c_request_resources(struct i2c_client *client) /* * st33zp24_i2c_probe initialize the TPM device - * @param: client, the i2c_client drescription (TPM I2C description). + * @param: client, the i2c_client description (TPM I2C description). * @param: id, the i2c_device_id struct. * @return: 0 in case of success. * -1 in other case. diff --git a/drivers/char/tpm/st33zp24/spi.c b/drivers/char/tpm/st33zp24/spi.c index 26e09de50f1e01..a75dafd3944517 100644 --- a/drivers/char/tpm/st33zp24/spi.c +++ b/drivers/char/tpm/st33zp24/spi.c @@ -329,7 +329,7 @@ static int st33zp24_spi_request_resources(struct spi_device *dev) /* * st33zp24_spi_probe initialize the TPM device - * @param: dev, the spi_device drescription (TPM SPI description). + * @param: dev, the spi_device description (TPM SPI description). * @return: 0 in case of success. * or a negative value describing the error. */ @@ -378,7 +378,7 @@ static int st33zp24_spi_probe(struct spi_device *dev) /* * st33zp24_spi_remove remove the TPM device - * @param: client, the spi_device drescription (TPM SPI description). + * @param: client, the spi_device description (TPM SPI description). * @return: 0 in case of success. */ static int st33zp24_spi_remove(struct spi_device *dev) diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 37bb13f516be66..4ec10ab5e5766e 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -502,7 +502,7 @@ static const struct tpm_class_ops st33zp24_tpm = { /* * st33zp24_probe initialize the TPM device - * @param: client, the i2c_client drescription (TPM I2C description). + * @param: client, the i2c_client description (TPM I2C description). * @param: id, the i2c_device_id struct. * @return: 0 in case of success. * -1 in other case. diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index 87f4493402021b..1784530b8387bb 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, goto out; } - /* atomic tpm command send and result receive. We only hold the ops - * lock during this period so that the tpm can be unregistered even if - * the char dev is held open. - */ - if (tpm_try_get_ops(priv->chip)) { - ret = -EPIPE; - goto out; - } - priv->response_length = 0; priv->response_read = false; *off = 0; @@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf, if (file->f_flags & O_NONBLOCK) { priv->command_enqueued = true; queue_work(tpm_dev_wq, &priv->async_work); - tpm_put_ops(priv->chip); mutex_unlock(&priv->buffer_mutex); return size; } + /* atomic tpm command send and result receive. We only hold the ops + * lock during this period so that the tpm can be unregistered even if + * the char dev is held open. + */ + if (tpm_try_get_ops(priv->chip)) { + ret = -EPIPE; + goto out; + } + ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer, sizeof(priv->data_buffer)); tpm_put_ops(priv->chip); diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 09fe45246b8cc0..994385bf37c0c0 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -683,13 +683,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, if (rc) goto init_irq_cleanup; - if (!strcmp(id->compat, "IBM,vtpm20")) { - chip->flags |= TPM_CHIP_FLAG_TPM2; - rc = tpm2_get_cc_attrs_tbl(chip); - if (rc) - goto init_irq_cleanup; - } - if (!wait_event_timeout(ibmvtpm->crq_queue.wq, ibmvtpm->rtce_buf != NULL, HZ)) { @@ -697,6 +690,13 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, goto init_irq_cleanup; } + if (!strcmp(id->compat, "IBM,vtpm20")) { + chip->flags |= TPM_CHIP_FLAG_TPM2; + rc = tpm2_get_cc_attrs_tbl(chip); + if (rc) + goto init_irq_cleanup; + } + return tpm_chip_register(chip); init_irq_cleanup: do { diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index e7df342a317d6c..c58ea10fc92f6a 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -238,7 +238,6 @@ static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, static struct pnp_device_id tpm_pnp_tbl[] = { {"PNP0C31", 0}, /* TPM */ {"ATM1200", 0}, /* Atmel */ - {"IFX0102", 0}, /* Infineon */ {"BCM0101", 0}, /* Broadcom */ {"BCM0102", 0}, /* Broadcom */ {"NSC1200", 0}, /* National */ diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 2435216bd10aaa..65ab1b027949c7 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -1085,7 +1085,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, return 0; out_err: - if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) + if (chip->ops->clk_enable != NULL) chip->ops->clk_enable(chip, false); tpm_tis_remove(chip); diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c index d967559355296e..3856f6ebcb34f7 100644 --- a/drivers/char/tpm/tpm_tis_spi_main.c +++ b/drivers/char/tpm/tpm_tis_spi_main.c @@ -53,8 +53,6 @@ static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy, if ((phy->iobuf[3] & 0x01) == 0) { // handle SPI wait states - phy->iobuf[0] = 0; - for (i = 0; i < TPM_RETRY; i++) { spi_xfer->len = 1; spi_message_init(&m); @@ -104,6 +102,8 @@ int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, if (ret < 0) goto exit; + /* Flow control transfers are receive only */ + spi_xfer.tx_buf = NULL; ret = phy->flow_control(phy, &spi_xfer); if (ret < 0) goto exit; @@ -113,9 +113,8 @@ int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, spi_xfer.delay.value = 5; spi_xfer.delay.unit = SPI_DELAY_UNIT_USECS; - if (in) { - spi_xfer.tx_buf = NULL; - } else if (out) { + if (out) { + spi_xfer.tx_buf = phy->iobuf; spi_xfer.rx_buf = NULL; memcpy(phy->iobuf, out, transfer_len); out += transfer_len; @@ -288,6 +287,7 @@ static struct spi_driver tpm_tis_spi_driver = { .pm = &tpm_tis_pm, .of_match_table = of_match_ptr(of_tis_spi_match), .acpi_match_table = ACPI_PTR(acpi_tis_spi_match), + .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe = tpm_tis_spi_driver_probe, .remove = tpm_tis_spi_remove, diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 01ce125f8e8d8a..412629601ad3b4 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -54,37 +54,11 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) dentry->d_name.name, ret > 0 ? name : ""); } -static const struct dentry_operations dma_buf_dentry_ops = { - .d_dname = dmabuffs_dname, -}; - -static struct vfsmount *dma_buf_mnt; - -static int dma_buf_fs_init_context(struct fs_context *fc) -{ - struct pseudo_fs_context *ctx; - - ctx = init_pseudo(fc, DMA_BUF_MAGIC); - if (!ctx) - return -ENOMEM; - ctx->dops = &dma_buf_dentry_ops; - return 0; -} - -static struct file_system_type dma_buf_fs_type = { - .name = "dmabuf", - .init_fs_context = dma_buf_fs_init_context, - .kill_sb = kill_anon_super, -}; - -static int dma_buf_release(struct inode *inode, struct file *file) +static void dma_buf_release(struct dentry *dentry) { struct dma_buf *dmabuf; - if (!is_dma_buf_file(file)) - return -EINVAL; - - dmabuf = file->private_data; + dmabuf = dentry->d_fsdata; BUG_ON(dmabuf->vmapping_counter); @@ -110,9 +84,32 @@ static int dma_buf_release(struct inode *inode, struct file *file) module_put(dmabuf->owner); kfree(dmabuf->name); kfree(dmabuf); +} + +static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = dmabuffs_dname, + .d_release = dma_buf_release, +}; + +static struct vfsmount *dma_buf_mnt; + +static int dma_buf_fs_init_context(struct fs_context *fc) +{ + struct pseudo_fs_context *ctx; + + ctx = init_pseudo(fc, DMA_BUF_MAGIC); + if (!ctx) + return -ENOMEM; + ctx->dops = &dma_buf_dentry_ops; return 0; } +static struct file_system_type dma_buf_fs_type = { + .name = "dmabuf", + .init_fs_context = dma_buf_fs_init_context, + .kill_sb = kill_anon_super, +}; + static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) { struct dma_buf *dmabuf; @@ -412,7 +409,6 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) } static const struct file_operations dma_buf_fops = { - .release = dma_buf_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 58f9d8c3a17ab9..44f927641b892d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -204,6 +204,7 @@ amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, (mode_info->atom_context->bios + data_offset); switch (crev) { case 11: + case 12: mem_channel_number = igp_info->v11.umachannelnumber; /* channel width is 64 */ if (vram_width) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 16596a9ccabefc..02e6f8c4dde084 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -2784,7 +2784,7 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000); + return snprintf(buf, PAGE_SIZE, "%u\n", sclk * 10 * 1000); } static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev, @@ -2819,7 +2819,7 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000); + return snprintf(buf, PAGE_SIZE, "%u\n", mclk * 10 * 1000); } static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 6f93a6ca4cf0c8..d016f50e187c8d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2538,10 +2538,12 @@ void dc_commit_updates_for_stream(struct dc *dc, copy_stream_update_to_stream(dc, context, stream, stream_update); - if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { - DC_ERROR("Mode validation failed for stream update!\n"); - dc_release_state(context); - return; + if (update_type > UPDATE_TYPE_FAST) { + if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { + DC_ERROR("Mode validation failed for stream update!\n"); + dc_release_state(context); + return; + } } commit_planes_for_stream( diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c index 2fb97554134f5a..c2e0fbbccf56a3 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c @@ -522,9 +522,11 @@ static int vega20_smu_init(struct pp_hwmgr *hwmgr) priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].version = 0x01; priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].size = sizeof(DpmActivityMonitorCoeffInt_t); - ret = smu_v11_0_i2c_eeprom_control_init(&adev->pm.smu_i2c); - if (ret) - goto err4; + if (adev->psp.ras.ras) { + ret = smu_v11_0_i2c_eeprom_control_init(&adev->pm.smu_i2c); + if (ret) + goto err4; + } return 0; @@ -560,7 +562,8 @@ static int vega20_smu_fini(struct pp_hwmgr *hwmgr) (struct vega20_smumgr *)(hwmgr->smu_backend); struct amdgpu_device *adev = hwmgr->adev; - smu_v11_0_i2c_eeprom_control_fini(&adev->pm.smu_i2c); + if (adev->psp.ras.ras) + smu_v11_0_i2c_eeprom_control_fini(&adev->pm.smu_i2c); if (priv) { amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle, diff --git a/drivers/gpu/drm/exynos/exynos_drm_dma.c b/drivers/gpu/drm/exynos/exynos_drm_dma.c index 619f81435c1b22..58b89ec11b0eb3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dma.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dma.c @@ -61,7 +61,7 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, struct device *subdrv_dev, void **dma_priv) { struct exynos_drm_private *priv = drm_dev->dev_private; - int ret; + int ret = 0; if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) { DRM_DEV_ERROR(subdrv_dev, "Device %s lacks support for IOMMU\n", @@ -92,7 +92,7 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, if (ret) clear_dma_max_seg_size(subdrv_dev); - return 0; + return ret; } /* diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index fcee33a43aca3e..03be3142718110 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -1498,7 +1498,6 @@ static int g2d_probe(struct platform_device *pdev) g2d->irq = platform_get_irq(pdev, 0); if (g2d->irq < 0) { - dev_err(dev, "failed to get irq\n"); ret = g2d->irq; goto err_put_clk; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index a86abc173605e5..3821ea76a7039d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -269,8 +269,10 @@ static void mic_pre_enable(struct drm_bridge *bridge) goto unlock; ret = pm_runtime_get_sync(mic->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(mic->dev); goto unlock; + } mic_set_path(mic, 1); diff --git a/drivers/gpu/drm/i915/gt/shaders/README b/drivers/gpu/drm/i915/gt/shaders/README new file mode 100644 index 00000000000000..e7e96d7073c7ea --- /dev/null +++ b/drivers/gpu/drm/i915/gt/shaders/README @@ -0,0 +1,46 @@ +ASM sources for auto generated shaders +====================================== + +The i915/gt/hsw_clear_kernel.c and i915/gt/ivb_clear_kernel.c files contain +pre-compiled batch chunks that will clear any residual render cache during +context switch. + +They are generated from their respective platform ASM files present on +i915/gt/shaders/clear_kernel directory. + +The generated .c files should never be modified directly. Instead, any modification +needs to be done on the on their respective ASM files and build instructions below +needes to be followed. + +Building +======== + +Environment +----------- + +IGT GPU tool scripts and the Mesa's i965 instruction assembler tool are used +on building. + +Please make sure your Mesa tool is compiled with "-Dtools=intel" and +"-Ddri-drivers=i965", and run this script from IGT source root directory" + +The instructions bellow assume: + * IGT gpu tools source code is located on your home directory (~) as ~/igt + * Mesa source code is located on your home directory (~) as ~/mesa + and built under the ~/mesa/build directory + * Linux kernel source code is under your home directory (~) as ~/linux + +Instructions +------------ + +~ $ cp ~/linux/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm \ + ~/igt/lib/i915/shaders/clear_kernel/ivb.asm +~ $ cd ~/igt +igt $ ./scripts/generate_clear_kernel.sh -g ivb \ + -m ~/mesa/build/src/intel/tools/i965_asm + +~ $ cp ~/linux/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm \ + ~/igt/lib/i915/shaders/clear_kernel/hsw.asm +~ $ cd ~/igt +igt $ ./scripts/generate_clear_kernel.sh -g hsw \ + -m ~/mesa/build/src/intel/tools/i965_asm \ No newline at end of file diff --git a/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm new file mode 100644 index 00000000000000..5fdf384bb6213e --- /dev/null +++ b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/hsw.asm @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2020 Intel Corporation + */ + +/* + * Kernel for PAVP buffer clear. + * + * 1. Clear all 64 GRF registers assigned to the kernel with designated value; + * 2. Write 32x16 block of all "0" to render target buffer which indirectly clears + * 512 bytes of Render Cache. + */ + +/* Store designated "clear GRF" value */ +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; + +/** + * Curbe Format + * + * DW 1.0 - Block Offset to write Render Cache + * DW 1.1 [15:0] - Clear Word + * DW 1.2 - Delay iterations + * DW 1.3 - Enable Instrumentation (only for debug) + * DW 1.4 - Rsvd (intended for context ID) + * DW 1.5 - [31:16]:SliceCount, [15:0]:SubSlicePerSliceCount + * DW 1.6 - Rsvd MBZ (intended for Enable Wait on Total Thread Count) + * DW 1.7 - Rsvd MBZ (inteded for Total Thread Count) + * + * Binding Table + * + * BTI 0: 2D Surface to help clear L3 (Render/Data Cache) + * BTI 1: Wait/Instrumentation Buffer + * Size : (SliceCount * SubSliceCount * 16 EUs/SubSlice) rows * (16 threads/EU) cols (Format R32_UINT) + * Expected to be initialized to 0 by driver/another kernel + * Layout: + * RowN: Histogram for EU-N: (SliceID*SubSlicePerSliceCount + SSID)*16 + EUID [assume max 16 EUs / SS] + * Col-k[DW-k]: Threads Executed on ThreadID-k for EU-N + */ +add(1) g1.2<1>UD g1.2<0,1,0>UD 0x00000001UD { align1 1N }; /* Loop count to delay kernel: Init to (g1.2 + 1) */ +cmp.z.f0.0(1) null<1>UD g1.3<0,1,0>UD 0x00000000UD { align1 1N }; +(+f0.0) jmpi(1) 352D { align1 WE_all 1N }; + +/** + * State Register has info on where this thread is running + * IVB: sr0.0 :: [15:13]: MBZ, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID + * HSW: sr0.0 :: 15: MBZ, [14:13]: SliceID, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID + */ +mov(8) g3<1>UD 0x00000000UD { align1 1Q }; +shr(1) g3<1>D sr0<0,1,0>D 12D { align1 1N }; +and(1) g3<1>D g3<0,1,0>D 1D { align1 1N }; /* g3 has HSID */ +shr(1) g3.1<1>D sr0<0,1,0>D 13D { align1 1N }; +and(1) g3.1<1>D g3.1<0,1,0>D 3D { align1 1N }; /* g3.1 has sliceID */ +mul(1) g3.5<1>D g3.1<0,1,0>D g1.10<0,1,0>UW { align1 1N }; +add(1) g3<1>D g3<0,1,0>D g3.5<0,1,0>D { align1 1N }; /* g3 = sliceID * SubSlicePerSliceCount + HSID */ +shr(1) g3.2<1>D sr0<0,1,0>D 8D { align1 1N }; +and(1) g3.2<1>D g3.2<0,1,0>D 15D { align1 1N }; /* g3.2 = EUID */ +mul(1) g3.4<1>D g3<0,1,0>D 16D { align1 1N }; +add(1) g3.2<1>D g3.2<0,1,0>D g3.4<0,1,0>D { align1 1N }; /* g3.2 now points to EU row number (Y-pixel = V address ) in instrumentation surf */ + +mov(8) g5<1>UD 0x00000000UD { align1 1Q }; +and(1) g3.3<1>D sr0<0,1,0>D 7D { align1 1N }; +mul(1) g3.3<1>D g3.3<0,1,0>D 4D { align1 1N }; + +mov(8) g4<1>UD g0<8,8,1>UD { align1 1Q }; /* Initialize message header with g0 */ +mov(1) g4<1>UD g3.3<0,1,0>UD { align1 1N }; /* Block offset */ +mov(1) g4.1<1>UD g3.2<0,1,0>UD { align1 1N }; /* Block offset */ +mov(1) g4.2<1>UD 0x00000003UD { align1 1N }; /* Block size (1 row x 4 bytes) */ +and(1) g4.3<1>UD g4.3<0,1,0>UW 0xffffffffUD { align1 1N }; + +/* Media block read to fetch current value at specified location in instrumentation buffer */ +sendc(8) g5<1>UD g4<8,8,1>F 0x02190001 + + render MsgDesc: media block read MsgCtrl = 0x0 Surface = 1 mlen 1 rlen 1 { align1 1Q }; +add(1) g5<1>D g5<0,1,0>D 1D { align1 1N }; + +/* Media block write for updated value at specified location in instrumentation buffer */ +sendc(8) g5<1>UD g4<8,8,1>F 0x040a8001 + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 1 mlen 2 rlen 0 { align1 1Q }; + +/* Delay thread for specified parameter */ +add.nz.f0.0(1) g1.2<1>UD g1.2<0,1,0>UD -1D { align1 1N }; +(+f0.0) jmpi(1) -32D { align1 WE_all 1N }; + +/* Store designated "clear GRF" value */ +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; + +/* Initialize looping parameters */ +mov(1) a0<1>D 0D { align1 1N }; /* Initialize a0.0:w=0 */ +mov(1) a0.4<1>W 127W { align1 1N }; /* Loop count. Each loop contains 16 GRF's */ + +/* Write 32x16 all "0" block */ +mov(8) g2<1>UD g0<8,8,1>UD { align1 1Q }; +mov(8) g127<1>UD g0<8,8,1>UD { align1 1Q }; +mov(2) g2<1>UD g1<2,2,1>UW { align1 1N }; +mov(1) g2.2<1>UD 0x000f000fUD { align1 1N }; /* Block size (16x16) */ +and(1) g2.3<1>UD g2.3<0,1,0>UW 0xffffffefUD { align1 1N }; +mov(16) g3<1>UD 0x00000000UD { align1 1H }; +mov(16) g4<1>UD 0x00000000UD { align1 1H }; +mov(16) g5<1>UD 0x00000000UD { align1 1H }; +mov(16) g6<1>UD 0x00000000UD { align1 1H }; +mov(16) g7<1>UD 0x00000000UD { align1 1H }; +mov(16) g8<1>UD 0x00000000UD { align1 1H }; +mov(16) g9<1>UD 0x00000000UD { align1 1H }; +mov(16) g10<1>UD 0x00000000UD { align1 1H }; +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; +add(1) g2<1>UD g1<0,1,0>UW 0x0010UW { align1 1N }; +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; + +/* Now, clear all GRF registers */ +add.nz.f0.0(1) a0.4<1>W a0.4<0,1,0>W -1W { align1 1N }; +mov(16) g[a0]<1>UW f0.1<0,1,0>UW { align1 1H }; +add(1) a0<1>D a0<0,1,0>D 32D { align1 1N }; +(+f0.0) jmpi(1) -64D { align1 WE_all 1N }; + +/* Terminante the thread */ +sendc(8) null<1>UD g127<8,8,1>F 0x82000010 + thread_spawner MsgDesc: mlen 1 rlen 0 { align1 1Q EOT }; diff --git a/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm new file mode 100644 index 00000000000000..97c7ac9e385491 --- /dev/null +++ b/drivers/gpu/drm/i915/gt/shaders/clear_kernel/ivb.asm @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2020 Intel Corporation + */ + +/* + * Kernel for PAVP buffer clear. + * + * 1. Clear all 64 GRF registers assigned to the kernel with designated value; + * 2. Write 32x16 block of all "0" to render target buffer which indirectly clears + * 512 bytes of Render Cache. + */ + +/* Store designated "clear GRF" value */ +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; + +/** + * Curbe Format + * + * DW 1.0 - Block Offset to write Render Cache + * DW 1.1 [15:0] - Clear Word + * DW 1.2 - Delay iterations + * DW 1.3 - Enable Instrumentation (only for debug) + * DW 1.4 - Rsvd (intended for context ID) + * DW 1.5 - [31:16]:SliceCount, [15:0]:SubSlicePerSliceCount + * DW 1.6 - Rsvd MBZ (intended for Enable Wait on Total Thread Count) + * DW 1.7 - Rsvd MBZ (inteded for Total Thread Count) + * + * Binding Table + * + * BTI 0: 2D Surface to help clear L3 (Render/Data Cache) + * BTI 1: Wait/Instrumentation Buffer + * Size : (SliceCount * SubSliceCount * 16 EUs/SubSlice) rows * (16 threads/EU) cols (Format R32_UINT) + * Expected to be initialized to 0 by driver/another kernel + * Layout : + * RowN: Histogram for EU-N: (SliceID*SubSlicePerSliceCount + SSID)*16 + EUID [assume max 16 EUs / SS] + * Col-k[DW-k]: Threads Executed on ThreadID-k for EU-N + */ +add(1) g1.2<1>UD g1.2<0,1,0>UD 0x00000001UD { align1 1N }; /* Loop count to delay kernel: Init to (g1.2 + 1) */ +cmp.z.f0.0(1) null<1>UD g1.3<0,1,0>UD 0x00000000UD { align1 1N }; +(+f0.0) jmpi(1) 44D { align1 WE_all 1N }; + +/** + * State Register has info on where this thread is running + * IVB: sr0.0 :: [15:13]: MBZ, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID + * HSW: sr0.0 :: 15: MBZ, [14:13]: SliceID, 12: HSID (Half-Slice ID), [11:8]EUID, [2:0] ThreadSlotID + */ +mov(8) g3<1>UD 0x00000000UD { align1 1Q }; +shr(1) g3<1>D sr0<0,1,0>D 12D { align1 1N }; +and(1) g3<1>D g3<0,1,0>D 1D { align1 1N }; /* g3 has HSID */ +shr(1) g3.1<1>D sr0<0,1,0>D 13D { align1 1N }; +and(1) g3.1<1>D g3.1<0,1,0>D 3D { align1 1N }; /* g3.1 has sliceID */ +mul(1) g3.5<1>D g3.1<0,1,0>D g1.10<0,1,0>UW { align1 1N }; +add(1) g3<1>D g3<0,1,0>D g3.5<0,1,0>D { align1 1N }; /* g3 = sliceID * SubSlicePerSliceCount + HSID */ +shr(1) g3.2<1>D sr0<0,1,0>D 8D { align1 1N }; +and(1) g3.2<1>D g3.2<0,1,0>D 15D { align1 1N }; /* g3.2 = EUID */ +mul(1) g3.4<1>D g3<0,1,0>D 16D { align1 1N }; +add(1) g3.2<1>D g3.2<0,1,0>D g3.4<0,1,0>D { align1 1N }; /* g3.2 now points to EU row number (Y-pixel = V address ) in instrumentation surf */ + +mov(8) g5<1>UD 0x00000000UD { align1 1Q }; +and(1) g3.3<1>D sr0<0,1,0>D 7D { align1 1N }; +mul(1) g3.3<1>D g3.3<0,1,0>D 4D { align1 1N }; + +mov(8) g4<1>UD g0<8,8,1>UD { align1 1Q }; /* Initialize message header with g0 */ +mov(1) g4<1>UD g3.3<0,1,0>UD { align1 1N }; /* Block offset */ +mov(1) g4.1<1>UD g3.2<0,1,0>UD { align1 1N }; /* Block offset */ +mov(1) g4.2<1>UD 0x00000003UD { align1 1N }; /* Block size (1 row x 4 bytes) */ +and(1) g4.3<1>UD g4.3<0,1,0>UW 0xffffffffUD { align1 1N }; + +/* Media block read to fetch current value at specified location in instrumentation buffer */ +sendc(8) g5<1>UD g4<8,8,1>F 0x02190001 + render MsgDesc: media block read MsgCtrl = 0x0 Surface = 1 mlen 1 rlen 1 { align1 1Q }; +add(1) g5<1>D g5<0,1,0>D 1D { align1 1N }; + +/* Media block write for updated value at specified location in instrumentation buffer */ +sendc(8) g5<1>UD g4<8,8,1>F 0x040a8001 + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 1 mlen 2 rlen 0 { align1 1Q }; +/* Delay thread for specified parameter */ +add.nz.f0.0(1) g1.2<1>UD g1.2<0,1,0>UD -1D { align1 1N }; +(+f0.0) jmpi(1) -4D { align1 WE_all 1N }; + +/* Store designated "clear GRF" value */ +mov(1) f0.1<1>UW g1.2<0,1,0>UW { align1 1N }; + +/* Initialize looping parameters */ +mov(1) a0<1>D 0D { align1 1N }; /* Initialize a0.0:w=0 */ +mov(1) a0.4<1>W 127W { align1 1N }; /* Loop count. Each loop contains 16 GRF's */ + +/* Write 32x16 all "0" block */ +mov(8) g2<1>UD g0<8,8,1>UD { align1 1Q }; +mov(8) g127<1>UD g0<8,8,1>UD { align1 1Q }; +mov(2) g2<1>UD g1<2,2,1>UW { align1 1N }; +mov(1) g2.2<1>UD 0x000f000fUD { align1 1N }; /* Block size (16x16) */ +and(1) g2.3<1>UD g2.3<0,1,0>UW 0xffffffefUD { align1 1N }; +mov(16) g3<1>UD 0x00000000UD { align1 1H }; +mov(16) g4<1>UD 0x00000000UD { align1 1H }; +mov(16) g5<1>UD 0x00000000UD { align1 1H }; +mov(16) g6<1>UD 0x00000000UD { align1 1H }; +mov(16) g7<1>UD 0x00000000UD { align1 1H }; +mov(16) g8<1>UD 0x00000000UD { align1 1H }; +mov(16) g9<1>UD 0x00000000UD { align1 1H }; +mov(16) g10<1>UD 0x00000000UD { align1 1H }; +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; +add(1) g2<1>UD g1<0,1,0>UW 0x0010UW { align1 1N }; +sendc(8) null<1>UD g2<8,8,1>F 0x120a8000 + render MsgDesc: media block write MsgCtrl = 0x0 Surface = 0 mlen 9 rlen 0 { align1 1Q }; + +/* Now, clear all GRF registers */ +add.nz.f0.0(1) a0.4<1>W a0.4<0,1,0>W -1W { align1 1N }; +mov(16) g[a0]<1>UW f0.1<0,1,0>UW { align1 1H }; +add(1) a0<1>D a0<0,1,0>D 32D { align1 1N }; +(+f0.0) jmpi(1) -8D { align1 WE_all 1N }; + +/* Terminante the thread */ +sendc(8) null<1>UD g127<8,8,1>F 0x82000010 + thread_spawner MsgDesc: mlen 1 rlen 0 { align1 1Q EOT }; diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c index ec47d41145541a..62e6a14ad58ef7 100644 --- a/drivers/gpu/drm/i915/gvt/debugfs.c +++ b/drivers/gpu/drm/i915/gvt/debugfs.c @@ -66,7 +66,7 @@ static inline int mmio_diff_handler(struct intel_gvt *gvt, vreg = vgpu_vreg(param->vgpu, offset); if (preg != vreg) { - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kmalloc(sizeof(*node), GFP_ATOMIC); if (!node) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 3e88e3b5c43ad4..fadd2adb803072 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1726,13 +1726,13 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(2); write_vreg(vgpu, offset, p_data, bytes); - if (data & _MASKED_BIT_ENABLE(1)) { + if (IS_MASKED_BITS_ENABLED(data, 1)) { enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); return 0; } if (IS_COFFEELAKE(vgpu->gvt->gt->i915) && - data & _MASKED_BIT_ENABLE(2)) { + IS_MASKED_BITS_ENABLED(data, 2)) { enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); return 0; } @@ -1741,14 +1741,14 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, * pvinfo, if not, we will treat this guest as non-gvtg-aware * guest, and stop emulating its cfg space, mmio, gtt, etc. */ - if (((data & _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)) || - (data & _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE))) - && !vgpu->pv_notified) { + if ((IS_MASKED_BITS_ENABLED(data, GFX_PPGTT_ENABLE) || + IS_MASKED_BITS_ENABLED(data, GFX_RUN_LIST_ENABLE)) && + !vgpu->pv_notified) { enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); return 0; } - if ((data & _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)) - || (data & _MASKED_BIT_DISABLE(GFX_RUN_LIST_ENABLE))) { + if (IS_MASKED_BITS_ENABLED(data, GFX_RUN_LIST_ENABLE) || + IS_MASKED_BITS_DISABLED(data, GFX_RUN_LIST_ENABLE)) { enable_execlist = !!(data & GFX_RUN_LIST_ENABLE); gvt_dbg_core("EXECLIST %s on ring %s\n", @@ -1809,7 +1809,7 @@ static int ring_reset_ctl_write(struct intel_vgpu *vgpu, write_vreg(vgpu, offset, p_data, bytes); data = vgpu_vreg(vgpu, offset); - if (data & _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)) + if (IS_MASKED_BITS_ENABLED(data, RESET_CTL_REQUEST_RESET)) data |= RESET_CTL_READY_TO_RESET; else if (data & _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)) data &= ~RESET_CTL_READY_TO_RESET; @@ -1827,7 +1827,8 @@ static int csfe_chicken1_mmio_write(struct intel_vgpu *vgpu, (*(u32 *)p_data) &= ~_MASKED_BIT_ENABLE(0x18); write_vreg(vgpu, offset, p_data, bytes); - if (data & _MASKED_BIT_ENABLE(0x10) || data & _MASKED_BIT_ENABLE(0x8)) + if (IS_MASKED_BITS_ENABLED(data, 0x10) || + IS_MASKED_BITS_ENABLED(data, 0x8)) enter_failsafe_mode(vgpu, GVT_FAILSAFE_UNSUPPORTED_GUEST); return 0; @@ -3055,6 +3056,7 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_D(_MMIO(0x72380), D_SKL_PLUS); MMIO_D(_MMIO(0x7239c), D_SKL_PLUS); MMIO_D(_MMIO(_PLANE_SURF_3_A), D_SKL_PLUS); + MMIO_D(_MMIO(_PLANE_SURF_3_B), D_SKL_PLUS); MMIO_D(CSR_SSP_BASE, D_SKL_PLUS); MMIO_D(CSR_HTP_SKL, D_SKL_PLUS); @@ -3131,8 +3133,8 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_DFH(GEN9_WM_CHICKEN3, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); - MMIO_D(GAMT_CHKN_BIT_REG, D_KBL); - MMIO_D(GEN9_CTX_PREEMPT_REG, D_KBL | D_SKL); + MMIO_D(GAMT_CHKN_BIT_REG, D_KBL | D_CFL); + MMIO_D(GEN9_CTX_PREEMPT_REG, D_SKL_PLUS); return 0; } diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.h b/drivers/gpu/drm/i915/gvt/mmio_context.h index 970704b18f2394..3b25e7fe32f6fa 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.h +++ b/drivers/gpu/drm/i915/gvt/mmio_context.h @@ -54,8 +54,8 @@ bool is_inhibit_context(struct intel_context *ce); int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, struct i915_request *req); -#define IS_RESTORE_INHIBIT(a) \ - (_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) == \ - ((a) & _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT))) + +#define IS_RESTORE_INHIBIT(a) \ + IS_MASKED_BITS_ENABLED(a, CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) #endif diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index 5b66e14c5b7b2b..b88e033cbed439 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h @@ -94,6 +94,11 @@ #define GFX_MODE_BIT_SET_IN_MASK(val, bit) \ ((((bit) & 0xffff0000) == 0) && !!((val) & (((bit) << 16)))) +#define IS_MASKED_BITS_ENABLED(_val, _b) \ + (((_val) & _MASKED_BIT_ENABLE(_b)) == _MASKED_BIT_ENABLE(_b)) +#define IS_MASKED_BITS_DISABLED(_val, _b) \ + ((_val) & _MASKED_BIT_DISABLE(_b)) + #define FORCEWAKE_RENDER_GEN9_REG 0xa278 #define FORCEWAKE_ACK_RENDER_GEN9_REG 0x0D84 #define FORCEWAKE_BLITTER_GEN9_REG 0xa188 diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 60f6472a3e5825..6021f8d9efd1fb 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -408,7 +408,7 @@ a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev) struct msm_gem_address_space *aspace; aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M, - SZ_16M + 0xfff * SZ_64K); + 0xfff * SZ_64K); if (IS_ERR(aspace) && !IS_ERR(mmu)) mmu->funcs->destroy(mmu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 096be97ce9f961..21e77d67151f58 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1121,7 +1121,7 @@ static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu) return -ENODEV; mmu = msm_iommu_new(gmu->dev, domain); - gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x7fffffff); + gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x80000000); if (IS_ERR(gmu->aspace)) { iommu_domain_free(domain); return PTR_ERR(gmu->aspace); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index a1589e040c57e7..7768557cdfb280 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -893,8 +893,8 @@ static const struct adreno_gpu_funcs funcs = { #if defined(CONFIG_DRM_MSM_GPU_STATE) .gpu_state_get = a6xx_gpu_state_get, .gpu_state_put = a6xx_gpu_state_put, - .create_address_space = adreno_iommu_create_address_space, #endif + .create_address_space = adreno_iommu_create_address_space, }, .get_timestamp = a6xx_get_timestamp, }; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 89673c7ed47354..5db06b5909438f 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -194,7 +194,7 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, struct msm_gem_address_space *aspace; aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M, - 0xfffffff); + 0xffffffff - SZ_16M); if (IS_ERR(aspace) && !IS_ERR(mmu)) mmu->funcs->destroy(mmu); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 63976dcd2ac87f..0946a86b37b285 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -521,7 +521,7 @@ static struct msm_display_topology dpu_encoder_get_topology( struct dpu_kms *dpu_kms, struct drm_display_mode *mode) { - struct msm_display_topology topology; + struct msm_display_topology topology = {0}; int i, intf_count = 0; for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) @@ -537,7 +537,8 @@ static struct msm_display_topology dpu_encoder_get_topology( * 1 LM, 1 INTF * 2 LM, 1 INTF (stream merge to support high resolution interfaces) * - * Adding color blocks only to primary interface + * Adding color blocks only to primary interface if available in + * sufficient number */ if (intf_count == 2) topology.num_lm = 2; @@ -546,8 +547,11 @@ static struct msm_display_topology dpu_encoder_get_topology( else topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; - if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) - topology.num_dspp = topology.num_lm; + if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) { + if (dpu_kms->catalog->dspp && + (dpu_kms->catalog->dspp_count >= topology.num_lm)) + topology.num_dspp = topology.num_lm; + } topology.num_enc = 0; topology.num_intf = intf_count; @@ -2136,7 +2140,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, dpu_enc = to_dpu_encoder_virt(enc); - mutex_init(&dpu_enc->enc_lock); ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); if (ret) goto fail; @@ -2151,7 +2154,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, 0); - mutex_init(&dpu_enc->rc_lock); INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, dpu_encoder_off_work); dpu_enc->idle_timeout = IDLE_TIMEOUT; @@ -2183,7 +2185,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); if (!dpu_enc) - return ERR_PTR(ENOMEM); + return ERR_PTR(-ENOMEM); rc = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, drm_enc_mode, NULL); @@ -2196,6 +2198,8 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, spin_lock_init(&dpu_enc->enc_spinlock); dpu_enc->enabled = false; + mutex_init(&dpu_enc->enc_lock); + mutex_init(&dpu_enc->rc_lock); return &dpu_enc->base; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index b8615d4fe8a3f7..680527e28d09b0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -780,7 +780,7 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) mmu = msm_iommu_new(dpu_kms->dev->dev, domain); aspace = msm_gem_address_space_create(mmu, "dpu1", - 0x1000, 0xfffffff); + 0x1000, 0x100000000 - 0x1000); if (IS_ERR(aspace)) { mmu->funcs->destroy(mmu); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 08897184b1d97d..fc6a3f8134c7ff 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -514,7 +514,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) config->iommu); aspace = msm_gem_address_space_create(mmu, - "mdp4", 0x1000, 0xffffffff); + "mdp4", 0x1000, 0x100000000 - 0x1000); if (IS_ERR(aspace)) { if (!IS_ERR(mmu)) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 19ec48695ffb4f..e193865ce9a26e 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -633,7 +633,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) mmu = msm_iommu_new(iommu_dev, config->platform.iommu); aspace = msm_gem_address_space_create(mmu, "mdp5", - 0x1000, 0xffffffff); + 0x1000, 0x100000000 - 0x1000); if (IS_ERR(aspace)) { if (!IS_ERR(mmu)) diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index 001fbf537440a9..a1d94be7883a06 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -71,8 +71,10 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, queue->flags = flags; if (priv->gpu) { - if (prio >= priv->gpu->nr_rings) + if (prio >= priv->gpu->nr_rings) { + kfree(queue); return -EINVAL; + } queue->prio = prio; } diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index ce07ddc3e058aa..557cbe5ab35f02 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -259,9 +259,8 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force) struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); unsigned long reg; - if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg, - reg & SUN4I_HDMI_HPD_HIGH, - 0, 500000)) { + reg = readl(hdmi->base + SUN4I_HDMI_HPD_REG); + if (reg & SUN4I_HDMI_HPD_HIGH) { cec_phys_addr_invalidate(hdmi->cec_adap); return connector_status_disconnected; } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 9147ee9d5f7d06..d69f4efa371980 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1368,7 +1368,7 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper, * Write dump contents to the page. No need to synchronize; panic should * be single-threaded. */ - kmsg_dump_get_buffer(dumper, true, hv_panic_page, HV_HYP_PAGE_SIZE, + kmsg_dump_get_buffer(dumper, false, hv_panic_page, HV_HYP_PAGE_SIZE, &bytes_written); if (bytes_written) hyperv_report_panic_msg(panic_pa, bytes_written); diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 0db8ef4fd6e18b..a270b975e90bb4 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -883,7 +883,7 @@ static int acpi_power_meter_add(struct acpi_device *device) res = setup_attrs(resource); if (res) - goto exit_free; + goto exit_free_capability; resource->hwmon_dev = hwmon_device_register(&device->dev); if (IS_ERR(resource->hwmon_dev)) { @@ -896,6 +896,8 @@ static int acpi_power_meter_add(struct acpi_device *device) exit_remove: remove_attrs(resource); +exit_free_capability: + free_capabilities(resource); exit_free: kfree(resource); exit: diff --git a/drivers/hwmon/bt1-pvt.c b/drivers/hwmon/bt1-pvt.c index 1a9772fb1f7354..94698cae049711 100644 --- a/drivers/hwmon/bt1-pvt.c +++ b/drivers/hwmon/bt1-pvt.c @@ -64,7 +64,7 @@ static const struct pvt_sensor_info pvt_info[] = { * 48380, * where T = [-48380, 147438] mC and N = [0, 1023]. */ -static const struct pvt_poly poly_temp_to_N = { +static const struct pvt_poly __maybe_unused poly_temp_to_N = { .total_divider = 10000, .terms = { {4, 18322, 10000, 10000}, @@ -96,7 +96,7 @@ static const struct pvt_poly poly_N_to_temp = { * N = (18658e-3*V - 11572) / 10, * V = N * 10^5 / 18658 + 11572 * 10^4 / 18658. */ -static const struct pvt_poly poly_volt_to_N = { +static const struct pvt_poly __maybe_unused poly_volt_to_N = { .total_divider = 10, .terms = { {1, 18658, 1000, 1}, @@ -300,12 +300,12 @@ static irqreturn_t pvt_soft_isr(int irq, void *data) return IRQ_HANDLED; } -inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) +static inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) { return 0644; } -inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) +static inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) { return 0444; } @@ -462,12 +462,12 @@ static irqreturn_t pvt_hard_isr(int irq, void *data) #define pvt_soft_isr NULL -inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) +static inline umode_t pvt_limit_is_visible(enum pvt_sensor_type type) { return 0; } -inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) +static inline umode_t pvt_alarm_is_visible(enum pvt_sensor_type type) { return 0; } diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c index 743752a2467a27..64122eb38060d0 100644 --- a/drivers/hwmon/max6697.c +++ b/drivers/hwmon/max6697.c @@ -38,8 +38,9 @@ static const u8 MAX6697_REG_CRIT[] = { * Map device tree / platform data register bit map to chip bit map. * Applies to alert register and over-temperature register. */ -#define MAX6697_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ +#define MAX6697_ALERT_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ (((reg) & 0x01) << 6) | ((reg) & 0x80)) +#define MAX6697_OVERT_MAP_BITS(reg) (((reg) >> 1) | (((reg) & 0x01) << 7)) #define MAX6697_REG_STAT(n) (0x44 + (n)) @@ -562,12 +563,12 @@ static int max6697_init_chip(struct max6697_data *data, return ret; ret = i2c_smbus_write_byte_data(client, MAX6697_REG_ALERT_MASK, - MAX6697_MAP_BITS(pdata->alert_mask)); + MAX6697_ALERT_MAP_BITS(pdata->alert_mask)); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(client, MAX6697_REG_OVERT_MASK, - MAX6697_MAP_BITS(pdata->over_temperature_mask)); + MAX6697_OVERT_MAP_BITS(pdata->over_temperature_mask)); if (ret < 0) return ret; diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index a337195b1c395e..ea516cec1d354e 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -71,7 +71,7 @@ config SENSORS_IR35221 Infineon IR35221 controller. This driver can also be built as a module. If so, the module will - be called ir35521. + be called ir35221. config SENSORS_IR38064 tristate "Infineon IR38064" diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index a420877ba5335c..2191575a448b57 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -1869,7 +1869,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client, struct pmbus_sensor *sensor; sensor = pmbus_add_sensor(data, "fan", "target", index, page, - PMBUS_VIRT_FAN_TARGET_1 + id, 0xff, PSC_FAN, + 0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN, false, false, true); if (!sensor) @@ -1880,14 +1880,14 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client, return 0; sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, - PMBUS_VIRT_PWM_1 + id, 0xff, PSC_PWM, + 0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM, false, false, true); if (!sensor) return -ENOMEM; sensor = pmbus_add_sensor(data, "pwm", "enable", index, page, - PMBUS_VIRT_PWM_ENABLE_1 + id, 0xff, PSC_PWM, + 0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM, true, false, false); if (!sensor) @@ -1929,7 +1929,7 @@ static int pmbus_add_fan_attributes(struct i2c_client *client, continue; if (pmbus_add_sensor(data, "fan", "input", index, - page, pmbus_fan_registers[f], 0xff, + page, 0xff, pmbus_fan_registers[f], PSC_FAN, true, true, true) == NULL) return -ENOMEM; diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index ef39c83aaf337a..bae1dc08ec9a96 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -113,11 +113,18 @@ config I2C_STUB config I2C_SLAVE bool "I2C slave support" + help + This enables Linux to act as an I2C slave device. Note that your I2C + bus master driver also needs to support this functionality. Please + read Documentation/i2c/slave-interface.rst for further details. if I2C_SLAVE config I2C_SLAVE_EEPROM tristate "I2C eeprom slave driver" + help + This backend makes Linux behave like an I2C EEPROM. Please read + Documentation/i2c/slave-eeprom-backend.rst for further details. endif diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 7f10312d1b88f5..388978775be042 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -314,7 +314,8 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, DEB2("BUS ERROR - SDA Stuck low\n"); pca_reset(adap); goto out; - case 0x90: /* Bus error - SCL stuck low */ + case 0x78: /* Bus error - SCL stuck low (PCA9665) */ + case 0x90: /* Bus error - SCL stuck low (PCA9564) */ DEB2("BUS ERROR - SCL Stuck low\n"); pca_reset(adap); goto out; diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index c2efaaaac25275..a71bc58fc03c0c 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -191,6 +192,17 @@ static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev) return ret; } +static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = { + { + .ident = "Qtechnology QT5222", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Qtechnology"), + DMI_MATCH(DMI_PRODUCT_NAME, "QT5222"), + }, + }, + { } /* terminate list */ +}; + static int dw_i2c_plat_probe(struct platform_device *pdev) { struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -267,7 +279,8 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) adap = &dev->adapter; adap->owner = THIS_MODULE; - adap->class = I2C_CLASS_DEPRECATED; + adap->class = dmi_check_system(dw_i2c_hwmon_class_dmi) ? + I2C_CLASS_HWMON : I2C_CLASS_DEPRECATED; ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev)); adap->dev.of_node = pdev->dev.of_node; adap->nr = -1; diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index bb810dee8fb5e4..73f139690e4e54 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -180,6 +180,7 @@ static const struct pci_device_id pch_pcidev_id[] = { { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_I2C), 1, }, {0,} }; +MODULE_DEVICE_TABLE(pci, pch_pcidev_id); static irqreturn_t pch_i2c_handler(int irq, void *pData); diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c index 2fd717d8dd30ec..71d7bae2cbcadc 100644 --- a/drivers/i2c/busses/i2c-mlxcpld.c +++ b/drivers/i2c/busses/i2c-mlxcpld.c @@ -337,9 +337,9 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv) if (priv->smbus_block && (val & MLXCPLD_I2C_SMBUS_BLK_BIT)) { mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG, &datalen, 1); - if (unlikely(datalen > (I2C_SMBUS_BLOCK_MAX + 1))) { + if (unlikely(datalen > I2C_SMBUS_BLOCK_MAX)) { dev_err(priv->dev, "Incorrect smbus block read message len\n"); - return -E2BIG; + return -EPROTO; } } else { datalen = priv->xfer.data_len; diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 29fead208cad5a..216b3b8392b5e6 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -563,7 +563,7 @@ config LOONGSON_PCH_PIC Support for the Loongson PCH PIC Controller. config LOONGSON_PCH_MSI - bool "Loongson PCH PIC Controller" + bool "Loongson PCH MSI Controller" depends on MACH_LOONGSON64 || COMPILE_TEST depends on PCI default MACH_LOONGSON64 diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index cd685f521c77ac..6a5a87fc4601f4 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -3797,10 +3797,10 @@ static void its_wait_vpt_parse_complete(void) if (!gic_rdists->has_vpend_valid_dirty) return; - WARN_ON_ONCE(readq_relaxed_poll_timeout(vlpi_base + GICR_VPENDBASER, - val, - !(val & GICR_VPENDBASER_Dirty), - 10, 500)); + WARN_ON_ONCE(readq_relaxed_poll_timeout_atomic(vlpi_base + GICR_VPENDBASER, + val, + !(val & GICR_VPENDBASER_Dirty), + 10, 500)); } static void its_vpe_schedule(struct its_vpe *vpe) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 00de05abd3c3ad..c17fabd6741e26 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -329,10 +329,8 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { - void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); - unsigned int cpu, shift = (gic_irq(d) % 4) * 8; - u32 val, mask, bit; - unsigned long flags; + void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); + unsigned int cpu; if (!force) cpu = cpumask_any_and(mask_val, cpu_online_mask); @@ -342,13 +340,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) return -EINVAL; - gic_lock_irqsave(flags); - mask = 0xff << shift; - bit = gic_cpu_map[cpu] << shift; - val = readl_relaxed(reg) & ~mask; - writel_relaxed(val | bit, reg); - gic_unlock_irqrestore(flags); - + writeb_relaxed(gic_cpu_map[cpu], reg); irq_data_update_effective_affinity(d, cpumask_of(cpu)); return IRQ_SET_MASK_OK_DONE; diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c index a6f97fa6ff69d5..8017f6d32d52b7 100644 --- a/drivers/irqchip/irq-riscv-intc.c +++ b/drivers/irqchip/irq-riscv-intc.c @@ -99,7 +99,7 @@ static int __init riscv_intc_init(struct device_node *node, hartid = riscv_of_parent_hartid(node); if (hartid < 0) { - pr_warn("unable to fine hart id for %pOF\n", node); + pr_warn("unable to find hart id for %pOF\n", node); return 0; } diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 68aea22f2b8978..5216487db4fbea 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1324,13 +1324,13 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) return 0; /* fw doesn't need any host buffers */ /* spin till we get enough memory */ - while(host_page_buffer_sz > 0) { - - if((ioc->HostPageBuffer = pci_alloc_consistent( - ioc->pcidev, - host_page_buffer_sz, - &ioc->HostPageBuffer_dma)) != NULL) { - + while (host_page_buffer_sz > 0) { + ioc->HostPageBuffer = + dma_alloc_coherent(&ioc->pcidev->dev, + host_page_buffer_sz, + &ioc->HostPageBuffer_dma, + GFP_KERNEL); + if (ioc->HostPageBuffer) { dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", ioc->name, ioc->HostPageBuffer, @@ -2741,8 +2741,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) sz = ioc->alloc_sz; dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n", ioc->name, ioc->alloc, ioc->alloc_sz)); - pci_free_consistent(ioc->pcidev, sz, - ioc->alloc, ioc->alloc_dma); + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc, + ioc->alloc_dma); ioc->reply_frames = NULL; ioc->req_frames = NULL; ioc->alloc = NULL; @@ -2751,8 +2751,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) if (ioc->sense_buf_pool != NULL) { sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); - pci_free_consistent(ioc->pcidev, sz, - ioc->sense_buf_pool, ioc->sense_buf_pool_dma); + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool, + ioc->sense_buf_pool_dma); ioc->sense_buf_pool = NULL; ioc->alloc_total -= sz; } @@ -2802,7 +2802,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc) "HostPageBuffer free @ %p, sz=%d bytes\n", ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz)); - pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, + dma_free_coherent(&ioc->pcidev->dev, ioc->HostPageBuffer_sz, ioc->HostPageBuffer, ioc->HostPageBuffer_dma); ioc->HostPageBuffer = NULL; ioc->HostPageBuffer_sz = 0; @@ -4497,7 +4497,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc) ioc->name, sz, sz, num_chain)); total_size += sz; - mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma); + mem = dma_alloc_coherent(&ioc->pcidev->dev, total_size, + &alloc_dma, GFP_KERNEL); if (mem == NULL) { printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n", ioc->name); @@ -4574,8 +4575,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc) spin_unlock_irqrestore(&ioc->FreeQlock, flags); sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); - ioc->sense_buf_pool = - pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma); + ioc->sense_buf_pool = dma_alloc_coherent(&ioc->pcidev->dev, sz, + &ioc->sense_buf_pool_dma, GFP_KERNEL); if (ioc->sense_buf_pool == NULL) { printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n", ioc->name); @@ -4613,18 +4614,16 @@ PrimeIocFifos(MPT_ADAPTER *ioc) if (ioc->alloc != NULL) { sz = ioc->alloc_sz; - pci_free_consistent(ioc->pcidev, - sz, - ioc->alloc, ioc->alloc_dma); + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc, + ioc->alloc_dma); ioc->reply_frames = NULL; ioc->req_frames = NULL; ioc->alloc_total -= sz; } if (ioc->sense_buf_pool != NULL) { sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); - pci_free_consistent(ioc->pcidev, - sz, - ioc->sense_buf_pool, ioc->sense_buf_pool_dma); + dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool, + ioc->sense_buf_pool_dma); ioc->sense_buf_pool = NULL; } diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 28f4388c13373b..8410d03b940d74 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1116,10 +1116,16 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, dev_warn(ctrl->device, "Identify Descriptors failed (%d)\n", status); /* - * Don't treat an error as fatal, as we potentially already - * have a NGUID or EUI-64. + * Don't treat non-retryable errors as fatal, as we potentially + * already have a NGUID or EUI-64. If we failed with DNR set, + * we want to silently ignore the error as we can still + * identify the device, but if the status has DNR set, we want + * to propagate the error back specifically for the disk + * revalidation flow to make sure we don't abandon the + * device just because of a temporal retry-able error (such + * as path of transport errors). */ - if (status > 0 && !(status & NVME_SC_DNR)) + if (status > 0 && (status & NVME_SC_DNR)) status = 0; goto free_data; } diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 18d084ed497ef3..66509472fe06ae 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -672,10 +672,11 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id) } if (bdi_cap_stable_pages_required(ns->queue->backing_dev_info)) { - struct backing_dev_info *info = - ns->head->disk->queue->backing_dev_info; + struct gendisk *disk = ns->head->disk; - info->capabilities |= BDI_CAP_STABLE_WRITES; + if (disk) + disk->queue->backing_dev_info->capabilities |= + BDI_CAP_STABLE_WRITES; } } diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 773c45af938709..278d15ff1c5ae2 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -133,8 +133,10 @@ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) lockdep_assert_held(&lport->disc.disc_mutex); rdata = fc_rport_lookup(lport, port_id); - if (rdata) + if (rdata) { + kref_put(&rdata->kref, fc_rport_destroy); return rdata; + } if (lport->rport_priv_size > 0) rport_priv_size = lport->rport_priv_size; @@ -481,10 +483,11 @@ static void fc_rport_enter_delete(struct fc_rport_priv *rdata, fc_rport_state_enter(rdata, RPORT_ST_DELETE); - kref_get(&rdata->kref); - if (rdata->event == RPORT_EV_NONE && - !queue_work(rport_event_queue, &rdata->event_work)) - kref_put(&rdata->kref, fc_rport_destroy); + if (rdata->event == RPORT_EV_NONE) { + kref_get(&rdata->kref); + if (!queue_work(rport_event_queue, &rdata->event_work)) + kref_put(&rdata->kref, fc_rport_destroy); + } rdata->event = event; } diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4576d3ae993729..2436a17f5cd915 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5944,7 +5944,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) break; } - if (NVME_TARGET(vha->hw, fcport)) { + if (found && NVME_TARGET(vha->hw, fcport)) { if (fcport->disc_state == DSC_DELETE_PEND) { qla2x00_set_fcport_disc_state(fcport, DSC_GNL); vha->fcport_count--; diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 58190c94561fcc..91c6affe139c99 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -1109,6 +1109,8 @@ static int dspi_suspend(struct device *dev) struct spi_controller *ctlr = dev_get_drvdata(dev); struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); + if (dspi->irq) + disable_irq(dspi->irq); spi_controller_suspend(ctlr); clk_disable_unprepare(dspi->clk); @@ -1129,6 +1131,8 @@ static int dspi_resume(struct device *dev) if (ret) return ret; spi_controller_resume(ctlr); + if (dspi->irq) + enable_irq(dspi->irq); return 0; } @@ -1385,22 +1389,22 @@ static int dspi_probe(struct platform_device *pdev) goto poll_mode; } - ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, - IRQF_SHARED, pdev->name, dspi); + init_completion(&dspi->xfer_done); + + ret = request_threaded_irq(dspi->irq, dspi_interrupt, NULL, + IRQF_SHARED, pdev->name, dspi); if (ret < 0) { dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); goto out_clk_put; } - init_completion(&dspi->xfer_done); - poll_mode: if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { ret = dspi_request_dma(dspi, res->start); if (ret < 0) { dev_err(&pdev->dev, "can't get dma channels\n"); - goto out_clk_put; + goto out_free_irq; } } @@ -1415,11 +1419,14 @@ static int dspi_probe(struct platform_device *pdev) ret = spi_register_controller(ctlr); if (ret != 0) { dev_err(&pdev->dev, "Problem registering DSPI ctlr\n"); - goto out_clk_put; + goto out_free_irq; } return ret; +out_free_irq: + if (dspi->irq) + free_irq(dspi->irq, dspi); out_clk_put: clk_disable_unprepare(dspi->clk); out_ctlr_put: @@ -1434,18 +1441,8 @@ static int dspi_remove(struct platform_device *pdev) struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); /* Disconnect from the SPI framework */ - dspi_release_dma(dspi); - clk_disable_unprepare(dspi->clk); spi_unregister_controller(dspi->ctlr); - return 0; -} - -static void dspi_shutdown(struct platform_device *pdev) -{ - struct spi_controller *ctlr = platform_get_drvdata(pdev); - struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); - /* Disable RX and TX */ regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF, @@ -1455,8 +1452,16 @@ static void dspi_shutdown(struct platform_device *pdev) regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, SPI_MCR_HALT); dspi_release_dma(dspi); + if (dspi->irq) + free_irq(dspi->irq, dspi); clk_disable_unprepare(dspi->clk); - spi_unregister_controller(dspi->ctlr); + + return 0; +} + +static void dspi_shutdown(struct platform_device *pdev) +{ + dspi_remove(pdev); } static struct platform_driver fsl_dspi_driver = { diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 6721910e5f2aaa..0040362b716227 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1485,6 +1485,11 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { { PCI_VDEVICE(INTEL, 0x4daa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x4dfb), LPSS_CNL_SSP }, + /* TGL-H */ + { PCI_VDEVICE(INTEL, 0x43aa), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x43ab), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x43fb), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x43fd), LPSS_CNL_SSP }, /* APL */ { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 9e124020519fc2..6c0e1b053126e0 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -123,12 +123,12 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev, { int i; - for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) { - if (power > cpufreq_cdev->em->table[i].power) + for (i = cpufreq_cdev->max_level; i >= 0; i--) { + if (power >= cpufreq_cdev->em->table[i].power) break; } - return cpufreq_cdev->em->table[i + 1].frequency; + return cpufreq_cdev->em->table[i].frequency; } /** diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index e761c9b422179d..1b84ea674edb74 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -649,7 +649,7 @@ MODULE_DEVICE_TABLE(of, of_imx_thermal_match); static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) { struct device_node *np; - int ret; + int ret = 0; data->policy = cpufreq_cpu_get(0); if (!data->policy) { @@ -664,11 +664,12 @@ static int imx_thermal_register_legacy_cooling(struct imx_thermal_data *data) if (IS_ERR(data->cdev)) { ret = PTR_ERR(data->cdev); cpufreq_cpu_put(data->policy); - return ret; } } - return 0; + of_node_put(np); + + return ret; } static void imx_thermal_unregister_legacy_cooling(struct imx_thermal_data *data) diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 76e30603d4d588..6b7ef1993d7e23 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -211,6 +211,9 @@ enum { /* The total number of temperature sensors in the MT8183 */ #define MT8183_NUM_SENSORS 6 +/* The number of banks in the MT8183 */ +#define MT8183_NUM_ZONES 1 + /* The number of sensing points per bank */ #define MT8183_NUM_SENSORS_PER_ZONE 6 @@ -497,7 +500,7 @@ static const struct mtk_thermal_data mt7622_thermal_data = { */ static const struct mtk_thermal_data mt8183_thermal_data = { .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL, - .num_banks = MT8183_NUM_SENSORS_PER_ZONE, + .num_banks = MT8183_NUM_ZONES, .num_sensors = MT8183_NUM_SENSORS, .vts_index = mt8183_vts_index, .cali_val = MT8183_CALIBRATION, diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 8d3e94d2a9ed44..39c4462e38f622 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -382,7 +382,7 @@ static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver) * * Return: IRQ_HANDLED */ -irqreturn_t tsens_critical_irq_thread(int irq, void *data) +static irqreturn_t tsens_critical_irq_thread(int irq, void *data) { struct tsens_priv *priv = data; struct tsens_irq_data d; @@ -452,7 +452,7 @@ irqreturn_t tsens_critical_irq_thread(int irq, void *data) * * Return: IRQ_HANDLED */ -irqreturn_t tsens_irq_thread(int irq, void *data) +static irqreturn_t tsens_irq_thread(int irq, void *data) { struct tsens_priv *priv = data; struct tsens_irq_data d; @@ -520,7 +520,7 @@ irqreturn_t tsens_irq_thread(int irq, void *data) return IRQ_HANDLED; } -int tsens_set_trips(void *_sensor, int low, int high) +static int tsens_set_trips(void *_sensor, int low, int high) { struct tsens_sensor *s = _sensor; struct tsens_priv *priv = s->priv; @@ -557,7 +557,7 @@ int tsens_set_trips(void *_sensor, int low, int high) return 0; } -int tsens_enable_irq(struct tsens_priv *priv) +static int tsens_enable_irq(struct tsens_priv *priv) { int ret; int val = tsens_version(priv) > VER_1_X ? 7 : 1; @@ -570,7 +570,7 @@ int tsens_enable_irq(struct tsens_priv *priv) return ret; } -void tsens_disable_irq(struct tsens_priv *priv) +static void tsens_disable_irq(struct tsens_priv *priv) { regmap_field_write(priv->rf[INT_EN], 0); } diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c index 58fe7c1ef00b12..c48c5e9b8f203d 100644 --- a/drivers/thermal/rcar_gen3_thermal.c +++ b/drivers/thermal/rcar_gen3_thermal.c @@ -167,7 +167,7 @@ static int rcar_gen3_thermal_get_temp(void *devdata, int *temp) { struct rcar_gen3_thermal_tsc *tsc = devdata; int mcelsius, val; - u32 reg; + int reg; /* Read register and convert to mili Celsius */ reg = rcar_gen3_thermal_read(tsc, REG_GEN3_TEMP) & CTEMP_MASK; diff --git a/drivers/thermal/sprd_thermal.c b/drivers/thermal/sprd_thermal.c index a340374e8c51ae..4cde70dcf65565 100644 --- a/drivers/thermal/sprd_thermal.c +++ b/drivers/thermal/sprd_thermal.c @@ -348,8 +348,8 @@ static int sprd_thm_probe(struct platform_device *pdev) thm->var_data = pdata; thm->base = devm_platform_ioremap_resource(pdev, 0); - if (!thm->base) - return -ENOMEM; + if (IS_ERR(thm->base)) + return PTR_ERR(thm->base); thm->nr_sensors = of_get_child_count(np); if (thm->nr_sensors == 0 || thm->nr_sensors > SPRD_THM_MAX_SENSOR) { diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 040d2a43e8e350..4f168b46fbca58 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -69,11 +69,27 @@ struct xenbus_map_node { unsigned int nr_handles; }; +struct map_ring_valloc { + struct xenbus_map_node *node; + + /* Why do we need two arrays? See comment of __xenbus_map_ring */ + union { + unsigned long addrs[XENBUS_MAX_RING_GRANTS]; + pte_t *ptes[XENBUS_MAX_RING_GRANTS]; + }; + phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS]; + + struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS]; + struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS]; + + unsigned int idx; /* HVM only. */ +}; + static DEFINE_SPINLOCK(xenbus_valloc_lock); static LIST_HEAD(xenbus_valloc_pages); struct xenbus_ring_ops { - int (*map)(struct xenbus_device *dev, + int (*map)(struct xenbus_device *dev, struct map_ring_valloc *info, grant_ref_t *gnt_refs, unsigned int nr_grefs, void **vaddr); int (*unmap)(struct xenbus_device *dev, void *vaddr); @@ -440,8 +456,7 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn); * Map @nr_grefs pages of memory into this domain from another * domain's grant table. xenbus_map_ring_valloc allocates @nr_grefs * pages of virtual address space, maps the pages to that address, and - * sets *vaddr to that address. Returns 0 on success, and GNTST_* - * (see xen/include/interface/grant_table.h) or -ENOMEM / -EINVAL on + * sets *vaddr to that address. Returns 0 on success, and -errno on * error. If an error is returned, device will switch to * XenbusStateClosing and the error message will be saved in XenStore. */ @@ -449,12 +464,25 @@ int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs, unsigned int nr_grefs, void **vaddr) { int err; + struct map_ring_valloc *info; + + *vaddr = NULL; + + if (nr_grefs > XENBUS_MAX_RING_GRANTS) + return -EINVAL; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; - err = ring_ops->map(dev, gnt_refs, nr_grefs, vaddr); - /* Some hypervisors are buggy and can return 1. */ - if (err > 0) - err = GNTST_general_error; + info->node = kzalloc(sizeof(*info->node), GFP_KERNEL); + if (!info->node) + err = -ENOMEM; + else + err = ring_ops->map(dev, info, gnt_refs, nr_grefs, vaddr); + kfree(info->node); + kfree(info); return err; } EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc); @@ -466,62 +494,57 @@ static int __xenbus_map_ring(struct xenbus_device *dev, grant_ref_t *gnt_refs, unsigned int nr_grefs, grant_handle_t *handles, - phys_addr_t *addrs, + struct map_ring_valloc *info, unsigned int flags, bool *leaked) { - struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS]; - struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS]; int i, j; - int err = GNTST_okay; if (nr_grefs > XENBUS_MAX_RING_GRANTS) return -EINVAL; for (i = 0; i < nr_grefs; i++) { - memset(&map[i], 0, sizeof(map[i])); - gnttab_set_map_op(&map[i], addrs[i], flags, gnt_refs[i], - dev->otherend_id); + gnttab_set_map_op(&info->map[i], info->phys_addrs[i], flags, + gnt_refs[i], dev->otherend_id); handles[i] = INVALID_GRANT_HANDLE; } - gnttab_batch_map(map, i); + gnttab_batch_map(info->map, i); for (i = 0; i < nr_grefs; i++) { - if (map[i].status != GNTST_okay) { - err = map[i].status; - xenbus_dev_fatal(dev, map[i].status, + if (info->map[i].status != GNTST_okay) { + xenbus_dev_fatal(dev, info->map[i].status, "mapping in shared page %d from domain %d", gnt_refs[i], dev->otherend_id); goto fail; } else - handles[i] = map[i].handle; + handles[i] = info->map[i].handle; } - return GNTST_okay; + return 0; fail: for (i = j = 0; i < nr_grefs; i++) { if (handles[i] != INVALID_GRANT_HANDLE) { - memset(&unmap[j], 0, sizeof(unmap[j])); - gnttab_set_unmap_op(&unmap[j], (phys_addr_t)addrs[i], + gnttab_set_unmap_op(&info->unmap[j], + info->phys_addrs[i], GNTMAP_host_map, handles[i]); j++; } } - if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, j)) + if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, info->unmap, j)) BUG(); *leaked = false; for (i = 0; i < j; i++) { - if (unmap[i].status != GNTST_okay) { + if (info->unmap[i].status != GNTST_okay) { *leaked = true; break; } } - return err; + return -ENOENT; } /** @@ -566,21 +589,12 @@ static int xenbus_unmap_ring(struct xenbus_device *dev, grant_handle_t *handles, return err; } -struct map_ring_valloc_hvm -{ - unsigned int idx; - - /* Why do we need two arrays? See comment of __xenbus_map_ring */ - phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS]; - unsigned long addrs[XENBUS_MAX_RING_GRANTS]; -}; - static void xenbus_map_ring_setup_grant_hvm(unsigned long gfn, unsigned int goffset, unsigned int len, void *data) { - struct map_ring_valloc_hvm *info = data; + struct map_ring_valloc *info = data; unsigned long vaddr = (unsigned long)gfn_to_virt(gfn); info->phys_addrs[info->idx] = vaddr; @@ -589,39 +603,28 @@ static void xenbus_map_ring_setup_grant_hvm(unsigned long gfn, info->idx++; } -static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, - grant_ref_t *gnt_ref, - unsigned int nr_grefs, - void **vaddr) +static int xenbus_map_ring_hvm(struct xenbus_device *dev, + struct map_ring_valloc *info, + grant_ref_t *gnt_ref, + unsigned int nr_grefs, + void **vaddr) { - struct xenbus_map_node *node; + struct xenbus_map_node *node = info->node; int err; void *addr; bool leaked = false; - struct map_ring_valloc_hvm info = { - .idx = 0, - }; unsigned int nr_pages = XENBUS_PAGES(nr_grefs); - if (nr_grefs > XENBUS_MAX_RING_GRANTS) - return -EINVAL; - - *vaddr = NULL; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - err = alloc_xenballooned_pages(nr_pages, node->hvm.pages); if (err) goto out_err; gnttab_foreach_grant(node->hvm.pages, nr_grefs, xenbus_map_ring_setup_grant_hvm, - &info); + info); err = __xenbus_map_ring(dev, gnt_ref, nr_grefs, node->handles, - info.phys_addrs, GNTMAP_host_map, &leaked); + info, GNTMAP_host_map, &leaked); node->nr_handles = nr_grefs; if (err) @@ -641,11 +644,13 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, spin_unlock(&xenbus_valloc_lock); *vaddr = addr; + info->node = NULL; + return 0; out_xenbus_unmap_ring: if (!leaked) - xenbus_unmap_ring(dev, node->handles, nr_grefs, info.addrs); + xenbus_unmap_ring(dev, node->handles, nr_grefs, info->addrs); else pr_alert("leaking %p size %u page(s)", addr, nr_pages); @@ -653,7 +658,6 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev, if (!leaked) free_xenballooned_pages(nr_pages, node->hvm.pages); out_err: - kfree(node); return err; } @@ -676,40 +680,30 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr) EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree); #ifdef CONFIG_XEN_PV -static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev, - grant_ref_t *gnt_refs, - unsigned int nr_grefs, - void **vaddr) +static int xenbus_map_ring_pv(struct xenbus_device *dev, + struct map_ring_valloc *info, + grant_ref_t *gnt_refs, + unsigned int nr_grefs, + void **vaddr) { - struct xenbus_map_node *node; + struct xenbus_map_node *node = info->node; struct vm_struct *area; - pte_t *ptes[XENBUS_MAX_RING_GRANTS]; - phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS]; int err = GNTST_okay; int i; bool leaked; - *vaddr = NULL; - - if (nr_grefs > XENBUS_MAX_RING_GRANTS) - return -EINVAL; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - - area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, ptes); + area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, info->ptes); if (!area) { kfree(node); return -ENOMEM; } for (i = 0; i < nr_grefs; i++) - phys_addrs[i] = arbitrary_virt_to_machine(ptes[i]).maddr; + info->phys_addrs[i] = + arbitrary_virt_to_machine(info->ptes[i]).maddr; err = __xenbus_map_ring(dev, gnt_refs, nr_grefs, node->handles, - phys_addrs, - GNTMAP_host_map | GNTMAP_contains_pte, + info, GNTMAP_host_map | GNTMAP_contains_pte, &leaked); if (err) goto failed; @@ -722,6 +716,8 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev, spin_unlock(&xenbus_valloc_lock); *vaddr = area->addr; + info->node = NULL; + return 0; failed: @@ -730,11 +726,10 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev, else pr_alert("leaking VM area %p size %u page(s)", area, nr_grefs); - kfree(node); return err; } -static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr) +static int xenbus_unmap_ring_pv(struct xenbus_device *dev, void *vaddr) { struct xenbus_map_node *node; struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS]; @@ -798,12 +793,12 @@ static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr) } static const struct xenbus_ring_ops ring_ops_pv = { - .map = xenbus_map_ring_valloc_pv, - .unmap = xenbus_unmap_ring_vfree_pv, + .map = xenbus_map_ring_pv, + .unmap = xenbus_unmap_ring_pv, }; #endif -struct unmap_ring_vfree_hvm +struct unmap_ring_hvm { unsigned int idx; unsigned long addrs[XENBUS_MAX_RING_GRANTS]; @@ -814,19 +809,19 @@ static void xenbus_unmap_ring_setup_grant_hvm(unsigned long gfn, unsigned int len, void *data) { - struct unmap_ring_vfree_hvm *info = data; + struct unmap_ring_hvm *info = data; info->addrs[info->idx] = (unsigned long)gfn_to_virt(gfn); info->idx++; } -static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr) +static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr) { int rv; struct xenbus_map_node *node; void *addr; - struct unmap_ring_vfree_hvm info = { + struct unmap_ring_hvm info = { .idx = 0, }; unsigned int nr_pages; @@ -887,8 +882,8 @@ enum xenbus_state xenbus_read_driver_state(const char *path) EXPORT_SYMBOL_GPL(xenbus_read_driver_state); static const struct xenbus_ring_ops ring_ops_hvm = { - .map = xenbus_map_ring_valloc_hvm, - .unmap = xenbus_unmap_ring_vfree_hvm, + .map = xenbus_map_ring_hvm, + .unmap = xenbus_unmap_ring_hvm, }; void __init xenbus_ring_ops_init(void) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index fc98b97b396a44..53588d7517b4d0 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -399,6 +399,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) if (ses->sign) seq_puts(m, " signed"); + seq_printf(m, "\n\tUser: %d Cred User: %d", + from_kuid(&init_user_ns, ses->linux_uid), + from_kuid(&init_user_ns, ses->cred_uid)); + if (ses->chan_count > 1) { seq_printf(m, "\n\n\tExtra Channels: %zu\n", ses->chan_count-1); @@ -406,7 +410,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) cifs_dump_channel(m, j, &ses->chans[j]); } - seq_puts(m, "\n\tShares:"); + seq_puts(m, "\n\n\tShares:"); j = 0; seq_printf(m, "\n\t%d) IPC: ", j); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 5fac34f192afd8..a61abde09ffe1f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -5306,9 +5306,15 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) vol_info->nocase = master_tcon->nocase; vol_info->nohandlecache = master_tcon->nohandlecache; vol_info->local_lease = master_tcon->local_lease; + vol_info->no_lease = master_tcon->no_lease; + vol_info->resilient = master_tcon->use_resilient; + vol_info->persistent = master_tcon->use_persistent; + vol_info->handle_timeout = master_tcon->handle_timeout; vol_info->no_linux_ext = !master_tcon->unix_ext; + vol_info->linux_ext = master_tcon->posix_extensions; vol_info->sectype = master_tcon->ses->sectype; vol_info->sign = master_tcon->ses->sign; + vol_info->seal = master_tcon->seal; rc = cifs_set_vol_auth(vol_info, master_tcon->ses); if (rc) { @@ -5334,10 +5340,6 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) goto out; } - /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ - if (tcon->posix_extensions) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; - if (cap_unix(ses)) reset_cifs_unix_caps(0, tcon, NULL, vol_info); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ce95801e9b6644..49c3ea8aa84588 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2044,6 +2044,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, FILE_UNIX_BASIC_INFO *info_buf_target; unsigned int xid; int rc, tmprc; + bool new_target = d_really_is_negative(target_dentry); if (flags & ~RENAME_NOREPLACE) return -EINVAL; @@ -2120,8 +2121,13 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, */ unlink_target: - /* Try unlinking the target dentry if it's not negative */ - if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) { + /* + * If the target dentry was created during the rename, try + * unlinking it if it's not negative + */ + if (new_target && + d_really_is_positive(target_dentry) && + (rc == -EACCES || rc == -EEXIST)) { if (d_is_dir(target_dentry)) tmprc = cifs_rmdir(target_dir, target_dentry); else diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index d11e31064679b1..84433d0653f92a 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -523,7 +523,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, const int timeout, const int flags, unsigned int *instance) { - int rc; + long rc; int *credits; int optype; long int t; diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index de43534aa2997a..91ece649285d28 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -309,7 +309,7 @@ const struct file_operations exfat_dir_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, .iterate = exfat_iterate, - .fsync = generic_file_fsync, + .fsync = exfat_file_fsync, }; int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu) @@ -425,10 +425,12 @@ static void exfat_init_name_entry(struct exfat_dentry *ep, ep->dentry.name.flags = 0x0; for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) { - ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname); - if (*uniname == 0x0) - break; - uniname++; + if (*uniname != 0x0) { + ep->dentry.name.unicode_0_14[i] = cpu_to_le16(*uniname); + uniname++; + } else { + ep->dentry.name.unicode_0_14[i] = 0x0; + } } } diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 595f3117f49248..7579cd3bbadba8 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -420,6 +420,7 @@ void exfat_truncate(struct inode *inode, loff_t size); int exfat_setattr(struct dentry *dentry, struct iattr *attr); int exfat_getattr(const struct path *path, struct kstat *stat, unsigned int request_mask, unsigned int query_flags); +int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); /* namei.c */ extern const struct dentry_operations exfat_dentry_ops; diff --git a/fs/exfat/file.c b/fs/exfat/file.c index fce03f31878735..3b7fea465fd41e 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "exfat_raw.h" #include "exfat_fs.h" @@ -346,12 +347,28 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr) return error; } +int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) +{ + struct inode *inode = filp->f_mapping->host; + int err; + + err = __generic_file_fsync(filp, start, end, datasync); + if (err) + return err; + + err = sync_blockdev(inode->i_sb->s_bdev); + if (err) + return err; + + return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL); +} + const struct file_operations exfat_file_operations = { .llseek = generic_file_llseek, .read_iter = generic_file_read_iter, .write_iter = generic_file_write_iter, .mmap = generic_file_mmap, - .fsync = generic_file_fsync, + .fsync = exfat_file_fsync, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, }; diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index 5b0f35329d63e0..2b9e21094a96db 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -975,7 +975,6 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry) goto unlock; } - exfat_set_vol_flags(sb, VOL_DIRTY); exfat_chain_set(&clu_to_free, ei->start_clu, EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags); @@ -1002,6 +1001,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry) num_entries++; brelse(bh); + exfat_set_vol_flags(sb, VOL_DIRTY); err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries); if (err) { exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err); @@ -1077,10 +1077,14 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir, epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh, §or_old); + if (!epold) + return -EIO; epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh, §or_new); - if (!epold || !epnew) + if (!epnew) { + brelse(old_bh); return -EIO; + } memcpy(epnew, epold, DENTRY_SIZE); exfat_update_bh(sb, new_bh, sync); @@ -1161,10 +1165,14 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir, epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh, §or_mov); + if (!epmov) + return -EIO; epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh, §or_new); - if (!epmov || !epnew) + if (!epnew) { + brelse(mov_bh); return -EIO; + } memcpy(epnew, epmov, DENTRY_SIZE); exfat_update_bh(sb, new_bh, IS_DIRSYNC(inode)); diff --git a/fs/exfat/super.c b/fs/exfat/super.c index e650e65536f848..253a92460d5222 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -693,10 +693,20 @@ static void exfat_free(struct fs_context *fc) } } +static int exfat_reconfigure(struct fs_context *fc) +{ + fc->sb_flags |= SB_NODIRATIME; + + /* volume flag will be updated in exfat_sync_fs */ + sync_filesystem(fc->root->d_sb); + return 0; +} + static const struct fs_context_operations exfat_context_ops = { .parse_param = exfat_parse_param, .get_tree = exfat_get_tree, .free = exfat_free, + .reconfigure = exfat_reconfigure, }; static int exfat_init_fs_context(struct fs_context *fc) diff --git a/fs/file_table.c b/fs/file_table.c index 65603502fed6f4..656647f9575a7c 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -230,7 +230,7 @@ struct file *alloc_file_pseudo(struct inode *inode, struct vfsmount *mnt, d_set_d_op(path.dentry, &anon_ops); path.mnt = mntget(mnt); d_instantiate(path.dentry, inode); - file = alloc_file(&path, flags | FMODE_NONOTIFY, fops); + file = alloc_file(&path, flags, fops); if (IS_ERR(file)) { ihold(inode); path_put(&path); diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 2299dcc417eae9..8545024a1401f7 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1899,7 +1899,10 @@ bool gfs2_delete_work_queued(const struct gfs2_glock *gl) static void flush_delete_work(struct gfs2_glock *gl) { - flush_delayed_work(&gl->gl_delete); + if (cancel_delayed_work(&gl->gl_delete)) { + queue_delayed_work(gfs2_delete_workqueue, + &gl->gl_delete, 0); + } gfs2_glock_queue_work(gl, 0); } diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index c84887769b5ade..de1d5f1d9ff856 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -531,8 +531,7 @@ static int freeze_go_sync(struct gfs2_glock *gl) int error = 0; struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; - if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp) && - test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + if (gl->gl_req == LM_ST_EXCLUSIVE && !gfs2_withdrawn(sdp)) { atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); error = freeze_super(sdp->sd_vfs); if (error) { @@ -545,8 +544,11 @@ static int freeze_go_sync(struct gfs2_glock *gl) gfs2_assert_withdraw(sdp, 0); } queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE | - GFS2_LFC_FREEZE_GO_SYNC); + if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE | + GFS2_LFC_FREEZE_GO_SYNC); + else /* read-only mounts */ + atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); } return 0; } diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 03ab11fab96268..ca2ec02436ec7f 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -399,7 +399,6 @@ enum { GIF_QD_LOCKED = 1, GIF_ALLOC_FAILED = 2, GIF_SW_PAGED = 3, - GIF_ORDERED = 4, GIF_FREE_VFS_INODE = 5, GIF_GLOP_PENDING = 6, GIF_DEFERRED_DELETE = 7, diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 370c3a4b31acad..6774865f5b5b5c 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -207,10 +207,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, if (no_formal_ino && ip->i_no_formal_ino && no_formal_ino != ip->i_no_formal_ino) { + error = -ESTALE; if (inode->i_state & I_NEW) goto fail; iput(inode); - return ERR_PTR(-ESTALE); + return ERR_PTR(error); } if (inode->i_state & I_NEW) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 3e473443178329..a76e55bc28ebfd 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -613,6 +613,12 @@ static int ip_cmp(void *priv, struct list_head *a, struct list_head *b) return 0; } +static void __ordered_del_inode(struct gfs2_inode *ip) +{ + if (!list_empty(&ip->i_ordered)) + list_del_init(&ip->i_ordered); +} + static void gfs2_ordered_write(struct gfs2_sbd *sdp) { struct gfs2_inode *ip; @@ -623,8 +629,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp) while (!list_empty(&sdp->sd_log_ordered)) { ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered); if (ip->i_inode.i_mapping->nrpages == 0) { - test_and_clear_bit(GIF_ORDERED, &ip->i_flags); - list_del(&ip->i_ordered); + __ordered_del_inode(ip); continue; } list_move(&ip->i_ordered, &written); @@ -643,8 +648,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp) spin_lock(&sdp->sd_ordered_lock); while (!list_empty(&sdp->sd_log_ordered)) { ip = list_first_entry(&sdp->sd_log_ordered, struct gfs2_inode, i_ordered); - list_del(&ip->i_ordered); - WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags)); + __ordered_del_inode(ip); if (ip->i_inode.i_mapping->nrpages == 0) continue; spin_unlock(&sdp->sd_ordered_lock); @@ -659,8 +663,7 @@ void gfs2_ordered_del_inode(struct gfs2_inode *ip) struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); spin_lock(&sdp->sd_ordered_lock); - if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) - list_del(&ip->i_ordered); + __ordered_del_inode(ip); spin_unlock(&sdp->sd_ordered_lock); } @@ -1002,6 +1005,16 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) out: if (gfs2_withdrawn(sdp)) { + /** + * If the tr_list is empty, we're withdrawing during a log + * flush that targets a transaction, but the transaction was + * never queued onto any of the ail lists. Here we add it to + * ail1 just so that ail_drain() will find and free it. + */ + spin_lock(&sdp->sd_ail_lock); + if (tr && list_empty(&tr->tr_list)) + list_add(&tr->tr_list, &sdp->sd_ail1_list); + spin_unlock(&sdp->sd_ail_lock); ail_drain(sdp); /* frees all transactions */ tr = NULL; } diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index c1cd6ae176597c..8965c751a30396 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h @@ -53,9 +53,9 @@ static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip) if (gfs2_is_jdata(ip) || !gfs2_is_ordered(sdp)) return; - if (!test_bit(GIF_ORDERED, &ip->i_flags)) { + if (list_empty(&ip->i_ordered)) { spin_lock(&sdp->sd_ordered_lock); - if (!test_and_set_bit(GIF_ORDERED, &ip->i_flags)) + if (list_empty(&ip->i_ordered)) list_add(&ip->i_ordered, &sdp->sd_log_ordered); spin_unlock(&sdp->sd_ordered_lock); } diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 733470ca6be9d5..c7393ee9cf6836 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -39,6 +39,7 @@ static void gfs2_init_inode_once(void *foo) atomic_set(&ip->i_sizehint, 0); init_rwsem(&ip->i_rw_mutex); INIT_LIST_HEAD(&ip->i_trunc_list); + INIT_LIST_HEAD(&ip->i_ordered); ip->i_qadata = NULL; gfs2_holder_mark_uninitialized(&ip->i_rgd_gh); memset(&ip->i_res, 0, sizeof(ip->i_res)); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 094f5fe7c00906..6d18d2c91add28 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1136,7 +1136,18 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) goto fail_per_node; } - if (!sb_rdonly(sb)) { + if (sb_rdonly(sb)) { + struct gfs2_holder freeze_gh; + + error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, + LM_FLAG_NOEXP | GL_EXACT, + &freeze_gh); + if (error) { + fs_err(sdp, "can't make FS RO: %d\n", error); + goto fail_per_node; + } + gfs2_glock_dq_uninit(&freeze_gh); + } else { error = gfs2_make_fs_rw(sdp); if (error) { fs_err(sdp, "can't make FS RW: %d\n", error); diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 96c345f4927387..390ea79d682c25 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -364,8 +364,8 @@ void gfs2_recover_func(struct work_struct *work) /* Acquire a shared hold on the freeze lock */ error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, - LM_FLAG_NOEXP | LM_FLAG_PRIORITY, - &thaw_gh); + LM_FLAG_NOEXP | LM_FLAG_PRIORITY | + GL_EXACT, &thaw_gh); if (error) goto fail_gunlock_ji; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 32d8d26126a161..47d0ae158b6990 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -167,7 +167,8 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) if (error) return error; - error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, + error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, + LM_FLAG_NOEXP | GL_EXACT, &freeze_gh); if (error) goto fail_threads; @@ -203,7 +204,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) return 0; fail: - freeze_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&freeze_gh); fail_threads: if (sdp->sd_quotad_process) @@ -430,7 +430,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp) } error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE, - GL_NOCACHE, &sdp->sd_freeze_gh); + LM_FLAG_NOEXP, &sdp->sd_freeze_gh); if (error) goto out; @@ -613,13 +613,15 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) !gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) { if (!log_write_allowed) { error = gfs2_glock_nq_init(sdp->sd_freeze_gl, - LM_ST_SHARED, GL_NOCACHE | - LM_FLAG_TRY, &freeze_gh); + LM_ST_SHARED, LM_FLAG_TRY | + LM_FLAG_NOEXP | GL_EXACT, + &freeze_gh); if (error == GLR_TRYFAILED) error = 0; } else { error = gfs2_glock_nq_init(sdp->sd_freeze_gl, - LM_ST_SHARED, GL_NOCACHE, + LM_ST_SHARED, + LM_FLAG_NOEXP | GL_EXACT, &freeze_gh); if (error && !gfs2_withdrawn(sdp)) return error; @@ -761,8 +763,8 @@ void gfs2_freeze_func(struct work_struct *work) struct super_block *sb = sdp->sd_vfs; atomic_inc(&sb->s_active); - error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, - &freeze_gh); + error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, + LM_FLAG_NOEXP | GL_EXACT, &freeze_gh); if (error) { fs_info(sdp, "GFS2: couldn't get freeze lock : %d\n", error); gfs2_assert_withdraw(sdp, 0); @@ -774,8 +776,6 @@ void gfs2_freeze_func(struct work_struct *work) error); gfs2_assert_withdraw(sdp, 0); } - if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) - freeze_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&freeze_gh); } deactivate_super(sb); diff --git a/fs/io_uring.c b/fs/io_uring.c index e507737f044e08..d37d7ea5ebe58c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4072,6 +4072,29 @@ struct io_poll_table { int error; }; +static int io_req_task_work_add(struct io_kiocb *req, struct callback_head *cb) +{ + struct task_struct *tsk = req->task; + struct io_ring_ctx *ctx = req->ctx; + int ret, notify = TWA_RESUME; + + /* + * SQPOLL kernel thread doesn't need notification, just a wakeup. + * If we're not using an eventfd, then TWA_RESUME is always fine, + * as we won't have dependencies between request completions for + * other kernel wait conditions. + */ + if (ctx->flags & IORING_SETUP_SQPOLL) + notify = 0; + else if (ctx->cq_ev_fd) + notify = TWA_SIGNAL; + + ret = task_work_add(tsk, cb, notify); + if (!ret) + wake_up_process(tsk); + return ret; +} + static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll, __poll_t mask, task_work_func_t func) { @@ -4095,13 +4118,13 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll, * of executing it. We can't safely execute it anyway, as we may not * have the needed state needed for it anyway. */ - ret = task_work_add(tsk, &req->task_work, true); + ret = io_req_task_work_add(req, &req->task_work); if (unlikely(ret)) { WRITE_ONCE(poll->canceled, true); tsk = io_wq_get_task(req->ctx->io_wq); - task_work_add(tsk, &req->task_work, true); + task_work_add(tsk, &req->task_work, 0); + wake_up_process(tsk); } - wake_up_process(tsk); return 1; } @@ -6182,15 +6205,23 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, do { prepare_to_wait_exclusive(&ctx->wait, &iowq.wq, TASK_INTERRUPTIBLE); + /* make sure we run task_work before checking for signals */ if (current->task_works) task_work_run(); - if (io_should_wake(&iowq, false)) - break; - schedule(); if (signal_pending(current)) { + if (current->jobctl & JOBCTL_TASK_WORK) { + spin_lock_irq(¤t->sighand->siglock); + current->jobctl &= ~JOBCTL_TASK_WORK; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + continue; + } ret = -EINTR; break; } + if (io_should_wake(&iowq, false)) + break; + schedule(); } while (1); finish_wait(&ctx->wait, &iowq.wq); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bb3d2c32664ad9..cce2510b2ccaaf 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7912,9 +7912,14 @@ nfs4_state_start_net(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int ret; - ret = nfs4_state_create_net(net); + ret = get_nfsdfs(net); if (ret) return ret; + ret = nfs4_state_create_net(net); + if (ret) { + mntput(nn->nfsd_mnt); + return ret; + } locks_start_grace(net, &nn->nfsd4_manager); nfsd4_client_tracking_init(net); if (nn->track_reclaim_completes && nn->reclaim_str_hashtbl_size == 0) @@ -7984,6 +7989,7 @@ nfs4_state_shutdown_net(struct net *net) nfsd4_client_tracking_exit(net); nfs4_state_destroy_net(net); + mntput(nn->nfsd_mnt); } void diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index b68e96681522ec..cd05732f8eaa84 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1335,6 +1335,7 @@ void nfsd_client_rmdir(struct dentry *dentry) WARN_ON_ONCE(ret); fsnotify_rmdir(dir, dentry); d_delete(dentry); + dput(dentry); inode_unlock(dir); } @@ -1424,6 +1425,18 @@ static struct file_system_type nfsd_fs_type = { }; MODULE_ALIAS_FS("nfsd"); +int get_nfsdfs(struct net *net) +{ + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct vfsmount *mnt; + + mnt = vfs_kern_mount(&nfsd_fs_type, SB_KERNMOUNT, "nfsd", NULL); + if (IS_ERR(mnt)) + return PTR_ERR(mnt); + nn->nfsd_mnt = mnt; + return 0; +} + #ifdef CONFIG_PROC_FS static int create_proc_exports_entry(void) { @@ -1451,7 +1464,6 @@ unsigned int nfsd_net_id; static __net_init int nfsd_init_net(struct net *net) { int retval; - struct vfsmount *mnt; struct nfsd_net *nn = net_generic(net, nfsd_net_id); retval = nfsd_export_init(net); @@ -1478,16 +1490,8 @@ static __net_init int nfsd_init_net(struct net *net) init_waitqueue_head(&nn->ntf_wq); seqlock_init(&nn->boot_lock); - mnt = vfs_kern_mount(&nfsd_fs_type, SB_KERNMOUNT, "nfsd", NULL); - if (IS_ERR(mnt)) { - retval = PTR_ERR(mnt); - goto out_mount_err; - } - nn->nfsd_mnt = mnt; return 0; -out_mount_err: - nfsd_reply_cache_shutdown(nn); out_drc_error: nfsd_idmap_shutdown(net); out_idmap_error: @@ -1500,7 +1504,6 @@ static __net_exit void nfsd_exit_net(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); - mntput(nn->nfsd_mnt); nfsd_reply_cache_shutdown(nn); nfsd_idmap_shutdown(net); nfsd_export_shutdown(net); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 36cdd81b6688a0..57c832d1b30fd8 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -90,6 +90,8 @@ void nfsd_destroy(struct net *net); bool i_am_nfsd(void); +int get_nfsdfs(struct net *); + struct nfsdfs_client { struct kref cl_ref; void (*cl_release)(struct kref *kref); @@ -100,6 +102,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, struct nfsdfs_client *ncl, u32 id, const struct tree_descr *); void nfsd_client_rmdir(struct dentry *dentry); + #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) #ifdef CONFIG_NFSD_V2_ACL extern const struct svc_version nfsd_acl_version2; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index c3fbab1753ec8e..d22a056da477a0 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1226,6 +1226,9 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, iap->ia_mode = 0; iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type; + if (!IS_POSIXACL(dirp)) + iap->ia_mode &= ~current_umask(); + err = 0; host_err = 0; switch (type) { @@ -1458,6 +1461,9 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } + if (!IS_POSIXACL(dirp)) + iap->ia_mode &= ~current_umask(); + host_err = vfs_create(dirp, dchild, iap->ia_mode, true); if (host_err < 0) { fh_drop_write(fhp); diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 42c5128c7d1c76..6c1166ccdaea57 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -566,8 +566,9 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, goto out; /* don't even try if the size is too large */ - if (count > KMALLOC_MAX_SIZE) - return -ENOMEM; + error = -ENOMEM; + if (count >= KMALLOC_MAX_SIZE) + goto out; if (write) { kbuf = memdup_user_nul(ubuf, count); @@ -576,7 +577,6 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *ubuf, goto out; } } else { - error = -ENOMEM; kbuf = kzalloc(count, GFP_KERNEL); if (!kbuf) goto out; diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index b43f0e8f43f2e0..9ed90368ab311c 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -671,7 +671,8 @@ xlog_cil_push_work( /* * Wake up any background push waiters now this context is being pushed. */ - wake_up_all(&ctx->push_wait); + if (ctx->space_used >= XLOG_CIL_BLOCKING_SPACE_LIMIT(log)) + wake_up_all(&cil->xc_push_wait); /* * Check if we've anything to push. If there is nothing, then we don't @@ -743,13 +744,12 @@ xlog_cil_push_work( /* * initialise the new context and attach it to the CIL. Then attach - * the current context to the CIL committing lsit so it can be found + * the current context to the CIL committing list so it can be found * during log forces to extract the commit lsn of the sequence that * needs to be forced. */ INIT_LIST_HEAD(&new_ctx->committing); INIT_LIST_HEAD(&new_ctx->busy_extents); - init_waitqueue_head(&new_ctx->push_wait); new_ctx->sequence = ctx->sequence + 1; new_ctx->cil = cil; cil->xc_ctx = new_ctx; @@ -937,7 +937,7 @@ xlog_cil_push_background( if (cil->xc_ctx->space_used >= XLOG_CIL_BLOCKING_SPACE_LIMIT(log)) { trace_xfs_log_cil_wait(log, cil->xc_ctx->ticket); ASSERT(cil->xc_ctx->space_used < log->l_logsize); - xlog_wait(&cil->xc_ctx->push_wait, &cil->xc_push_lock); + xlog_wait(&cil->xc_push_wait, &cil->xc_push_lock); return; } @@ -1216,12 +1216,12 @@ xlog_cil_init( INIT_LIST_HEAD(&cil->xc_committing); spin_lock_init(&cil->xc_cil_lock); spin_lock_init(&cil->xc_push_lock); + init_waitqueue_head(&cil->xc_push_wait); init_rwsem(&cil->xc_ctx_lock); init_waitqueue_head(&cil->xc_commit_wait); INIT_LIST_HEAD(&ctx->committing); INIT_LIST_HEAD(&ctx->busy_extents); - init_waitqueue_head(&ctx->push_wait); ctx->sequence = 1; ctx->cil = cil; cil->xc_ctx = ctx; diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index ec22c7a3867f19..75a62870b63af0 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -240,7 +240,6 @@ struct xfs_cil_ctx { struct xfs_log_vec *lv_chain; /* logvecs being pushed */ struct list_head iclog_entry; struct list_head committing; /* ctx committing list */ - wait_queue_head_t push_wait; /* background push throttle */ struct work_struct discard_endio_work; }; @@ -274,6 +273,7 @@ struct xfs_cil { wait_queue_head_t xc_commit_wait; xfs_lsn_t xc_current_sequence; struct work_struct xc_push_work; + wait_queue_head_t xc_push_wait; /* background push throttle */ } ____cacheline_aligned_in_smp; /* diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index 56527c85d12222..088c1ded271486 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -29,8 +29,8 @@ struct alg_sock { struct sock *parent; - unsigned int refcnt; - unsigned int nokey_refcnt; + atomic_t refcnt; + atomic_t nokey_refcnt; const struct af_alg_type *type; void *private; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 8fd900998b4e2e..57241417ff2f86 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -590,6 +590,7 @@ struct request_queue { u64 write_hints[BLK_MAX_WRITE_HINTS]; }; +/* Keep blk_queue_flag_name[] in sync with the definitions below */ #define QUEUE_FLAG_STOPPED 0 /* queue is stopped */ #define QUEUE_FLAG_DYING 1 /* queue being torn down */ #define QUEUE_FLAG_NOMERGES 3 /* disable merge attempts */ diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 6791813cd439c0..af998f93d25607 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -150,7 +150,7 @@ LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer, size_t buffer_size) LSM_HOOK(void, LSM_RET_VOID, inode_getsecid, struct inode *inode, u32 *secid) LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new) -LSM_HOOK(int, 0, inode_copy_up_xattr, const char *name) +LSM_HOOK(int, -EOPNOTSUPP, inode_copy_up_xattr, const char *name) LSM_HOOK(int, 0, kernfs_init_security, struct kernfs_node *kn_dir, struct kernfs_node *kn) LSM_HOOK(int, 0, file_permission, struct file *file, int mask) @@ -360,7 +360,7 @@ LSM_HOOK(int, 0, key_alloc, struct key *key, const struct cred *cred, unsigned long flags) LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key) LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred, - unsigned perm) + enum key_need_perm need_perm) LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **_buffer) #endif /* CONFIG_KEYS */ diff --git a/include/linux/pci.h b/include/linux/pci.h index c79d83304e5293..34c1c4f45288f7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2169,12 +2169,11 @@ static inline int pci_pcie_type(const struct pci_dev *dev) */ static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev) { - struct pci_dev *bridge = pci_upstream_bridge(dev); - - while (bridge) { - if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) - return bridge; - bridge = pci_upstream_bridge(bridge); + while (dev) { + if (pci_is_pcie(dev) && + pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) + return dev; + dev = pci_upstream_bridge(dev); } return NULL; diff --git a/include/linux/sched/jobctl.h b/include/linux/sched/jobctl.h index fa067de9f1a948..d2b4204ba4d349 100644 --- a/include/linux/sched/jobctl.h +++ b/include/linux/sched/jobctl.h @@ -19,6 +19,7 @@ struct task_struct; #define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ #define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */ #define JOBCTL_TRAP_FREEZE_BIT 23 /* trap for cgroup freezer */ +#define JOBCTL_TASK_WORK_BIT 24 /* set by TWA_SIGNAL */ #define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT) #define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT) @@ -28,9 +29,10 @@ struct task_struct; #define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT) #define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT) #define JOBCTL_TRAP_FREEZE (1UL << JOBCTL_TRAP_FREEZE_BIT) +#define JOBCTL_TASK_WORK (1UL << JOBCTL_TASK_WORK_BIT) #define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY) -#define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK) +#define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK | JOBCTL_TASK_WORK) extern bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask); extern void task_clear_jobctl_trapping(struct task_struct *task); diff --git a/include/linux/task_work.h b/include/linux/task_work.h index bd9a6a91c097e2..0fb93aafa4785e 100644 --- a/include/linux/task_work.h +++ b/include/linux/task_work.h @@ -13,7 +13,10 @@ init_task_work(struct callback_head *twork, task_work_func_t func) twork->func = func; } -int task_work_add(struct task_struct *task, struct callback_head *twork, bool); +#define TWA_RESUME 1 +#define TWA_SIGNAL 2 +int task_work_add(struct task_struct *task, struct callback_head *twork, int); + struct callback_head *task_work_cancel(struct task_struct *, task_work_func_t); void task_work_run(void); diff --git a/include/sound/gus.h b/include/sound/gus.h index 410939ecf3a5d2..cd8da68cab9216 100644 --- a/include/sound/gus.h +++ b/include/sound/gus.h @@ -613,4 +613,8 @@ int snd_gus_dram_write(struct snd_gus_card *gus, char __user *ptr, int snd_gus_dram_read(struct snd_gus_card *gus, char __user *ptr, unsigned int addr, unsigned int size, int rom); +/* gus_timer.c */ +void snd_gf1_timers_init(struct snd_gus_card *gus); +void snd_gf1_timers_done(struct snd_gus_card *gus); + #endif /* __SOUND_GUS_H */ diff --git a/include/sound/rt5670.h b/include/sound/rt5670.h deleted file mode 100644 index 02e1d777835495..00000000000000 --- a/include/sound/rt5670.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * linux/sound/rt5670.h -- Platform data for RT5670 - * - * Copyright 2014 Realtek Microelectronics - */ - -#ifndef __LINUX_SND_RT5670_H -#define __LINUX_SND_RT5670_H - -struct rt5670_platform_data { - int jd_mode; - bool in2_diff; - bool dev_gpio; - bool gpio1_is_ext_spk_en; - - bool dmic_en; - unsigned int dmic1_data_pin; - /* 0 = GPIO6; 1 = IN2P; 3 = GPIO7*/ - unsigned int dmic2_data_pin; - /* 0 = GPIO8; 1 = IN3N; */ - unsigned int dmic3_data_pin; - /* 0 = GPIO9; 1 = GPIO10; 2 = GPIO5*/ -}; - -#endif diff --git a/include/sound/soc.h b/include/sound/soc.h index 6791b7570a67a9..59235e55363065 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -426,6 +426,8 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_component(struct device *dev); +void snd_soc_unregister_component_by_driver(struct device *dev, + const struct snd_soc_component_driver *component_driver); struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev, const char *driver_name); struct snd_soc_component *snd_soc_lookup_component(struct device *dev, diff --git a/init/Kconfig b/init/Kconfig index a46aa8f3174d53..0498af567f7060 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -49,13 +49,13 @@ config CLANG_VERSION config CC_CAN_LINK bool - default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(m64-flag)) if 64BIT - default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(m32-flag)) + default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(m64-flag)) if 64BIT + default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(m32-flag)) config CC_CAN_LINK_STATIC bool - default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) -static $(m64-flag)) if 64BIT - default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) -static $(m32-flag)) + default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(m64-flag) -static) if 64BIT + default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(m32-flag) -static) config CC_HAS_ASM_GOTO def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC)) diff --git a/kernel/fork.c b/kernel/fork.c index 142b23645d82e7..efc5493203ae0b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1977,7 +1977,7 @@ static __latent_entropy struct task_struct *copy_process( * to stop root fork bombs. */ retval = -EAGAIN; - if (nr_threads >= max_threads) + if (data_race(nr_threads >= max_threads)) goto bad_fork_cleanup_count; delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ diff --git a/kernel/module.c b/kernel/module.c index 0c6573b98c3662..bee1c25ca5c5ec 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2785,7 +2785,7 @@ void * __weak module_alloc(unsigned long size) { return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, - NUMA_NO_NODE, __func__); + NUMA_NO_NODE, __builtin_return_address(0)); } bool __weak module_init_section(const char *name) diff --git a/kernel/padata.c b/kernel/padata.c index 29fc5d87a4cddd..4373f7adaa40a1 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -335,7 +335,7 @@ static void padata_reorder(struct parallel_data *pd) * * Ensure reorder queue is read after pd->lock is dropped so we see * new objects from another task in padata_do_serial. Pairs with - * smp_mb__after_atomic in padata_do_serial. + * smp_mb in padata_do_serial. */ smp_mb(); @@ -418,7 +418,7 @@ void padata_do_serial(struct padata_priv *padata) * with the trylock of pd->lock in padata_reorder. Pairs with smp_mb * in padata_reorder. */ - smp_mb__after_atomic(); + smp_mb(); padata_reorder(pd); } diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c index 16dd1e6b7c09fb..9eb39c20082c52 100644 --- a/kernel/rcu/rcuperf.c +++ b/kernel/rcu/rcuperf.c @@ -723,7 +723,7 @@ kfree_perf_init(void) schedule_timeout_uninterruptible(1); } - pr_alert("kfree object size=%lu\n", kfree_mult * sizeof(struct kfree_obj)); + pr_alert("kfree object size=%zu\n", kfree_mult * sizeof(struct kfree_obj)); kfree_reader_tasks = kcalloc(kfree_nrealthreads, sizeof(kfree_reader_tasks[0]), GFP_KERNEL); diff --git a/kernel/signal.c b/kernel/signal.c index 5ca48cc5da760d..ee22ec78fd6d5c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2529,9 +2529,6 @@ bool get_signal(struct ksignal *ksig) struct signal_struct *signal = current->signal; int signr; - if (unlikely(current->task_works)) - task_work_run(); - if (unlikely(uprobe_deny_signal())) return false; @@ -2544,6 +2541,13 @@ bool get_signal(struct ksignal *ksig) relock: spin_lock_irq(&sighand->siglock); + current->jobctl &= ~JOBCTL_TASK_WORK; + if (unlikely(current->task_works)) { + spin_unlock_irq(&sighand->siglock); + task_work_run(); + goto relock; + } + /* * Every stopped thread goes here after wakeup. Check to see if * we should notify the parent, prepare_signal(SIGCONT) encodes diff --git a/kernel/task_work.c b/kernel/task_work.c index 825f28259a19a2..5c0848ca1287df 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -25,9 +25,10 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ * 0 if succeeds or -ESRCH. */ int -task_work_add(struct task_struct *task, struct callback_head *work, bool notify) +task_work_add(struct task_struct *task, struct callback_head *work, int notify) { struct callback_head *head; + unsigned long flags; do { head = READ_ONCE(task->task_works); @@ -36,8 +37,19 @@ task_work_add(struct task_struct *task, struct callback_head *work, bool notify) work->next = head; } while (cmpxchg(&task->task_works, head, work) != head); - if (notify) + switch (notify) { + case TWA_RESUME: set_notify_resume(task); + break; + case TWA_SIGNAL: + if (lock_task_sighand(task, &flags)) { + task->jobctl |= JOBCTL_TASK_WORK; + signal_wake_up(task, 0); + unlock_task_sighand(task, &flags); + } + break; + } + return 0; } diff --git a/mm/cma.c b/mm/cma.c index 0463ad2ce06b75..26ecff8188817c 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -339,13 +339,13 @@ int __init cma_declare_contiguous_nid(phys_addr_t base, */ if (base < highmem_start && limit > highmem_start) { addr = memblock_alloc_range_nid(size, alignment, - highmem_start, limit, nid, false); + highmem_start, limit, nid, true); limit = highmem_start; } if (!addr) { addr = memblock_alloc_range_nid(size, alignment, base, - limit, nid, false); + limit, nid, true); if (!addr) { ret = -ENOMEM; goto err; diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 57ece74e3aae1e..fab4485b9e52b6 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1593,7 +1593,7 @@ static struct address_space *_get_hugetlb_page_mapping(struct page *hpage) /* Use first found vma */ pgoff_start = page_to_pgoff(hpage); - pgoff_end = pgoff_start + hpage_nr_pages(hpage) - 1; + pgoff_end = pgoff_start + pages_per_huge_page(page_hstate(hpage)) - 1; anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff_start, pgoff_end) { struct vm_area_struct *vma = avc->vma; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 48eb0f1410d47c..e028b87ce29428 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7832,7 +7832,7 @@ void setup_per_zone_wmarks(void) * Initialise min_free_kbytes. * * For small machines we want it small (128k min). For large machines - * we want it large (64MB max). But it is not linear, because network + * we want it large (256MB max). But it is not linear, because network * bandwidth does not increase linearly with machine size. We use * * min_free_kbytes = 4 * sqrt(lowmem_kbytes), for better accuracy: diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 5c4ec9386f81df..c537272f9c7ed1 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/samples/vfs/test-statx.c b/samples/vfs/test-statx.c index 76c577ea4fd8b6..49c7a46cee0739 100644 --- a/samples/vfs/test-statx.c +++ b/samples/vfs/test-statx.c @@ -23,6 +23,8 @@ #include #define statx foo #define statx_timestamp foo_timestamp +struct statx; +struct statx_timestamp; #include #undef statx #undef statx_timestamp diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 99ac59c5982658..916b2f7f70987c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -212,6 +212,9 @@ $(foreach m, $(notdir $1), \ $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) endef +quiet_cmd_copy = COPY $@ + cmd_copy = cp $< $@ + # Shipped files # =========================================================================== @@ -259,6 +262,7 @@ quiet_cmd_gzip = GZIP $@ # DTC # --------------------------------------------------------------------------- DTC ?= $(objtree)/scripts/dtc/dtc +DTC_FLAGS += -Wno-interrupt_provider # Disable noisy checks by default ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) @@ -274,7 +278,8 @@ endif ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),) DTC_FLAGS += -Wnode_name_chars_strict \ - -Wproperty_name_chars_strict + -Wproperty_name_chars_strict \ + -Winterrupt_provider endif DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 4b3c486f1399f8..b7955dbd71caac 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -1022,6 +1022,9 @@ static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct no } WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells); +#define I2C_OWN_SLAVE_ADDRESS (1U << 30) +#define I2C_TEN_BIT_ADDRESS (1U << 31) + static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node) { struct property *prop; @@ -1044,6 +1047,8 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node } reg = fdt32_to_cpu(*cells); + /* Ignore I2C_OWN_SLAVE_ADDRESS */ + reg &= ~I2C_OWN_SLAVE_ADDRESS; snprintf(unit_addr, sizeof(unit_addr), "%x", reg); if (!streq(unitname, unit_addr)) FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"", @@ -1051,10 +1056,15 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node for (len = prop->val.len; len > 0; len -= 4) { reg = fdt32_to_cpu(*(cells++)); - if (reg > 0x3ff) + /* Ignore I2C_OWN_SLAVE_ADDRESS */ + reg &= ~I2C_OWN_SLAVE_ADDRESS; + + if ((reg & I2C_TEN_BIT_ADDRESS) && ((reg & ~I2C_TEN_BIT_ADDRESS) > 0x3ff)) FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"", reg); - + else if (reg > 0x7f) + FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\". Set I2C_TEN_BIT_ADDRESS for 10 bit addresses or fix the property", + reg); } } WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, ®_format, &i2c_bus_bridge); @@ -1547,6 +1557,28 @@ static bool node_is_interrupt_provider(struct node *node) return false; } + +static void check_interrupt_provider(struct check *c, + struct dt_info *dti, + struct node *node) +{ + struct property *prop; + + if (!node_is_interrupt_provider(node)) + return; + + prop = get_property(node, "#interrupt-cells"); + if (!prop) + FAIL(c, dti, node, + "Missing #interrupt-cells in interrupt provider"); + + prop = get_property(node, "#address-cells"); + if (!prop) + FAIL(c, dti, node, + "Missing #address-cells in interrupt provider"); +} +WARNING(interrupt_provider, check_interrupt_provider, NULL); + static void check_interrupts_property(struct check *c, struct dt_info *dti, struct node *node) @@ -1604,7 +1636,7 @@ static void check_interrupts_property(struct check *c, prop = get_property(irq_node, "#interrupt-cells"); if (!prop) { - FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); + /* We warn about that already in another test. */ return; } @@ -1828,6 +1860,7 @@ static struct check *check_table[] = { &deprecated_gpio_property, &gpios_property, &interrupts_property, + &interrupt_provider, &alias_paths, diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index 6e74ecea55a392..a08f4159cd0366 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -51,6 +51,37 @@ extern int annotate; /* annotate .dts with input source location */ typedef uint32_t cell_t; +static inline uint16_t dtb_ld16(const void *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint16_t)bp[0] << 8) + | bp[1]; +} + +static inline uint32_t dtb_ld32(const void *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint32_t)bp[0] << 24) + | ((uint32_t)bp[1] << 16) + | ((uint32_t)bp[2] << 8) + | bp[3]; +} + +static inline uint64_t dtb_ld64(const void *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint64_t)bp[0] << 56) + | ((uint64_t)bp[1] << 48) + | ((uint64_t)bp[2] << 40) + | ((uint64_t)bp[3] << 32) + | ((uint64_t)bp[4] << 24) + | ((uint64_t)bp[5] << 16) + | ((uint64_t)bp[6] << 8) + | bp[7]; +} #define streq(a, b) (strcmp((a), (b)) == 0) #define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0) diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index bd6977eedcb860..07f10d2b5d7984 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -156,7 +156,7 @@ static void asm_emit_data(void *e, struct data d) emit_offset_label(f, m->ref, m->offset); while ((d.len - off) >= sizeof(uint32_t)) { - asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off)))); + asm_emit_cell(e, dtb_ld32(d.val + off)); off += sizeof(uint32_t); } diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 524b520c848647..93e4a2b563486d 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c @@ -436,7 +436,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) return struct_size; } - if (can_assume(LIBFDT_ORDER) | + if (can_assume(LIBFDT_ORDER) || !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { /* no further work necessary */ err = fdt_move(fdt, buf, bufsize); diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c index 26759d5dfb8cd4..94ce4bb91a0070 100644 --- a/scripts/dtc/libfdt/fdt_sw.c +++ b/scripts/dtc/libfdt/fdt_sw.c @@ -32,7 +32,7 @@ static int fdt_sw_probe_(void *fdt) /* 'memrsv' state: Initial state after fdt_create() * * Allowed functions: - * fdt_add_reservmap_entry() + * fdt_add_reservemap_entry() * fdt_finish_reservemap() [moves to 'struct' state] */ static int fdt_sw_probe_memrsv_(void *fdt) diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index 36fadcdea516a2..fe49b5d789382c 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -9,6 +9,10 @@ #include "libfdt_env.h" #include "fdt.h" +#ifdef __cplusplus +extern "C" { +#endif + #define FDT_FIRST_SUPPORTED_VERSION 0x02 #define FDT_LAST_SUPPORTED_VERSION 0x11 @@ -2069,4 +2073,8 @@ int fdt_overlay_apply(void *fdt, void *fdto); const char *fdt_strerror(int errval); +#ifdef __cplusplus +} +#endif + #endif /* LIBFDT_H */ diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c index c9d980c8abfc49..061ba8c9c5e832 100644 --- a/scripts/dtc/treesource.c +++ b/scripts/dtc/treesource.c @@ -110,13 +110,13 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width) fprintf(f, "%02"PRIx8, *(const uint8_t*)p); break; case 2: - fprintf(f, "0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p)); + fprintf(f, "0x%02"PRIx16, dtb_ld16(p)); break; case 4: - fprintf(f, "0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p)); + fprintf(f, "0x%02"PRIx32, dtb_ld32(p)); break; case 8: - fprintf(f, "0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p)); + fprintf(f, "0x%02"PRIx64, dtb_ld64(p)); break; } if (p + width < end) @@ -183,7 +183,7 @@ static enum markertype guess_value_type(struct property *prop) nnotcelllbl++; } - if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) + if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul)) && (nnotstringlbl == 0)) { return TYPE_STRING; } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 61dd7112d6e4ae..0714799446f883 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.6.0-g87a656ae" +#define DTC_VERSION "DTC 1.6.0-g9d7888cb" diff --git a/scripts/dtc/yamltree.c b/scripts/dtc/yamltree.c index 5b6ea8ea862f0d..4e93c12dc65839 100644 --- a/scripts/dtc/yamltree.c +++ b/scripts/dtc/yamltree.c @@ -59,10 +59,10 @@ static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, ch sprintf(buf, "0x%"PRIx8, *(uint8_t*)(data + off)); break; case 2: - sprintf(buf, "0x%"PRIx16, fdt16_to_cpu(*(fdt16_t*)(data + off))); + sprintf(buf, "0x%"PRIx16, dtb_ld16(data + off)); break; case 4: - sprintf(buf, "0x%"PRIx32, fdt32_to_cpu(*(fdt32_t*)(data + off))); + sprintf(buf, "0x%"PRIx32, dtb_ld32(data + off)); m = markers; is_phandle = false; for_each_marker_of_type(m, REF_PHANDLE) { @@ -73,7 +73,7 @@ static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, ch } break; case 8: - sprintf(buf, "0x%"PRIx64, fdt64_to_cpu(*(fdt64_t*)(data + off))); + sprintf(buf, "0x%"PRIx64, dtb_ld64(data + off)); break; } diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index ce0b99fb584711..ae19fb0243b9bd 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -78,7 +78,7 @@ config GCC_PLUGIN_RANDSTRUCT source tree isn't cleaned after kernel installation). The seed used for compilation is located at - scripts/gcc-plgins/randomize_layout_seed.h. It remains after + scripts/gcc-plugins/randomize_layout_seed.h. It remains after a make clean to allow for external modules to be compiled with the existing seed and will be removed by a make mrproper or make distclean. diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index c0ac8f7b5f1abd..4a616128a15484 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -4,27 +4,19 @@ * Copyright (C) 2015 Boris Barbulovski */ -#include - -#include -#include -#include #include +#include +#include +#include +#include #include +#include +#include +#include #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include @@ -445,9 +437,10 @@ void ConfigList::updateList(ConfigItem* item) if (rootEntry != &rootmenu && (mode == singleMode || (mode == symbolMode && rootEntry->parent != &rootmenu))) { item = (ConfigItem *)topLevelItem(0); - if (!item) + if (!item && mode != symbolMode) { item = new ConfigItem(this, 0, true); - last = item; + last = item; + } } if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && rootEntry->sym && rootEntry->prompt) { @@ -545,7 +538,7 @@ void ConfigList::setRootMenu(struct menu *menu) rootEntry = menu; updateListAll(); if (currentItem()) { - currentItem()->setSelected(hasFocus()); + setSelected(currentItem(), hasFocus()); scrollToItem(currentItem()); } } @@ -873,7 +866,7 @@ void ConfigList::focusInEvent(QFocusEvent *e) ConfigItem* item = (ConfigItem *)currentItem(); if (item) { - item->setSelected(true); + setSelected(item, true); menu = item->menu; } emit gotFocus(menu); @@ -1021,7 +1014,7 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) : Parent(parent), sym(0), _menu(0) { setObjectName(name); - + setOpenLinks(false); if (!objectName().isEmpty()) { configSettings->beginGroup(objectName()); @@ -1094,7 +1087,7 @@ void ConfigInfoView::menuInfo(void) if (sym->name) { head += " ("; if (showDebug()) - head += QString().sprintf("", sym); + head += QString().sprintf("", sym->name); head += print_filter(sym->name); if (showDebug()) head += ""; @@ -1103,7 +1096,7 @@ void ConfigInfoView::menuInfo(void) } else if (sym->name) { head += ""; if (showDebug()) - head += QString().sprintf("", sym); + head += QString().sprintf("", sym->name); head += print_filter(sym->name); if (showDebug()) head += ""; @@ -1154,13 +1147,16 @@ QString ConfigInfoView::debug_info(struct symbol *sym) switch (prop->type) { case P_PROMPT: case P_MENU: - debug += QString().sprintf("prompt: ", prop->menu); + debug += QString().sprintf("prompt: ", sym->name); debug += print_filter(prop->text); debug += "
"; break; case P_DEFAULT: case P_SELECT: case P_RANGE: + case P_COMMENT: + case P_IMPLY: + case P_SYMBOL: debug += prop_get_type_name(prop->type); debug += ": "; expr_print(prop->expr, expr_print_help, &debug, E_NONE); @@ -1226,13 +1222,62 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char QString str2 = print_filter(str); if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { - *text += QString().sprintf("", sym); + *text += QString().sprintf("", sym->name); *text += str2; *text += ""; } else *text += str2; } +void ConfigInfoView::clicked(const QUrl &url) +{ + QByteArray str = url.toEncoded(); + const std::size_t count = str.size(); + char *data = new char[count + 1]; + struct symbol **result; + struct menu *m = NULL; + + if (count < 1) { + qInfo() << "Clicked link is empty"; + delete data; + return; + } + + memcpy(data, str.constData(), count); + data[count] = '\0'; + + /* Seek for exact match */ + data[0] = '^'; + strcat(data, "$"); + result = sym_re_search(data); + if (!result) { + qInfo() << "Clicked symbol is invalid:" << data; + delete data; + return; + } + + sym = *result; + + /* Seek for the menu which holds the symbol */ + for (struct property *prop = sym->prop; prop; prop = prop->next) { + if (prop->type != P_PROMPT && prop->type != P_MENU) + continue; + m = prop->menu; + break; + } + + if (!m) { + /* Symbol is not visible as a menu */ + symbolInfo(); + emit showDebugChanged(true); + } else { + emit menuSelected(m); + } + + free(result); + delete data; +} + QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos) { QMenu* popup = Parent::createStandardContextMenu(pos); @@ -1402,18 +1447,22 @@ ConfigMainWindow::ConfigMainWindow(void) addToolBar(toolBar); backAction = new QAction(QPixmap(xpm_back), "Back", this); - connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); - backAction->setEnabled(false); + connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack())); + QAction *quitAction = new QAction("&Quit", this); quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); - connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); + connect(quitAction, SIGNAL(triggered(bool)), SLOT(close())); + QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); loadAction->setShortcut(Qt::CTRL + Qt::Key_L); - connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); + connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig())); + saveAction = new QAction(QPixmap(xpm_save), "&Save", this); saveAction->setShortcut(Qt::CTRL + Qt::Key_S); - connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); + connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig())); + conf_set_changed_callback(conf_changed); + // Set saveAction's initial state conf_changed(); configname = xstrdup(conf_get_configname()); @@ -1506,6 +1555,9 @@ ConfigMainWindow::ConfigMainWindow(void) helpMenu->addAction(showIntroAction); helpMenu->addAction(showAboutAction); + connect (helpText, SIGNAL (anchorClicked (const QUrl &)), + helpText, SLOT (clicked (const QUrl &)) ); + connect(configList, SIGNAL(menuChanged(struct menu *)), helpText, SLOT(setInfo(struct menu *))); connect(configList, SIGNAL(menuSelected(struct menu *)), @@ -1611,21 +1663,11 @@ void ConfigMainWindow::searchConfig(void) void ConfigMainWindow::changeItens(struct menu *menu) { configList->setRootMenu(menu); - - if (configList->rootEntry->parent == &rootmenu) - backAction->setEnabled(false); - else - backAction->setEnabled(true); } void ConfigMainWindow::changeMenu(struct menu *menu) { menuList->setRootMenu(menu); - - if (menuList->rootEntry->parent == &rootmenu) - backAction->setEnabled(false); - else - backAction->setEnabled(true); } void ConfigMainWindow::setMenuLink(struct menu *menu) @@ -1645,22 +1687,26 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) return; list->setRootMenu(parent); break; - case symbolMode: + case menuMode: if (menu->flags & MENU_ROOT) { - configList->setRootMenu(menu); + menuList->setRootMenu(menu); configList->clearSelection(); - list = menuList; - } else { list = configList; + } else { parent = menu_get_parent_menu(menu->parent); if (!parent) return; - item = menuList->findConfigItem(parent); + + /* Select the config view */ + item = configList->findConfigItem(parent); if (item) { - item->setSelected(true); - menuList->scrollToItem(item); + configList->setSelected(item, true); + configList->scrollToItem(item); } - list->setRootMenu(parent); + + menuList->setRootMenu(parent); + menuList->clearSelection(); + list = menuList; } break; case fullMode: @@ -1673,9 +1719,10 @@ void ConfigMainWindow::setMenuLink(struct menu *menu) if (list) { item = list->findConfigItem(menu); if (item) { - item->setSelected(true); + list->setSelected(item, true); list->scrollToItem(item); list->setFocus(); + helpText->setInfo(menu); } } } @@ -1688,25 +1735,11 @@ void ConfigMainWindow::listFocusChanged(void) void ConfigMainWindow::goBack(void) { - ConfigItem* item, *oldSelection; - - configList->setParentMenu(); +qInfo() << __FUNCTION__; if (configList->rootEntry == &rootmenu) - backAction->setEnabled(false); - - if (menuList->selectedItems().count() == 0) return; - item = (ConfigItem*)menuList->selectedItems().first(); - oldSelection = item; - while (item) { - if (item->menu == configList->rootEntry) { - oldSelection->setSelected(false); - item->setSelected(true); - break; - } - item = (ConfigItem*)item->parent(); - } + configList->setParentMenu(); } void ConfigMainWindow::showSingleView(void) @@ -1718,6 +1751,8 @@ void ConfigMainWindow::showSingleView(void) fullViewAction->setEnabled(true); fullViewAction->setChecked(false); + backAction->setEnabled(true); + menuView->hide(); menuList->setRootMenu(0); configList->mode = singleMode; @@ -1737,6 +1772,8 @@ void ConfigMainWindow::showSplitView(void) fullViewAction->setEnabled(true); fullViewAction->setChecked(false); + backAction->setEnabled(false); + configList->mode = menuMode; if (configList->rootEntry == &rootmenu) configList->updateListAll(); @@ -1760,6 +1797,8 @@ void ConfigMainWindow::showFullView(void) fullViewAction->setEnabled(false); fullViewAction->setChecked(true); + backAction->setEnabled(false); + menuView->hide(); menuList->setRootMenu(0); configList->mode = fullMode; diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h index c879d79ce8170b..fb9e9729266fc5 100644 --- a/scripts/kconfig/qconf.h +++ b/scripts/kconfig/qconf.h @@ -3,17 +3,17 @@ * Copyright (C) 2002 Roman Zippel */ -#include -#include -#include +#include +#include #include -#include +#include +#include #include #include -#include #include -#include -#include +#include +#include + #include "expr.h" class ConfigView; @@ -45,11 +45,17 @@ class ConfigList : public QTreeWidget { public: ConfigList(ConfigView* p, const char *name = 0); void reinit(void); + ConfigItem* findConfigItem(struct menu *); ConfigView* parent(void) const { return (ConfigView*)Parent::parent(); } - ConfigItem* findConfigItem(struct menu *); + void setSelected(QTreeWidgetItem *item, bool enable) { + for (int i = 0; i < selectedItems().size(); i++) + selectedItems().at(i)->setSelected(false); + + item->setSelected(enable); + } protected: void keyPressEvent(QKeyEvent *e); @@ -250,6 +256,7 @@ public slots: void setInfo(struct menu *menu); void saveSettings(void); void setShowDebug(bool); + void clicked (const QUrl &url); signals: void showDebugChanged(bool); diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index df93ac258e0135..9d94080bdad82f 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -30,7 +30,7 @@ enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN, IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII }; -enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; +enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 }; /* digest size for IMA, fits SHA1 or MD5 */ #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 220b14920c377a..011c3c76af8658 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -823,13 +823,26 @@ static int ima_calc_boot_aggregate_tfm(char *digest, u16 alg_id, if (rc != 0) return rc; - /* cumulative sha1 over tpm registers 0-7 */ + /* cumulative digest over TPM registers 0-7 */ for (i = TPM_PCR0; i < TPM_PCR8; i++) { ima_pcrread(i, &d); /* now accumulate with current aggregate */ rc = crypto_shash_update(shash, d.digest, crypto_shash_digestsize(tfm)); } + /* + * Extend cumulative digest over TPM registers 8-9, which contain + * measurement for the kernel command line (reg. 8) and image (reg. 9) + * in a typical PCR allocation. Registers 8-9 are only included in + * non-SHA1 boot_aggregate digests to avoid ambiguity. + */ + if (alg_id != TPM_ALG_SHA1) { + for (i = TPM_PCR8; i < TPM_PCR10; i++) { + ima_pcrread(i, &d); + rc = crypto_shash_update(shash, d.digest, + crypto_shash_digestsize(tfm)); + } + } if (!rc) crypto_shash_final(shash, digest); return rc; diff --git a/security/security.c b/security/security.c index 0ce3e73edd4227..70a7ad357bc6ab 100644 --- a/security/security.c +++ b/security/security.c @@ -1414,7 +1414,22 @@ EXPORT_SYMBOL(security_inode_copy_up); int security_inode_copy_up_xattr(const char *name) { - return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, name); + struct security_hook_list *hp; + int rc; + + /* + * The implementation can return 0 (accept the xattr), 1 (discard the + * xattr), -EOPNOTSUPP if it does not know anything about the xattr or + * any other error code incase of an error. + */ + hlist_for_each_entry(hp, + &security_hook_heads.inode_copy_up_xattr, list) { + rc = hp->hook.inode_copy_up_xattr(name); + if (rc != LSM_RET_DEFAULT(inode_copy_up_xattr)) + return rc; + } + + return LSM_RET_DEFAULT(inode_copy_up_xattr); } EXPORT_SYMBOL(security_inode_copy_up_xattr); diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index a1dce9725b98e4..1006458f7f8515 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -219,7 +219,7 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: break; - case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ + case SNDRV_PCM_FORMAT_S16_BE: word &= ~(AC97C_CMR_CEM_LITTLE); break; default: @@ -301,7 +301,7 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: break; - case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ + case SNDRV_PCM_FORMAT_S16_BE: word &= ~(AC97C_CMR_CEM_LITTLE); break; default: @@ -356,14 +356,14 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) camr = ac97c_readl(chip, CAMR); switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ - case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_START: ptcr = ATMEL_PDC_TXTEN; camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX; break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ - case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: ptcr |= ATMEL_PDC_TXTDIS; if (chip->opened <= 1) @@ -388,14 +388,14 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) ptcr = readl(chip->regs + ATMEL_PDC_PTSR); switch (cmd) { - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ - case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_START: ptcr = ATMEL_PDC_RXTEN; camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX; break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ - case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: ptcr |= ATMEL_PDC_RXTDIS; if (chip->opened <= 1) diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index d8f28d03098548..ad74ea9cbff547 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -158,7 +158,7 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size, */ dmab->dev.type = SNDRV_DMA_TYPE_DEV; #endif /* CONFIG_GENERIC_ALLOCATOR */ - /* fall through */ + fallthrough; case SNDRV_DMA_TYPE_DEV: case SNDRV_DMA_TYPE_DEV_UC: snd_malloc_dev_pages(dmab, size); diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 68630244b00ff2..327ec42a36b098 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -2851,7 +2851,7 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; if (substream) break; - /* Fall through */ + fallthrough; case VM_READ: substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; break; diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 1545f8fdb4db6c..d5ca161d588c50 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -357,7 +357,7 @@ snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, if (snd_mask_test(format_mask, (__force int)format1)) return format1; } - /* fall through */ + fallthrough; default: return (__force snd_pcm_format_t)-EINVAL; } diff --git a/sound/core/pcm_iec958.c b/sound/core/pcm_iec958.c index 073540f73b2f20..f9a211cc1f2c7c 100644 --- a/sound/core/pcm_iec958.c +++ b/sound/core/pcm_iec958.c @@ -103,7 +103,7 @@ EXPORT_SYMBOL(snd_pcm_create_iec958_consumer); /** * snd_pcm_create_iec958_consumer_hw_params - create IEC958 channel status - * @hw_params: the hw_params instance for extracting rate and sample format + * @params: the hw_params instance for extracting rate and sample format * @cs: channel status buffer, at least four bytes * @len: length of channel status buffer * diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 8326d16d35964e..795af1b88051e8 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -41,8 +41,9 @@ static int do_alloc_pages(struct snd_card *card, int type, struct device *dev, card->total_pcm_alloc_bytes + size > max_alloc_per_card) return -ENOMEM; - if (IS_ENABLED(CONFIG_SND_DMA_SGBUF) && - (type == SNDRV_DMA_TYPE_DEV_SG || type == SNDRV_DMA_TYPE_DEV_UC_SG) && + +#ifdef CONFIG_SND_DMA_SGBUF + if ((type == SNDRV_DMA_TYPE_DEV_SG || type == SNDRV_DMA_TYPE_DEV_UC_SG) && !dma_is_direct(get_dma_ops(dev))) { /* mutate to continuous page allocation */ dev_dbg(dev, "Use continuous page allocator\n"); @@ -51,6 +52,7 @@ static int do_alloc_pages(struct snd_card *card, int type, struct device *dev, else type = SNDRV_DMA_TYPE_DEV_UC; } +#endif /* CONFIG_SND_DMA_SGBUF */ err = snd_dma_alloc_pages(type, dev, size, dmab); if (!err) { diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 1e51c849d3d4c0..9e0b2d73faf6bf 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1903,7 +1903,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream, switch (substream->runtime->status->state) { case SNDRV_PCM_STATE_PAUSED: snd_pcm_pause(substream, false); - /* fallthru */ + fallthrough; case SNDRV_PCM_STATE_SUSPENDED: snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); break; @@ -2811,7 +2811,7 @@ static int do_pcm_hwsync(struct snd_pcm_substream *substream) case SNDRV_PCM_STATE_DRAINING: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) return -EBADFD; - /* Fall through */ + fallthrough; case SNDRV_PCM_STATE_RUNNING: return snd_pcm_update_hw_ptr(substream); case SNDRV_PCM_STATE_PREPARED: @@ -3814,7 +3814,7 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) case SNDRV_PCM_MMAP_OFFSET_STATUS_OLD: if (pcm_file->no_compat_mmap || !IS_ENABLED(CONFIG_64BIT)) return -ENXIO; - /* fallthrough */ + fallthrough; case SNDRV_PCM_MMAP_OFFSET_STATUS_NEW: if (!pcm_status_mmap_allowed(pcm_file)) return -ENXIO; @@ -3822,7 +3822,7 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) case SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD: if (pcm_file->no_compat_mmap || !IS_ENABLED(CONFIG_64BIT)) return -ENXIO; - /* fallthrough */ + fallthrough; case SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW: if (!pcm_control_mmap_allowed(pcm_file)) return -ENXIO; diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c index a35d429e4c27c1..f9f57232a83f9c 100644 --- a/sound/core/seq/oss/seq_oss_timer.c +++ b/sound/core/seq/oss/seq_oss_timer.c @@ -79,7 +79,7 @@ snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *ev) case TMR_WAIT_REL: parm += rec->cur_tick; rec->realtime = 0; - /* fall through */ + fallthrough; case TMR_WAIT_ABS: if (parm == 0) { rec->realtime = 1; diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c index 198f285594e310..81d2ef5e58116d 100644 --- a/sound/core/seq/seq_midi_emul.c +++ b/sound/core/seq/seq_midi_emul.c @@ -309,7 +309,7 @@ do_control(const struct snd_midi_op *ops, void *drv, break; case MIDI_CTL_MSB_DATA_ENTRY: chan->control[MIDI_CTL_LSB_DATA_ENTRY] = 0; - /* fall through */ + fallthrough; case MIDI_CTL_LSB_DATA_ENTRY: if (chan->param_type == SNDRV_MIDI_PARAM_TYPE_REGISTERED) rpn(ops, drv, chan, chset); diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 2f6e8023e05cd1..eb23c55323ae1d 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -354,7 +354,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) instr_4op = 1; break; } - /* fall through */ + fallthrough; default: spin_unlock_irqrestore(&opl3->voice_lock, flags); return; @@ -443,7 +443,7 @@ void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) switch (connection) { case 0x03: snd_opl3_calc_volume(&vol_op[2], vel, chan); - /* fallthru */ + fallthrough; case 0x02: snd_opl3_calc_volume(&vol_op[0], vel, chan); break; diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index ffab0400d7fbed..26d591fe6a6bff 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -511,8 +511,9 @@ irqreturn_t snd_vx_threaded_irq_handler(int irq, void *dev) /* The start on time code conditions are filled (ie the time code * received by the board is equal to one of those given to it). */ - if (events & TIME_CODE_EVENT_PENDING) + if (events & TIME_CODE_EVENT_PENDING) { ; /* so far, nothing to do yet */ + } /* The frequency has changed on the board (UER mode). */ if (events & FREQUENCY_CHANGE_EVENT_PENDING) diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index 14abbe7175b69b..b596bec19774c8 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c @@ -293,7 +293,6 @@ static int pcr_set_check(struct cmp_connection *c, __be32 pcr) /** * cmp_connection_establish - establish a connection to the target * @c: the connection manager - * @max_payload_bytes: the amount of data (including CIP headers) per packet * * This function establishes a point-to-point connection from the local * computer to the target by allocating isochronous resources (channel and diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index d1135f6ae1045f..b417a750c60a6b 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -998,7 +998,7 @@ static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem val = 3; } else retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00; - /* fall through */ + fallthrough; /* 4 source chips */ case 0x1868: case 0x1878: diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c index ce409e75ae51ff..65f9f46c9f583a 100644 --- a/sound/isa/galaxy/galaxy.c +++ b/sound/isa/galaxy/galaxy.c @@ -247,7 +247,7 @@ static int snd_galaxy_match(struct device *dev, unsigned int n) break; case 2: irq[n] = 9; - /* Fall through */ + fallthrough; case 9: wss_config[n] |= WSS_CONFIG_IRQ_9; break; @@ -292,7 +292,7 @@ static int snd_galaxy_match(struct device *dev, unsigned int n) case 1: if (dma1[n] == 0) break; - /* Fall through */ + fallthrough; default: dev_err(dev, "invalid capture DMA %d\n", dma2[n]); return 0; @@ -322,7 +322,7 @@ static int snd_galaxy_match(struct device *dev, unsigned int n) break; case 2: mpu_irq[n] = 9; - /* Fall through */ + fallthrough; case 9: config[n] |= GALAXY_CONFIG_MPUIRQ_2; break; diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c index 07bfcda4382738..9a1ab5872c4fab 100644 --- a/sound/isa/gus/gus_reset.c +++ b/sound/isa/gus/gus_reset.c @@ -9,8 +9,6 @@ #include #include -extern void snd_gf1_timers_init(struct snd_gus_card * gus); -extern void snd_gf1_timers_done(struct snd_gus_card * gus); extern int snd_gf1_synth_init(struct snd_gus_card * gus); extern void snd_gf1_synth_done(struct snd_gus_card * gus); diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c index 7586619770b30e..4fb4ed79e262c0 100644 --- a/sound/isa/gus/gus_uart.c +++ b/sound/isa/gus/gus_uart.c @@ -13,7 +13,8 @@ static void snd_gf1_interrupt_midi_in(struct snd_gus_card * gus) { int count; - unsigned char stat, data, byte; + unsigned char stat, byte; + __always_unused unsigned char data; unsigned long flags; count = 10; diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c index 02c566fca9e567..63633bd41e5b6c 100644 --- a/sound/isa/msnd/msnd_pinnacle_mixer.c +++ b/sound/isa/msnd/msnd_pinnacle_mixer.c @@ -219,11 +219,9 @@ static int snd_msndmix_set(struct snd_msnd *dev, int d, int left, int right) case MSND_MIXER_VOLUME: /* master volume */ writew(wLeft, dev->SMA + SMA_wCurrMastVolLeft); writew(wRight, dev->SMA + SMA_wCurrMastVolRight); - /* fall through */ - + fallthrough; case MSND_MIXER_AUX: /* aux pot control */ /* scaled by master volume */ - /* fall through */ /* digital controls */ case MSND_MIXER_SYNTH: /* synth vol (dsp mix) */ diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index b039429e687171..44ed1b65f6ce80 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -163,13 +163,13 @@ static int aci_busy_wait(struct snd_miro_aci *aci) switch (timeout-ACI_MINTIME) { case 0 ... 9: out /= 10; - /* fall through */ + fallthrough; case 10 ... 19: out /= 10; - /* fall through */ + fallthrough; case 20 ... 30: out /= 10; - /* fall through */ + fallthrough; default: set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(out); @@ -824,7 +824,7 @@ static unsigned char snd_miro_read(struct snd_miro *chip, retval = inb(chip->mc_base + 9); break; } - /* fall through */ + fallthrough; case OPTi9XX_HW_82C929: retval = inb(chip->mc_base + reg); @@ -854,7 +854,7 @@ static void snd_miro_write(struct snd_miro *chip, unsigned char reg, outb(value, chip->mc_base + 9); break; } - /* fall through */ + fallthrough; case OPTi9XX_HW_82C929: outb(value, chip->mc_base + reg); diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 0e6d20e4915854..881d3b5711d273 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -249,7 +249,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip, retval = inb(chip->mc_base + 9); break; } - /* Fall through */ + fallthrough; case OPTi9XX_HW_82C928: case OPTi9XX_HW_82C929: @@ -292,7 +292,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, outb(value, chip->mc_base + 9); break; } - /* Fall through */ + fallthrough; case OPTi9XX_HW_82C928: case OPTi9XX_HW_82C929: @@ -343,7 +343,7 @@ static int snd_opti9xx_configure(struct snd_opti9xx *chip, snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); /* enable wave audio */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); - /* Fall through */ + fallthrough; case OPTi9XX_HW_82C925: /* enable WSS mode */ @@ -380,7 +380,8 @@ static int snd_opti9xx_configure(struct snd_opti9xx *chip, case OPTi9XX_HW_82C931: /* disable 3D sound (set GPIO1 as output, low) */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c); - /* fall through */ + fallthrough; + case OPTi9XX_HW_82C933: /* * The BTC 1817DW has QS1000 wavetable which is connected @@ -392,7 +393,8 @@ static int snd_opti9xx_configure(struct snd_opti9xx *chip, * or digital input signal. */ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01); - /* fall through */ + fallthrough; + case OPTi9XX_HW_82C930: snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x03); snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0x00, 0xff); diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index e33dfe165276bf..86d0d2fdf48a86 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -116,13 +116,13 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream) chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; break; } - /* fall through */ + fallthrough; case SB_HW_201: if (rate > 23000) { chip->playback_format = SB_DSP_HI_OUTPUT_AUTO; break; } - /* fall through */ + fallthrough; case SB_HW_20: chip->playback_format = SB_DSP_LO_OUTPUT_AUTO; break; @@ -261,7 +261,7 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) chip->capture_format = SB_DSP_HI_INPUT_AUTO; break; } - /* fall through */ + fallthrough; case SB_HW_20: chip->capture_format = SB_DSP_LO_INPUT_AUTO; break; @@ -361,7 +361,7 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) case SB_MODE_PLAYBACK_16: /* ok.. playback is active */ if (chip->hardware != SB_HW_JAZZ16) break; - /* fall through */ + fallthrough; case SB_MODE_PLAYBACK_8: substream = chip->playback_substream; if (chip->playback_format == SB_DSP_OUTPUT) @@ -371,7 +371,7 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip) case SB_MODE_CAPTURE_16: if (chip->hardware != SB_HW_JAZZ16) break; - /* fall through */ + fallthrough; case SB_MODE_CAPTURE_8: substream = chip->capture_substream; if (chip->capture_format == SB_DSP_INPUT) diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 823ccfa089b27d..81c6a98307273e 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c @@ -1449,7 +1449,7 @@ static int FalconMixerIoctl(u_int cmd, u_long arg) tt_dmasnd.input_gain = RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 | RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff); - /* fall through - return set value */ + fallthrough; /* return set value */ case SOUND_MIXER_READ_MIC: return IOCTL_OUT(arg, RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) | diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index f802ea331e244d..38f25e97538fa8 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -1478,13 +1478,13 @@ static int dmasound_setup(char *str) printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); else catchRadius = ints[3]; - /* fall through */ + fallthrough; case 2: if (ints[1] < MIN_BUFFERS) printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs); else numWriteBufs = ints[1]; - /* fall through */ + fallthrough; case 1: if ((size = ints[2]) < 256) /* check for small buffer specs */ size <<= 10 ; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6758c072000e67..012a7ee849e8aa 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -218,11 +218,11 @@ static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) case AC97_ID_ST_AC97_ID4: if (reg == 0x08) return 0; - /* fall through */ + fallthrough; case AC97_ID_ST7597: if (reg == 0x22 || reg == 0x7a) return 1; - /* fall through */ + fallthrough; case AC97_ID_AK4540: case AC97_ID_AK4542: if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c) diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index a9540c2c4a1a9e..023c35a2a95139 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -1904,7 +1904,7 @@ static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol, */ u16 band, idx; u16 tuner_bands[HPI_TUNER_BAND_LAST]; - u32 num_bands = 0; + __always_unused u32 num_bands; num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, HPI_TUNER_BAND_LAST); @@ -1931,7 +1931,7 @@ static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol, unsigned int idx; u16 band; u16 tuner_bands[HPI_TUNER_BAND_LAST]; - u32 num_bands = 0; + __always_unused u32 num_bands; num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, HPI_TUNER_BAND_LAST); @@ -2161,7 +2161,6 @@ static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control) static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - int err; u16 src_node_type, src_node_index; u32 h_control = kcontrol->private_value; @@ -2174,10 +2173,9 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol, uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - err = - hpi_multiplexer_query_source(h_control, - uinfo->value.enumerated.item, - &src_node_type, &src_node_index); + hpi_multiplexer_query_source(h_control, + uinfo->value.enumerated.item, + &src_node_type, &src_node_index); sprintf(uinfo->value.enumerated.name, "%s %d", asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE], diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 968510bc2552a1..7d1abaedb46acc 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -28,10 +28,12 @@ struct hpi_adapters_list { static struct hpi_adapters_list adapters; /** -* Given an HPI Message that was sent out and a response that was received, -* validate that the response has the correct fields filled in, -* i.e ObjectType, Function etc -**/ + * hpi_validate_response - Given an HPI Message that was sent out and + * a response that was received, validate that the response has the + * correct fields filled in, i.e ObjectType, Function etc + * @phm: message + * @phr: response + */ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) { if (phr->type != HPI_TYPE_RESPONSE) { @@ -106,10 +108,11 @@ void hpi_delete_adapter(struct hpi_adapter_obj *pao) } /** -* FindAdapter returns a pointer to the struct hpi_adapter_obj with -* index wAdapterIndex in an HPI_ADAPTERS_LIST structure. -* -*/ + * hpi_find_adapter - FindAdapter returns a pointer to the struct + * hpi_adapter_obj with index wAdapterIndex in an HPI_ADAPTERS_LIST + * structure. + * @adapter_index: value in [0, HPI_MAX_ADAPTERS[ + */ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index) { struct hpi_adapter_obj *pao = NULL; @@ -137,10 +140,9 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index) } /** -* -* wipe an HPI_ADAPTERS_LIST structure. -* -**/ + * wipe_adapter_list - wipe an HPI_ADAPTERS_LIST structure. + * + */ static void wipe_adapter_list(void) { memset(&adapters, 0, sizeof(adapters)); diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 85d3b4e954898b..a25d754558028a 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -896,15 +896,15 @@ static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream) case 8: data |= ATI_REG_OUT_DMA_SLOT_BIT(10) | ATI_REG_OUT_DMA_SLOT_BIT(11); - /* fall through */ + fallthrough; case 6: data |= ATI_REG_OUT_DMA_SLOT_BIT(7) | ATI_REG_OUT_DMA_SLOT_BIT(8); - /* fall through */ + fallthrough; case 4: data |= ATI_REG_OUT_DMA_SLOT_BIT(6) | ATI_REG_OUT_DMA_SLOT_BIT(9); - /* fall through */ + fallthrough; default: data |= ATI_REG_OUT_DMA_SLOT_BIT(3) | ATI_REG_OUT_DMA_SLOT_BIT(4); diff --git a/sound/pci/au88x0/au88x0_a3ddata.c b/sound/pci/au88x0/au88x0_a3ddata.c index 18623cb6bc523d..a5da3b3a546a2e 100644 --- a/sound/pci/au88x0/au88x0_a3ddata.c +++ b/sound/pci/au88x0/au88x0_a3ddata.c @@ -21,7 +21,7 @@ static const a3d_Hrtf_t A3dHrirZeros = { 0, 0, 0 }; -static const a3d_Hrtf_t A3dHrirImpulse = { +static __maybe_unused const a3d_Hrtf_t A3dHrirImpulse = { 0x7fff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -30,7 +30,7 @@ static const a3d_Hrtf_t A3dHrirImpulse = { 0, 0, 0 }; -static const a3d_Hrtf_t A3dHrirOnes = { +static __maybe_unused const a3d_Hrtf_t A3dHrirOnes = { 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, @@ -47,7 +47,7 @@ static const a3d_Hrtf_t A3dHrirOnes = { 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff }; -static const a3d_Hrtf_t A3dHrirSatTest = { +static __maybe_unused const a3d_Hrtf_t A3dHrirSatTest = { 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, @@ -59,7 +59,7 @@ static const a3d_Hrtf_t A3dHrirSatTest = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static const a3d_Hrtf_t A3dHrirDImpulse = { +static __maybe_unused const a3d_Hrtf_t A3dHrirDImpulse = { 0, 0x7fff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index f5512b72b3e0df..5180f1bd1326c3 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -1103,7 +1103,7 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc, snd_pcm_sgbuf_get_addr(dma->substream, psize * 3)); - /* fall through */ + fallthrough; /* 3 pages */ case 3: dma->cfg0 |= 0x12000000; @@ -1111,14 +1111,14 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8, snd_pcm_sgbuf_get_addr(dma->substream, psize * 2)); - /* fall through */ + fallthrough; /* 2 pages */ case 2: dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4, snd_pcm_sgbuf_get_addr(dma->substream, psize)); - /* fall through */ + fallthrough; /* 1 page */ case 1: dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc); @@ -1381,20 +1381,20 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc, snd_pcm_sgbuf_get_addr(dma->substream, psize * 3)); - /* fall through */ + fallthrough; /* 3 pages */ case 3: dma->cfg0 |= 0x12000000; dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8, snd_pcm_sgbuf_get_addr(dma->substream, psize * 2)); - /* fall through */ + fallthrough; /* 2 pages */ case 2: dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4, snd_pcm_sgbuf_get_addr(dma->substream, psize)); - /* fall through */ + fallthrough; /* 1 page */ case 1: dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc); diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c index 084fcbf8ae804e..27859536d7c021 100644 --- a/sound/pci/au88x0/au88x0_xtalk.c +++ b/sound/pci/au88x0/au88x0_xtalk.c @@ -17,35 +17,35 @@ static short const sXtalkWideKLeftEq = 0x269C; static short const sXtalkWideKRightEq = 0x269C; static short const sXtalkWideKLeftXt = 0xF25E; -static short const sXtalkWideKRightXt = 0xF25E; +static __maybe_unused short const sXtalkWideKRightXt = 0xF25E; static short const sXtalkWideShiftLeftEq = 1; static short const sXtalkWideShiftRightEq = 1; static short const sXtalkWideShiftLeftXt = 0; -static short const sXtalkWideShiftRightXt = 0; +static __maybe_unused short const sXtalkWideShiftRightXt = 0; static unsigned short const wXtalkWideLeftDelay = 0xd; static unsigned short const wXtalkWideRightDelay = 0xd; static short const sXtalkNarrowKLeftEq = 0x468D; static short const sXtalkNarrowKRightEq = 0x468D; static short const sXtalkNarrowKLeftXt = 0xF82E; -static short const sXtalkNarrowKRightXt = 0xF82E; +static __maybe_unused short const sXtalkNarrowKRightXt = 0xF82E; static short const sXtalkNarrowShiftLeftEq = 0x3; static short const sXtalkNarrowShiftRightEq = 0x3; static short const sXtalkNarrowShiftLeftXt = 0; -static short const sXtalkNarrowShiftRightXt = 0; +static __maybe_unused short const sXtalkNarrowShiftRightXt = 0; static unsigned short const wXtalkNarrowLeftDelay = 0x7; static unsigned short const wXtalkNarrowRightDelay = 0x7; -static xtalk_gains_t const asXtalkGainsDefault = { +static __maybe_unused xtalk_gains_t const asXtalkGainsDefault = { 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000 }; -static xtalk_gains_t const asXtalkGainsTest = { +static __maybe_unused xtalk_gains_t const asXtalkGainsTest = { 0x7fff, 0x8000, 0x0000, 0x0000, 0x0001, 0xffff, 0x4000, 0xc000, 0x0002, 0xfffe }; -static xtalk_gains_t const asXtalkGains1Chan = { +static __maybe_unused xtalk_gains_t const asXtalkGains1Chan = { 0x7FFF, 0, 0, 0, 0, 0x7FFF, 0, 0, 0, 0, }; @@ -64,7 +64,7 @@ static xtalk_dline_t const alXtalkDlineZeros = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static xtalk_dline_t const alXtalkDlineTest = { +static __maybe_unused xtalk_dline_t const alXtalkDlineTest = { 0x0000fc18, 0xfff03e8, 0x000186a0, 0xfffe7960, 1, 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -74,7 +74,7 @@ static xtalk_instate_t const asXtalkInStateZeros = { 0, 0, 0, 0 }; -static xtalk_instate_t const asXtalkInStateTest = { +static __maybe_unused xtalk_instate_t const asXtalkInStateTest = { 0x0080, 0xff80, 0x0001, 0xffff }; @@ -89,11 +89,11 @@ static xtalk_state_t const asXtalkOutStateZeros = { static short const sDiamondKLeftEq = 0x401d; static short const sDiamondKRightEq = 0x401d; static short const sDiamondKLeftXt = 0xF90E; -static short const sDiamondKRightXt = 0xF90E; +static __maybe_unused short const sDiamondKRightXt = 0xF90E; static short const sDiamondShiftLeftEq = 1; static short const sDiamondShiftRightEq = 1; static short const sDiamondShiftLeftXt = 0; -static short const sDiamondShiftRightXt = 0; +static __maybe_unused short const sDiamondShiftRightXt = 0; static unsigned short const wDiamondLeftDelay = 0xb; static unsigned short const wDiamondRightDelay = 0xb; @@ -118,7 +118,7 @@ static xtalk_coefs_t const asXtalkWideCoefsLeftXt = { {0x77dc, 0xc79e, 0xffb8, 0x000a, 0}, {0, 0, 0, 0, 0} }; -static xtalk_coefs_t const asXtalkWideCoefsRightXt = { +static __maybe_unused xtalk_coefs_t const asXtalkWideCoefsRightXt = { {0x55c6, 0xc97b, 0x005b, 0x0047, 0}, {0x6a60, 0xca20, 0xffc6, 0x0040, 0}, {0x6411, 0xd711, 0xfca1, 0x0190, 0}, @@ -149,7 +149,7 @@ static xtalk_coefs_t const asXtalkNarrowCoefsLeftXt = { {0, 0, 0, 0, 0} }; -static xtalk_coefs_t const asXtalkNarrowCoefsRightXt = { +static __maybe_unused xtalk_coefs_t const asXtalkNarrowCoefsRightXt = { {0x3CB2, 0xDF49, 0xF6EA, 0x095B, 0}, {0x6777, 0xC915, 0xFEAF, 0x00B1, 0}, {0x7762, 0xC7D9, 0x025B, 0xFDA6, 0}, @@ -172,7 +172,7 @@ static xtalk_coefs_t const asXtalkCoefsPipe = { {0, 0, 0x0FA0, 0, 0}, {0, 0, 0x1180, 0, 0}, }; -static xtalk_coefs_t const asXtalkCoefsNegPipe = { +static __maybe_unused xtalk_coefs_t const asXtalkCoefsNegPipe = { {0, 0, 0xF380, 0, 0}, {0, 0, 0xF380, 0, 0}, {0, 0, 0xF380, 0, 0}, @@ -180,7 +180,7 @@ static xtalk_coefs_t const asXtalkCoefsNegPipe = { {0, 0, 0xF200, 0, 0} }; -static xtalk_coefs_t const asXtalkCoefsNumTest = { +static __maybe_unused xtalk_coefs_t const asXtalkCoefsNumTest = { {0, 0, 0xF380, 0x8000, 0x6D60}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, @@ -188,7 +188,7 @@ static xtalk_coefs_t const asXtalkCoefsNumTest = { {0, 0, 0, 0, 0} }; -static xtalk_coefs_t const asXtalkCoefsDenTest = { +static __maybe_unused xtalk_coefs_t const asXtalkCoefsDenTest = { {0xC000, 0x2000, 0x4000, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, @@ -196,7 +196,7 @@ static xtalk_coefs_t const asXtalkCoefsDenTest = { {0, 0, 0, 0, 0} }; -static xtalk_state_t const asXtalkOutStateTest = { +static __maybe_unused xtalk_state_t const asXtalkOutStateTest = { {0x7FFF, 0x0004, 0xFFFC, 0}, {0xFE00, 0x0008, 0xFFF8, 0x4000}, {0x0200, 0x0010, 0xFFF0, 0xC000}, @@ -228,7 +228,7 @@ static xtalk_coefs_t const asDiamondCoefsLeftXt = { {0, 0, 0, 0, 0} }; -static xtalk_coefs_t const asDiamondCoefsRightXt = { +static __maybe_unused xtalk_coefs_t const asDiamondCoefsRightXt = { {0x3B50, 0xFE08, 0xF959, 0x0060, 0}, {0x9FCB, 0xD8F1, 0x00A2, 0x003A, 0}, {0, 0, 0, 0, 0}, diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c index 4e64eb5d8f64c7..c84f1a45194f17 100644 --- a/sound/pci/aw2/aw2-saa7146.c +++ b/sound/pci/aw2/aw2-saa7146.c @@ -330,7 +330,7 @@ void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146 *chip, irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id) { unsigned int isr; - unsigned int iicsta; + __always_unused unsigned int iicsta; struct snd_aw2_saa7146 *chip = dev_id; isr = READREG(ISR); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 58167d8469e1ba..77c7030ebbfa9e 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1232,7 +1232,7 @@ snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec, case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break; default: snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); - /* fall-through */ + fallthrough; case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break; case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break; case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break; diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index e56a230f6a9c23..b1898fafc6a9cd 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1655,6 +1655,10 @@ static const struct ct_atc atc_preset = { * ct_atc_create - create and initialize a hardware manager * @card: corresponding alsa card object * @pci: corresponding kernel pci device object + * @rsr: reference sampling rate + * @msr: master sampling rate + * @chip_type: CHIPTYP enum values + * @ssid: vendor ID (upper 16 bits) and device ID (lower 16 bits) * @ratc: return created object address in it * * Creates and initializes a hardware manager. diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c index 9b7e63f4a3a7f3..1d506448621785 100644 --- a/sound/pci/ctxfi/cthardware.c +++ b/sound/pci/ctxfi/cthardware.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File cthardware.c diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 015c0d676897a4..108ab449c968d8 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File cthw20k1.c diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index ce44cbe6459f24..fc1bc18caee989 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File cthw20k2.c diff --git a/sound/pci/ctxfi/ctimap.c b/sound/pci/ctxfi/ctimap.c index eb1825e13fc5c2..d5a53d2f5f15ac 100644 --- a/sound/pci/ctxfi/ctimap.c +++ b/sound/pci/ctxfi/ctimap.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctimap.c diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index 84514dc90d87ad..6797fde3d78897 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctmixer.c diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 6ee6a9675ca518..3f48ad0e27e7f6 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctpcm.c diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 0941a7a17623a4..e81f42811f455c 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -2,6 +2,7 @@ /* * ALSA driver for Echoaudio soundcards. * Copyright (C) 2003-2004 Giuliano Pochini + * Copyright (C) 2020 Mark Hills */ #include @@ -245,13 +246,20 @@ static int hw_rule_sample_rate(struct snd_pcm_hw_params *params, SNDRV_PCM_HW_PARAM_RATE); struct echoaudio *chip = rule->private; struct snd_interval fixed; + int err; + + mutex_lock(&chip->mode_mutex); - if (!chip->can_set_rate) { + if (chip->can_set_rate) { + err = 0; + } else { snd_interval_any(&fixed); fixed.min = fixed.max = chip->sample_rate; - return snd_interval_refine(rate, &fixed); + err = snd_interval_refine(rate, &fixed); } - return 0; + + mutex_unlock(&chip->mode_mutex); + return err; } @@ -322,7 +330,7 @@ static int pcm_open(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) return err; - /* Finally allocate a page for the scatter-gather list */ + /* Allocate a page for the scatter-gather list */ if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, PAGE_SIZE, &pipe->sgpage)) < 0) { @@ -330,6 +338,17 @@ static int pcm_open(struct snd_pcm_substream *substream, return err; } + /* + * Sole ownership required to set the rate + */ + + dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d", + chip->opencount, chip->can_set_rate, chip->rate_set); + + chip->opencount++; + if (chip->opencount > 1 && chip->rate_set) + chip->can_set_rate = 0; + return 0; } @@ -353,12 +372,7 @@ static int pcm_analog_in_open(struct snd_pcm_substream *substream) hw_rule_capture_format_by_channels, NULL, SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) return err; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; - dev_dbg(chip->card->dev, "pcm_analog_in_open cs=%d oc=%d r=%d\n", - chip->can_set_rate, atomic_read(&chip->opencount), - chip->sample_rate); + return 0; } @@ -388,12 +402,7 @@ static int pcm_analog_out_open(struct snd_pcm_substream *substream) NULL, SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) return err; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; - dev_dbg(chip->card->dev, "pcm_analog_out_open cs=%d oc=%d r=%d\n", - chip->can_set_rate, atomic_read(&chip->opencount), - chip->sample_rate); + return 0; } @@ -429,10 +438,6 @@ static int pcm_digital_in_open(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) goto din_exit; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; - din_exit: mutex_unlock(&chip->mode_mutex); return err; @@ -471,9 +476,7 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream) NULL, SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) goto dout_exit; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; + dout_exit: mutex_unlock(&chip->mode_mutex); return err; @@ -488,23 +491,29 @@ static int pcm_digital_out_open(struct snd_pcm_substream *substream) static int pcm_close(struct snd_pcm_substream *substream) { struct echoaudio *chip = snd_pcm_substream_chip(substream); - int oc; /* Nothing to do here. Audio is already off and pipe will be * freed by its callback */ - atomic_dec(&chip->opencount); - oc = atomic_read(&chip->opencount); - dev_dbg(chip->card->dev, "pcm_close oc=%d cs=%d rs=%d\n", oc, - chip->can_set_rate, chip->rate_set); - if (oc < 2) + mutex_lock(&chip->mode_mutex); + + dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d", + chip->opencount, chip->can_set_rate, chip->rate_set); + + chip->opencount--; + + switch (chip->opencount) { + case 1: chip->can_set_rate = 1; - if (oc == 0) + break; + + case 0: chip->rate_set = 0; - dev_dbg(chip->card->dev, "pcm_close2 oc=%d cs=%d rs=%d\n", oc, - chip->can_set_rate, chip->rate_set); + break; + } + mutex_unlock(&chip->mode_mutex); return 0; } @@ -582,7 +591,7 @@ static int init_engine(struct snd_pcm_substream *substream, /* This stuff is used by the irq handler, so it must be * initialized before chip->substream */ - chip->last_period[pipe_index] = 0; + pipe->last_period = 0; pipe->last_counter = 0; pipe->position = 0; smp_wmb(); @@ -690,7 +699,7 @@ static int pcm_prepare(struct snd_pcm_substream *substream) break; case SNDRV_PCM_FORMAT_S32_BE: format.data_are_bigendian = 1; - /* fall through */ + fallthrough; case SNDRV_PCM_FORMAT_S32_LE: format.bits_per_sample = 32; break; @@ -703,9 +712,22 @@ static int pcm_prepare(struct snd_pcm_substream *substream) if (snd_BUG_ON(pipe_index >= px_num(chip))) return -EINVAL; - if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) + + /* + * We passed checks we can do independently; now take + * exclusive control + */ + + spin_lock_irq(&chip->lock); + + if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) { + spin_unlock(&chip->lock); return -EINVAL; + } + set_audio_format(chip, pipe_index, &format); + spin_unlock_irq(&chip->lock); + return 0; } @@ -738,11 +760,11 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) pipe = chip->substream[i]->runtime->private_data; switch (pipe->state) { case PIPE_STATE_STOPPED: - chip->last_period[i] = 0; + pipe->last_period = 0; pipe->last_counter = 0; pipe->position = 0; *pipe->dma_counter = 0; - /* fall through */ + fallthrough; case PIPE_STATE_PAUSED: pipe->state = PIPE_STATE_STARTED; break; @@ -786,19 +808,26 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct audiopipe *pipe = runtime->private_data; - size_t cnt, bufsize, pos; + u32 counter, step; - cnt = le32_to_cpu(*pipe->dma_counter); - pipe->position += cnt - pipe->last_counter; - pipe->last_counter = cnt; - bufsize = substream->runtime->buffer_size; - pos = bytes_to_frames(substream->runtime, pipe->position); + /* + * IRQ handling runs concurrently. Do not share tracking of + * counter with it, which would race or require locking + */ - while (pos >= bufsize) { - pipe->position -= frames_to_bytes(substream->runtime, bufsize); - pos -= bufsize; - } - return pos; + counter = le32_to_cpu(*pipe->dma_counter); /* presumed atomic */ + + step = counter - pipe->last_counter; /* handles wrapping */ + pipe->last_counter = counter; + + /* counter doesn't neccessarily wrap on a multiple of + * buffer_size, so can't derive the position; must + * accumulate */ + + pipe->position += step; + pipe->position %= frames_to_bytes(runtime, runtime->buffer_size); /* wrap */ + + return bytes_to_frames(runtime, pipe->position); } @@ -1409,7 +1438,7 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, /* Do not allow the user to change the digital mode when a pcm device is open because it also changes the number of channels and the allowed sample rates */ - if (atomic_read(&chip->opencount)) { + if (chip->opencount) { changed = -EAGAIN; } else { changed = set_digital_mode(chip, dmode); @@ -1761,14 +1790,43 @@ static const struct snd_kcontrol_new snd_echo_channels_info = { /****************************************************************************** - IRQ Handler + IRQ Handling ******************************************************************************/ +/* Check if a period has elapsed since last interrupt + * + * Don't make any updates to state; PCM core handles this with the + * correct locks. + * + * \return true if a period has elapsed, otherwise false + */ +static bool period_has_elapsed(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct audiopipe *pipe = runtime->private_data; + u32 counter, step; + size_t period_bytes; + + if (pipe->state != PIPE_STATE_STARTED) + return false; + + period_bytes = frames_to_bytes(runtime, runtime->period_size); + + counter = le32_to_cpu(*pipe->dma_counter); /* presumed atomic */ + + step = counter - pipe->last_period; /* handles wrapping */ + step -= step % period_bytes; /* acknowledge whole periods only */ + + if (step == 0) + return false; /* haven't advanced a whole period yet */ + + pipe->last_period += step; /* used exclusively by us */ + return true; +} static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) { struct echoaudio *chip = dev_id; - struct snd_pcm_substream *substream; - int period, ss, st; + int ss, st; spin_lock(&chip->lock); st = service_irq(chip); @@ -1779,17 +1837,13 @@ static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) /* The hardware doesn't tell us which substream caused the irq, thus we have to check all running substreams. */ for (ss = 0; ss < DSP_MAXPIPES; ss++) { + struct snd_pcm_substream *substream; + substream = chip->substream[ss]; - if (substream && ((struct audiopipe *)substream->runtime-> - private_data)->state == PIPE_STATE_STARTED) { - period = pcm_pointer(substream) / - substream->runtime->period_size; - if (period != chip->last_period[ss]) { - chip->last_period[ss] = period; - spin_unlock(&chip->lock); - snd_pcm_period_elapsed(substream); - spin_lock(&chip->lock); - } + if (substream && period_has_elapsed(substream)) { + spin_unlock(&chip->lock); + snd_pcm_period_elapsed(substream); + spin_lock(&chip->lock); } } spin_unlock(&chip->lock); @@ -1874,7 +1928,7 @@ static int snd_echo_create(struct snd_card *card, chip->card = card; chip->pci = pci; chip->irq = -1; - atomic_set(&chip->opencount, 0); + chip->opencount = 0; mutex_init(&chip->mode_mutex); chip->can_set_rate = 1; } else { @@ -1955,7 +2009,8 @@ static int snd_echo_probe(struct pci_dev *pci, struct snd_card *card; struct echoaudio *chip; char *dsp; - int i, err; + __maybe_unused int i; + int err; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index be4d0489394a2d..30c640931f1e36 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h @@ -298,7 +298,12 @@ struct audiopipe { * the current dma position * (lower 32 bits only) */ - u32 last_counter; /* The last position, which is used + u32 last_period; /* Counter position last time a + * period elapsed + */ + u32 last_counter; /* Used exclusively by pcm_pointer + * under PCM core locks. + * The last position, which is used * to compute... */ u32 position; /* ...the number of bytes tranferred @@ -332,11 +337,10 @@ struct audioformat { struct echoaudio { spinlock_t lock; struct snd_pcm_substream *substream[DSP_MAXPIPES]; - int last_period[DSP_MAXPIPES]; struct mutex mode_mutex; u16 num_digital_modes, digital_mode_list[6]; u16 num_clock_sources, clock_source_list[10]; - atomic_t opencount; + unsigned int opencount; /* protected by mode_mutex */ struct snd_kcontrol *clock_src_ctl; struct snd_pcm *analog_pcm, *digital_pcm; struct snd_card *card; @@ -353,8 +357,8 @@ struct echoaudio { struct timer_list timer; char tinuse; /* Timer in use */ char midi_full; /* MIDI output buffer is full */ - char can_set_rate; - char rate_set; + char can_set_rate; /* protected by mode_mutex */ + char rate_set; /* protected by mode_mutex */ /* This stuff is used mainly by the lowlevel code */ struct comm_page *comm_page; /* Virtual address of the memory diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index f02f5b1568dee6..d10d0e460f0bd9 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -898,7 +898,7 @@ static int pause_transport(struct echoaudio *chip, u32 channel_mask) return 0; } - dev_warn(chip->card->dev, "pause_transport: No pipes to stop!\n"); + dev_dbg(chip->card->dev, "pause_transport: No pipes to stop!\n"); return 0; } @@ -924,7 +924,7 @@ static int stop_transport(struct echoaudio *chip, u32 channel_mask) return 0; } - dev_warn(chip->card->dev, "stop_transport: No pipes to stop!\n"); + dev_dbg(chip->card->dev, "stop_transport: No pipes to stop!\n"); return 0; } diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c index dce9e57d01c4a9..f77db83dd73dbc 100644 --- a/sound/pci/echoaudio/mona_dsp.c +++ b/sound/pci/echoaudio/mona_dsp.c @@ -300,11 +300,6 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) u32 control_reg, clocks_from_dsp; int err; - - /* Prevent two simultaneous calls to switch_asic() */ - if (atomic_read(&chip->opencount)) - return -EAGAIN; - /* Mask off the clock select bits */ control_reg = le32_to_cpu(chip->comm_page->control_register) & GML_CLOCK_CLEAR_MASK; diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 6ff581733a199c..bd70e112ffd7af 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -623,7 +623,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 *emu) static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu) { unsigned long special_port; - unsigned int value; + __always_unused unsigned int value; /* Special initialisation routine * before the rest of the IO-Ports become active. @@ -653,7 +653,7 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int n, i; int reg; int value; - unsigned int write_post; + __always_unused unsigned int write_post; unsigned long flags; if (!fw_entry) diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c index b3aa7bbe106741..89890f24509f03 100644 --- a/sound/pci/emu10k1/emu10k1_patch.c +++ b/sound/pci/emu10k1/emu10k1_patch.c @@ -27,7 +27,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, const void __user *data, long count) { int offset; - int truesize, size, loopsize, blocksize; + int truesize, size, blocksize; + __maybe_unused int loopsize; int loopend, sampleend; unsigned int start_addr; struct snd_emu10k1 *emu; diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index b934c6ac52dd4a..b2ddabb9943813 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -753,7 +753,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */ snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]); - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) @@ -902,8 +902,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream, snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]); } snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); - - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL); diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index b4a0adf7451cc7..09704a78d799eb 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1619,7 +1619,8 @@ static int snd_es1938_create(struct snd_card *card, static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id) { struct es1938 *chip = dev_id; - unsigned char status, audiostatus; + unsigned char status; + __always_unused unsigned char audiostatus; int handled = 0; status = inb(SLIO_REG(chip, IRQCONTROL)); diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 181ebafa550a21..0a95032fd297fa 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -144,6 +144,8 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers"); /** * struct fm801 - describes FM801 chip + * @dev: device for this chio + * @irq: irq number * @port: I/O port number * @multichannel: multichannel support * @secondary: secondary codec @@ -151,6 +153,31 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers"); * @tea575x_tuner: tuner access method & flags * @ply_ctrl: playback control * @cap_ctrl: capture control + * @ply_buffer: playback buffer + * @ply_buf: playback buffer index + * @ply_count: playback buffer count + * @ply_size: playback buffer size + * @ply_pos: playback position + * @cap_buffer: capture buffer + * @cap_buf: capture buffer index + * @cap_count: capture buffer count + * @cap_size: capture buffer size + * @cap_pos: capture position + * @ac97_bus: ac97 bus handle + * @ac97: ac97 handle + * @ac97_sec: ac97 secondary handle + * @card: ALSA card + * @pcm: PCM devices + * @rmidi: rmidi device + * @playback_substream: substream for playback + * @capture_substream: substream for capture + * @p_dma_size: playback DMA size + * @c_dma_size: capture DMA size + * @reg_lock: lock + * @proc_entry: /proc entry + * @v4l2_dev: v4l2 device + * @tea: tea575a structure + * @saved_regs: context saved during suspend */ struct fm801 { struct device *dev; diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 3f9abdaef7f513..90759391cbac82 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -221,6 +221,7 @@ comment "Set to Y if you want auto-loading the codec driver" config SND_HDA_GENERIC tristate "Enable generic HD-audio codec parser" + select NEW_LEDS if SND_HDA_GENERIC_LEDS select LEDS_CLASS if SND_HDA_GENERIC_LEDS select LEDS_TRIGGERS if SND_HDA_GENERIC_LEDS select LEDS_TRIGGER_AUDIO if SND_HDA_GENERIC_LEDS @@ -239,6 +240,20 @@ config SND_HDA_POWER_SAVE_DEFAULT The default time-out value in seconds for HD-audio automatic power-save mode. 0 means to disable the power-save mode. +config SND_HDA_INTEL_HDMI_SILENT_STREAM + bool "Enable Silent Stream always for HDMI" + depends on SND_HDA_INTEL + help + Intel hardware has a feature called 'silent stream', that + keeps external HDMI receiver's analog circuitry powered on + avoiding 2-3 sec silence during playback start. This mechanism + relies on setting channel_id as 0xf, sending info packet and + preventing codec D3 entry (increasing platform static power + consumption when HDMI receiver is plugged-in). 2-3 sec silence + at the playback start is expected whenever there is format change. + (default is 2 channel format). + Say Y to enable Silent Stream feature. + endif endmenu diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 841523f6b88de6..53a2b89f8983ce 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -102,7 +102,7 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, case SND_BELL: if (hz) hz = 1000; - /* fallthru */ + fallthrough; case SND_TONE: if (beep->linear_tone) beep->tone = beep_linear_tone(beep, hz); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index d796963b80d7fc..be5000dd158532 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1018,7 +1018,7 @@ static int patch_conexant_auto(struct hda_codec *codec) break; case 0x14f150f2: codec->power_save_node = 1; - /* Fall through */ + fallthrough; default: codec->pin_amp_workaround = 1; snd_hda_pick_fixup(codec, cxt5066_fixup_models, diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 41eaa89660c3ee..836e44bc3675af 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -42,6 +42,11 @@ static bool enable_acomp = true; module_param(enable_acomp, bool, 0444); MODULE_PARM_DESC(enable_acomp, "Enable audio component binding (default=yes)"); +static bool enable_silent_stream = +IS_ENABLED(CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM); +module_param(enable_silent_stream, bool, 0644); +MODULE_PARM_DESC(enable_silent_stream, "Enable Silent Stream for HDMI devices"); + struct hdmi_spec_per_cvt { hda_nid_t cvt_nid; int assigned; @@ -167,6 +172,7 @@ struct hdmi_spec { hda_nid_t vendor_nid; const int *port_map; int port_num; + bool send_silent_stream; /* Flag to enable silent stream feature */ }; #ifdef CONFIG_SND_HDA_COMPONENT @@ -1635,21 +1641,72 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, snd_hda_power_down_pm(codec); } +static void silent_stream_enable(struct hda_codec *codec, + struct hdmi_spec_per_pin *per_pin) +{ + unsigned int newval, oldval; + + codec_dbg(codec, "hdmi: enabling silent stream for NID %d\n", + per_pin->pin_nid); + + mutex_lock(&per_pin->lock); + + if (!per_pin->channels) + per_pin->channels = 2; + + oldval = snd_hda_codec_read(codec, per_pin->pin_nid, 0, + AC_VERB_GET_CONV, 0); + newval = (oldval & 0xF0) | 0xF; + snd_hda_codec_write(codec, per_pin->pin_nid, 0, + AC_VERB_SET_CHANNEL_STREAMID, newval); + + hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); + + mutex_unlock(&per_pin->lock); +} + /* update ELD and jack state via audio component */ static void sync_eld_via_acomp(struct hda_codec *codec, struct hdmi_spec_per_pin *per_pin) { struct hdmi_spec *spec = codec->spec; struct hdmi_eld *eld = &spec->temp_eld; + bool monitor_prev, monitor_next; mutex_lock(&per_pin->lock); eld->monitor_present = false; + monitor_prev = per_pin->sink_eld.monitor_present; eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, per_pin->dev_id, &eld->monitor_present, eld->eld_buffer, ELD_MAX_SIZE); eld->eld_valid = (eld->eld_size > 0); update_eld(codec, per_pin, eld, 0); + monitor_next = per_pin->sink_eld.monitor_present; mutex_unlock(&per_pin->lock); + + /* + * Power-up will call hdmi_present_sense, so the PM calls + * have to be done without mutex held. + */ + + if (spec->send_silent_stream) { + int pm_ret; + + if (!monitor_prev && monitor_next) { + pm_ret = snd_hda_power_up_pm(codec); + if (pm_ret < 0) + codec_err(codec, + "Monitor plugged-in, Failed to power up codec ret=[%d]\n", + pm_ret); + silent_stream_enable(codec, per_pin); + } else if (monitor_prev && !monitor_next) { + pm_ret = snd_hda_power_down_pm(codec); + if (pm_ret < 0) + codec_err(codec, + "Monitor plugged-out, Failed to power down codec ret=[%d]\n", + pm_ret); + } + } } static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) @@ -2802,6 +2859,13 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid, spec->ops.setup_stream = i915_hsw_setup_stream; spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup; + /* + * Enable silent stream feature, if it is enabled via + * module param or Kconfig option + */ + if (enable_silent_stream) + spec->send_silent_stream = true; + return parse_intel_hdmi(codec); } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5a11ac2d446db7..a0f079bc733864 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -382,7 +382,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) case 0x10ec0295: case 0x10ec0299: alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); - /* fallthrough */ + fallthrough; case 0x10ec0215: case 0x10ec0233: case 0x10ec0235: @@ -4698,7 +4698,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, break; case 0x10ec0867: alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14); - /* fallthru */ + fallthrough; case 0x10ec0221: case 0x10ec0662: snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 81929063b2fad4..1d2a0287284b50 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -691,7 +691,7 @@ static int snd_ice1712_delta_init(struct snd_ice1712 *ice) break; case ICE1712_SUBDEVICE_DELTADIO2496: ice->gpio.set_pro_rate = delta_1010_set_rate_val; - /* fall thru */ + fallthrough; case ICE1712_SUBDEVICE_DELTA66: ice->spdif.ops.open = delta_open_spdif; ice->spdif.ops.setup_rate = delta_setup_spdif; diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 1781a1c081c3d4..675bb0da00a0e0 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -810,7 +810,7 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: ichdev->suspended = 0; - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: val = ICH_IOCE | ICH_STARTBM; @@ -818,7 +818,7 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd break; case SNDRV_PCM_TRIGGER_SUSPEND: ichdev->suspended = 1; - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_STOP: val = 0; break; @@ -852,7 +852,7 @@ static int snd_intel8x0_ali_trigger(struct snd_pcm_substream *substream, int cmd switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: ichdev->suspended = 0; - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -869,7 +869,7 @@ static int snd_intel8x0_ali_trigger(struct snd_pcm_substream *substream, int cmd break; case SNDRV_PCM_TRIGGER_SUSPEND: ichdev->suspended = 1; - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* pause */ diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 65a887b217ee50..2eddd9de9e6daa 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -2149,7 +2149,9 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci, { int err, rc; unsigned int i; - unsigned ioport_size, iomem_size, iomem2_size; + unsigned iomem_size; + __maybe_unused unsigned ioport_size; + __maybe_unused unsigned iomem2_size; struct snd_korg1212 * korg1212; const struct firmware *dsp_code; diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 7ba487443c7f7b..efff220b26ea7c 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -169,7 +169,7 @@ static int mixart_set_clock(struct mixart_mgr *mgr, case PIPE_RUNNING: if(rate != 0) break; - /* fall through */ + fallthrough; default: if(rate == 0) return 0; /* nothing to do */ diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c index 048a2660d18d4d..0bdd33b0af654b 100644 --- a/sound/pci/mixart/mixart_core.c +++ b/sound/pci/mixart/mixart_core.c @@ -527,7 +527,7 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id) dev_err(&mgr->pci->dev, "canceled notification %x !\n", msg); } - /* fall through */ + fallthrough; case MSG_TYPE_ANSWER: /* answer or notification to a message we are waiting for*/ mutex_lock(&mgr->msg_lock); diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index ebce4d259e0693..240195e85e3d31 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -560,7 +560,7 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: s->suspended = 0; - /* fallthru */ + fallthrough; case SNDRV_PCM_TRIGGER_START: if (! s->running) { snd_nm256_playback_start(chip, s, substream); @@ -569,7 +569,7 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd) break; case SNDRV_PCM_TRIGGER_SUSPEND: s->suspended = 1; - /* fallthru */ + fallthrough; case SNDRV_PCM_TRIGGER_STOP: if (s->running) { snd_nm256_playback_stop(chip); @@ -1664,7 +1664,7 @@ static int snd_nm256_probe(struct pci_dev *pci, return -ENODEV; case NM_RESET_WORKAROUND_2: reset_workaround_2 = 1; - /* Fall-through */ + fallthrough; case NM_RESET_WORKAROUND: reset_workaround = 1; break; diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 75b25ecf83a9ce..b2a3fcfe31d443 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -137,7 +137,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_64000); runtime->hw.rate_min = 44100; } - /* fall through */ + fallthrough; case PCM_A: case PCM_B: runtime->hw.fifo_size = 0; diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 0767276582cafa..8aa92f3e5ee888 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -116,7 +116,8 @@ static void wm8776_write(struct oxygen *chip, else wm8776_write_i2c(chip, reg, value); if (reg < ARRAY_SIZE(data->wm8776_regs)) { - if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) + /* reg >= WM8776_HPLVOL is always true */ + if (reg <= WM8776_DACMASTER) value &= ~WM8776_UPDATE; data->wm8776_regs[reg] = value; } @@ -144,7 +145,8 @@ static void wm8766_write(struct oxygen *chip, OXYGEN_SPI_CEN_LATCH_CLOCK_LO, (reg << 9) | value); if (reg < ARRAY_SIZE(data->wm8766_regs)) { - if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) || + /* reg >= WM8766_LDA1 is always true */ + if (reg <= WM8766_RDA1 || (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA)) value &= ~WM8766_UPDATE; data->wm8766_regs[reg] = value; diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index f7cda906208895..0fa49f4d15cff7 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -3027,8 +3027,8 @@ static int hdspm_autosync_ref(struct hdspm *hdspm) unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF; - if ((syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD) && - (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN)) { + /* syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD is always true */ + if (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN) { return syncref; } return HDSPM_AES32_AUTOSYNC_FROM_NONE; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 8b03e2dc503f01..7abd47dbfe5526 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -544,7 +544,7 @@ static int snd_via82xx_codec_valid(struct via82xx *chip, int secondary) static void snd_via82xx_codec_wait(struct snd_ac97 *ac97) { struct via82xx *chip = ac97->private_data; - int err; + __always_unused int err; err = snd_via82xx_codec_ready(chip, ac97->num); /* here we need to wait fairly for long time.. */ if (!nodelay) diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 607b7100db1cfe..addfa196df21da 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -398,7 +398,7 @@ static int snd_via82xx_codec_valid(struct via82xx_modem *chip, int secondary) static void snd_via82xx_codec_wait(struct snd_ac97 *ac97) { struct via82xx_modem *chip = ac97->private_data; - int err; + __always_unused int err; err = snd_via82xx_codec_ready(chip, ac97->num); /* here we need to wait fairly for long time.. */ msleep(500); diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index db7d76a3cfeb75..cacc6a9d14c8b6 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -400,7 +400,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, kctl = chip->pcm_mixer[substream->number].ctl; kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; } - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 6c33ea91cc0513..27d9da6d61e83b 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -139,6 +139,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link) /** * snd_pdacf_assign_resources - initialize the hardware and card instance. + * @pdacf: context * @port: i/o port for the card * @irq: irq number for the card * diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index 6cbe5cb3435828..dfc4295b69c413 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -45,7 +45,7 @@ static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd) case SNDRV_PCM_TRIGGER_START: chip->pcm_hwptr = 0; chip->pcm_tdone = 0; - /* fall thru */ + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: mask = 0; @@ -132,7 +132,7 @@ static int pdacf_pcm_prepare(struct snd_pcm_substream *subs) case SNDRV_PCM_FORMAT_S24_3LE: case SNDRV_PCM_FORMAT_S24_3BE: chip->pcm_sample = 3; - /* fall through */ + fallthrough; default: /* 24-bit */ aval = AK4117_DIF_24R; chip->pcm_frame = 3; diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c index 9414d7269c4f58..7d8986379d8082 100644 --- a/sound/soc/amd/acp-da7219-max98357a.c +++ b/sound/soc/amd/acp-da7219-max98357a.c @@ -450,11 +450,13 @@ static int cz_probe(struct platform_device *pdev) return 0; } +#ifdef CONFIG_ACPI static const struct acpi_device_id cz_audio_acpi_match[] = { { "AMD7219", 0 }, {}, }; MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match); +#endif static struct platform_driver cz_pcm_driver = { .driver = { diff --git a/sound/soc/amd/acp-rt5645.c b/sound/soc/amd/acp-rt5645.c index 73b31f88a6b566..87f0060e771f17 100644 --- a/sound/soc/amd/acp-rt5645.c +++ b/sound/soc/amd/acp-rt5645.c @@ -182,11 +182,13 @@ static int cz_probe(struct platform_device *pdev) return 0; } +#ifdef CONFIG_ACPI static const struct acpi_device_id cz_audio_acpi_match[] = { { "AMDI1002", 0 }, {}, }; MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match); +#endif static struct platform_driver cz_pcm_driver = { .driver = { diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c index 14607563abd28b..c3eb9b347eaa9c 100644 --- a/sound/soc/amd/raven/acp3x-i2s.c +++ b/sound/soc/amd/raven/acp3x-i2s.c @@ -149,14 +149,10 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct i2s_stream_instance *rtd; - struct snd_soc_pcm_runtime *prtd; - struct snd_soc_card *card; u32 ret, val, period_bytes, reg_val, ier_val, water_val; u32 buf_size, buf_reg; - prtd = substream->private_data; rtd = substream->runtime->private_data; - card = prtd->card; period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); buf_size = frames_to_bytes(substream->runtime, diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index e6386de20ac7fc..17290c829c4b5d 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -238,7 +238,7 @@ static int acp3x_dma_open(struct snd_soc_component *component, } if (!adata->play_stream && !adata->capture_stream && - adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) + !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); i2s_data->acp3x_base = adata->acp3x_base; @@ -301,15 +301,11 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component, static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *prtd; - struct snd_soc_card *card; struct i2s_stream_instance *rtd; u32 pos; u32 buffersize; u64 bytescount; - prtd = substream->private_data; - card = prtd->card; rtd = substream->runtime->private_data; buffersize = frames_to_bytes(substream->runtime, diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c index f25ce50f1a9016..ebf4388b626215 100644 --- a/sound/soc/amd/raven/pci-acp3x.c +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -232,9 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci, } pm_runtime_set_autosuspend_delay(&pci->dev, 2000); pm_runtime_use_autosuspend(&pci->dev); - pm_runtime_set_active(&pci->dev); pm_runtime_put_noidle(&pci->dev); - pm_runtime_enable(&pci->dev); pm_runtime_allow(&pci->dev); return 0; @@ -303,7 +301,7 @@ static void snd_acp3x_remove(struct pci_dev *pci) ret = acp3x_deinit(adata->acp3x_base); if (ret) dev_err(&pci->dev, "ACP de-init failed\n"); - pm_runtime_disable(&pci->dev); + pm_runtime_forbid(&pci->dev); pm_runtime_get_noresume(&pci->dev); pci_disable_msi(pci); pci_release_regions(pci); diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c index 859ed67b93cfff..b943e59fc30243 100644 --- a/sound/soc/amd/renoir/rn-pci-acp3x.c +++ b/sound/soc/amd/renoir/rn-pci-acp3x.c @@ -5,6 +5,7 @@ //Copyright 2020 Advanced Micro Devices, Inc. #include +#include #include #include #include @@ -18,6 +19,16 @@ static int acp_power_gating; module_param(acp_power_gating, int, 0644); MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating"); +/** + * dmic_acpi_check = -1 - Checks ACPI method to know DMIC hardware status runtime + * = 0 - Skips the DMIC device creation and returns probe failure + * = 1 - Assumes that platform has DMIC support and skips ACPI + * method check + */ +static int dmic_acpi_check = ACP_DMIC_AUTO; +module_param(dmic_acpi_check, bint, 0644); +MODULE_PARM_DESC(dmic_acpi_check, "checks Dmic hardware runtime"); + struct acp_dev_data { void __iomem *acp_base; struct resource *res; @@ -157,6 +168,10 @@ static int snd_rn_acp_probe(struct pci_dev *pci, { struct acp_dev_data *adata; struct platform_device_info pdevinfo[ACP_DEVS]; +#if defined(CONFIG_ACPI) + acpi_handle handle; + acpi_integer dmic_status; +#endif unsigned int irqflags; int ret, index; u32 addr; @@ -201,6 +216,24 @@ static int snd_rn_acp_probe(struct pci_dev *pci, if (ret) goto disable_msi; + if (!dmic_acpi_check) { + ret = -ENODEV; + goto de_init; + } else if (dmic_acpi_check == ACP_DMIC_AUTO) { +#if defined(CONFIG_ACPI) + handle = ACPI_HANDLE(&pci->dev); + ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); + if (ACPI_FAILURE(ret)) { + ret = -EINVAL; + goto de_init; + } + if (!dmic_status) { + ret = -ENODEV; + goto de_init; + } +#endif + } + adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource) * 2, GFP_KERNEL); diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h index 75228e306e0b46..14620399d766c4 100644 --- a/sound/soc/amd/renoir/rn_acp3x.h +++ b/sound/soc/amd/renoir/rn_acp3x.h @@ -55,6 +55,8 @@ #define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS) #define MIN_BUFFER MAX_BUFFER +#define ACP_DMIC_AUTO -1 + struct pdm_dev_data { u32 pdm_irq; void __iomem *acp_base; diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index e98601eccfa337..2d35b08f056571 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c @@ -120,39 +120,21 @@ static int atmel_classd_cpu_dai_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); + int err; regmap_write(dd->regmap, CLASSD_THR, 0x0); - return clk_prepare_enable(dd->pclk); -} - -static void atmel_classd_cpu_dai_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); - - clk_disable_unprepare(dd->pclk); + err = clk_prepare_enable(dd->pclk); + if (err) + return err; + err = clk_prepare_enable(dd->gclk); + if (err) { + clk_disable_unprepare(dd->pclk); + return err; + } + return 0; } -static const struct snd_soc_dai_ops atmel_classd_cpu_dai_ops = { - .startup = atmel_classd_cpu_dai_startup, - .shutdown = atmel_classd_cpu_dai_shutdown, -}; - -static struct snd_soc_dai_driver atmel_classd_cpu_dai = { - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = ATMEL_CLASSD_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &atmel_classd_cpu_dai_ops, -}; - -static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = { - .name = "atmel-classd", -}; - /* platform */ static int atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream, @@ -306,31 +288,10 @@ static int atmel_classd_component_resume(struct snd_soc_component *component) return regcache_sync(dd->regmap); } -static struct snd_soc_component_driver soc_component_dev_classd = { - .probe = atmel_classd_component_probe, - .resume = atmel_classd_component_resume, - .controls = atmel_classd_snd_controls, - .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), - .idle_bias_on = 1, - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -/* codec dai component */ -static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); - - return clk_prepare_enable(dd->gclk); -} - -static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai, - int mute) +static int atmel_classd_cpu_dai_digital_mute(struct snd_soc_dai *cpu_dai, + int mute) { - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_component *component = cpu_dai->component; u32 mask, val; mask = CLASSD_MR_LMUTE_MASK | CLASSD_MR_RMUTE_MASK; @@ -373,13 +334,13 @@ static struct { }; static int -atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *codec_dai) +atmel_classd_cpu_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *cpu_dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_component *component = cpu_dai->component; int fs; int i, best, best_val, cur_val, ret; u32 mask, val; @@ -417,8 +378,8 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, } static void -atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) +atmel_classd_cpu_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); @@ -426,10 +387,10 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream, clk_disable_unprepare(dd->gclk); } -static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) +static int atmel_classd_cpu_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) { - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_component *component = cpu_dai->component; snd_soc_component_update_bits(component, CLASSD_MR, CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK, @@ -439,10 +400,10 @@ static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, return 0; } -static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *codec_dai) +static int atmel_classd_cpu_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *cpu_dai) { - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_component *component = cpu_dai->component; u32 mask, val; mask = CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK; @@ -468,19 +429,16 @@ static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream, return 0; } -static const struct snd_soc_dai_ops atmel_classd_codec_dai_ops = { - .digital_mute = atmel_classd_codec_dai_digital_mute, - .startup = atmel_classd_codec_dai_startup, - .shutdown = atmel_classd_codec_dai_shutdown, - .hw_params = atmel_classd_codec_dai_hw_params, - .prepare = atmel_classd_codec_dai_prepare, - .trigger = atmel_classd_codec_dai_trigger, +static const struct snd_soc_dai_ops atmel_classd_cpu_dai_ops = { + .startup = atmel_classd_cpu_dai_startup, + .shutdown = atmel_classd_cpu_dai_shutdown, + .digital_mute = atmel_classd_cpu_dai_digital_mute, + .hw_params = atmel_classd_cpu_dai_hw_params, + .prepare = atmel_classd_cpu_dai_prepare, + .trigger = atmel_classd_cpu_dai_trigger, }; -#define ATMEL_CLASSD_CODEC_DAI_NAME "atmel-classd-hifi" - -static struct snd_soc_dai_driver atmel_classd_codec_dai = { - .name = ATMEL_CLASSD_CODEC_DAI_NAME, +static struct snd_soc_dai_driver atmel_classd_cpu_dai = { .playback = { .stream_name = "Playback", .channels_min = 1, @@ -488,7 +446,18 @@ static struct snd_soc_dai_driver atmel_classd_codec_dai = { .rates = ATMEL_CLASSD_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &atmel_classd_codec_dai_ops, + .ops = &atmel_classd_cpu_dai_ops, +}; + +static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = { + .name = "atmel-classd", + .probe = atmel_classd_component_probe, + .resume = atmel_classd_component_resume, + .controls = atmel_classd_snd_controls, + .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, }; /* ASoC sound card */ @@ -517,9 +486,9 @@ static int atmel_classd_asoc_card_init(struct device *dev, dai_link->name = "CLASSD"; dai_link->stream_name = "CLASSD PCM"; - dai_link->codecs->dai_name = ATMEL_CLASSD_CODEC_DAI_NAME; + dai_link->codecs->dai_name = "snd-soc-dummy-dai"; dai_link->cpus->dai_name = dev_name(dev); - dai_link->codecs->name = dev_name(dev); + dai_link->codecs->name = "snd-soc-dummy"; dai_link->platforms->name = dev_name(dev); card->dai_link = dai_link; @@ -620,13 +589,6 @@ static int atmel_classd_probe(struct platform_device *pdev) return ret; } - ret = devm_snd_soc_register_component(dev, &soc_component_dev_classd, - &atmel_classd_codec_dai, 1); - if (ret) { - dev_err(dev, "could not register component: %d\n", ret); - return ret; - } - /* register sound card */ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) { diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index cb03c4f7324c9c..0a2e956232afe4 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -44,7 +44,7 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { .buffer_bytes_max = 512 * 1024, }; -/** +/* * atmel_pcm_dma_irq: SSC interrupt handler for DMAENGINE enabled SSC * * We use DMAENGINE to send/receive data to/from SSC so this ISR is only to diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index 5245826cd99d2a..c2b639928c69ab 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c @@ -147,32 +147,26 @@ static int atmel_pdmic_cpu_dai_prepare(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_component *component = cpu_dai->component; u32 val; + int ret; /* Clean the PDMIC Converted Data Register */ - return regmap_read(dd->regmap, PDMIC_CDR, &val); -} - -static const struct snd_soc_dai_ops atmel_pdmic_cpu_dai_ops = { - .startup = atmel_pdmic_cpu_dai_startup, - .shutdown = atmel_pdmic_cpu_dai_shutdown, - .prepare = atmel_pdmic_cpu_dai_prepare, -}; + ret = regmap_read(dd->regmap, PDMIC_CDR, &val); + if (ret < 0) + return 0; -#define ATMEL_PDMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) + ret = snd_soc_component_update_bits(component, PDMIC_CR, + PDMIC_CR_ENPDM_MASK, + PDMIC_CR_ENPDM_DIS << + PDMIC_CR_ENPDM_SHIFT); + if (ret < 0) + return ret; -static struct snd_soc_dai_driver atmel_pdmic_cpu_dai = { - .capture = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = ATMEL_PDMIC_FORMATS,}, - .ops = &atmel_pdmic_cpu_dai_ops, -}; + return 0; +} -static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = { - .name = "atmel-pdmic", -}; +#define ATMEL_PDMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) /* platform */ #define ATMEL_PDMIC_MAX_BUF_SIZE (64 * 1024) @@ -355,27 +349,16 @@ static int atmel_pdmic_component_probe(struct snd_soc_component *component) return 0; } -static struct snd_soc_component_driver soc_component_dev_pdmic = { - .probe = atmel_pdmic_component_probe, - .controls = atmel_pdmic_snd_controls, - .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), - .idle_bias_on = 1, - .use_pmdown_time = 1, - .endianness = 1, - .non_legacy_dai_naming = 1, -}; - -/* codec dai component */ #define PDMIC_MR_PRESCAL_MAX_VAL 127 static int -atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *codec_dai) +atmel_pdmic_cpu_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *cpu_dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_component *component = cpu_dai->component; unsigned int rate_min = substream->runtime->hw.rate_min; unsigned int rate_max = substream->runtime->hw.rate_max; int fs = params_rate(params); @@ -445,21 +428,10 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream, return 0; } -static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *codec_dai) -{ - struct snd_soc_component *component = codec_dai->component; - - snd_soc_component_update_bits(component, PDMIC_CR, PDMIC_CR_ENPDM_MASK, - PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT); - - return 0; -} - -static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *codec_dai) +static int atmel_pdmic_cpu_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *cpu_dai) { - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_component *component = cpu_dai->component; u32 val; switch (cmd) { @@ -482,16 +454,16 @@ static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream, return 0; } -static const struct snd_soc_dai_ops atmel_pdmic_codec_dai_ops = { - .hw_params = atmel_pdmic_codec_dai_hw_params, - .prepare = atmel_pdmic_codec_dai_prepare, - .trigger = atmel_pdmic_codec_dai_trigger, +static const struct snd_soc_dai_ops atmel_pdmic_cpu_dai_ops = { + .startup = atmel_pdmic_cpu_dai_startup, + .shutdown = atmel_pdmic_cpu_dai_shutdown, + .prepare = atmel_pdmic_cpu_dai_prepare, + .hw_params = atmel_pdmic_cpu_dai_hw_params, + .trigger = atmel_pdmic_cpu_dai_trigger, }; -#define ATMEL_PDMIC_CODEC_DAI_NAME "atmel-pdmic-hifi" -static struct snd_soc_dai_driver atmel_pdmic_codec_dai = { - .name = ATMEL_PDMIC_CODEC_DAI_NAME, +static struct snd_soc_dai_driver atmel_pdmic_cpu_dai = { .capture = { .stream_name = "Capture", .channels_min = 1, @@ -499,7 +471,17 @@ static struct snd_soc_dai_driver atmel_pdmic_codec_dai = { .rates = SNDRV_PCM_RATE_KNOT, .formats = ATMEL_PDMIC_FORMATS, }, - .ops = &atmel_pdmic_codec_dai_ops, + .ops = &atmel_pdmic_cpu_dai_ops, +}; + +static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = { + .name = "atmel-pdmic", + .probe = atmel_pdmic_component_probe, + .controls = atmel_pdmic_snd_controls, + .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, }; /* ASoC sound card */ @@ -528,9 +510,9 @@ static int atmel_pdmic_asoc_card_init(struct device *dev, dai_link->name = "PDMIC"; dai_link->stream_name = "PDMIC PCM"; - dai_link->codecs->dai_name = ATMEL_PDMIC_CODEC_DAI_NAME; + dai_link->codecs->dai_name = "snd-soc-dummy-dai"; dai_link->cpus->dai_name = dev_name(dev); - dai_link->codecs->name = dev_name(dev); + dai_link->codecs->name = "snd-soc-dummy"; dai_link->platforms->name = dev_name(dev); card->dai_link = dai_link; @@ -684,16 +666,6 @@ static int atmel_pdmic_probe(struct platform_device *pdev) return ret; } - /* register codec and codec dai */ - atmel_pdmic_codec_dai.capture.rate_min = rate_min; - atmel_pdmic_codec_dai.capture.rate_max = rate_max; - ret = devm_snd_soc_register_component(dev, &soc_component_dev_pdmic, - &atmel_pdmic_codec_dai, 1); - if (ret) { - dev_err(dev, "could not register component: %d\n", ret); - return ret; - } - /* register sound card */ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) { diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 0f18dfb85bfeda..6a63e8797a0b6b 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -887,6 +887,7 @@ static int asoc_ssc_init(struct device *dev) /** * atmel_ssc_set_audio - Allocate the specified SSC for audio use. + * @ssc_id: SSD ID in [0, NUM_SSC_DEVICES[ */ int atmel_ssc_set_audio(int ssc_id) { diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index ea92007d1ef536..31a8c4162d209c 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2126,7 +2126,7 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) dev_err(dai->component->dev, "%s: ERROR: The device is either a master or a slave.\n", __func__); - /* fall through */ + fallthrough; default: dev_err(dai->component->dev, "%s: ERROR: Unsupporter master mask 0x%x\n", diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 5ca9b744b7d849..fb006fc81653a6 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -642,7 +642,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component) ARRAY_SIZE(adau1761_jack_detect_controls)); if (ret) return ret; - /* fall through */ + fallthrough; case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes, ARRAY_SIZE(adau1761_no_dmic_routes)); @@ -693,7 +693,7 @@ static int adau1761_setup_headphone_mode(struct snd_soc_component *component) ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE, ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP | ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE); - /* fallthrough */ + fallthrough; case ADAU1761_OUTPUT_MODE_HEADPHONE: regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL, ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP, diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index b6352de077b523..30e072c80ac179 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -385,7 +385,7 @@ static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, case ADAU17X1_CLK_SRC_PLL_AUTO: if (!adau->mclk) return -EINVAL; - /* Fall-through */ + fallthrough; case ADAU17X1_CLK_SRC_PLL: is_pll = true; break; @@ -469,7 +469,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, ret = adau17x1_auto_pll(dai, params); if (ret) return ret; - /* Fall-through */ + fallthrough; case ADAU17X1_CLK_SRC_PLL: freq = adau->pll_freq; break; diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index c4b9722c3d8f5f..4fd99280d7dbb9 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -647,7 +647,7 @@ static int adav80x_set_pll(struct snd_soc_component *component, int pll_id, pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV; break; } - /* fall through */ + fallthrough; default: return -EINVAL; } diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index d4d2f0d9231a9a..8d663e8d64c498 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -451,13 +451,13 @@ static int ak4613_set_bias_level(struct snd_soc_component *component, switch (level) { case SND_SOC_BIAS_ON: mgmt1 |= RSTN; - /* fall through */ + fallthrough; case SND_SOC_BIAS_PREPARE: mgmt1 |= PMADC | PMDAC; - /* fall through */ + fallthrough; case SND_SOC_BIAS_STANDBY: mgmt1 |= PMVR; - /* fall through */ + fallthrough; case SND_SOC_BIAS_OFF: default: break; diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 8d45c628e988e9..f23956cf4ed84b 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -1053,11 +1053,13 @@ static const struct of_device_id cros_ec_codec_of_match[] = { MODULE_DEVICE_TABLE(of, cros_ec_codec_of_match); #endif +#ifdef CONFIG_ACPI static const struct acpi_device_id cros_ec_codec_acpi_id[] = { { "GOOG0013", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, cros_ec_codec_acpi_id); +#endif static struct platform_driver cros_ec_codec_platform_driver = { .driver = { diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 3e8dabc14f050c..bd17c806d54371 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -499,7 +499,7 @@ static struct snd_soc_dai_driver cs4270_dai = { /** * cs4270_probe - ASoC probe function - * @pdev: platform device + * @component: ASoC component * * This function is called when ASoC has all the pieces it needs to * instantiate a sound driver. @@ -540,7 +540,7 @@ static int cs4270_probe(struct snd_soc_component *component) /** * cs4270_remove - ASoC remove function - * @pdev: platform device + * @component: ASoC component * * This function is the counterpart to cs4270_probe(). */ diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 3bc2fa229ef30c..d391b507490420 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1658,8 +1658,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client, ret = of_property_read_u32(np, "cirrus,btn-det-init-dbnce", &val); if (!ret) { - if ((val >= CS42L42_BTN_DET_INIT_DBNCE_MIN) && - (val <= CS42L42_BTN_DET_INIT_DBNCE_MAX)) + if (val <= CS42L42_BTN_DET_INIT_DBNCE_MAX) cs42l42->btn_det_init_dbnce = val; else { dev_err(&i2c_client->dev, @@ -1676,8 +1675,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client, ret = of_property_read_u32(np, "cirrus,btn-det-event-dbnce", &val); if (!ret) { - if ((val >= CS42L42_BTN_DET_EVENT_DBNCE_MIN) && - (val <= CS42L42_BTN_DET_EVENT_DBNCE_MAX)) + if (val <= CS42L42_BTN_DET_EVENT_DBNCE_MAX) cs42l42->btn_det_event_dbnce = val; else { dev_err(&i2c_client->dev, @@ -1695,8 +1693,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client, if (!ret) { for (i = 0; i < CS42L42_NUM_BIASES; i++) { - if ((thresholds[i] >= CS42L42_HS_DET_LEVEL_MIN) && - (thresholds[i] <= CS42L42_HS_DET_LEVEL_MAX)) + if (thresholds[i] <= CS42L42_HS_DET_LEVEL_MAX) cs42l42->bias_thresholds[i] = thresholds[i]; else { dev_err(&i2c_client->dev, diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 0c99dcf242e428..2bb727dd3a20de 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -971,14 +971,16 @@ static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai, /** * da7210_set_dai_pll :Configure the codec PLL - * @param codec_dai : pointer to codec DAI - * @param pll_id : da7210 has only one pll, so pll_id is always zero - * @param fref : MCLK frequency, should be < 20MHz - * @param fout : FsDM value, Refer page 44 & 45 of datasheet - * @return int : Zero for success, negative error code for error + * @codec_dai: pointer to codec DAI + * @pll_id: da7210 has only one pll, so pll_id is always zero + * @source: clock source + * @fref: MCLK frequency, should be < 20MHz + * @fout: FsDM value, Refer page 44 & 45 of datasheet * * Note: Supported PLL input frequencies are 12MHz, 13MHz, 13.5MHz, 14.4MHz, * 19.2MHz, 19.6MHz and 19.8MHz + * + * Return: Zero for success, negative error code for error */ static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, int source, unsigned int fref, unsigned int fout) diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index cc4ae7b311b425..fe93ec7026457e 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; + struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); u8 dai_ctrl = 0; u8 fs; @@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct snd_pcm_substream *substream, switch (params_rate(params)) { case 8000: fs = DA7213_SR_8000; + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; break; case 11025: fs = DA7213_SR_11025; + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; break; case 12000: fs = DA7213_SR_12000; + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; break; case 16000: fs = DA7213_SR_16000; + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; break; case 22050: fs = DA7213_SR_22050; + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; break; case 32000: fs = DA7213_SR_32000; + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; break; case 44100: fs = DA7213_SR_44100; + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; break; case 48000: fs = DA7213_SR_48000; + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; break; case 88200: fs = DA7213_SR_88200; + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800; break; case 96000: fs = DA7213_SR_96000; + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000; break; default: return -EINVAL; @@ -1392,9 +1403,9 @@ static int da7213_set_component_sysclk(struct snd_soc_component *component, } /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */ -static int da7213_set_component_pll(struct snd_soc_component *component, - int pll_id, int source, - unsigned int fref, unsigned int fout) +static int _da7213_set_component_pll(struct snd_soc_component *component, + int pll_id, int source, + unsigned int fref, unsigned int fout) { struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); @@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct snd_soc_component *component, return 0; } +static int da7213_set_component_pll(struct snd_soc_component *component, + int pll_id, int source, + unsigned int fref, unsigned int fout) +{ + struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); + da7213->fixed_clk_auto_pll = false; + + return _da7213_set_component_pll(component, pll_id, source, fref, fout); +} + /* DAI operations */ static const struct snd_soc_dai_ops da7213_dai_ops = { .hw_params = da7213_hw_params, @@ -1532,6 +1553,50 @@ static struct snd_soc_dai_driver da7213_dai = { .symmetric_rates = 1, }; +static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable) +{ + struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); + int mode; + + if (!da7213->fixed_clk_auto_pll) + return 0; + + da7213->mclk_rate = clk_get_rate(da7213->mclk); + + if (enable) { + /* Slave mode needs SRM for non-harmonic frequencies */ + if (da7213->master) + mode = DA7213_SYSCLK_PLL; + else + mode = DA7213_SYSCLK_PLL_SRM; + + /* PLL is not required for harmonic frequencies */ + switch (da7213->out_rate) { + case DA7213_PLL_FREQ_OUT_90316800: + if (da7213->mclk_rate == 11289600 || + da7213->mclk_rate == 22579200 || + da7213->mclk_rate == 45158400) + mode = DA7213_SYSCLK_MCLK; + break; + case DA7213_PLL_FREQ_OUT_98304000: + if (da7213->mclk_rate == 12288000 || + da7213->mclk_rate == 24576000 || + da7213->mclk_rate == 49152000) + mode = DA7213_SYSCLK_MCLK; + + break; + default: + return -1; + } + } else { + /* Disable PLL in standby */ + mode = DA7213_SYSCLK_MCLK; + } + + return _da7213_set_component_pll(component, 0, mode, + da7213->mclk_rate, da7213->out_rate); +} + static int da7213_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { @@ -1551,6 +1616,8 @@ static int da7213_set_bias_level(struct snd_soc_component *component, "Failed to enable mclk\n"); return ret; } + + da7213_set_auto_pll(component, true); } } break; @@ -1562,8 +1629,10 @@ static int da7213_set_bias_level(struct snd_soc_component *component, DA7213_VMID_EN | DA7213_BIAS_EN); } else { /* Remove MCLK */ - if (da7213->mclk) + if (da7213->mclk) { + da7213_set_auto_pll(component, false); clk_disable_unprepare(da7213->mclk); + } } break; case SND_SOC_BIAS_OFF: @@ -1693,7 +1762,6 @@ static struct da7213_platform_data return pdata; } - static int da7213_probe(struct snd_soc_component *component) { struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component); @@ -1829,6 +1897,11 @@ static int da7213_probe(struct snd_soc_component *component) return PTR_ERR(da7213->mclk); else da7213->mclk = NULL; + } else { + /* Do automatic PLL handling assuming fixed clock until + * set_pll() has been called. This makes the codec usable + * with the simple-audio-card driver. */ + da7213->fixed_clk_auto_pll = true; } return 0; diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 3890829dfb6e1f..97ccf0ddd2be20 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -535,10 +535,12 @@ struct da7213_priv { struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES]; struct clk *mclk; unsigned int mclk_rate; + unsigned int out_rate; int clk_src; bool master; bool alc_calib_auto; bool alc_en; + bool fixed_clk_auto_pll; struct da7213_platform_data *pdata; }; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index f2520a6c78755c..153ea30b5a8f85 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1708,11 +1708,13 @@ static const struct of_device_id da7219_of_match[] = { }; MODULE_DEVICE_TABLE(of, da7219_of_match); +#ifdef CONFIG_ACPI static const struct acpi_device_id da7219_acpi_match[] = { { .id = "DLGS7219", }, { } }; MODULE_DEVICE_TABLE(acpi, da7219_acpi_match); +#endif static enum da7219_micbias_voltage da7219_fw_micbias_lvl(struct device *dev, u32 val) diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 36eef1fb3d181e..70af35c5f727f0 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -839,11 +839,13 @@ static const struct of_device_id es8316_of_match[] = { }; MODULE_DEVICE_TABLE(of, es8316_of_match); +#ifdef CONFIG_ACPI static const struct acpi_device_id es8316_acpi_match[] = { {"ESSX8316", 0}, {}, }; MODULE_DEVICE_TABLE(acpi, es8316_acpi_match); +#endif static struct i2c_driver es8316_i2c_driver = { .driver = { diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index fdf64c29f563d0..757e740459fb54 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -562,14 +562,14 @@ static int es8328_set_sysclk(struct snd_soc_dai *codec_dai, break; case 22579200: mclkdiv2 = 1; - /* fall through */ + fallthrough; case 11289600: es8328->sysclk_constraints = &constraints_11289; es8328->mclk_ratios = ratios_11289; break; case 24576000: mclkdiv2 = 1; - /* fall through */ + fallthrough; case 12288000: es8328->sysclk_constraints = &constraints_12288; es8328->mclk_ratios = ratios_12288; diff --git a/sound/soc/codecs/jz4770.c b/sound/soc/codecs/jz4770.c index 34775aa6240248..4dee585761c247 100644 --- a/sound/soc/codecs/jz4770.c +++ b/sound/soc/codecs/jz4770.c @@ -303,7 +303,6 @@ static int jz4770_codec_digital_mute(struct snd_soc_dai *dai, int mute) static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 0); static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 600); -static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 400, 0); static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0); /* Unconditional controls. */ diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index b345e626956dbe..3e80942416456f 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -944,14 +944,6 @@ static const struct regmap_config max98390_regmap = { .cache_type = REGCACHE_RBTREE, }; -#ifdef CONFIG_OF -static const struct of_device_id max98390_dt_ids[] = { - { .compatible = "maxim,max98390", }, - { } -}; -MODULE_DEVICE_TABLE(of, max98390_dt_ids); -#endif - static int max98390_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 8be636fe655206..d5925c42b4b572 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -334,7 +334,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } ifc1a ^= MAX9860_WCI; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_IB_NF: ifc1a ^= MAX9860_DBCI; ifc1b ^= MAX9860_ABCI; diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 30da00a3e789bb..4428c62e25cf03 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -608,7 +608,7 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w, case CDC_A_TX_2_EN: snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL, MICB_1_CTL_CFILT_REF_SEL_MASK, 0); - /* fall through */ + fallthrough; case CDC_A_TX_3_EN: snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL, CONN_TX2_SERIAL_TX2_MUX, diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index cbb5e176d11a88..70cf17c0aa99ec 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -760,7 +760,7 @@ static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, break; default: dev_warn(component->dev, "invalid pll source, use BCLK\n"); - /* fall through */ + fallthrough; case RT274_PLL2_S_BCLK: snd_soc_component_update_bits(component, RT274_PLL2_CTRL, RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK); @@ -788,7 +788,7 @@ static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, break; default: dev_warn(component->dev, "invalid freq_in, assume 4.8M\n"); - /* fall through */ + fallthrough; case 100: snd_soc_component_write(component, 0x7a, 0xaab6); snd_soc_component_write(component, 0x7b, 0x0301); @@ -1105,12 +1105,14 @@ static const struct i2c_device_id rt274_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt274_i2c_id); +#ifdef CONFIG_ACPI static const struct acpi_device_id rt274_acpi_match[] = { { "10EC0274", 0 }, { "INT34C2", 0 }, {}, }; MODULE_DEVICE_TABLE(acpi, rt274_acpi_match); +#endif static int rt274_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 9593a9a27bf858..5fb9653d9131f3 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -272,13 +272,13 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf); *mic = buf & 0x80000000; } - if (!*mic) { + + if (!*hp) { snd_soc_dapm_disable_pin(dapm, "HV"); snd_soc_dapm_disable_pin(dapm, "VREF"); - } - if (!*hp) snd_soc_dapm_disable_pin(dapm, "LDO1"); - snd_soc_dapm_sync(dapm); + snd_soc_dapm_sync(dapm); + } return 0; } @@ -1079,11 +1079,13 @@ static const struct i2c_device_id rt286_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); +#ifdef CONFIG_ACPI static const struct acpi_device_id rt286_acpi_match[] = { { "INT343A", 0 }, {}, }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); +#endif static const struct dmi_system_id force_combo_jack_table[] = { { diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index 7fc7d6181630c5..dc0273a5a11f7d 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1145,11 +1145,13 @@ static const struct i2c_device_id rt298_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt298_i2c_id); +#ifdef CONFIG_ACPI static const struct acpi_device_id rt298_acpi_match[] = { { "INT343A", 0 }, {}, }; MODULE_DEVICE_TABLE(acpi, rt298_acpi_match); +#endif static const struct dmi_system_id force_combo_jack_table[] = { { diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 3b2bb62a213658..1414ad15d01cff 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1662,7 +1662,7 @@ static int get_sdp_info(struct snd_soc_component *component, int dai_id) break; case RT5640_IF_113: ret |= RT5640_U_IF1; - /* fall through */ + fallthrough; case RT5640_IF_312: case RT5640_IF_213: ret |= RT5640_U_IF2; @@ -1678,7 +1678,7 @@ static int get_sdp_info(struct snd_soc_component *component, int dai_id) break; case RT5640_IF_223: ret |= RT5640_U_IF1; - /* fall through */ + fallthrough; case RT5640_IF_123: case RT5640_IF_321: ret |= RT5640_U_IF2; diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 78371e51bc34ff..9e3813f7583d97 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1241,12 +1241,14 @@ static const struct of_device_id rt5660_of_match[] = { }; MODULE_DEVICE_TABLE(of, rt5660_of_match); +#ifdef CONFIG_ACPI static const struct acpi_device_id rt5660_acpi_match[] = { { "10EC5660", 0 }, { "10EC3277", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match); +#endif static int rt5660_parse_dt(struct rt5660_priv *rt5660, struct device *dev) { diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 91c68c8965d189..a0c8f58d729b3e 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -25,13 +25,12 @@ #include #include #include -#include #include "rl6231.h" #include "rt5670.h" #include "rt5670-dsp.h" -#define RT5670_DEV_GPIO BIT(0) +#define RT5670_GPIO1_IS_IRQ BIT(0) #define RT5670_IN2_DIFF BIT(1) #define RT5670_DMIC_EN BIT(2) #define RT5670_DMIC1_IN2P BIT(3) @@ -518,7 +517,7 @@ static int rt5670_irq_detection(void *data) struct snd_soc_jack *jack = rt5670->jack; int val, btn_type, report = jack->status; - if (rt5670->pdata.jd_mode == 1) /* 2 port */ + if (rt5670->jd_mode == 1) /* 2 port */ val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070; else val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020; @@ -1454,7 +1453,7 @@ static int rt5670_spk_event(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component); - if (!rt5670->pdata.gpio1_is_ext_spk_en) + if (!rt5670->gpio1_is_ext_spk_en) return 0; switch (event) { @@ -2624,7 +2623,7 @@ static int rt5670_set_bias_level(struct snd_soc_component *component, RT5670_LDO_SEL_MASK, 0x3); break; case SND_SOC_BIAS_OFF: - if (rt5670->pdata.jd_mode) + if (rt5670->jd_mode) snd_soc_component_update_bits(component, RT5670_PWR_ANLG1, RT5670_PWR_VREF1 | RT5670_PWR_MB | RT5670_PWR_BG | RT5670_PWR_VREF2 | @@ -2834,7 +2833,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2846,7 +2845,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2858,7 +2857,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC2_INR | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2870,7 +2869,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2882,7 +2881,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC1_IN2P | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE1), }, { @@ -2906,7 +2905,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC2_INR | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE3), }, { @@ -2918,7 +2917,7 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { }, .driver_data = (unsigned long *)(RT5670_DMIC_EN | RT5670_DMIC2_INR | - RT5670_DEV_GPIO | + RT5670_GPIO1_IS_IRQ | RT5670_JD_MODE3), }, {} @@ -2927,7 +2926,6 @@ static const struct dmi_system_id dmi_platform_intel_quirks[] = { static int rt5670_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct rt5670_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5670_priv *rt5670; int ret; unsigned int val; @@ -2940,9 +2938,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5670); - if (pdata) - rt5670->pdata = *pdata; - dmi_check_system(dmi_platform_intel_quirks); if (quirk_override) { dev_info(&i2c->dev, "Overriding quirk 0x%x => 0x%x\n", @@ -2950,57 +2945,57 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, rt5670_quirk = quirk_override; } - if (rt5670_quirk & RT5670_DEV_GPIO) { - rt5670->pdata.dev_gpio = true; - dev_info(&i2c->dev, "quirk dev_gpio\n"); + if (rt5670_quirk & RT5670_GPIO1_IS_IRQ) { + rt5670->gpio1_is_irq = true; + dev_info(&i2c->dev, "quirk GPIO1 is IRQ\n"); } if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) { - rt5670->pdata.gpio1_is_ext_spk_en = true; + rt5670->gpio1_is_ext_spk_en = true; dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n"); } if (rt5670_quirk & RT5670_IN2_DIFF) { - rt5670->pdata.in2_diff = true; + rt5670->in2_diff = true; dev_info(&i2c->dev, "quirk IN2_DIFF\n"); } if (rt5670_quirk & RT5670_DMIC_EN) { - rt5670->pdata.dmic_en = true; + rt5670->dmic_en = true; dev_info(&i2c->dev, "quirk DMIC enabled\n"); } if (rt5670_quirk & RT5670_DMIC1_IN2P) { - rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; + rt5670->dmic1_data_pin = RT5670_DMIC_DATA_IN2P; dev_info(&i2c->dev, "quirk DMIC1 on IN2P pin\n"); } if (rt5670_quirk & RT5670_DMIC1_GPIO6) { - rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_GPIO6; + rt5670->dmic1_data_pin = RT5670_DMIC_DATA_GPIO6; dev_info(&i2c->dev, "quirk DMIC1 on GPIO6 pin\n"); } if (rt5670_quirk & RT5670_DMIC1_GPIO7) { - rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_GPIO7; + rt5670->dmic1_data_pin = RT5670_DMIC_DATA_GPIO7; dev_info(&i2c->dev, "quirk DMIC1 on GPIO7 pin\n"); } if (rt5670_quirk & RT5670_DMIC2_INR) { - rt5670->pdata.dmic2_data_pin = RT5670_DMIC_DATA_IN3N; + rt5670->dmic2_data_pin = RT5670_DMIC_DATA_IN3N; dev_info(&i2c->dev, "quirk DMIC2 on INR pin\n"); } if (rt5670_quirk & RT5670_DMIC2_GPIO8) { - rt5670->pdata.dmic2_data_pin = RT5670_DMIC_DATA_GPIO8; + rt5670->dmic2_data_pin = RT5670_DMIC_DATA_GPIO8; dev_info(&i2c->dev, "quirk DMIC2 on GPIO8 pin\n"); } if (rt5670_quirk & RT5670_DMIC3_GPIO5) { - rt5670->pdata.dmic3_data_pin = RT5670_DMIC_DATA_GPIO5; + rt5670->dmic3_data_pin = RT5670_DMIC_DATA_GPIO5; dev_info(&i2c->dev, "quirk DMIC3 on GPIO5 pin\n"); } if (rt5670_quirk & RT5670_JD_MODE1) { - rt5670->pdata.jd_mode = 1; + rt5670->jd_mode = 1; dev_info(&i2c->dev, "quirk JD mode 1\n"); } if (rt5670_quirk & RT5670_JD_MODE2) { - rt5670->pdata.jd_mode = 2; + rt5670->jd_mode = 2; dev_info(&i2c->dev, "quirk JD mode 2\n"); } if (rt5670_quirk & RT5670_JD_MODE3) { - rt5670->pdata.jd_mode = 3; + rt5670->jd_mode = 3; dev_info(&i2c->dev, "quirk JD mode 3\n"); } @@ -3041,11 +3036,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5670->regmap, RT5670_DIG_MISC, RT5670_MCLK_DET, RT5670_MCLK_DET); - if (rt5670->pdata.in2_diff) + if (rt5670->in2_diff) regmap_update_bits(rt5670->regmap, RT5670_IN2, RT5670_IN_DF2, RT5670_IN_DF2); - if (rt5670->pdata.dev_gpio) { + if (rt5670->gpio1_is_irq) { /* for push button */ regmap_write(rt5670->regmap, RT5670_IL_CMD, 0x0000); regmap_write(rt5670->regmap, RT5670_IL_CMD2, 0x0010); @@ -3057,14 +3052,14 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); } - if (rt5670->pdata.gpio1_is_ext_spk_en) { + if (rt5670->gpio1_is_ext_spk_en) { regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1); regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); } - if (rt5670->pdata.jd_mode) { + if (rt5670->jd_mode) { regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK, RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK); rt5670->sysclk = 0; @@ -3079,7 +3074,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, RT5670_JD_TRI_CBJ_SEL_MASK | RT5670_JD_TRI_HPO_SEL_MASK, RT5670_JD_CBJ_JD1_1 | RT5670_JD_HPO_JD1_1); - switch (rt5670->pdata.jd_mode) { + switch (rt5670->jd_mode) { case 1: regmap_update_bits(rt5670->regmap, RT5670_A_JD_CTRL1, RT5670_JD1_MODE_MASK, @@ -3100,12 +3095,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, } } - if (rt5670->pdata.dmic_en) { + if (rt5670->dmic_en) { regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, RT5670_GP2_PIN_MASK, RT5670_GP2_PIN_DMIC1_SCL); - switch (rt5670->pdata.dmic1_data_pin) { + switch (rt5670->dmic1_data_pin) { case RT5670_DMIC_DATA_IN2P: regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1, RT5670_DMIC_1_DP_MASK, @@ -3134,7 +3129,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, break; } - switch (rt5670->pdata.dmic2_data_pin) { + switch (rt5670->dmic2_data_pin) { case RT5670_DMIC_DATA_IN3N: regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL1, RT5670_DMIC_2_DP_MASK, @@ -3154,7 +3149,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, break; } - switch (rt5670->pdata.dmic3_data_pin) { + switch (rt5670->dmic3_data_pin) { case RT5670_DMIC_DATA_GPIO5: regmap_update_bits(rt5670->regmap, RT5670_DMIC_CTRL2, RT5670_DMIC_3_DP_MASK, diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h index de0203369b7cd9..56b13fe6bd3cb9 100644 --- a/sound/soc/codecs/rt5670.h +++ b/sound/soc/codecs/rt5670.h @@ -9,8 +9,6 @@ #ifndef __RT5670_H__ #define __RT5670_H__ -#include - /* Info */ #define RT5670_RESET 0x00 #define RT5670_VENDOR_ID 0xfd @@ -1988,11 +1986,23 @@ int rt5670_sel_asrc_clk_src(struct snd_soc_component *component, struct rt5670_priv { struct snd_soc_component *component; - struct rt5670_platform_data pdata; struct regmap *regmap; struct snd_soc_jack *jack; struct snd_soc_jack_gpio hp_gpio; + int jd_mode; + bool in2_diff; + bool gpio1_is_irq; + bool gpio1_is_ext_spk_en; + + bool dmic_en; + unsigned int dmic1_data_pin; + /* 0 = GPIO6; 1 = IN2P; 3 = GPIO7*/ + unsigned int dmic2_data_pin; + /* 0 = GPIO8; 1 = IN3N; */ + unsigned int dmic3_data_pin; + /* 0 = GPIO9; 1 = GPIO10; 2 = GPIO5*/ + int sysclk; int sysclk_src; int lrck[RT5670_AIFS]; diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c index 7bfade8b3d6e8a..95ac12a5cc6b1d 100644 --- a/sound/soc/codecs/rt5677-spi.c +++ b/sound/soc/codecs/rt5677-spi.c @@ -614,11 +614,13 @@ static int rt5677_spi_probe(struct spi_device *spi) return ret; } +#ifdef CONFIG_ACPI static const struct acpi_device_id rt5677_spi_acpi_id[] = { { "RT5677AA", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id); +#endif static struct spi_driver rt5677_spi_driver = { .driver = { diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index e9a051a50ab2d1..9e449d35fc2820 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -4609,7 +4609,7 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, break; case 25: slot_width_25 = 0x8080; - /* fall through */ + fallthrough; case 24: val |= (2 << 8); break; diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index e9514c81b9ba44..de40b6cd16cf23 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -992,16 +992,17 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, rt5682->hs_jack = hs_jack; - if (!rt5682->is_sdw) { - if (!hs_jack) { - regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, - RT5682_JD1_EN_MASK, RT5682_JD1_DIS); - regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, - RT5682_POW_JDH | RT5682_POW_JDL, 0); - cancel_delayed_work_sync(&rt5682->jack_detect_work); - return 0; - } + if (!hs_jack) { + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, + RT5682_JD1_EN_MASK, RT5682_JD1_DIS); + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, + RT5682_POW_JDH | RT5682_POW_JDL, 0); + cancel_delayed_work_sync(&rt5682->jack_detect_work); + return 0; + } + + if (!rt5682->is_sdw) { switch (rt5682->pdata.jd_src) { case RT5682_JD1: snd_soc_component_update_bits(component, diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index e8d2ca4b4603bd..86528b930de891 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -697,7 +697,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, switch (params_width(params)) { case 24: dev_dbg(component->dev, "24bit\n"); - /* fall through */ + fallthrough; case 32: dev_dbg(component->dev, "24bit or 32bit\n"); switch (sta32x->format) { diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index ccb7100b66444c..75d3b0618ab500 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -726,7 +726,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream, switch (params_width(params)) { case 24: dev_dbg(component->dev, "24bit\n"); - /* fall through */ + fallthrough; case 32: dev_dbg(component->dev, "24bit or 32bit\n"); switch (sta350->format) { diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 529c0fb93f9b2d..d9d239d4256e73 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -407,7 +407,7 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, clk_id = TAS2552_PLL_CLKIN_BCLK; freq = 0; } - /* fall through */ + fallthrough; case TAS2552_PLL_CLKIN_BCLK: case TAS2552_PLL_CLKIN_1_8_FIXED: mask = TAS2552_PLL_SRC_MASK; diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 35fe8ee5bce9fa..d900af967f8c12 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -313,6 +313,14 @@ static const struct snd_kcontrol_new adcx140_dapm_ch3_en_switch = SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 5, 1, 0); static const struct snd_kcontrol_new adcx140_dapm_ch4_en_switch = SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 4, 1, 0); +static const struct snd_kcontrol_new adcx140_dapm_ch5_en_switch = + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 3, 1, 0); +static const struct snd_kcontrol_new adcx140_dapm_ch6_en_switch = + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 2, 1, 0); +static const struct snd_kcontrol_new adcx140_dapm_ch7_en_switch = + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 1, 1, 0); +static const struct snd_kcontrol_new adcx140_dapm_ch8_en_switch = + SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 0, 1, 0); static const struct snd_kcontrol_new adcx140_dapm_ch1_dre_en_switch = SOC_DAPM_SINGLE("Switch", ADCX140_CH1_CFG0, 0, 1, 0); @@ -406,6 +414,15 @@ static const struct snd_soc_dapm_widget adcx140_dapm_widgets[] = { SND_SOC_DAPM_SWITCH("CH4_ASI_EN", SND_SOC_NOPM, 0, 0, &adcx140_dapm_ch4_en_switch), + SND_SOC_DAPM_SWITCH("CH5_ASI_EN", SND_SOC_NOPM, 0, 0, + &adcx140_dapm_ch5_en_switch), + SND_SOC_DAPM_SWITCH("CH6_ASI_EN", SND_SOC_NOPM, 0, 0, + &adcx140_dapm_ch6_en_switch), + SND_SOC_DAPM_SWITCH("CH7_ASI_EN", SND_SOC_NOPM, 0, 0, + &adcx140_dapm_ch7_en_switch), + SND_SOC_DAPM_SWITCH("CH8_ASI_EN", SND_SOC_NOPM, 0, 0, + &adcx140_dapm_ch8_en_switch), + SND_SOC_DAPM_SWITCH("DRE_ENABLE", SND_SOC_NOPM, 0, 0, &adcx140_dapm_dre_en_switch), @@ -446,6 +463,11 @@ static const struct snd_soc_dapm_route adcx140_audio_map[] = { {"CH3_ASI_EN", "Switch", "CH3_ADC"}, {"CH4_ASI_EN", "Switch", "CH4_ADC"}, + {"CH5_ASI_EN", "Switch", "CH5_OUT"}, + {"CH6_ASI_EN", "Switch", "CH6_OUT"}, + {"CH7_ASI_EN", "Switch", "CH7_OUT"}, + {"CH8_ASI_EN", "Switch", "CH8_OUT"}, + {"Decimation Filter", "Linear Phase", "DRE_ENABLE"}, {"Decimation Filter", "Low Latency", "DRE_ENABLE"}, {"Decimation Filter", "Ultra-low Latency", "DRE_ENABLE"}, @@ -624,6 +646,8 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); u8 iface_reg1 = 0; u8 iface_reg2 = 0; + int offset = 0; + int width = adcx140->slot_width; /* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -666,7 +690,10 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_reg1 |= ADCX140_LEFT_JUST_BIT; break; case SND_SOC_DAIFMT_DSP_A: + offset += (adcx140->tdm_delay * width + 1); + break; case SND_SOC_DAIFMT_DSP_B: + offset += adcx140->tdm_delay * width; break; default: dev_err(component->dev, "Invalid DAI interface format\n"); @@ -683,6 +710,11 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, snd_soc_component_update_bits(component, ADCX140_MST_CFG0, ADCX140_BCLK_FSYNC_MASTER, iface_reg2); + /* Configure data offset */ + snd_soc_component_update_bits(component, ADCX140_ASI_CFG1, + ADCX140_TX_OFFSET_MASK, offset); + + return 0; } @@ -694,11 +726,6 @@ static int adcx140_set_dai_tdm_slot(struct snd_soc_dai *codec_dai, struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); unsigned int lsb; - if (tx_mask != rx_mask) { - dev_err(component->dev, "tx and rx masks must be symmetric\n"); - return -EINVAL; - } - /* TDM based on DSP mode requires slots to be adjacent */ lsb = __ffs(tx_mask); if ((lsb + 1) != __fls(tx_mask)) { @@ -723,34 +750,9 @@ static int adcx140_set_dai_tdm_slot(struct snd_soc_dai *codec_dai, return 0; } -static int adcx140_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_component *component = dai->component; - struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); - int offset = 0; - int width = adcx140->slot_width; - - if (!width) - width = substream->runtime->sample_bits; - - /* TDM slot selection only valid in DSP_A/_B mode */ - if (adcx140->dai_fmt == SND_SOC_DAIFMT_DSP_A) - offset += (adcx140->tdm_delay * width + 1); - else if (adcx140->dai_fmt == SND_SOC_DAIFMT_DSP_B) - offset += adcx140->tdm_delay * width; - - /* Configure data offset */ - snd_soc_component_update_bits(component, ADCX140_ASI_CFG1, - ADCX140_TX_OFFSET_MASK, offset); - - return 0; -} - static const struct snd_soc_dai_ops adcx140_dai_ops = { .hw_params = adcx140_hw_params, .set_fmt = adcx140_set_dai_fmt, - .prepare = adcx140_prepare, .set_tdm_slot = adcx140_set_dai_tdm_slot, }; diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index d22f75e8fb6a9b..7d5b6dbf627361 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -449,7 +449,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, break; case SND_SOC_DAIFMT_DSP_A: iface_reg |= TLV320AIC23_LRP_ON; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_B: iface_reg |= TLV320AIC23_FOR_DSP; break; diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 31daa60695bdae..6694e56cfe1f75 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1080,7 +1080,8 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_I2S: break; case SND_SOC_DAIFMT_DSP_A: - dsp_a_val = 0x1; /* fall through */ + dsp_a_val = 0x1; + fallthrough; case SND_SOC_DAIFMT_DSP_B: /* * NOTE: This CODEC samples on the falling edge of BCLK in diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 0b1f1a5e2a2d77..e2d7ae615c528c 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -261,7 +261,7 @@ static int tpa6130a2_probe(struct i2c_client *client, default: dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", data->id); - /* fall through */ + fallthrough; case TPA6130A2: regulator = "Vdd"; break; diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 2551eb0f1868cd..35ffa7765c85cf 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -67,16 +67,12 @@ static void wm8400_component_reset(struct snd_soc_component *component) wm8400_reset_codec_reg_cache(wm8400->wm8400); } -static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); - static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0); static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); -static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); - static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0); @@ -439,14 +435,6 @@ static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum, static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls = SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum); -/* RXVOICE */ -static const struct snd_kcontrol_new wm8400_dapm_rxvoice_controls[] = { -SOC_DAPM_SINGLE_TLV("LIN4/RXN", WM8400_INPUT_MIXER5, WM8400_LR4BVOL_SHIFT, - WM8400_LR4BVOL_MASK, 0, in_mix_tlv), -SOC_DAPM_SINGLE_TLV("RIN4/RXP", WM8400_INPUT_MIXER6, WM8400_RL4BVOL_SHIFT, - WM8400_RL4BVOL_MASK, 0, in_mix_tlv), -}; - /* LOMIX */ static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = { SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1, diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index a1b6765c8f23e7..f3c31121d100c9 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -966,7 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_component *component, case SND_SOC_DAIFMT_CBS_CFS: break; case SND_SOC_DAIFMT_CBM_CFM: - ioctl |= 0x2; /* fall through */ + ioctl |= 0x2; + fallthrough; case SND_SOC_DAIFMT_CBM_CFS: voice |= 0x0040; break; @@ -1091,7 +1092,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_component *component, case SND_SOC_DAIFMT_CBS_CFS: break; case SND_SOC_DAIFMT_CBM_CFM: - ioctl |= 0x1; /* fall through */ + ioctl |= 0x1; + fallthrough; case SND_SOC_DAIFMT_CBM_CFS: hifi |= 0x0040; break; diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 5de663d61ba611..a52cb8fee82f9a 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1927,7 +1927,7 @@ static int wm8903_set_pdata_irq_trigger(struct i2c_client *i2c, * We assume the controller imposes no restrictions, * so we are able to select active-high */ - /* Fall-through */ + fallthrough; case IRQ_TYPE_LEVEL_HIGH: pdata->irq_active_low = false; break; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 3f0e49c51fd570..d54257097d569c 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1436,7 +1436,7 @@ static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: aif1 |= 0x3 | WM8904_AIF_LRCLK_INV; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif1 |= 0x3; break; @@ -1824,7 +1824,7 @@ static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id, break; } clk_id = WM8904_CLK_MCLK; - /* fallthrough */ + fallthrough; case WM8904_CLK_MCLK: priv->sysclk_src = clk_id; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 73c192f5838280..0630dcb66c6f72 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -683,7 +683,7 @@ static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: aif |= WM8955_LRP; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif |= 0x3; break; diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 96c4400e92f878..e1ab2be51ee7ed 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -612,7 +612,7 @@ static const int bclk_divs[] = { * triplet, we relax the bclk such that bclk is chosen as the * closest available frequency greater than expected bclk. * - * @wm8960_priv: wm8960 codec private data + * @wm8960: codec private data * @mclk: MCLK used to derive sysclk * @sysclk_idx: sysclk_divs index for found sysclk * @dac_idx: dac_divs index for found lrclk @@ -836,7 +836,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream, iface |= 0x000c; break; } - /* fall through */ + fallthrough; default: dev_err(component->dev, "unsupported width %d\n", params_width(params)); diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index d11a38a0b283a7..e62a0a8ac29788 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -650,7 +650,7 @@ static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_DSP_B: aif |= WM8961_LRP; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif |= 3; switch (fmt & SND_SOC_DAIFMT_INV_MASK) { diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 6ef022295f551c..df8cdc71357d77 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2645,7 +2645,7 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: aif0 |= WM8962_LRCLK_INV | 3; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif0 |= 3; diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 953d12e4576fbd..9f0c9529214dd4 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0), /* Boost mixer */ static const struct snd_kcontrol_new wm8974_boost_mixer[] = { -SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 0), +SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1), }; /* Input PGA */ @@ -474,6 +474,10 @@ static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai, iface |= 0x0008; break; case SND_SOC_DAIFMT_DSP_A: + if ((fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_IB_IF || + (fmt & SND_SOC_DAIFMT_INV_MASK) == SND_SOC_DAIFMT_NB_IF) { + return -EINVAL; + } iface |= 0x00018; break; default: diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 207c0211caa95d..8c9f82efcceb53 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1073,7 +1073,7 @@ static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai, switch (clk_id) { case WM8993_SYSCLK_MCLK: wm8993->mclk_rate = freq; - /* fall through */ + fallthrough; case WM8993_SYSCLK_FLL: wm8993->sysclk_source = clk_id; break; @@ -1121,7 +1121,7 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai, switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: aif1 |= WM8993_AIF_LRCLK_INV; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif1 |= 0x18; break; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 5e1ce243feb17e..903f8e81cd896b 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -853,7 +853,7 @@ static void vmid_reference(struct snd_soc_component *component) switch (wm8994->vmid_mode) { default: WARN_ON(NULL == "Invalid VMID mode"); - /* fall through */ + fallthrough; case WM8994_VMID_NORMAL: /* Startup bias, VMID ramp & buffer */ snd_soc_component_update_bits(component, WM8994_ANTIPOP_2, @@ -2776,7 +2776,7 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_DSP_B: aif1 |= WM8994_AIF1_LRCLK_INV; lrclk |= WM8958_AIF1_LRCLK_INV; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif1 |= 0x18; break; @@ -3877,6 +3877,10 @@ static void wm1811_jackdet_bootstrap(struct work_struct *work) * * @component: WM8958 component * @jack: jack to report detection events on + * @det_cb: detection callback + * @det_cb_data: data for detection callback + * @id_cb: mic id callback + * @id_cb_data: data for mic id callback * * Enable microphone detection functionality for the WM8958. By * default simple detection which supports the detection of up to 6 diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 276ffa84cc318f..ec752819cb2c1d 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -1462,7 +1462,7 @@ static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: aif |= WM8995_AIF1_LRCLK_INV; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif |= (0x3 << WM8995_AIF1_FMT_SHIFT); break; diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 0c176449ee2d59..d303ef7571e9d3 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -1854,7 +1854,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, case 24576000: ratediv = WM8996_SYSCLK_DIV; wm8996->sysclk /= 2; - /* fall through */ + fallthrough; case 11289600: case 12288000: snd_soc_component_update_bits(component, WM8996_AIF_RATE, @@ -2224,6 +2224,9 @@ static void wm8996_free_gpio(struct wm8996_priv *wm8996) /** * wm8996_detect - Enable default WM8996 jack detection + * @component: ASoC component + * @jack: jack pointer + * @polarity_cb: polarity callback * * The WM8996 has advanced accessory detection support for headsets. * This function provides a default implementation which integrates diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index be5c9c2b0162bb..b5465e486fb576 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -929,7 +929,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai, switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: aif2 |= WM9081_AIF_LRCLK_INV; - /* fall through */ + fallthrough; case SND_SOC_DAIFMT_DSP_A: aif2 |= 0x3; break; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index a662a5547eb632..7072ffacbdfd49 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -807,7 +807,7 @@ static void pll_factors(struct snd_soc_component *component, pll_div->k = K; } -/** +/* * Please note that changing the PLL input frequency may require * resynchronisation with the AC97 controller. */ diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 57ea1b072326b5..faac6ce9a82cbc 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -33,8 +33,7 @@ #define DAI_FMT_BASE (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) /** - * CODEC private data - * + * struct codec_priv - CODEC private data * @mclk_freq: Clock rate of MCLK * @mclk_id: MCLK (or main clock) id for set_sysclk() * @fll_id: FLL (or secordary clock) id for set_sysclk() @@ -48,11 +47,10 @@ struct codec_priv { }; /** - * CPU private data - * - * @sysclk_freq[2]: SYSCLK rates for set_sysclk() - * @sysclk_dir[2]: SYSCLK directions for set_sysclk() - * @sysclk_id[2]: SYSCLK ids for set_sysclk() + * struct cpu_priv - CPU private data + * @sysclk_freq: SYSCLK rates for set_sysclk() + * @sysclk_dir: SYSCLK directions for set_sysclk() + * @sysclk_id: SYSCLK ids for set_sysclk() * @slot_width: Slot width of each frame * * Note: [1] for tx and [0] for rx @@ -65,9 +63,8 @@ struct cpu_priv { }; /** - * Freescale Generic ASOC card private data - * - * @dai_link[3]: DAI link structure including normal one and DPCM link + * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data + * @dai_link: DAI link structure including normal one and DPCM link * @pdev: platform device pointer * @codec_priv: CODEC private data * @cpu_priv: CPU private data @@ -94,8 +91,8 @@ struct fsl_asoc_card_priv { char name[32]; }; -/** - * This dapm route map exsits for DPCM link only. +/* + * This dapm route map exits for DPCM link only. * The other routes shall go through Device Tree. * * Note: keep all ASRC routes in the second half diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 95f6a9617b0b8a..02c81d2e34ad00 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -37,7 +37,7 @@ static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = { .list = supported_asrc_rate, }; -/** +/* * The following tables map the relationship between asrc_inclk/asrc_outclk in * fsl_asrc.h and the registers of ASRCSR */ @@ -68,7 +68,7 @@ static unsigned char output_clk_map_imx53[ASRC_CLK_MAP_LEN] = { 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, }; -/** +/* * i.MX8QM/i.MX8QXP uses the same map for input and output. * clk_map_imx8qm[0] is for i.MX8QM asrc0 * clk_map_imx8qm[1] is for i.MX8QM asrc1 @@ -102,16 +102,17 @@ static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = { }; /** - * Select the pre-processing and post-processing options + * fsl_asrc_sel_proc - Select the pre-processing and post-processing options + * @inrate: input sample rate + * @outrate: output sample rate + * @pre_proc: return value for pre-processing option + * @post_proc: return value for post-processing option + * * Make sure to exclude following unsupported cases before * calling this function: * 1) inrate > 8.125 * outrate * 2) inrate > 16.125 * outrate * - * inrate: input sample rate - * outrate: output sample rate - * pre_proc: return value for pre-processing option - * post_proc: return value for post-processing option */ static void fsl_asrc_sel_proc(int inrate, int outrate, int *pre_proc, int *post_proc) @@ -148,7 +149,9 @@ static void fsl_asrc_sel_proc(int inrate, int outrate, } /** - * Request ASRC pair + * fsl_asrc_request_pair - Request ASRC pair + * @channels: number of channels + * @pair: pointer to pair * * It assigns pair by the order of A->C->B because allocation of pair B, * within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A @@ -193,7 +196,8 @@ static int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair) } /** - * Release ASRC pair + * fsl_asrc_release_pair - Release ASRC pair + * @pair: pair to release * * It clears the resource from asrc and releases the occupied channels. */ @@ -217,7 +221,10 @@ static void fsl_asrc_release_pair(struct fsl_asrc_pair *pair) } /** - * Configure input and output thresholds + * fsl_asrc_set_watermarks- configure input and output thresholds + * @pair: pointer to pair + * @in: input threshold + * @out: output threshold */ static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out) { @@ -234,7 +241,9 @@ static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 out) } /** - * Calculate the total divisor between asrck clock rate and sample rate + * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate + * @pair: pointer to pair + * @div: divider * * It follows the formula clk_rate = samplerate * (2 ^ prescaler) * divider */ @@ -250,7 +259,10 @@ static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair *pair, u32 div) } /** - * Calculate and set the ratio for Ideal Ratio mode only + * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only + * @pair: pointer to pair + * @inrate: input rate + * @outrate: output rate * * The ratio is a 32-bit fixed point value with 26 fractional bits. */ @@ -293,7 +305,9 @@ static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair, } /** - * Configure the assigned ASRC pair + * fsl_asrc_config_pair - Configure the assigned ASRC pair + * @pair: pointer to pair + * @use_ideal_rate: boolean configuration * * It configures those ASRC registers according to a configuration instance * of struct asrc_config which includes in/output sample rate, width, channel @@ -508,7 +522,8 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) } /** - * Start the assigned ASRC pair + * fsl_asrc_start_pair - Start the assigned ASRC pair + * @pair: pointer to pair * * It enables the assigned pair and makes it stopped at the stall level. */ @@ -539,7 +554,8 @@ static void fsl_asrc_start_pair(struct fsl_asrc_pair *pair) } /** - * Stop the assigned ASRC pair + * fsl_asrc_stop_pair - Stop the assigned ASRC pair + * @pair: pointer to pair */ static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair) { @@ -552,7 +568,9 @@ static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair) } /** - * Get DMA channel according to the pair and direction. + * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction. + * @pair: pointer to pair + * @dir: DMA direction */ static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir) @@ -582,11 +600,51 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints); } +/* Select proper clock source for internal ratio mode */ +static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv, + struct fsl_asrc_pair *pair, + int in_rate, + int out_rate) +{ + struct fsl_asrc_pair_priv *pair_priv = pair->private; + struct asrc_config *config = pair_priv->config; + int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */ + int clk_rate, clk_index; + int i = 0, j = 0; + + rate[IN] = in_rate; + rate[OUT] = out_rate; + + /* Select proper clock source for internal ratio mode */ + for (j = 0; j < 2; j++) { + for (i = 0; i < ASRC_CLK_MAP_LEN; i++) { + clk_index = asrc_priv->clk_map[j][i]; + clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]); + /* Only match a perfect clock source with no remainder */ + if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 && + (clk_rate % rate[j]) == 0) + break; + } + + select_clk[j] = i; + } + + /* Switch to ideal ratio mode if there is no proper clock source */ + if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == ASRC_CLK_MAP_LEN) { + select_clk[IN] = INCLK_NONE; + select_clk[OUT] = OUTCLK_ASRCK1_CLK; + } + + config->inclk = select_clk[IN]; + config->outclk = select_clk[OUT]; +} + static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); + struct fsl_asrc_priv *asrc_priv = asrc->private; struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_asrc_pair *pair = runtime->private_data; struct fsl_asrc_pair_priv *pair_priv = pair->private; @@ -605,8 +663,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, config.pair = pair->index; config.channel_num = channels; - config.inclk = INCLK_NONE; - config.outclk = OUTCLK_ASRCK1_CLK; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { config.input_format = params_format(params); @@ -620,6 +676,10 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, config.output_sample_rate = rate; } + fsl_asrc_select_clk(asrc_priv, pair, + config.input_sample_rate, + config.output_sample_rate); + ret = fsl_asrc_config_pair(pair, false); if (ret) { dev_err(dai->dev, "fail to config asrc pair\n"); @@ -854,7 +914,8 @@ static const struct regmap_config fsl_asrc_regmap_config = { }; /** - * Initialize ASRC registers with a default configurations + * fsl_asrc_init - Initialize ASRC registers with a default configuration + * @asrc: ASRC context */ static int fsl_asrc_init(struct fsl_asrc *asrc) { @@ -888,7 +949,9 @@ static int fsl_asrc_init(struct fsl_asrc *asrc) } /** - * Interrupt handler for ASRC + * fsl_asrc_isr- Interrupt handler for ASRC + * @irq: irq number + * @dev_id: ASRC context */ static irqreturn_t fsl_asrc_isr(int irq, void *dev_id) { diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index cbcb70d6f8c83b..b8fbd7ba94af64 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -22,8 +22,7 @@ SNDRV_PCM_FMTBIT_S24_LE) /** - * fsl_esai_soc_data: soc specific data - * + * struct fsl_esai_soc_data - soc specific data * @imx: for imx platform * @reset_at_xrun: flags for enable reset operaton */ @@ -33,8 +32,7 @@ struct fsl_esai_soc_data { }; /** - * fsl_esai: ESAI private data - * + * struct fsl_esai - ESAI private data * @dma_params_rx: DMA parameters for receive channel * @dma_params_tx: DMA parameters for transmit channel * @pdev: platform device pointer @@ -49,6 +47,8 @@ struct fsl_esai_soc_data { * @fifo_depth: depth of tx/rx FIFO * @slot_width: width of each DAI slot * @slots: number of slots + * @tx_mask: slot mask for TX + * @rx_mask: slot mask for RX * @channels: channel num for tx or rx * @hck_rate: clock rate of desired HCKx clock * @sck_rate: clock rate of desired SCKx clock @@ -157,13 +157,15 @@ static irqreturn_t esai_isr(int irq, void *devid) } /** - * This function is used to calculate the divisors of psr, pm, fp and it is - * supposed to be called in set_dai_sysclk() and set_bclk(). + * fsl_esai_divisor_cal - This function is used to calculate the + * divisors of psr, pm, fp and it is supposed to be called in + * set_dai_sysclk() and set_bclk(). * + * @dai: pointer to DAI + * @tx: current setting is for playback or capture * @ratio: desired overall ratio for the paticipating dividers * @usefp: for HCK setting, there is no need to set fp divider * @fp: bypass other dividers by setting fp directly if fp != 0 - * @tx: current setting is for playback or capture */ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio, bool usefp, u32 fp) @@ -250,13 +252,12 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio, } /** - * This function mainly configures the clock frequency of MCLK (HCKT/HCKR) - * - * @Parameters: - * clk_id: The clock source of HCKT/HCKR + * fsl_esai_set_dai_sysclk - configure the clock frequency of MCLK (HCKT/HCKR) + * @dai: pointer to DAI + * @clk_id: The clock source of HCKT/HCKR * (Input from outside; output from inside, FSYS or EXTAL) - * freq: The required clock rate of HCKT/HCKR - * dir: The clock direction of HCKT/HCKR + * @freq: The required clock rate of HCKT/HCKR + * @dir: The clock direction of HCKT/HCKR * * Note: If the direction is input, we do not care about clk_id. */ @@ -358,7 +359,10 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, } /** - * This function configures the related dividers according to the bclk rate + * fsl_esai_set_bclk - configure the related dividers according to the bclk rate + * @dai: pointer to DAI + * @tx: direction boolean + * @freq: bclk freq */ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) { diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 9d436b0c5718a2..a22562f2df47d1 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1016,6 +1016,7 @@ static int fsl_sai_probe(struct platform_device *pdev) platform_set_drvdata(pdev, sai); pm_runtime_enable(&pdev->dev); + regcache_cache_only(sai->regmap, true); ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, &fsl_sai_dai, 1); @@ -1107,7 +1108,6 @@ static int fsl_sai_runtime_suspend(struct device *dev) clk_disable_unprepare(sai->bus_clk); regcache_cache_only(sai->regmap, true); - regcache_mark_dirty(sai->regmap); return 0; } @@ -1137,6 +1137,7 @@ static int fsl_sai_runtime_resume(struct device *dev) } regcache_cache_only(sai->regmap, false); + regcache_mark_dirty(sai->regmap); regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); usleep_range(1000, 2000); diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 5b2689ae63d4df..9fb95c6ee7baa4 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -81,8 +81,8 @@ struct spdif_mixer_control { }; /** - * fsl_spdif_priv: Freescale SPDIF private data - * + * struct fsl_spdif_priv - Freescale SPDIF private data + * @soc: SPDIF soc data * @fsl_spdif_control: SPDIF control data * @cpu_dai_drv: cpu dai driver * @pdev: platform device pointer @@ -100,6 +100,7 @@ struct spdif_mixer_control { * @spbaclk: SPBA clock (optional, depending on SoC design) * @dma_params_tx: DMA parameters for transmit channel * @dma_params_rx: DMA parameters for receive channel + * @regcache_srpc: regcache for SRPC */ struct fsl_spdif_priv { const struct fsl_spdif_soc_data *soc; diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 1a2fa7f181423b..7ec80b240563e9 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -203,12 +203,10 @@ struct fsl_ssi_soc_data { }; /** - * fsl_ssi: per-SSI private data - * + * struct fsl_ssi - per-SSI private data * @regs: Pointer to the regmap registers * @irq: IRQ of this SSI * @cpu_dai_drv: CPU DAI driver for this device - * * @dai_fmt: DAI configuration this device is currently used with * @streams: Mask of current active streams: BIT(TX) and BIT(RX) * @i2s_net: I2S and Network mode configurations of SCR register @@ -221,38 +219,29 @@ struct fsl_ssi_soc_data { * @slot_width: Width of each DAI slot * @slots: Number of slots * @regvals: Specific RX/TX register settings - * * @clk: Clock source to access register * @baudclk: Clock source to generate bit and frame-sync clocks * @baudclk_streams: Active streams that are using baudclk - * * @regcache_sfcsr: Cache sfcsr register value during suspend and resume * @regcache_sacnt: Cache sacnt register value during suspend and resume - * * @dma_params_tx: DMA transmit parameters * @dma_params_rx: DMA receive parameters * @ssi_phys: physical address of the SSI registers - * * @fiq_params: FIQ stream filtering parameters - * * @card_pdev: Platform_device pointer to register a sound card for PowerPC or * to register a CODEC platform device for AC97 * @card_name: Platform_device name to register a sound card for PowerPC or * to register a CODEC platform device for AC97 * @card_idx: The index of SSI to register a sound card for PowerPC or * to register a CODEC platform device for AC97 - * * @dbg_stats: Debugging statistics - * * @soc: SoC specific data * @dev: Pointer to &pdev->dev - * * @fifo_watermark: The FIFO watermark setting. Notifies DMA when there are * @fifo_watermark or fewer words in TX fifo or * @fifo_watermark or more empty words in RX fifo. * @dma_maxburst: Max number of words to transfer in one go. So far, * this is always the same as fifo_watermark. - * * @ac97_reg_lock: Mutex lock to serialize AC97 register access operations */ struct fsl_ssi { @@ -374,7 +363,9 @@ static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi *ssi) } /** - * Interrupt handler to gather states + * fsl_ssi_irq - Interrupt handler to gather states + * @irq: irq number + * @dev_id: context */ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) { @@ -395,7 +386,10 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) } /** - * Set SCR, SIER, STCR and SRCR registers with cached values in regvals + * fsl_ssi_config_enable - Set SCR, SIER, STCR and SRCR registers with + * cached values in regvals + * @ssi: SSI context + * @tx: direction * * Notes: * 1) For offline_config SoCs, enable all necessary bits of both streams @@ -474,7 +468,7 @@ static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx) ssi->streams |= BIT(dir); } -/** +/* * Exclude bits that are used by the opposite stream * * When both streams are active, disabling some bits for the current stream @@ -495,7 +489,10 @@ static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx) ((vals) & _ssi_xor_shared_bits(vals, avals, aactive)) /** - * Unset SCR, SIER, STCR and SRCR registers with cached values in regvals + * fsl_ssi_config_disable - Unset SCR, SIER, STCR and SRCR registers + * with cached values in regvals + * @ssi: SSI context + * @tx: direction * * Notes: * 1) For offline_config SoCs, to avoid online reconfigurations, disable all @@ -577,7 +574,9 @@ static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi) } /** - * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely + * fsl_ssi_setup_regvals - Cache critical bits of SIER, SRCR, STCR and + * SCR to later set them safely + * @ssi: SSI context */ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi) { @@ -661,9 +660,12 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, } /** - * Configure Digital Audio Interface bit clock + * fsl_ssi_set_bclk - Configure Digital Audio Interface bit clock + * @substream: ASoC substream + * @dai: pointer to DAI + * @hw_params: pointers to hw_params * - * Note: This function can be only called when using SSI as DAI master + * Notes: This function can be only called when using SSI as DAI master * * Quick instruction for parameters: * freq: Output BCLK frequency = samplerate * slots * slot_width @@ -782,7 +784,10 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, } /** - * Configure SSI based on PCM hardware parameters + * fsl_ssi_hw_params - Configure SSI based on PCM hardware parameters + * @substream: ASoC substream + * @hw_params: pointers to hw_params + * @dai: pointer to DAI * * Notes: * 1) SxCCR.WL bits are critical bits that require SSI to be temporarily @@ -997,7 +1002,9 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) } /** - * Configure Digital Audio Interface (DAI) Format + * fsl_ssi_set_dai_fmt - Configure Digital Audio Interface (DAI) Format + * @dai: pointer to DAI + * @fmt: format mask */ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { @@ -1011,7 +1018,12 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) } /** - * Set TDM slot number and slot width + * fsl_ssi_set_dai_tdm_slot - Set TDM slot number and slot width + * @dai: pointer to DAI + * @tx_mask: mask for TX + * @rx_mask: mask for RX + * @slots: number of slots + * @slot_width: number of bits per slot */ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mask, int slots, int slot_width) @@ -1055,7 +1067,10 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, } /** - * Start or stop SSI and corresponding DMA transaction. + * fsl_ssi_trigger - Start or stop SSI and corresponding DMA transaction. + * @substream: ASoC substream + * @cmd: trigger command + * @dai: pointer to DAI * * The DMA channel is in external master start and pause mode, which * means the SSI completely controls the flow of data. @@ -1239,7 +1254,8 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = { }; /** - * Initialize SSI registers + * fsl_ssi_hw_init - Initialize SSI registers + * @ssi: SSI context */ static int fsl_ssi_hw_init(struct fsl_ssi *ssi) { @@ -1268,7 +1284,8 @@ static int fsl_ssi_hw_init(struct fsl_ssi *ssi) } /** - * Clear SSI registers + * fsl_ssi_hw_clean - Clear SSI registers + * @ssi: SSI context */ static void fsl_ssi_hw_clean(struct fsl_ssi *ssi) { @@ -1285,7 +1302,8 @@ static void fsl_ssi_hw_clean(struct fsl_ssi *ssi) regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0); } } -/** + +/* * Make every character in a string lower-case */ static void make_lowercase(char *s) diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c index 2a20ee23dc52d1..2c46c55f0a8829 100644 --- a/sound/soc/fsl/fsl_ssi_dbg.c +++ b/sound/soc/fsl/fsl_ssi_dbg.c @@ -78,7 +78,7 @@ void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr) dbg->stats.tfe0++; } -/** +/* * Show the statistics of a flag only if its interrupt is enabled * * Compilers will optimize it to a no-op if the interrupt is disabled @@ -90,7 +90,7 @@ void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr) } while (0) -/** +/* * Display the statistics for the current SSI device * * To avoid confusion, only show those counts that are enabled diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index f7bd90051ce70b..b3090fea4290e6 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -426,9 +426,11 @@ static int __init mpc8610_hpcd_init(void) guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts"); if (of_address_to_resource(guts_np, 0, &res)) { pr_err("mpc8610-hpcd: missing/invalid global utilities node\n"); + of_node_put(guts_np); return -EINVAL; } guts_phys = res.start; + of_node_put(guts_np); return platform_driver_register(&mpc8610_hpcd_driver); } diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index 69f3af4524abb1..ff42f629b03538 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c @@ -61,8 +61,13 @@ static int sst_fill_and_send_cmd_unlocked(struct sst_data *drv, /** * sst_fill_and_send_cmd - generate the IPC message and send it to the FW - * @ipc_msg: type of IPC (CMD, SET_PARAMS, GET_PARAMS) - * @cmd_data: the IPC payload + * @drv: sst_data + * @ipc_msg: type of IPC (CMD, SET_PARAMS, GET_PARAMS) + * @block: block index + * @task_id: task index + * @pipe_id: pipe index + * @cmd_data: the IPC payload + * @len: length of data to be sent */ static int sst_fill_and_send_cmd(struct sst_data *drv, u8 ipc_msg, u8 block, u8 task_id, u8 pipe_id, @@ -78,7 +83,7 @@ static int sst_fill_and_send_cmd(struct sst_data *drv, return ret; } -/** +/* * tx map value is a bitfield where each bit represents a FW channel * * 3 2 1 0 # 0 = codec0, 1 = codec1 @@ -90,7 +95,7 @@ static u8 sst_ssp_tx_map[SST_MAX_TDM_SLOTS] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, /* default rx map */ }; -/** +/* * rx map value is a bitfield where each bit represents a slot * * 76543210 # 0 = slot 0, 1 = slot 1 @@ -101,7 +106,7 @@ static u8 sst_ssp_rx_map[SST_MAX_TDM_SLOTS] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, /* default tx map */ }; -/** +/* * NOTE: this is invoked with lock held */ static int sst_send_slot_map(struct sst_data *drv) @@ -145,7 +150,8 @@ static int sst_slot_enum_info(struct snd_kcontrol *kcontrol, /** * sst_slot_get - get the status of the interleaver/deinterleaver control - * + * @kcontrol: control pointer + * @ucontrol: User data * Searches the map where the control status is stored, and gets the * channel/slot which is currently set for this enumerated control. Since it is * an enumerated control, there is only one possible value. @@ -197,7 +203,8 @@ static int sst_check_and_send_slot_map(struct sst_data *drv, struct snd_kcontrol /** * sst_slot_put - set the status of interleaver/deinterleaver control - * + * @kcontrol: control pointer + * @ucontrol: User data * (de)interleaver controls are defined in opposite sense to be user-friendly * * Instead of the enum value being the value written to the register, it is the @@ -280,7 +287,9 @@ static int sst_send_algo_cmd(struct sst_data *drv, /** * sst_find_and_send_pipe_algo - send all the algo parameters for a pipe - * + * @drv: sst_data + * @pipe: string identifier + * @ids: list of algorithms * The algos which are in each pipeline are sent to the firmware one by one * * Called with lock held @@ -379,11 +388,15 @@ static int sst_gain_ctl_info(struct snd_kcontrol *kcontrol, /** * sst_send_gain_cmd - send the gain algorithm IPC to the FW - * @gv: the stored value of gain (also contains rampduration) - * @mute: flag that indicates whether this was called from the - * digital_mute callback or directly. If called from the - * digital_mute callback, module will be muted/unmuted based on this - * flag. The flag is always 0 if called directly. + * @drv: sst_data + * @gv:the stored value of gain (also contains rampduration) + * @task_id: task index + * @loc_id: location/position index + * @module_id: module index + * @mute: flag that indicates whether this was called from the + * digital_mute callback or directly. If called from the + * digital_mute callback, module will be muted/unmuted based on this + * flag. The flag is always 0 if called directly. * * Called with sst_data.lock held * @@ -544,9 +557,12 @@ static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = { /** * fill_swm_input - fill in the SWM input ids given the register + * @cmpnt: ASoC component + * @swm_input: array of swm_input_ids + * @reg: the register value is a bit-field inicated which mixer inputs are ON. * - * The register value is a bit-field inicated which mixer inputs are ON. Use the - * lookup table to get the input-id and fill it in the structure. + * Use the lookup table to get the input-id and fill it in the + * structure. */ static int fill_swm_input(struct snd_soc_component *cmpnt, struct swm_input_ids *swm_input, unsigned int reg) @@ -577,7 +593,7 @@ static int fill_swm_input(struct snd_soc_component *cmpnt, } -/** +/* * called with lock held */ static int sst_set_pipe_gain(struct sst_ids *ids, @@ -707,7 +723,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_pcm2_controls); SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_sprot_l0_controls); SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l1_controls); SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls); -SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls); +SST_SBA_DECLARE_MIX_CONTROLS(__maybe_unused sst_mix_voip_controls); SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls); SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls); SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls); @@ -881,7 +897,7 @@ int sst_fill_ssp_config(struct snd_soc_dai *dai, unsigned int fmt) return 0; } -/** +/* * sst_ssp_config - contains SSP configuration for media UC * this can be overwritten by set_dai_xxx APIs */ @@ -1300,6 +1316,9 @@ static bool is_sst_dapm_widget(struct snd_soc_dapm_widget *w) /** * sst_send_pipe_gains - send gains for the front-end DAIs + * @dai: front-end dai + * @stream: direction + * @mute: boolean indicating mute status * * The gains in the pipes connected to the front-ends are muted/unmuted * automatically via the digital_mute() DAPM callback. This function sends the @@ -1357,7 +1376,9 @@ int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute) /** * sst_fill_module_list - populate the list of modules/gains for a pipe - * + * @kctl: kcontrol pointer + * @w: dapm widget + * @type: widget type * * Fills the widget pointer in the kcontrol private data, and also fills the * kcontrol pointer in the widget private data. @@ -1403,7 +1424,8 @@ static int sst_fill_module_list(struct snd_kcontrol *kctl, /** * sst_fill_widget_module_info - fill list of gains/algos for the pipe - * @widget: pipe modelled as a DAPM widget + * @w: pipe modeled as a DAPM widget + * @component: ASoC component * * Fill the list of gains/algos for the widget by looking at all the card * controls and comparing the name of the widget with the first part of control @@ -1463,6 +1485,8 @@ static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w, /** * sst_fill_linked_widgets - fill the parent pointer for the linked widget + * @component: ASoC component + * @ids: sst_ids array */ static void sst_fill_linked_widgets(struct snd_soc_component *component, struct sst_ids *ids) @@ -1480,6 +1504,7 @@ static void sst_fill_linked_widgets(struct snd_soc_component *component, /** * sst_map_modules_to_pipe - fill algo/gains list for all pipes + * @component: ASoC component */ static int sst_map_modules_to_pipe(struct snd_soc_component *component) { diff --git a/sound/soc/intel/atom/sst/sst_loader.c b/sound/soc/intel/atom/sst/sst_loader.c index 9b0e3739c738cb..8ad0ca70ec6203 100644 --- a/sound/soc/intel/atom/sst/sst_loader.c +++ b/sound/soc/intel/atom/sst/sst_loader.c @@ -49,6 +49,7 @@ void memcpy32_fromio(void *dst, const void __iomem *src, int count) /** * intel_sst_reset_dsp_mrfld - Resetting SST DSP + * @sst_drv_ctx: intel_sst_drv context pointer * * This resets DSP in case of MRFLD platfroms */ @@ -77,6 +78,7 @@ int intel_sst_reset_dsp_mrfld(struct intel_sst_drv *sst_drv_ctx) /** * sst_start_merrifield - Start the SST DSP processor + * @sst_drv_ctx: intel_sst_drv context pointer * * This starts the DSP in MERRIFIELD platfroms */ @@ -387,6 +389,8 @@ void sst_post_download_mrfld(struct intel_sst_drv *ctx) /** * sst_load_fw - function to load FW into DSP + * @sst_drv_ctx: intel_sst_drv context pointer + * * Transfers the FW to DSP using dma/memcpy */ int sst_load_fw(struct intel_sst_drv *sst_drv_ctx) diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c index ea09f4170201d4..c0221e103e7967 100644 --- a/sound/soc/intel/atom/sst/sst_stream.c +++ b/sound/soc/intel/atom/sst/sst_stream.c @@ -92,8 +92,8 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params) /** * sst_realloc_stream - Send msg for (re-)allocating a stream using the - * @sst_drv_ctx intel_sst_drv context pointer - * @str_id: stream ID + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID * * Send a msg for (re-)allocating a stream using the parameters previously * passed to sst_alloc_stream_mrfld() for the same stream ID. @@ -142,12 +142,13 @@ int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) } /** -* sst_start_stream - Send msg for a starting stream -* @str_id: stream ID -* -* This function is called by any function which wants to start -* a stream. -*/ + * sst_start_stream - Send msg for a starting stream + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID + * + * This function is called by any function which wants to start + * a stream. + */ int sst_start_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) { int retval = 0; @@ -234,7 +235,8 @@ int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, /** * sst_pause_stream - Send msg for a pausing stream - * @str_id: stream ID + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID * * This function is called by any function which wants to pause * an already running stream. @@ -278,7 +280,8 @@ int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) /** * sst_resume_stream - Send msg for resuming stream - * @str_id: stream ID + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID * * This function is called by any function which wants to resume * an already paused stream. @@ -345,7 +348,8 @@ int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) /** * sst_drop_stream - Send msg for stopping stream - * @str_id: stream ID + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID * * This function is called by any function which wants to stop * a stream. @@ -377,12 +381,14 @@ int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) } /** -* sst_drain_stream - Send msg for draining stream -* @str_id: stream ID -* -* This function is called by any function which wants to drain -* a stream. -*/ + * sst_drain_stream - Send msg for draining stream + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID + * @partial_drain: boolean indicating if a gapless transition is taking place + * + * This function is called by any function which wants to drain + * a stream. + */ int sst_drain_stream(struct intel_sst_drv *sst_drv_ctx, int str_id, bool partial_drain) { @@ -415,7 +421,8 @@ int sst_drain_stream(struct intel_sst_drv *sst_drv_ctx, /** * sst_free_stream - Frees a stream - * @str_id: stream ID + * @sst_drv_ctx: intel_sst_drv context pointer + * @str_id: stream ID * * This function is called by any function which wants to free * a stream. diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 13c91850037672..0a53d64861422d 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -291,6 +291,7 @@ config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC tristate select SND_SOC_DA7219 select SND_SOC_MAX98357A + select SND_SOC_MAX98390 select SND_SOC_DMIC select SND_SOC_HDAC_HDMI @@ -301,14 +302,14 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON if SND_SOC_INTEL_APL config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH - tristate "Broxton with DA7219 and MAX98357A in I2S Mode" + tristate "Broxton with DA7219 and MAX98357A/MAX98390 in I2S Mode" depends on I2C && ACPI && GPIOLIB depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON help This adds support for ASoC machine driver for Broxton-P platforms - with DA7219 + MAX98357A I2S audio codec. + with DA7219 + MAX98357A/MAX98390 I2S audio codec. Say Y or m if you have such a device. This is a recommended option. If unsure select "N". diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 44016c16f25e2e..0c0a717823c407 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -25,9 +25,14 @@ #define BXT_DIALOG_CODEC_DAI "da7219-hifi" #define BXT_MAXIM_CODEC_DAI "HiFi" +#define MAX98390_DEV0_NAME "i2c-MX98390:00" +#define MAX98390_DEV1_NAME "i2c-MX98390:01" #define DUAL_CHANNEL 2 #define QUAD_CHANNEL 4 +#define SPKAMP_MAX98357A 1 +#define SPKAMP_MAX98390 2 + static struct snd_soc_jack broxton_headset; static struct snd_soc_jack broxton_hdmi[3]; @@ -40,6 +45,7 @@ struct bxt_hdmi_pcm { struct bxt_card_private { struct list_head hdmi_pcm_list; bool common_hdmi_codec_drv; + int spkamp; }; enum { @@ -85,13 +91,20 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, static const struct snd_kcontrol_new broxton_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_kcontrol_new max98357a_controls[] = { SOC_DAPM_PIN_SWITCH("Spk"), }; +static const struct snd_kcontrol_new max98390_controls[] = { + SOC_DAPM_PIN_SWITCH("Left Spk"), + SOC_DAPM_PIN_SWITCH("Right Spk"), +}; + static const struct snd_soc_dapm_widget broxton_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Spk", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL), SND_SOC_DAPM_SPK("HDMI1", NULL), SND_SOC_DAPM_SPK("HDMI2", NULL), @@ -100,14 +113,20 @@ static const struct snd_soc_dapm_widget broxton_widgets[] = { platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU), }; +static const struct snd_soc_dapm_widget max98357a_widgets[] = { + SND_SOC_DAPM_SPK("Spk", NULL), +}; + +static const struct snd_soc_dapm_widget max98390_widgets[] = { + SND_SOC_DAPM_SPK("Left Spk", NULL), + SND_SOC_DAPM_SPK("Right Spk", NULL), +}; + static const struct snd_soc_dapm_route audio_map[] = { /* HP jack connectors - unknown if we have jack detection */ {"Headphone Jack", NULL, "HPL"}, {"Headphone Jack", NULL, "HPR"}, - /* speaker */ - {"Spk", NULL, "Speaker"}, - /* other jacks */ {"MIC", NULL, "Headset Mic"}, @@ -134,6 +153,17 @@ static const struct snd_soc_dapm_route audio_map[] = { { "Headset Mic", NULL, "Platform Clock" }, }; +static const struct snd_soc_dapm_route max98357a_routes[] = { + /* speaker */ + {"Spk", NULL, "Speaker"}, +}; + +static const struct snd_soc_dapm_route max98390_routes[] = { + /* Speaker */ + {"Left Spk", NULL, "Left BE_OUT"}, + {"Right Spk", NULL, "Right BE_OUT"}, +}; + static const struct snd_soc_dapm_route broxton_map[] = { {"HiFi Playback", NULL, "ssp5 Tx"}, {"ssp5 Tx", NULL, "codec0_out"}, @@ -404,6 +434,10 @@ SND_SOC_DAILINK_DEF(ssp5_pin, SND_SOC_DAILINK_DEF(ssp5_codec, DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", BXT_MAXIM_CODEC_DAI))); +SND_SOC_DAILINK_DEF(max98390_codec, + DAILINK_COMP_ARRAY( + /* Left */ COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"), + /* Right */ COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1"))); SND_SOC_DAILINK_DEF(ssp1_pin, DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); @@ -601,15 +635,69 @@ static struct snd_soc_dai_link broxton_dais[] = { }, }; +static struct snd_soc_codec_conf max98390_codec_confs[] = { + { + .dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME), + .name_prefix = "Right", + }, +}; + #define NAME_SIZE 32 static int bxt_card_late_probe(struct snd_soc_card *card) { struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card); struct bxt_hdmi_pcm *pcm; struct snd_soc_component *component = NULL; - int err, i = 0; + const struct snd_kcontrol_new *controls; + const struct snd_soc_dapm_widget *widgets; + const struct snd_soc_dapm_route *routes; + int num_controls, num_widgets, num_routes, err, i = 0; char jack_name[NAME_SIZE]; + switch (ctx->spkamp) { + case SPKAMP_MAX98357A: + controls = max98357a_controls; + num_controls = ARRAY_SIZE(max98357a_controls); + widgets = max98357a_widgets; + num_widgets = ARRAY_SIZE(max98357a_widgets); + routes = max98357a_routes; + num_routes = ARRAY_SIZE(max98357a_routes); + break; + case SPKAMP_MAX98390: + controls = max98390_controls; + num_controls = ARRAY_SIZE(max98390_controls); + widgets = max98390_widgets; + num_widgets = ARRAY_SIZE(max98390_widgets); + routes = max98390_routes; + num_routes = ARRAY_SIZE(max98390_routes); + break; + default: + dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp); + return -EINVAL; + } + + err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets); + if (err) { + dev_err(card->dev, "Fail to new widgets\n"); + return err; + } + + err = snd_soc_add_card_controls(card, controls, num_controls); + if (err) { + dev_err(card->dev, "Fail to add controls\n"); + return err; + } + + err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes); + if (err) { + dev_err(card->dev, "Fail to add routes\n"); + return err; + } + if (soc_intel_is_glk()) snd_soc_dapm_add_routes(&card->dapm, gemini_map, ARRAY_SIZE(gemini_map)); @@ -678,6 +766,11 @@ static int broxton_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + if (acpi_dev_present("MX98390", NULL, -1)) + ctx->spkamp = SPKAMP_MAX98390; + else + ctx->spkamp = SPKAMP_MAX98357A; + broxton_audio_card.dev = &pdev->dev; snd_soc_card_set_drvdata(&broxton_audio_card, ctx); if (soc_intel_is_glk()) { @@ -702,7 +795,13 @@ static int broxton_audio_probe(struct platform_device *pdev) } else if (soc_intel_is_cml()) { unsigned int i; - broxton_audio_card.name = "cmlda7219max"; + if (ctx->spkamp == SPKAMP_MAX98390) { + broxton_audio_card.name = "cml_max98390_da7219"; + + broxton_audio_card.codec_conf = max98390_codec_confs; + broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs); + } else + broxton_audio_card.name = "cmlda7219max"; for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { /* MAXIM_CODEC is connected to SSP1. */ @@ -710,6 +809,11 @@ static int broxton_audio_probe(struct platform_device *pdev) BXT_MAXIM_CODEC_DAI)) { broxton_dais[i].name = "SSP1-Codec"; broxton_dais[i].cpus->dai_name = "SSP1 Pin"; + + if (ctx->spkamp == SPKAMP_MAX98390) { + broxton_dais[i].codecs = max98390_codec; + broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec); + } } /* DIALOG_CODEC is connected to SSP0 */ else if (!strcmp(broxton_dais[i].codecs->dai_name, @@ -759,6 +863,7 @@ MODULE_AUTHOR("Harsha Priya "); MODULE_AUTHOR("Conrad Cooke "); MODULE_AUTHOR("Naveen Manohar "); MODULE_AUTHOR("Mac Chiang "); +MODULE_AUTHOR("Brent Lu "); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:bxt_da7219_max98357a"); MODULE_ALIAS("platform:glk_da7219_max98357a"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c index cdea0c09fe0aed..dee1f0fa998b5b 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs max98357a_spk_codecs = { .codecs = {"MX98357A"} }; +static struct snd_soc_acpi_codecs max98390_spk_codecs = { + .num_codecs = 1, + .codecs = {"MX98390"} +}; + /* * The order of the three entries with .id = "10EC5682" matters * here, because DSDT tables expose an ACPI HID for the MAX98357A @@ -55,6 +60,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = { .sof_fw_filename = "sof-cml.ri", .sof_tplg_filename = "sof-cml-da7219-max98357a.tplg", }, + { + .id = "DLGS7219", + .drv_name = "cml_da7219_max98357a", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &max98390_spk_codecs, + .sof_fw_filename = "sof-cml.ri", + .sof_tplg_filename = "sof-cml-da7219-max98357a.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines); diff --git a/sound/soc/intel/keembay/kmb_platform.h b/sound/soc/intel/keembay/kmb_platform.h index 29600652d8f49a..6bf221aa8fffc4 100644 --- a/sound/soc/intel/keembay/kmb_platform.h +++ b/sound/soc/intel/keembay/kmb_platform.h @@ -7,7 +7,7 @@ */ #ifndef KMB_PLATFORM_H_ -#define KMB_PLATFORMP_H_ +#define KMB_PLATFORM_H_ #include #include diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index a656d20141270e..786a8d5031e4ce 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -118,30 +118,32 @@ config SND_SOC_MT8183 If unsure select "N". config SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A - tristate "ASoC Audio driver for MT8183 with MT6358 TS3A227E MAX98357A codec" + tristate "ASoC Audio driver for MT8183 with MT6358 TS3A227E MAX98357A RT1015 codec" depends on I2C depends on SND_SOC_MT8183 select SND_SOC_MT6358 select SND_SOC_MAX98357A + select SND_SOC_RT1015 select SND_SOC_BT_SCO select SND_SOC_TS3A227E select SND_SOC_CROS_EC_CODEC if CROS_EC help This adds ASoC driver for Mediatek MT8183 boards - with the MT6358 TS3A227E MAX98357A audio codec. + with the MT6358 TS3A227E MAX98357A RT1015 audio codec. Select Y if you have such device. If unsure select "N". config SND_SOC_MT8183_DA7219_MAX98357A - tristate "ASoC Audio driver for MT8183 with DA7219 MAX98357A codec" + tristate "ASoC Audio driver for MT8183 with DA7219 MAX98357A RT1015 codec" depends on SND_SOC_MT8183 && I2C select SND_SOC_MT6358 select SND_SOC_MAX98357A + select SND_SOC_RT1015 select SND_SOC_DA7219 select SND_SOC_BT_SCO help This adds ASoC driver for Mediatek MT8183 boards - with the DA7219 MAX98357A audio codec. + with the DA7219 MAX98357A RT1015 audio codec. Select Y if you have such device. If unsure select "N". diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c index b61bb2de4ec39d..bc551a4af25f0d 100644 --- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c @@ -8,14 +8,22 @@ #include #include +#include #include #include #include #include -#include "mt8183-afe-common.h" #include "../../codecs/da7219-aad.h" #include "../../codecs/da7219.h" +#include "../../codecs/rt1015.h" +#include "mt8183-afe-common.h" + +#define DA7219_CODEC_DAI "da7219-hifi" +#define DA7219_DEV_NAME "da7219.5-001a" +#define RT1015_CODEC_DAI "rt1015-aif" +#define RT1015_DEV0_NAME "rt1015.6-0028" +#define RT1015_DEV1_NAME "rt1015.6-0029" struct mt8183_da7219_max98357_priv { struct snd_soc_jack headset_jack; @@ -54,8 +62,7 @@ static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream, dev_err(rtd->dev, "failed to set cpu dai sysclk\n"); for_each_rtd_codec_dais(rtd, j, codec_dai) { - - if (!strcmp(codec_dai->component->name, "da7219.5-001a")) { + if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, mclk_fs, @@ -87,8 +94,7 @@ static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream) int ret = 0, j; for_each_rtd_codec_dais(rtd, j, codec_dai) { - - if (!strcmp(codec_dai->component->name, "da7219.5-001a")) { + if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) { ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); if (ret < 0) { @@ -107,6 +113,51 @@ static const struct snd_soc_ops mt8183_da7219_i2s_ops = { .hw_free = mt8183_da7219_hw_free, }; +static int +mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int rate = params_rate(params); + struct snd_soc_dai *codec_dai; + int ret = 0, i; + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) || + !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) { + ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); + if (ret) { + dev_err(rtd->dev, "failed to set bclk ratio\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, 0, + RT1015_PLL_S_BCLK, + rate * 64, rate * 256); + if (ret) { + dev_err(rtd->dev, "failed to set pll\n"); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, + RT1015_SCLK_S_PLL, + rate * 256, + SND_SOC_CLOCK_IN); + if (ret) { + dev_err(rtd->dev, "failed to set sysclk\n"); + return ret; + } + } + } + + return mt8183_da7219_i2s_hw_params(substream, params); +} + +static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = { + .hw_params = mt8183_da7219_rt1015_i2s_hw_params, + .hw_free = mt8183_da7219_hw_free, +}; + static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -119,6 +170,18 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + static int mt8183_da7219_max98357_startup( struct snd_pcm_substream *substream) @@ -268,13 +331,20 @@ SND_SOC_DAILINK_DEFS(i2s1, SND_SOC_DAILINK_DEFS(i2s2, DAILINK_COMP_ARRAY(COMP_CPU("I2S2")), - DAILINK_COMP_ARRAY(COMP_CODEC("da7219.5-001a", "da7219-hifi")), + DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), DAILINK_COMP_ARRAY(COMP_EMPTY())); -SND_SOC_DAILINK_DEFS(i2s3, +SND_SOC_DAILINK_DEFS(i2s3_max98357a, DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"), - COMP_CODEC("da7219.5-001a", "da7219-hifi")), + COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(i2s3_rt1015, + DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI), + COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI), + COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)), DAILINK_COMP_ARRAY(COMP_EMPTY())); SND_SOC_DAILINK_DEFS(i2s5, @@ -287,7 +357,7 @@ SND_SOC_DAILINK_DEFS(tdm, DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); -static struct snd_soc_dai_link mt8183_da7219_max98357_dai_links[] = { +static struct snd_soc_dai_link mt8183_da7219_dai_links[] = { /* FE */ { .name = "Playback_1", @@ -422,9 +492,6 @@ static struct snd_soc_dai_link mt8183_da7219_max98357_dai_links[] = { .no_pcm = 1, .dpcm_playback = 1, .ignore_suspend = 1, - .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, - .ops = &mt8183_da7219_i2s_ops, - SND_SOC_DAILINK_REG(i2s3), }, { .name = "I2S5", @@ -449,7 +516,36 @@ static struct snd_soc_dai_link mt8183_da7219_max98357_dai_links[] = { }; static int -mt8183_da7219_max98357_headset_init(struct snd_soc_component *component); +mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) +{ + int ret; + struct mt8183_da7219_max98357_priv *priv = + snd_soc_card_get_drvdata(component->card); + + /* Enable Headset and 4 Buttons Jack detection */ + ret = snd_soc_card_jack_new(component->card, + "Headset Jack", + SND_JACK_HEADSET | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + &priv->headset_jack, + NULL, 0); + if (ret) + return ret; + + snd_jack_set_key( + priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key( + priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); + snd_jack_set_key( + priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); + snd_jack_set_key( + priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); + + da7219_aad_jack_det(component, &priv->headset_jack); + + return 0; +} static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = { .dlc = COMP_EMPTY(), @@ -488,57 +584,56 @@ static struct snd_soc_card mt8183_da7219_max98357_card = { .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), .dapm_routes = mt8183_da7219_max98357_dapm_routes, .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), - .dai_link = mt8183_da7219_max98357_dai_links, - .num_links = ARRAY_SIZE(mt8183_da7219_max98357_dai_links), + .dai_link = mt8183_da7219_dai_links, + .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), .aux_dev = &mt8183_da7219_max98357_headset_dev, .num_aux_devs = 1, .codec_conf = mt6358_codec_conf, .num_configs = ARRAY_SIZE(mt6358_codec_conf), }; -static int -mt8183_da7219_max98357_headset_init(struct snd_soc_component *component) -{ - int ret; - struct mt8183_da7219_max98357_priv *priv = - snd_soc_card_get_drvdata(component->card); - - /* Enable Headset and 4 Buttons Jack detection */ - ret = snd_soc_card_jack_new(&mt8183_da7219_max98357_card, - "Headset Jack", - SND_JACK_HEADSET | - SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - &priv->headset_jack, - NULL, 0); - if (ret) - return ret; - - snd_jack_set_key( - priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); - snd_jack_set_key( - priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); - snd_jack_set_key( - priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); - snd_jack_set_key( - priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - - da7219_aad_jack_det(component, &priv->headset_jack); +static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = { + { + .dlc = COMP_CODEC_CONF("mt6358-sound"), + .name_prefix = "Mt6358", + }, + { + .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), + .name_prefix = "Right", + }, +}; - return 0; -} +static struct snd_soc_card mt8183_da7219_rt1015_card = { + .name = "mt8183_da7219_rt1015", + .owner = THIS_MODULE, + .controls = mt8183_da7219_max98357_snd_controls, + .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls), + .dapm_widgets = mt8183_da7219_max98357_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets), + .dapm_routes = mt8183_da7219_max98357_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes), + .dai_link = mt8183_da7219_dai_links, + .num_links = ARRAY_SIZE(mt8183_da7219_dai_links), + .aux_dev = &mt8183_da7219_max98357_headset_dev, + .num_aux_devs = 1, + .codec_conf = mt8183_da7219_rt1015_codec_conf, + .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf), +}; static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) { - struct snd_soc_card *card = &mt8183_da7219_max98357_card; + struct snd_soc_card *card; struct device_node *platform_node; struct snd_soc_dai_link *dai_link; struct mt8183_da7219_max98357_priv *priv; struct pinctrl *pinctrl; + const struct of_device_id *match; int ret, i; - card->dev = &pdev->dev; - platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); if (!platform_node) { @@ -546,10 +641,46 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) return -EINVAL; } + match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); + if (!match || !match->data) + return -EINVAL; + + card = (struct snd_soc_card *)match->data; + card->dev = &pdev->dev; + for_each_card_prelinks(card, i, dai_link) { - if (dai_link->platforms->name) - continue; - dai_link->platforms->of_node = platform_node; + if (strcmp(dai_link->name, "I2S3") == 0) { + if (card == &mt8183_da7219_max98357_card) { + dai_link->be_hw_params_fixup = + mt8183_i2s_hw_params_fixup; + dai_link->ops = &mt8183_mt6358_i2s_ops; + dai_link->cpus = i2s3_max98357a_cpus; + dai_link->num_cpus = + ARRAY_SIZE(i2s3_max98357a_cpus); + dai_link->codecs = i2s3_max98357a_codecs; + dai_link->num_codecs = + ARRAY_SIZE(i2s3_max98357a_codecs); + dai_link->platforms = i2s3_max98357a_platforms; + dai_link->num_platforms = + ARRAY_SIZE(i2s3_max98357a_platforms); + } else if (card == &mt8183_da7219_rt1015_card) { + dai_link->be_hw_params_fixup = + mt8183_rt1015_i2s_hw_params_fixup; + dai_link->ops = &mt8183_da7219_rt1015_i2s_ops; + dai_link->cpus = i2s3_rt1015_cpus; + dai_link->num_cpus = + ARRAY_SIZE(i2s3_rt1015_cpus); + dai_link->codecs = i2s3_rt1015_codecs; + dai_link->num_codecs = + ARRAY_SIZE(i2s3_rt1015_codecs); + dai_link->platforms = i2s3_rt1015_platforms; + dai_link->num_platforms = + ARRAY_SIZE(i2s3_rt1015_platforms); + } + } + + if (!dai_link->platforms->name) + dai_link->platforms->of_node = platform_node; } mt8183_da7219_max98357_headset_dev.dlc.of_node = @@ -580,14 +711,21 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id mt8183_da7219_max98357_dt_match[] = { - {.compatible = "mediatek,mt8183_da7219_max98357",}, + { + .compatible = "mediatek,mt8183_da7219_max98357", + .data = &mt8183_da7219_max98357_card, + }, + { + .compatible = "mediatek,mt8183_da7219_rt1015", + .data = &mt8183_da7219_rt1015_card, + }, {} }; #endif static struct platform_driver mt8183_da7219_max98357_driver = { .driver = { - .name = "mt8183_da7219_max98357", + .name = "mt8183_da7219", #ifdef CONFIG_OF .of_match_table = mt8183_da7219_max98357_dt_match, #endif diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c index 1fca8df109b42f..964f2f82178276 100644 --- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c @@ -7,13 +7,19 @@ // Author: Shunli Wang #include +#include +#include +#include #include #include -#include -#include -#include "mt8183-afe-common.h" +#include "../../codecs/rt1015.h" #include "../../codecs/ts3a227e.h" +#include "mt8183-afe-common.h" + +#define RT1015_CODEC_DAI "rt1015-aif" +#define RT1015_DEV0_NAME "rt1015.6-0028" +#define RT1015_DEV1_NAME "rt1015.6-0029" enum PINCTRL_PIN_STATE { PIN_STATE_DEFAULT = 0, @@ -49,6 +55,48 @@ static const struct snd_soc_ops mt8183_mt6358_i2s_ops = { .hw_params = mt8183_mt6358_i2s_hw_params, }; +static int +mt8183_mt6358_rt1015_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 128; + unsigned int mclk_fs = rate * mclk_fs_ratio; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *codec_dai; + int ret, i; + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); + if (ret < 0) { + dev_err(card->dev, "failed to set bclk ratio\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, + rate * 64, rate * 256); + if (ret < 0) { + dev_err(card->dev, "failed to set pll\n"); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL, + rate * 256, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "failed to set sysclk\n"); + return ret; + } + } + + return snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), + 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8183_mt6358_rt1015_i2s_ops = { + .hw_params = mt8183_mt6358_rt1015_i2s_hw_params, +}; + static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -62,6 +110,19 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__); + + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + return 0; +} + static int mt8183_mt6358_ts3a227_max98357_bt_sco_startup( struct snd_pcm_substream *substream) @@ -179,11 +240,17 @@ SND_SOC_DAILINK_DEFS(i2s2, DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); -SND_SOC_DAILINK_DEFS(i2s3, +SND_SOC_DAILINK_DEFS(i2s3_max98357a, DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi")), DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(i2s3_rt1015, + DAILINK_COMP_ARRAY(COMP_CPU("I2S3")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI), + COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + SND_SOC_DAILINK_DEFS(i2s5, DAILINK_COMP_ARRAY(COMP_CPU("I2S5")), DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")), @@ -270,8 +337,7 @@ static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_wov_ops = { .shutdown = mt8183_mt6358_ts3a227_max98357_wov_shutdown, }; -static struct snd_soc_dai_link -mt8183_mt6358_ts3a227_max98357_dai_links[] = { +static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = { /* FE */ { .name = "Playback_1", @@ -413,9 +479,6 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = { .no_pcm = 1, .dpcm_playback = 1, .ignore_suspend = 1, - .be_hw_params_fixup = mt8183_i2s_hw_params_fixup, - .ops = &mt8183_mt6358_i2s_ops, - SND_SOC_DAILINK_REG(i2s3), }, { .name = "I2S5", @@ -443,8 +506,28 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = { static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = { .name = "mt8183_mt6358_ts3a227_max98357", .owner = THIS_MODULE, - .dai_link = mt8183_mt6358_ts3a227_max98357_dai_links, - .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links), + .dai_link = mt8183_mt6358_ts3a227_dai_links, + .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links), +}; + +static struct snd_soc_codec_conf mt8183_mt6358_ts3a227_rt1015_amp_conf[] = { + { + .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME), + .name_prefix = "Right", + }, +}; + +static struct snd_soc_card mt8183_mt6358_ts3a227_rt1015_card = { + .name = "mt8183_mt6358_ts3a227_rt1015", + .owner = THIS_MODULE, + .dai_link = mt8183_mt6358_ts3a227_dai_links, + .num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links), + .codec_conf = mt8183_mt6358_ts3a227_rt1015_amp_conf, + .num_configs = ARRAY_SIZE(mt8183_mt6358_ts3a227_rt1015_amp_conf), }; static int @@ -455,7 +538,7 @@ mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component) snd_soc_card_get_drvdata(component->card); /* Enable Headset and 4 Buttons Jack detection */ - ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card, + ret = snd_soc_card_jack_new(component->card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | @@ -478,14 +561,12 @@ static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = { static int mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) { - struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; + struct snd_soc_card *card; struct device_node *platform_node, *ec_codec; struct snd_soc_dai_link *dai_link; struct mt8183_mt6358_ts3a227_max98357_priv *priv; - int ret; - int i; - - card->dev = &pdev->dev; + const struct of_device_id *match; + int ret, i; platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); @@ -494,12 +575,16 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) return -EINVAL; } + match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); + if (!match || !match->data) + return -EINVAL; + + card = (struct snd_soc_card *)match->data; + card->dev = &pdev->dev; + ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0); for_each_card_prelinks(card, i, dai_link) { - if (dai_link->platforms->name) - continue; - if (ec_codec && strcmp(dai_link->name, "Wake on Voice") == 0) { dai_link->cpus[0].name = NULL; dai_link->cpus[0].of_node = ec_codec; @@ -509,9 +594,40 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) dai_link->codecs[0].dai_name = "Wake on Voice"; dai_link->platforms[0].of_node = ec_codec; dai_link->ignore = 0; - } else { - dai_link->platforms->of_node = platform_node; } + + if (strcmp(dai_link->name, "I2S3") == 0) { + if (card == &mt8183_mt6358_ts3a227_max98357_card) { + dai_link->be_hw_params_fixup = + mt8183_i2s_hw_params_fixup; + dai_link->ops = &mt8183_mt6358_i2s_ops; + dai_link->cpus = i2s3_max98357a_cpus; + dai_link->num_cpus = + ARRAY_SIZE(i2s3_max98357a_cpus); + dai_link->codecs = i2s3_max98357a_codecs; + dai_link->num_codecs = + ARRAY_SIZE(i2s3_max98357a_codecs); + dai_link->platforms = i2s3_max98357a_platforms; + dai_link->num_platforms = + ARRAY_SIZE(i2s3_max98357a_platforms); + } else if (card == &mt8183_mt6358_ts3a227_rt1015_card) { + dai_link->be_hw_params_fixup = + mt8183_rt1015_i2s_hw_params_fixup; + dai_link->ops = &mt8183_mt6358_rt1015_i2s_ops; + dai_link->cpus = i2s3_rt1015_cpus; + dai_link->num_cpus = + ARRAY_SIZE(i2s3_rt1015_cpus); + dai_link->codecs = i2s3_rt1015_codecs; + dai_link->num_codecs = + ARRAY_SIZE(i2s3_rt1015_codecs); + dai_link->platforms = i2s3_rt1015_platforms; + dai_link->num_platforms = + ARRAY_SIZE(i2s3_rt1015_platforms); + } + } + + if (!dai_link->platforms->name) + dai_link->platforms->of_node = platform_node; } mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node = @@ -568,14 +684,21 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) #ifdef CONFIG_OF static const struct of_device_id mt8183_mt6358_ts3a227_max98357_dt_match[] = { - {.compatible = "mediatek,mt8183_mt6358_ts3a227_max98357",}, + { + .compatible = "mediatek,mt8183_mt6358_ts3a227_max98357", + .data = &mt8183_mt6358_ts3a227_max98357_card, + }, + { + .compatible = "mediatek,mt8183_mt6358_ts3a227_rt1015", + .data = &mt8183_mt6358_ts3a227_rt1015_card, + }, {} }; #endif static struct platform_driver mt8183_mt6358_ts3a227_max98357_driver = { .driver = { - .name = "mt8183_mt6358_ts3a227_max98357", + .name = "mt8183_mt6358_ts3a227", #ifdef CONFIG_OF .of_match_table = mt8183_mt6358_ts3a227_max98357_dt_match, #endif diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index aff57052a73558..941f3216399cd5 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -218,6 +218,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, struct snd_soc_pcm_runtime *soc_prtd = substream->private_data; struct q6asm_dai_rtd *prtd = runtime->private_data; struct q6asm_dai_data *pdata; + struct device *dev = component->dev; int ret, i; pdata = snd_soc_component_get_drvdata(component); @@ -225,7 +226,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, return -EINVAL; if (!prtd || !prtd->audio_client) { - pr_err("%s: private data null or audio client freed\n", + dev_err(dev, "%s: private data null or audio client freed\n", __func__); return -EINVAL; } @@ -248,7 +249,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, prtd->periods); if (ret < 0) { - pr_err("Audio Start: Buffer Allocation failed rc = %d\n", + dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n", ret); return -ENOMEM; } @@ -262,7 +263,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, } if (ret < 0) { - pr_err("%s: q6asm_open_write failed\n", __func__); + dev_err(dev, "%s: q6asm_open_write failed\n", __func__); q6asm_audio_client_free(prtd->audio_client); prtd->audio_client = NULL; return -ENOMEM; @@ -272,7 +273,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE, prtd->session_id, substream->stream); if (ret) { - pr_err("%s: stream reg failed ret:%d\n", __func__, ret); + dev_err(dev, "%s: stream reg failed ret:%d\n", __func__, ret); return ret; } @@ -292,7 +293,7 @@ static int q6asm_dai_prepare(struct snd_soc_component *component, } if (ret < 0) - pr_info("%s: CMD Format block failed\n", __func__); + dev_info(dev, "%s: CMD Format block failed\n", __func__); prtd->state = Q6ASM_STREAM_RUNNING; @@ -344,7 +345,7 @@ static int q6asm_dai_open(struct snd_soc_component *component, pdata = snd_soc_component_get_drvdata(component); if (!pdata) { - pr_err("Drv data not found ..\n"); + dev_err(dev, "Drv data not found ..\n"); return -EINVAL; } @@ -357,7 +358,7 @@ static int q6asm_dai_open(struct snd_soc_component *component, (q6asm_cb)event_handler, prtd, stream_id, LEGACY_PCM_MODE); if (IS_ERR(prtd->audio_client)) { - pr_info("%s: Could not allocate memory\n", __func__); + dev_info(dev, "%s: Could not allocate memory\n", __func__); ret = PTR_ERR(prtd->audio_client); kfree(prtd); return ret; @@ -372,12 +373,12 @@ static int q6asm_dai_open(struct snd_soc_component *component, SNDRV_PCM_HW_PARAM_RATE, &constraints_sample_rates); if (ret < 0) - pr_info("snd_pcm_hw_constraint_list failed\n"); + dev_info(dev, "snd_pcm_hw_constraint_list failed\n"); /* Ensure that buffer size is a multiple of period size */ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) - pr_info("snd_pcm_hw_constraint_integer failed\n"); + dev_info(dev, "snd_pcm_hw_constraint_integer failed\n"); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ret = snd_pcm_hw_constraint_minmax(runtime, @@ -385,21 +386,21 @@ static int q6asm_dai_open(struct snd_soc_component *component, PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE, PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE); if (ret < 0) { - pr_err("constraint for buffer bytes min max ret = %d\n", - ret); + dev_err(dev, "constraint for buffer bytes min max ret = %d\n", + ret); } } ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); if (ret < 0) { - pr_err("constraint for period bytes step ret = %d\n", + dev_err(dev, "constraint for period bytes step ret = %d\n", ret); } ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); if (ret < 0) { - pr_err("constraint for buffer bytes step ret = %d\n", + dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret); } diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index ae4b2cabdf2d6c..e0983970cba904 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -311,7 +311,7 @@ static int q6asm_apr_send_session_pkt(struct q6asm *a, struct audio_client *ac, 5 * HZ); if (!rc) { - dev_err(a->dev, "CMD timeout\n"); + dev_err(a->dev, "CMD %x timeout\n", hdr->opcode); rc = -ETIMEDOUT; } else if (ac->result.status > 0) { dev_err(a->dev, "DSP returned error[%x]\n", @@ -891,7 +891,7 @@ static int q6asm_ac_send_cmd_sync(struct audio_client *ac, struct apr_pkt *pkt) rc = wait_event_timeout(ac->cmd_wait, (ac->result.opcode == hdr->opcode), 5 * HZ); if (!rc) { - dev_err(ac->dev, "CMD timeout\n"); + dev_err(ac->dev, "CMD %x timeout\n", hdr->opcode); rc = -ETIMEDOUT; goto err; } diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index f45e5aaa4b3028..9539b0d024fed2 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -219,19 +219,32 @@ static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, return 0; } +static int rockchip_sound_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; + return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, + 8000, 96000); +} + static const struct snd_soc_ops rockchip_sound_max98357a_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_max98357a_hw_params, }; static const struct snd_soc_ops rockchip_sound_rt5514_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_rt5514_hw_params, }; static const struct snd_soc_ops rockchip_sound_da7219_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_da7219_hw_params, }; static const struct snd_soc_ops rockchip_sound_dmic_ops = { + .startup = rockchip_sound_startup, .hw_params = rockchip_sound_dmic_hw_params, }; diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index a5b1a12b349660..45dfc534c6c7f6 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -104,8 +104,13 @@ /** * struct s3c_pcm_info - S3C PCM Controller information + * @lock: Spin lock * @dev: The parent device passed to use from the probe. * @regs: The pointer to the device register block. + * @sclk_per_fs: number of sclk per frame sync + * @idleclk: Whether to keep PCMSCLK enabled even when idle (no active xfer) + * @pclk: the PCLK_PCM (pcm) clock pointer + * @cclk: the SCLK_AUDIO (audio-bus) clock pointer * @dma_playback: DMA information for playback channel. * @dma_capture: DMA information for capture channel. */ diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 759fc66443298a..4ae7ff623b826e 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -70,9 +70,9 @@ * @clk_rate: Current clock rate for calcurate ratio. * @pclk: The peri-clock pointer for spdif master operation. * @sclk: The source clock pointer for making sync signals. - * @save_clkcon: Backup clkcon reg. in suspend. - * @save_con: Backup con reg. in suspend. - * @save_cstas: Backup cstas reg. in suspend. + * @saved_clkcon: Backup clkcon reg. in suspend. + * @saved_con: Backup con reg. in suspend. + * @saved_cstas: Backup cstas reg. in suspend. * @dma_playback: DMA information for playback channel. */ struct samsung_spdif_info { diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index 906106ed8ca146..65db083e242b36 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -393,6 +393,8 @@ EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops); /** * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions + * @ops: bus ops + * @pdev: platform device * * This function sets the reset and warm_reset properties of ops and parses * the device node of pdev to get pinctrl states and gpio numbers to use. diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index adedadcb0efb4d..7c58e45c1c3f24 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2513,6 +2513,33 @@ int snd_soc_register_component(struct device *dev, } EXPORT_SYMBOL_GPL(snd_soc_register_component); +/** + * snd_soc_unregister_component_by_driver - Unregister component using a given driver + * from the ASoC core + * + * @dev: The device to unregister + * @component_driver: The component driver to unregister + */ +void snd_soc_unregister_component_by_driver(struct device *dev, + const struct snd_soc_component_driver *component_driver) +{ + struct snd_soc_component *component; + + if (!component_driver) + return; + + mutex_lock(&client_mutex); + component = snd_soc_lookup_component_nolocked(dev, component_driver->name); + if (!component) + goto out; + + snd_soc_del_component_unlocked(component); + +out: + mutex_unlock(&client_mutex); +} +EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver); + /** * snd_soc_unregister_component - Unregister all related component * from the ASoC core diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 11e5d79623707a..4534a1c03e8e5e 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -48,7 +48,9 @@ EXPORT_SYMBOL_GPL(devm_snd_soc_register_dai); static void devm_component_release(struct device *dev, void *res) { - snd_soc_unregister_component(*(struct device **)res); + const struct snd_soc_component_driver **cmpnt_drv = res; + + snd_soc_unregister_component_by_driver(dev, *cmpnt_drv); } /** @@ -65,7 +67,7 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai) { - struct device **ptr; + const struct snd_soc_component_driver **ptr; int ret; ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); @@ -74,7 +76,7 @@ int devm_snd_soc_register_component(struct device *dev, ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); if (ret == 0) { - *ptr = dev; + *ptr = cmpnt_drv; devres_add(dev, ptr); } else { devres_free(ptr); diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 80a4e71f2d95d6..61844403f1817f 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -478,7 +478,7 @@ void snd_dmaengine_pcm_unregister(struct device *dev) pcm = soc_component_to_pcm(component); - snd_soc_unregister_component(dev); + snd_soc_unregister_component_by_driver(dev, component->driver); dmaengine_pcm_release_chan(pcm); kfree(pcm); } diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index c5eaaa9780549d..8aecc46b364782 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -35,7 +35,7 @@ MODULE_PARM_DESC(sof_acpi_debug, "SOF ACPI debug options (0x0 all off)"); #define SOF_ACPI_DISABLE_PM_RUNTIME BIT(0) -#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) +#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) static const struct sof_dev_desc sof_acpi_broadwell_desc = { .machines = snd_soc_acpi_intel_broadwell_machines, .resindex_lpe_base = 0, @@ -51,7 +51,7 @@ static const struct sof_dev_desc sof_acpi_broadwell_desc = { }; #endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) +#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) /* BYTCR uses different IRQ index */ static const struct sof_dev_desc sof_acpi_baytrailcr_desc = { @@ -133,7 +133,7 @@ static int sof_acpi_probe(struct platform_device *pdev) if (!desc) return -ENODEV; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) +#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev)) desc = &sof_acpi_baytrailcr_desc; #endif @@ -191,6 +191,7 @@ static int sof_acpi_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_ACPI static const struct acpi_device_id sof_acpi_match[] = { #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) { "INT3438", (unsigned long)&sof_acpi_broadwell_desc }, @@ -202,6 +203,7 @@ static const struct acpi_device_id sof_acpi_match[] = { { } }; MODULE_DEVICE_TABLE(acpi, sof_acpi_match); +#endif /* acpi_driver definition */ static struct platform_driver snd_sof_acpi_driver = { diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 1070b2710d5e67..79dba878d8542a 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -98,8 +98,7 @@ EXPORT_SYMBOL_GPL(tegra20_das_connect_dac_to_dap); static bool tegra20_das_wr_rd_reg(struct device *dev, unsigned int reg) { - if ((reg >= TEGRA20_DAS_DAP_CTRL_SEL) && - (reg <= LAST_REG(DAP_CTRL_SEL))) + if (reg <= LAST_REG(DAP_CTRL_SEL)) return true; if ((reg >= TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL) && (reg <= LAST_REG(DAC_INPUT_DATA_CLK_SEL))) diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig index c5408c129f342d..53df545efe0ad9 100644 --- a/sound/soc/ti/Kconfig +++ b/sound/soc/ti/Kconfig @@ -219,5 +219,13 @@ config SND_SOC_DM365_VOICE_CODEC_MODULE The is an internal symbol needed to ensure that the codec and MFD driver can be built as loadable modules if necessary. +config SND_SOC_J721E_EVM + tristate "SoC Audio support for j721e EVM" + depends on ARCH_K3_J721E_SOC || COMPILE_TEST + select SND_SOC_PCM3168A_I2C + select SND_SOC_DAVINCI_MCASP + help + Say Y if you want to add support for SoC audio on j721e Common + Processor Board and Infotainment expansion board. endmenu diff --git a/sound/soc/ti/Makefile b/sound/soc/ti/Makefile index ea48c6679cc72f..a21e5b0061de3c 100644 --- a/sound/soc/ti/Makefile +++ b/sound/soc/ti/Makefile @@ -34,6 +34,7 @@ snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o snd-soc-ams-delta-objs := ams-delta.o snd-soc-omap-hdmi-objs := omap-hdmi.o snd-soc-osk5912-objs := osk5912.o +snd-soc-j721e-evm-objs := j721e-evm.o obj-$(CONFIG_SND_SOC_DAVINCI_EVM) += snd-soc-davinci-evm.o obj-$(CONFIG_SND_SOC_NOKIA_N810) += snd-soc-n810.o @@ -44,3 +45,4 @@ obj-$(CONFIG_SND_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o obj-$(CONFIG_SND_SOC_OMAP_AMS_DELTA) += snd-soc-ams-delta.o obj-$(CONFIG_SND_SOC_OMAP_HDMI) += snd-soc-omap-hdmi.o obj-$(CONFIG_SND_SOC_OMAP_OSK5912) += snd-soc-osk5912.o +obj-$(CONFIG_SND_SOC_J721E_EVM) += snd-soc-j721e-evm.o diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index b93c1ee302c0c4..617440767c45fd 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -1623,12 +1623,14 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { .name = "davinci-mcasp.0", .probe = davinci_mcasp_dai_probe, .playback = { + .stream_name = "IIS Playback", .channels_min = 1, .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, .capture = { + .stream_name = "IIS Capture", .channels_min = 1, .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, @@ -1642,6 +1644,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { .name = "davinci-mcasp.1", .probe = davinci_mcasp_dai_probe, .playback = { + .stream_name = "DIT Playback", .channels_min = 1, .channels_max = 384, .rates = DAVINCI_MCASP_RATES, diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c new file mode 100644 index 00000000000000..174306cf53ad9e --- /dev/null +++ b/sound/soc/ti/j721e-evm.c @@ -0,0 +1,896 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com + * Author: Peter Ujfalusi + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "davinci-mcasp.h" + +/* + * Maximum number of configuration entries for prefixes: + * CPB: 2 (mcasp10 + codec) + * IVI: 3 (mcasp0 + 2x codec) + */ +#define J721E_CODEC_CONF_COUNT 5 + +#define J721E_AUDIO_DOMAIN_CPB 0 +#define J721E_AUDIO_DOMAIN_IVI 1 + +#define J721E_CLK_PARENT_48000 0 +#define J721E_CLK_PARENT_44100 1 + +#define J721E_MAX_CLK_HSDIV 128 +#define PCM1368A_MAX_SYSCLK 36864000 + +#define J721E_DAI_FMT (SND_SOC_DAIFMT_RIGHT_J | \ + SND_SOC_DAIFMT_NB_NF | \ + SND_SOC_DAIFMT_CBS_CFS) + +enum j721e_board_type { + J721E_BOARD_CPB = 1, + J721E_BOARD_CPB_IVI, +}; + +struct j721e_audio_match_data { + enum j721e_board_type board_type; + int num_links; + unsigned int pll_rates[2]; +}; + +static unsigned int ratios_for_pcm3168a[] = { + 256, + 512, + 768, +}; + +struct j721e_audio_clocks { + struct clk *target; + struct clk *parent[2]; +}; + +struct j721e_audio_domain { + struct j721e_audio_clocks codec; + struct j721e_audio_clocks mcasp; + int parent_clk_id; + + int active; + unsigned int active_link; + unsigned int rate; +}; + +struct j721e_priv { + struct device *dev; + struct snd_soc_card card; + struct snd_soc_dai_link *dai_links; + struct snd_soc_codec_conf codec_conf[J721E_CODEC_CONF_COUNT]; + struct snd_interval rate_range; + const struct j721e_audio_match_data *match_data; + u32 pll_rates[2]; + unsigned int hsdiv_rates[2]; + + struct j721e_audio_domain audio_domains[2]; + + struct mutex mutex; +}; + +static const struct snd_soc_dapm_widget j721e_cpb_dapm_widgets[] = { + SND_SOC_DAPM_HP("CPB Stereo HP 1", NULL), + SND_SOC_DAPM_HP("CPB Stereo HP 2", NULL), + SND_SOC_DAPM_HP("CPB Stereo HP 3", NULL), + SND_SOC_DAPM_LINE("CPB Line Out", NULL), + SND_SOC_DAPM_MIC("CPB Stereo Mic 1", NULL), + SND_SOC_DAPM_MIC("CPB Stereo Mic 2", NULL), + SND_SOC_DAPM_LINE("CPB Line In", NULL), +}; + +static const struct snd_soc_dapm_route j721e_cpb_dapm_routes[] = { + {"CPB Stereo HP 1", NULL, "codec-1 AOUT1L"}, + {"CPB Stereo HP 1", NULL, "codec-1 AOUT1R"}, + {"CPB Stereo HP 2", NULL, "codec-1 AOUT2L"}, + {"CPB Stereo HP 2", NULL, "codec-1 AOUT2R"}, + {"CPB Stereo HP 3", NULL, "codec-1 AOUT3L"}, + {"CPB Stereo HP 3", NULL, "codec-1 AOUT3R"}, + {"CPB Line Out", NULL, "codec-1 AOUT4L"}, + {"CPB Line Out", NULL, "codec-1 AOUT4R"}, + + {"codec-1 AIN1L", NULL, "CPB Stereo Mic 1"}, + {"codec-1 AIN1R", NULL, "CPB Stereo Mic 1"}, + {"codec-1 AIN2L", NULL, "CPB Stereo Mic 2"}, + {"codec-1 AIN2R", NULL, "CPB Stereo Mic 2"}, + {"codec-1 AIN3L", NULL, "CPB Line In"}, + {"codec-1 AIN3R", NULL, "CPB Line In"}, +}; + +static const struct snd_soc_dapm_widget j721e_ivi_codec_a_dapm_widgets[] = { + SND_SOC_DAPM_LINE("IVI A Line Out 1", NULL), + SND_SOC_DAPM_LINE("IVI A Line Out 2", NULL), + SND_SOC_DAPM_LINE("IVI A Line Out 3", NULL), + SND_SOC_DAPM_LINE("IVI A Line Out 4", NULL), + SND_SOC_DAPM_MIC("IVI A Stereo Mic 1", NULL), + SND_SOC_DAPM_MIC("IVI A Stereo Mic 2", NULL), + SND_SOC_DAPM_LINE("IVI A Line In", NULL), +}; + +static const struct snd_soc_dapm_route j721e_codec_a_dapm_routes[] = { + {"IVI A Line Out 1", NULL, "codec-a AOUT1L"}, + {"IVI A Line Out 1", NULL, "codec-a AOUT1R"}, + {"IVI A Line Out 2", NULL, "codec-a AOUT2L"}, + {"IVI A Line Out 2", NULL, "codec-a AOUT2R"}, + {"IVI A Line Out 3", NULL, "codec-a AOUT3L"}, + {"IVI A Line Out 3", NULL, "codec-a AOUT3R"}, + {"IVI A Line Out 4", NULL, "codec-a AOUT4L"}, + {"IVI A Line Out 4", NULL, "codec-a AOUT4R"}, + + {"codec-a AIN1L", NULL, "IVI A Stereo Mic 1"}, + {"codec-a AIN1R", NULL, "IVI A Stereo Mic 1"}, + {"codec-a AIN2L", NULL, "IVI A Stereo Mic 2"}, + {"codec-a AIN2R", NULL, "IVI A Stereo Mic 2"}, + {"codec-a AIN3L", NULL, "IVI A Line In"}, + {"codec-a AIN3R", NULL, "IVI A Line In"}, +}; + +static const struct snd_soc_dapm_widget j721e_ivi_codec_b_dapm_widgets[] = { + SND_SOC_DAPM_LINE("IVI B Line Out 1", NULL), + SND_SOC_DAPM_LINE("IVI B Line Out 2", NULL), + SND_SOC_DAPM_LINE("IVI B Line Out 3", NULL), + SND_SOC_DAPM_LINE("IVI B Line Out 4", NULL), + SND_SOC_DAPM_MIC("IVI B Stereo Mic 1", NULL), + SND_SOC_DAPM_MIC("IVI B Stereo Mic 2", NULL), + SND_SOC_DAPM_LINE("IVI B Line In", NULL), +}; + +static const struct snd_soc_dapm_route j721e_codec_b_dapm_routes[] = { + {"IVI B Line Out 1", NULL, "codec-b AOUT1L"}, + {"IVI B Line Out 1", NULL, "codec-b AOUT1R"}, + {"IVI B Line Out 2", NULL, "codec-b AOUT2L"}, + {"IVI B Line Out 2", NULL, "codec-b AOUT2R"}, + {"IVI B Line Out 3", NULL, "codec-b AOUT3L"}, + {"IVI B Line Out 3", NULL, "codec-b AOUT3R"}, + {"IVI B Line Out 4", NULL, "codec-b AOUT4L"}, + {"IVI B Line Out 4", NULL, "codec-b AOUT4R"}, + + {"codec-b AIN1L", NULL, "IVI B Stereo Mic 1"}, + {"codec-b AIN1R", NULL, "IVI B Stereo Mic 1"}, + {"codec-b AIN2L", NULL, "IVI B Stereo Mic 2"}, + {"codec-b AIN2R", NULL, "IVI B Stereo Mic 2"}, + {"codec-b AIN3L", NULL, "IVI B Line In"}, + {"codec-b AIN3R", NULL, "IVI B Line In"}, +}; + +static int j721e_configure_refclk(struct j721e_priv *priv, + unsigned int audio_domain, unsigned int rate) +{ + struct j721e_audio_domain *domain = &priv->audio_domains[audio_domain]; + unsigned int scki; + int ret = -EINVAL; + int i, clk_id; + + if (!(rate % 8000) && priv->pll_rates[J721E_CLK_PARENT_48000]) + clk_id = J721E_CLK_PARENT_48000; + else if (!(rate % 11025) && priv->pll_rates[J721E_CLK_PARENT_44100]) + clk_id = J721E_CLK_PARENT_44100; + else + return ret; + + for (i = 0; i < ARRAY_SIZE(ratios_for_pcm3168a); i++) { + scki = ratios_for_pcm3168a[i] * rate; + + if (priv->pll_rates[clk_id] / scki <= J721E_MAX_CLK_HSDIV) { + ret = 0; + break; + } + } + + if (ret) { + dev_err(priv->dev, "No valid clock configuration for %u Hz\n", + rate); + return ret; + } + + if (priv->hsdiv_rates[domain->parent_clk_id] != scki) { + dev_dbg(priv->dev, + "%s configuration for %u Hz: %s, %dxFS (SCKI: %u Hz)\n", + audio_domain == J721E_AUDIO_DOMAIN_CPB ? "CPB" : "IVI", + rate, + clk_id == J721E_CLK_PARENT_48000 ? "PLL4" : "PLL15", + ratios_for_pcm3168a[i], scki); + + if (domain->parent_clk_id != clk_id) { + ret = clk_set_parent(domain->codec.target, + domain->codec.parent[clk_id]); + if (ret) + return ret; + + ret = clk_set_parent(domain->mcasp.target, + domain->mcasp.parent[clk_id]); + if (ret) + return ret; + + domain->parent_clk_id = clk_id; + } + + ret = clk_set_rate(domain->codec.target, scki); + if (ret) { + dev_err(priv->dev, "codec set rate failed for %u Hz\n", + scki); + return ret; + } + + ret = clk_set_rate(domain->mcasp.target, scki); + if (!ret) { + priv->hsdiv_rates[domain->parent_clk_id] = scki; + } else { + dev_err(priv->dev, "mcasp set rate failed for %u Hz\n", + scki); + return ret; + } + } + + return ret; +} + +static int j721e_rule_rate(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + struct snd_interval *t = rule->private; + + return snd_interval_refine(hw_param_interval(params, rule->var), t); +} + +static int j721e_audio_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct j721e_priv *priv = snd_soc_card_get_drvdata(rtd->card); + unsigned int domain_id = rtd->dai_link->id; + struct j721e_audio_domain *domain = &priv->audio_domains[domain_id]; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai; + unsigned int active_rate; + int ret = 0; + int i; + + mutex_lock(&priv->mutex); + + domain->active++; + + if (priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].rate) + active_rate = priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].rate; + else + active_rate = priv->audio_domains[J721E_AUDIO_DOMAIN_IVI].rate; + + if (active_rate) + ret = snd_pcm_hw_constraint_single(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + active_rate); + else + ret = snd_pcm_hw_rule_add(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + j721e_rule_rate, &priv->rate_range, + SNDRV_PCM_HW_PARAM_RATE, -1); + + mutex_unlock(&priv->mutex); + + if (ret) + return ret; + + /* Reset TDM slots to 32 */ + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32); + if (ret && ret != -ENOTSUPP) + return ret; + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 2, 32); + if (ret && ret != -ENOTSUPP) + return ret; + } + + return 0; +} + +static int j721e_audio_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct j721e_priv *priv = snd_soc_card_get_drvdata(card); + unsigned int domain_id = rtd->dai_link->id; + struct j721e_audio_domain *domain = &priv->audio_domains[domain_id]; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai; + unsigned int sysclk_rate; + int slot_width = 32; + int ret; + int i; + + mutex_lock(&priv->mutex); + + if (domain->rate && domain->rate != params_rate(params)) { + ret = -EINVAL; + goto out; + } + + if (params_width(params) == 16) + slot_width = 16; + + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, slot_width); + if (ret && ret != -ENOTSUPP) + goto out; + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 2, + slot_width); + if (ret && ret != -ENOTSUPP) + goto out; + } + + ret = j721e_configure_refclk(priv, domain_id, params_rate(params)); + if (ret) + goto out; + + sysclk_rate = priv->hsdiv_rates[domain->parent_clk_id]; + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk_rate, + SND_SOC_CLOCK_IN); + if (ret && ret != -ENOTSUPP) { + dev_err(priv->dev, + "codec set_sysclk failed for %u Hz\n", + sysclk_rate); + goto out; + } + } + + ret = snd_soc_dai_set_sysclk(cpu_dai, MCASP_CLK_HCLK_AUXCLK, + sysclk_rate, SND_SOC_CLOCK_IN); + + if (ret && ret != -ENOTSUPP) { + dev_err(priv->dev, "mcasp set_sysclk failed for %u Hz\n", + sysclk_rate); + } else { + domain->rate = params_rate(params); + ret = 0; + } + +out: + mutex_unlock(&priv->mutex); + return ret; +} + +static void j721e_audio_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct j721e_priv *priv = snd_soc_card_get_drvdata(rtd->card); + unsigned int domain_id = rtd->dai_link->id; + struct j721e_audio_domain *domain = &priv->audio_domains[domain_id]; + + mutex_lock(&priv->mutex); + + domain->active--; + if (!domain->active) { + domain->rate = 0; + domain->active_link = 0; + } + + mutex_unlock(&priv->mutex); +} + +static const struct snd_soc_ops j721e_audio_ops = { + .startup = j721e_audio_startup, + .hw_params = j721e_audio_hw_params, + .shutdown = j721e_audio_shutdown, +}; + +static int j721e_audio_init(struct snd_soc_pcm_runtime *rtd) +{ + struct j721e_priv *priv = snd_soc_card_get_drvdata(rtd->card); + unsigned int domain_id = rtd->dai_link->id; + struct j721e_audio_domain *domain = &priv->audio_domains[domain_id]; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai; + unsigned int sysclk_rate; + int i, ret; + + /* Set up initial clock configuration */ + ret = j721e_configure_refclk(priv, domain_id, 48000); + if (ret) + return ret; + + sysclk_rate = priv->hsdiv_rates[domain->parent_clk_id]; + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk_rate, + SND_SOC_CLOCK_IN); + if (ret && ret != -ENOTSUPP) + return ret; + } + + ret = snd_soc_dai_set_sysclk(cpu_dai, MCASP_CLK_HCLK_AUXCLK, + sysclk_rate, SND_SOC_CLOCK_IN); + if (ret && ret != -ENOTSUPP) + return ret; + + /* Set initial tdm slots */ + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32); + if (ret && ret != -ENOTSUPP) + return ret; + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 2, 32); + if (ret && ret != -ENOTSUPP) + return ret; + } + + return 0; +} + +static int j721e_audio_init_ivi(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dapm_context *dapm = &rtd->card->dapm; + + snd_soc_dapm_new_controls(dapm, j721e_ivi_codec_a_dapm_widgets, + ARRAY_SIZE(j721e_ivi_codec_a_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, j721e_codec_a_dapm_routes, + ARRAY_SIZE(j721e_codec_a_dapm_routes)); + snd_soc_dapm_new_controls(dapm, j721e_ivi_codec_b_dapm_widgets, + ARRAY_SIZE(j721e_ivi_codec_b_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, j721e_codec_b_dapm_routes, + ARRAY_SIZE(j721e_codec_b_dapm_routes)); + + return j721e_audio_init(rtd); +} + +static int j721e_get_clocks(struct device *dev, + struct j721e_audio_clocks *clocks, char *prefix) +{ + struct clk *parent; + char *clk_name; + int ret; + + clocks->target = devm_clk_get(dev, prefix); + if (IS_ERR(clocks->target)) { + ret = PTR_ERR(clocks->target); + if (ret != -EPROBE_DEFER) + dev_err(dev, "failed to acquire %s: %d\n", + prefix, ret); + return ret; + } + + clk_name = kasprintf(GFP_KERNEL, "%s-48000", prefix); + if (clk_name) { + parent = devm_clk_get(dev, clk_name); + kfree(clk_name); + if (IS_ERR(parent)) { + ret = PTR_ERR(parent); + if (ret == -EPROBE_DEFER) + return ret; + + dev_dbg(dev, "no 48KHz parent for %s: %d\n", prefix, ret); + parent = NULL; + } + clocks->parent[J721E_CLK_PARENT_48000] = parent; + } else { + return -ENOMEM; + } + + clk_name = kasprintf(GFP_KERNEL, "%s-44100", prefix); + if (clk_name) { + parent = devm_clk_get(dev, clk_name); + kfree(clk_name); + if (IS_ERR(parent)) { + ret = PTR_ERR(parent); + if (ret == -EPROBE_DEFER) + return ret; + + dev_dbg(dev, "no 44.1KHz parent for %s: %d\n", prefix, ret); + parent = NULL; + } + clocks->parent[J721E_CLK_PARENT_44100] = parent; + } else { + return -ENOMEM; + } + + if (!clocks->parent[J721E_CLK_PARENT_44100] && + !clocks->parent[J721E_CLK_PARENT_48000]) { + dev_err(dev, "At least one parent clock is needed for %s\n", + prefix); + return -EINVAL; + } + + return 0; +} + +static const struct j721e_audio_match_data j721e_cpb_data = { + .board_type = J721E_BOARD_CPB, + .num_links = 2, /* CPB pcm3168a */ + .pll_rates = { + [J721E_CLK_PARENT_44100] = 1083801600, /* PLL15 */ + [J721E_CLK_PARENT_48000] = 1179648000, /* PLL4 */ + }, +}; + +static const struct j721e_audio_match_data j721e_cpb_ivi_data = { + .board_type = J721E_BOARD_CPB_IVI, + .num_links = 4, /* CPB pcm3168a + 2x pcm3168a on IVI */ + .pll_rates = { + [J721E_CLK_PARENT_44100] = 1083801600, /* PLL15 */ + [J721E_CLK_PARENT_48000] = 1179648000, /* PLL4 */ + }, +}; + +static const struct of_device_id j721e_audio_of_match[] = { + { + .compatible = "ti,j721e-cpb-audio", + .data = &j721e_cpb_data, + }, { + .compatible = "ti,j721e-cpb-ivi-audio", + .data = &j721e_cpb_ivi_data, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, j721e_audio_of_match); + +static int j721e_calculate_rate_range(struct j721e_priv *priv) +{ + const struct j721e_audio_match_data *match_data = priv->match_data; + struct j721e_audio_clocks *domain_clocks; + unsigned int min_rate, max_rate, pll_rate; + struct clk *pll; + + domain_clocks = &priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].mcasp; + + pll = clk_get_parent(domain_clocks->parent[J721E_CLK_PARENT_44100]); + if (IS_ERR_OR_NULL(pll)) { + priv->pll_rates[J721E_CLK_PARENT_44100] = + match_data->pll_rates[J721E_CLK_PARENT_44100]; + } else { + priv->pll_rates[J721E_CLK_PARENT_44100] = clk_get_rate(pll); + clk_put(pll); + } + + pll = clk_get_parent(domain_clocks->parent[J721E_CLK_PARENT_48000]); + if (IS_ERR_OR_NULL(pll)) { + priv->pll_rates[J721E_CLK_PARENT_48000] = + match_data->pll_rates[J721E_CLK_PARENT_48000]; + } else { + priv->pll_rates[J721E_CLK_PARENT_48000] = clk_get_rate(pll); + clk_put(pll); + } + + if (!priv->pll_rates[J721E_CLK_PARENT_44100] && + !priv->pll_rates[J721E_CLK_PARENT_48000]) { + dev_err(priv->dev, "At least one PLL is needed\n"); + return -EINVAL; + } + + if (priv->pll_rates[J721E_CLK_PARENT_44100]) + pll_rate = priv->pll_rates[J721E_CLK_PARENT_44100]; + else + pll_rate = priv->pll_rates[J721E_CLK_PARENT_48000]; + + min_rate = pll_rate / J721E_MAX_CLK_HSDIV; + min_rate /= ratios_for_pcm3168a[ARRAY_SIZE(ratios_for_pcm3168a) - 1]; + + if (priv->pll_rates[J721E_CLK_PARENT_48000]) + pll_rate = priv->pll_rates[J721E_CLK_PARENT_48000]; + else + pll_rate = priv->pll_rates[J721E_CLK_PARENT_44100]; + + if (pll_rate > PCM1368A_MAX_SYSCLK) + pll_rate = PCM1368A_MAX_SYSCLK; + + max_rate = pll_rate / ratios_for_pcm3168a[0]; + + snd_interval_any(&priv->rate_range); + priv->rate_range.min = min_rate; + priv->rate_range.max = max_rate; + + return 0; +} + +static int j721e_soc_probe_cpb(struct j721e_priv *priv, int *link_idx, + int *conf_idx) +{ + struct device_node *node = priv->dev->of_node; + struct snd_soc_dai_link_component *compnent; + struct device_node *dai_node, *codec_node; + struct j721e_audio_domain *domain; + int comp_count, comp_idx; + int ret; + + dai_node = of_parse_phandle(node, "ti,cpb-mcasp", 0); + if (!dai_node) { + dev_err(priv->dev, "CPB McASP node is not provided\n"); + return -EINVAL; + } + + codec_node = of_parse_phandle(node, "ti,cpb-codec", 0); + if (!codec_node) { + dev_err(priv->dev, "CPB codec node is not provided\n"); + return -EINVAL; + } + + domain = &priv->audio_domains[J721E_AUDIO_DOMAIN_CPB]; + ret = j721e_get_clocks(priv->dev, &domain->codec, "cpb-codec-scki"); + if (ret) + return ret; + + ret = j721e_get_clocks(priv->dev, &domain->mcasp, "cpb-mcasp-auxclk"); + if (ret) + return ret; + + /* + * Common Processor Board, two links + * Link 1: McASP10 -> pcm3168a_1 DAC + * Link 2: McASP10 <- pcm3168a_1 ADC + */ + comp_count = 6; + compnent = devm_kzalloc(priv->dev, comp_count * sizeof(*compnent), + GFP_KERNEL); + if (!compnent) + return -ENOMEM; + + comp_idx = 0; + priv->dai_links[*link_idx].cpus = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_cpus = 1; + priv->dai_links[*link_idx].codecs = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_codecs = 1; + priv->dai_links[*link_idx].platforms = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_platforms = 1; + + priv->dai_links[*link_idx].name = "CPB PCM3168A Playback"; + priv->dai_links[*link_idx].stream_name = "CPB PCM3168A Analog"; + priv->dai_links[*link_idx].cpus->of_node = dai_node; + priv->dai_links[*link_idx].platforms->of_node = dai_node; + priv->dai_links[*link_idx].codecs->of_node = codec_node; + priv->dai_links[*link_idx].codecs->dai_name = "pcm3168a-dac"; + priv->dai_links[*link_idx].playback_only = 1; + priv->dai_links[*link_idx].id = J721E_AUDIO_DOMAIN_CPB; + priv->dai_links[*link_idx].dai_fmt = J721E_DAI_FMT; + priv->dai_links[*link_idx].init = j721e_audio_init; + priv->dai_links[*link_idx].ops = &j721e_audio_ops; + (*link_idx)++; + + priv->dai_links[*link_idx].cpus = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_cpus = 1; + priv->dai_links[*link_idx].codecs = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_codecs = 1; + priv->dai_links[*link_idx].platforms = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_platforms = 1; + + priv->dai_links[*link_idx].name = "CPB PCM3168A Capture"; + priv->dai_links[*link_idx].stream_name = "CPB PCM3168A Analog"; + priv->dai_links[*link_idx].cpus->of_node = dai_node; + priv->dai_links[*link_idx].platforms->of_node = dai_node; + priv->dai_links[*link_idx].codecs->of_node = codec_node; + priv->dai_links[*link_idx].codecs->dai_name = "pcm3168a-adc"; + priv->dai_links[*link_idx].capture_only = 1; + priv->dai_links[*link_idx].id = J721E_AUDIO_DOMAIN_CPB; + priv->dai_links[*link_idx].dai_fmt = J721E_DAI_FMT; + priv->dai_links[*link_idx].init = j721e_audio_init; + priv->dai_links[*link_idx].ops = &j721e_audio_ops; + (*link_idx)++; + + priv->codec_conf[*conf_idx].dlc.of_node = codec_node; + priv->codec_conf[*conf_idx].name_prefix = "codec-1"; + (*conf_idx)++; + priv->codec_conf[*conf_idx].dlc.of_node = dai_node; + priv->codec_conf[*conf_idx].name_prefix = "McASP10"; + (*conf_idx)++; + + return 0; +} + +static int j721e_soc_probe_ivi(struct j721e_priv *priv, int *link_idx, + int *conf_idx) +{ + struct device_node *node = priv->dev->of_node; + struct snd_soc_dai_link_component *compnent; + struct device_node *dai_node, *codeca_node, *codecb_node; + struct j721e_audio_domain *domain; + int comp_count, comp_idx; + int ret; + + if (priv->match_data->board_type != J721E_BOARD_CPB_IVI) + return 0; + + dai_node = of_parse_phandle(node, "ti,ivi-mcasp", 0); + if (!dai_node) { + dev_err(priv->dev, "IVI McASP node is not provided\n"); + return -EINVAL; + } + + codeca_node = of_parse_phandle(node, "ti,ivi-codec-a", 0); + if (!codeca_node) { + dev_err(priv->dev, "IVI codec-a node is not provided\n"); + return -EINVAL; + } + + codecb_node = of_parse_phandle(node, "ti,ivi-codec-b", 0); + if (!codecb_node) { + dev_warn(priv->dev, "IVI codec-b node is not provided\n"); + return 0; + } + + domain = &priv->audio_domains[J721E_AUDIO_DOMAIN_IVI]; + ret = j721e_get_clocks(priv->dev, &domain->codec, "ivi-codec-scki"); + if (ret) + return ret; + + ret = j721e_get_clocks(priv->dev, &domain->mcasp, "ivi-mcasp-auxclk"); + if (ret) + return ret; + + /* + * IVI extension, two links + * Link 1: McASP0 -> pcm3168a_a DAC + * \> pcm3168a_b DAC + * Link 2: McASP0 <- pcm3168a_a ADC + * \ pcm3168a_b ADC + */ + comp_count = 8; + compnent = devm_kzalloc(priv->dev, comp_count * sizeof(*compnent), + GFP_KERNEL); + if (!compnent) + return -ENOMEM; + + comp_idx = 0; + priv->dai_links[*link_idx].cpus = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_cpus = 1; + priv->dai_links[*link_idx].platforms = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_platforms = 1; + priv->dai_links[*link_idx].codecs = &compnent[comp_idx]; + priv->dai_links[*link_idx].num_codecs = 2; + comp_idx += 2; + + priv->dai_links[*link_idx].name = "IVI 2xPCM3168A Playback"; + priv->dai_links[*link_idx].stream_name = "IVI 2xPCM3168A Analog"; + priv->dai_links[*link_idx].cpus->of_node = dai_node; + priv->dai_links[*link_idx].platforms->of_node = dai_node; + priv->dai_links[*link_idx].codecs[0].of_node = codeca_node; + priv->dai_links[*link_idx].codecs[0].dai_name = "pcm3168a-dac"; + priv->dai_links[*link_idx].codecs[1].of_node = codecb_node; + priv->dai_links[*link_idx].codecs[1].dai_name = "pcm3168a-dac"; + priv->dai_links[*link_idx].playback_only = 1; + priv->dai_links[*link_idx].id = J721E_AUDIO_DOMAIN_IVI; + priv->dai_links[*link_idx].dai_fmt = J721E_DAI_FMT; + priv->dai_links[*link_idx].init = j721e_audio_init_ivi; + priv->dai_links[*link_idx].ops = &j721e_audio_ops; + (*link_idx)++; + + priv->dai_links[*link_idx].cpus = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_cpus = 1; + priv->dai_links[*link_idx].platforms = &compnent[comp_idx++]; + priv->dai_links[*link_idx].num_platforms = 1; + priv->dai_links[*link_idx].codecs = &compnent[comp_idx]; + priv->dai_links[*link_idx].num_codecs = 2; + + priv->dai_links[*link_idx].name = "IVI 2xPCM3168A Capture"; + priv->dai_links[*link_idx].stream_name = "IVI 2xPCM3168A Analog"; + priv->dai_links[*link_idx].cpus->of_node = dai_node; + priv->dai_links[*link_idx].platforms->of_node = dai_node; + priv->dai_links[*link_idx].codecs[0].of_node = codeca_node; + priv->dai_links[*link_idx].codecs[0].dai_name = "pcm3168a-adc"; + priv->dai_links[*link_idx].codecs[1].of_node = codecb_node; + priv->dai_links[*link_idx].codecs[1].dai_name = "pcm3168a-adc"; + priv->dai_links[*link_idx].capture_only = 1; + priv->dai_links[*link_idx].id = J721E_AUDIO_DOMAIN_IVI; + priv->dai_links[*link_idx].dai_fmt = J721E_DAI_FMT; + priv->dai_links[*link_idx].init = j721e_audio_init; + priv->dai_links[*link_idx].ops = &j721e_audio_ops; + (*link_idx)++; + + priv->codec_conf[*conf_idx].dlc.of_node = codeca_node; + priv->codec_conf[*conf_idx].name_prefix = "codec-a"; + (*conf_idx)++; + + priv->codec_conf[*conf_idx].dlc.of_node = codecb_node; + priv->codec_conf[*conf_idx].name_prefix = "codec-b"; + (*conf_idx)++; + + priv->codec_conf[*conf_idx].dlc.of_node = dai_node; + priv->codec_conf[*conf_idx].name_prefix = "McASP0"; + (*conf_idx)++; + + return 0; +} + +static int j721e_soc_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct snd_soc_card *card; + const struct of_device_id *match; + struct j721e_priv *priv; + int link_cnt, conf_cnt, ret; + + if (!node) { + dev_err(&pdev->dev, "of node is missing.\n"); + return -ENODEV; + } + + match = of_match_node(j721e_audio_of_match, node); + if (!match) { + dev_err(&pdev->dev, "No compatible match found\n"); + return -ENODEV; + } + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->match_data = match->data; + + priv->dai_links = devm_kcalloc(&pdev->dev, priv->match_data->num_links, + sizeof(*priv->dai_links), GFP_KERNEL); + if (!priv->dai_links) + return -ENOMEM; + + priv->audio_domains[J721E_AUDIO_DOMAIN_CPB].parent_clk_id = -1; + priv->audio_domains[J721E_AUDIO_DOMAIN_IVI].parent_clk_id = -1; + priv->dev = &pdev->dev; + card = &priv->card; + card->dev = &pdev->dev; + card->owner = THIS_MODULE; + card->dapm_widgets = j721e_cpb_dapm_widgets; + card->num_dapm_widgets = ARRAY_SIZE(j721e_cpb_dapm_widgets); + card->dapm_routes = j721e_cpb_dapm_routes; + card->num_dapm_routes = ARRAY_SIZE(j721e_cpb_dapm_routes); + card->fully_routed = 1; + + if (snd_soc_of_parse_card_name(card, "model")) { + dev_err(&pdev->dev, "Card name is not provided\n"); + return -ENODEV; + } + + link_cnt = 0; + conf_cnt = 0; + ret = j721e_soc_probe_cpb(priv, &link_cnt, &conf_cnt); + if (ret) + return ret; + + ret = j721e_soc_probe_ivi(priv, &link_cnt, &conf_cnt); + if (ret) + return ret; + + card->dai_link = priv->dai_links; + card->num_links = link_cnt; + + card->codec_conf = priv->codec_conf; + card->num_configs = conf_cnt; + + ret = j721e_calculate_rate_range(priv); + if (ret) + return ret; + + snd_soc_card_set_drvdata(card, priv); + + mutex_init(&priv->mutex); + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) + dev_err(&pdev->dev, "devm_snd_soc_register_card() failed: %d\n", + ret); + + return ret; +} + +static struct platform_driver j721e_soc_driver = { + .driver = { + .name = "j721e-audio", + .pm = &snd_soc_pm_ops, + .of_match_table = of_match_ptr(j721e_audio_of_match), + }, + .probe = j721e_soc_probe, +}; + +module_platform_driver(j721e_soc_driver); + +MODULE_AUTHOR("Peter Ujfalusi "); +MODULE_DESCRIPTION("ASoC machine driver for j721e Common Processor Board"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/ti/omap-mcbsp-st.c b/sound/soc/ti/omap-mcbsp-st.c index 5a32b54bbf3bb5..0bc7d26c660aa4 100644 --- a/sound/soc/ti/omap-mcbsp-st.c +++ b/sound/soc/ti/omap-mcbsp-st.c @@ -142,11 +142,8 @@ static void omap_mcbsp_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir) static void omap_mcbsp_st_chgain(struct omap_mcbsp *mcbsp) { - u16 w; struct omap_mcbsp_st_data *st_data = mcbsp->st_data; - w = MCBSP_ST_READ(mcbsp, SSELCR); - MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | ST_CH1GAIN(st_data->ch1gain)); } diff --git a/sound/soc/uniphier/aio-core.c b/sound/soc/uniphier/aio-core.c index 9bcba06ba52ea3..b8195778953e1e 100644 --- a/sound/soc/uniphier/aio-core.c +++ b/sound/soc/uniphier/aio-core.c @@ -93,9 +93,9 @@ void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable) /** * aio_chip_set_pll - set frequency to audio PLL - * @chip : the AIO chip pointer - * @source: PLL - * @freq : frequency in Hz, 0 is ignored + * @chip: the AIO chip pointer + * @pll_id: PLL + * @freq: frequency in Hz, 0 is ignored * * Sets frequency of audio PLL. This function can be called anytime, * but it takes time till PLL is locked. @@ -267,7 +267,6 @@ void aio_port_reset(struct uniphier_aio_sub *sub) /** * aio_port_set_ch - set channels of LPCM * @sub: the AIO substream pointer, PCM substream only - * @ch : count of channels * * Set suitable slot selecting to input/output port block of AIO. * diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index cf70499992619b..17b79d45d17f66 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -580,16 +580,16 @@ static __u32 reverse_bytes(__u32 b, int len) switch (len) { case 32: b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16); - /* fall through */ + fallthrough; case 16: b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8); - /* fall through */ + fallthrough; case 8: b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4); - /* fall through */ + fallthrough; case 4: b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2); - /* fall through */ + fallthrough; case 2: b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1); case 1: diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index e9243d53a107db..3b6bb2cbe886b3 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -820,7 +820,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE): cdev->samplerates |= SNDRV_PCM_RATE_192000; - /* fall thru */ + fallthrough; case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index b669e119f65465..2af3b7eb0a88c5 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -187,7 +187,7 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb) break; } #ifdef CONFIG_SND_USB_CAIAQ_INPUT - /* fall through */ + fallthrough; case EP1_CMD_READ_ERP: case EP1_CMD_READ_ANALOG: snd_usb_caiaq_input_dispatch(cdev, buf, urb->actual_length); diff --git a/sound/usb/card.c b/sound/usb/card.c index 162bdd6eb4d4ba..696e788c5d311f 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -230,7 +230,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) dev_warn(&dev->dev, "unknown interface protocol %#02x, assuming v1\n", protocol); - /* fall through */ + fallthrough; case UAC_VERSION_1: { struct uac1_ac_header_descriptor *h1; diff --git a/sound/usb/clock.c b/sound/usb/clock.c index b118cf97607f3d..f3ca59005d9143 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -670,7 +670,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, else return 0; } - /* fall through */ + fallthrough; case UAC_VERSION_2: return set_sample_rate_v2v3(chip, iface, alts, fmt, rate); } diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 1a4e3700c80c95..ec20fbec647505 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -66,8 +66,8 @@ extern const unsigned char line6_midi_id[3]; -static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3; -static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; +#define SYSEX_DATA_OFS (sizeof(line6_midi_id) + 3) +#define SYSEX_EXTRA_SIZE (sizeof(line6_midi_id) + 4) /* Common properties of Line 6 devices. diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 047b90595d6581..fe3fd6e4bb9bc7 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -2401,7 +2401,7 @@ int __snd_usbmidi_create(struct snd_card *card, break; case QUIRK_MIDI_US122L: umidi->usb_protocol_ops = &snd_usbmidi_122l_ops; - /* fall through */ + fallthrough; case QUIRK_MIDI_FIXED_ENDPOINT: memcpy(&endpoints[0], quirk->data, sizeof(struct snd_usb_midi_endpoint_info)); diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index e42241087b778e..e725d836f93c08 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1742,7 +1742,7 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea switch (cmd) { case SNDRV_PCM_TRIGGER_START: subs->trigger_tstamp_pending_update = true; - /* fall through */ + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: subs->data_endpoint->prepare_data_urb = prepare_playback_urb; subs->data_endpoint->retire_data_urb = retire_playback_urb; diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 15296f2c902cd3..4d1e6579e54dcb 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -1146,9 +1146,8 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n", iface_no, altno, protocol); protocol = UAC_VERSION_1; - /* fall through */ + fallthrough; case UAC_VERSION_1: - /* fall through */ case UAC_VERSION_2: { int bm_quirk = 0; diff --git a/sound/xen/xen_snd_front.c b/sound/xen/xen_snd_front.c index a9e5c2cd769809..228d8203129731 100644 --- a/sound/xen/xen_snd_front.c +++ b/sound/xen/xen_snd_front.c @@ -114,7 +114,7 @@ int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl, int xen_snd_front_stream_close(struct xen_snd_front_evtchnl *evtchnl) { - struct xensnd_req *req; + __always_unused struct xensnd_req *req; int ret; mutex_lock(&evtchnl->u.req.req_io_lock); @@ -246,11 +246,8 @@ static void sndback_changed(struct xenbus_device *xb_dev, switch (backend_state) { case XenbusStateReconfiguring: - /* fall through */ case XenbusStateReconfigured: - /* fall through */ case XenbusStateInitialised: - /* fall through */ break; case XenbusStateInitialising: @@ -289,7 +286,6 @@ static void sndback_changed(struct xenbus_device *xb_dev, break; case XenbusStateUnknown: - /* fall through */ case XenbusStateClosed: if (xb_dev->state == XenbusStateClosed) break; diff --git a/sound/xen/xen_snd_front_evtchnl.c b/sound/xen/xen_snd_front_evtchnl.c index 102d6e096cc845..29e0f0ea67ebdd 100644 --- a/sound/xen/xen_snd_front_evtchnl.c +++ b/sound/xen/xen_snd_front_evtchnl.c @@ -46,13 +46,9 @@ static irqreturn_t evtchnl_interrupt_req(int irq, void *dev_id) continue; switch (resp->operation) { case XENSND_OP_OPEN: - /* fall through */ case XENSND_OP_CLOSE: - /* fall through */ case XENSND_OP_READ: - /* fall through */ case XENSND_OP_WRITE: - /* fall through */ case XENSND_OP_TRIGGER: channel->u.req.resp_status = resp->status; complete(&channel->u.req.completion); diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 787b6d4ad7162e..f9b769f3437ddc 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -82,7 +82,9 @@ def build_tests(linux: kunit_kernel.LinuxSourceTree, request.make_options) build_end = time.time() if not success: - return KunitResult(KunitStatus.BUILD_FAILURE, 'could not build kernel') + return KunitResult(KunitStatus.BUILD_FAILURE, + 'could not build kernel', + build_end - build_start) if not success: return KunitResult(KunitStatus.BUILD_FAILURE, 'could not build kernel', diff --git a/tools/testing/kunit/kunit_config.py b/tools/testing/kunit/kunit_config.py index e75063d603b5be..02ffc3a3e5dc7f 100644 --- a/tools/testing/kunit/kunit_config.py +++ b/tools/testing/kunit/kunit_config.py @@ -10,7 +10,7 @@ import re CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$' -CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+)$' +CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$' KconfigEntryBase = collections.namedtuple('KconfigEntry', ['name', 'value']) diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py index 64aac9dcd4314d..f13e0c0d666395 100644 --- a/tools/testing/kunit/kunit_parser.py +++ b/tools/testing/kunit/kunit_parser.py @@ -265,11 +265,9 @@ def bubble_up_suite_errors(test_suite_list: List[TestSuite]) -> TestStatus: return bubble_up_errors(lambda x: x.status, test_suite_list) def parse_test_result(lines: List[str]) -> TestResult: - if not lines: - return TestResult(TestStatus.NO_TESTS, [], lines) consume_non_diagnositic(lines) - if not parse_tap_header(lines): - return None + if not lines or not parse_tap_header(lines): + return TestResult(TestStatus.NO_TESTS, [], lines) test_suites = [] test_suite = parse_test_suite(lines) while test_suite: @@ -282,6 +280,8 @@ def parse_run_tests(kernel_output) -> TestResult: failed_tests = 0 crashed_tests = 0 test_result = parse_test_result(list(isolate_kunit_output(kernel_output))) + if test_result.status == TestStatus.NO_TESTS: + print_with_timestamp(red('[ERROR] ') + 'no kunit output detected') for test_suite in test_result.suites: if test_suite.status == TestStatus.SUCCESS: print_suite_divider(green('[PASSED] ') + test_suite.name) diff --git a/tools/testing/kunit/kunit_tool_test.py b/tools/testing/kunit/kunit_tool_test.py index 5bb7b118ebd941..f9eeaea94cad11 100755 --- a/tools/testing/kunit/kunit_tool_test.py +++ b/tools/testing/kunit/kunit_tool_test.py @@ -170,6 +170,17 @@ def test_no_tests(self): result.status) file.close() + def test_no_kunit_output(self): + crash_log = get_absolute_path( + 'test_data/test_insufficient_memory.log') + file = open(crash_log) + print_mock = mock.patch('builtins.print').start() + result = kunit_parser.parse_run_tests( + kunit_parser.isolate_kunit_output(file.readlines())) + print_mock.assert_any_call(StrContains("no kunit output detected")) + print_mock.stop() + file.close() + def test_crashed_test(self): crashed_log = get_absolute_path( 'test_data/test_is_test_passed-crash.log') diff --git a/tools/testing/kunit/test_data/test_insufficient_memory.log b/tools/testing/kunit/test_data/test_insufficient_memory.log new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/tools/testing/selftests/tpm2/test_smoke.sh b/tools/testing/selftests/tpm2/test_smoke.sh index 663062701d5aa6..1334e301d2a039 100755 --- a/tools/testing/selftests/tpm2/test_smoke.sh +++ b/tools/testing/selftests/tpm2/test_smoke.sh @@ -1,15 +1,10 @@ -#!/bin/bash +#!/bin/sh # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) # Kselftest framework requirement - SKIP code is 4. ksft_skip=4 -[ -f /dev/tpm0 ] || exit $ksft_skip +[ -e /dev/tpm0 ] || exit $ksft_skip python -m unittest -v tpm2_tests.SmokeTest python -m unittest -v tpm2_tests.AsyncTest - -CLEAR_CMD=$(which tpm2_clear) -if [ -n $CLEAR_CMD ]; then - tpm2_clear -T device -fi diff --git a/tools/testing/selftests/tpm2/test_space.sh b/tools/testing/selftests/tpm2/test_space.sh index 36c9d030a1c636..00259cb746cf62 100755 --- a/tools/testing/selftests/tpm2/test_space.sh +++ b/tools/testing/selftests/tpm2/test_space.sh @@ -1,9 +1,9 @@ -#!/bin/bash +#!/bin/sh # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) # Kselftest framework requirement - SKIP code is 4. ksft_skip=4 -[ -f /dev/tpmrm0 ] || exit $ksft_skip +[ -e /dev/tpmrm0 ] || exit $ksft_skip python -m unittest -v tpm2_tests.SpaceTest diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 5f16821c7f63a6..d2796ea98c5ac1 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -70,10 +70,10 @@ all_64: $(BINARIES_64) EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) -$(BINARIES_32): $(OUTPUT)/%_32: %.c +$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm -$(BINARIES_64): $(OUTPUT)/%_64: %.c +$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl # x86_64 users should be encouraged to install 32-bit libraries diff --git a/tools/testing/selftests/x86/helpers.h b/tools/testing/selftests/x86/helpers.h new file mode 100644 index 00000000000000..f5ff2a2615df0a --- /dev/null +++ b/tools/testing/selftests/x86/helpers.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0-only +#ifndef __SELFTESTS_X86_HELPERS_H +#define __SELFTESTS_X86_HELPERS_H + +#include + +static inline unsigned long get_eflags(void) +{ + unsigned long eflags; + + asm volatile ( +#ifdef __x86_64__ + "subq $128, %%rsp\n\t" + "pushfq\n\t" + "popq %0\n\t" + "addq $128, %%rsp" +#else + "pushfl\n\t" + "popl %0" +#endif + : "=r" (eflags) :: "memory"); + + return eflags; +} + +static inline void set_eflags(unsigned long eflags) +{ + asm volatile ( +#ifdef __x86_64__ + "subq $128, %%rsp\n\t" + "pushq %0\n\t" + "popfq\n\t" + "addq $128, %%rsp" +#else + "pushl %0\n\t" + "popfl" +#endif + :: "r" (eflags) : "flags", "memory"); +} + +#endif /* __SELFTESTS_X86_HELPERS_H */ diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 1063328e275c90..120ac741fe4405 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -31,6 +31,8 @@ #include #include +#include "helpers.h" + static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags) { @@ -67,21 +69,6 @@ static unsigned char altstack_data[SIGSTKSZ]; # define INT80_CLOBBERS #endif -static unsigned long get_eflags(void) -{ - unsigned long eflags; - asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); - return eflags; -} - -static void set_eflags(unsigned long eflags) -{ - asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH - : : "rm" (eflags) : "flags"); -} - -#define X86_EFLAGS_TF (1UL << 8) - static void sigtrap(int sig, siginfo_t *info, void *ctx_void) { ucontext_t *ctx = (ucontext_t*)ctx_void; diff --git a/tools/testing/selftests/x86/syscall_arg_fault.c b/tools/testing/selftests/x86/syscall_arg_fault.c index bc0ecc2e862ef7..5b7abebbcbb9b8 100644 --- a/tools/testing/selftests/x86/syscall_arg_fault.c +++ b/tools/testing/selftests/x86/syscall_arg_fault.c @@ -15,30 +15,11 @@ #include #include -#ifdef __x86_64__ -# define WIDTH "q" -#else -# define WIDTH "l" -#endif +#include "helpers.h" /* Our sigaltstack scratch space. */ static unsigned char altstack_data[SIGSTKSZ]; -static unsigned long get_eflags(void) -{ - unsigned long eflags; - asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); - return eflags; -} - -static void set_eflags(unsigned long eflags) -{ - asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH - : : "rm" (eflags) : "flags"); -} - -#define X86_EFLAGS_TF (1UL << 8) - static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags) { diff --git a/tools/testing/selftests/x86/syscall_nt.c b/tools/testing/selftests/x86/syscall_nt.c index 02309a19504131..a108b80dd08230 100644 --- a/tools/testing/selftests/x86/syscall_nt.c +++ b/tools/testing/selftests/x86/syscall_nt.c @@ -13,29 +13,11 @@ #include #include #include -#include -#ifdef __x86_64__ -# define WIDTH "q" -#else -# define WIDTH "l" -#endif +#include "helpers.h" static unsigned int nerrs; -static unsigned long get_eflags(void) -{ - unsigned long eflags; - asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); - return eflags; -} - -static void set_eflags(unsigned long eflags) -{ - asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH - : : "rm" (eflags) : "flags"); -} - static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags) { @@ -59,6 +41,7 @@ static void do_it(unsigned long extraflags) set_eflags(get_eflags() | extraflags); syscall(SYS_getpid); flags = get_eflags(); + set_eflags(X86_EFLAGS_IF | X86_EFLAGS_FIXED); if ((flags & extraflags) == extraflags) { printf("[OK]\tThe syscall worked and flags are still set\n"); } else { @@ -73,6 +56,12 @@ int main(void) printf("[RUN]\tSet NT and issue a syscall\n"); do_it(X86_EFLAGS_NT); + printf("[RUN]\tSet AC and issue a syscall\n"); + do_it(X86_EFLAGS_AC); + + printf("[RUN]\tSet NT|AC and issue a syscall\n"); + do_it(X86_EFLAGS_NT | X86_EFLAGS_AC); + /* * Now try it again with TF set -- TF forces returns via IRET in all * cases except non-ptregs-using 64-bit full fast path syscalls. @@ -80,8 +69,28 @@ int main(void) sethandler(SIGTRAP, sigtrap, 0); + printf("[RUN]\tSet TF and issue a syscall\n"); + do_it(X86_EFLAGS_TF); + printf("[RUN]\tSet NT|TF and issue a syscall\n"); do_it(X86_EFLAGS_NT | X86_EFLAGS_TF); + printf("[RUN]\tSet AC|TF and issue a syscall\n"); + do_it(X86_EFLAGS_AC | X86_EFLAGS_TF); + + printf("[RUN]\tSet NT|AC|TF and issue a syscall\n"); + do_it(X86_EFLAGS_NT | X86_EFLAGS_AC | X86_EFLAGS_TF); + + /* + * Now try DF. This is evil and it's plausible that we will crash + * glibc, but glibc would have to do something rather surprising + * for this to happen. + */ + printf("[RUN]\tSet DF and issue a syscall\n"); + do_it(X86_EFLAGS_DF); + + printf("[RUN]\tSet TF|DF and issue a syscall\n"); + do_it(X86_EFLAGS_TF | X86_EFLAGS_DF); + return nerrs == 0 ? 0 : 1; } diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index a4f4d4cf22c3b4..c41f24b517f401 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c @@ -20,6 +20,8 @@ #include #include +#include "helpers.h" + #ifdef __x86_64__ # define VSYS(x) (x) #else @@ -493,21 +495,8 @@ static int test_process_vm_readv(void) } #ifdef __x86_64__ -#define X86_EFLAGS_TF (1UL << 8) static volatile sig_atomic_t num_vsyscall_traps; -static unsigned long get_eflags(void) -{ - unsigned long eflags; - asm volatile ("pushfq\n\tpopq %0" : "=rm" (eflags)); - return eflags; -} - -static void set_eflags(unsigned long eflags) -{ - asm volatile ("pushq %0\n\tpopfq" : : "rm" (eflags) : "flags"); -} - static void sigtrap(int sig, siginfo_t *info, void *ctx_void) { ucontext_t *ctx = (ucontext_t *)ctx_void; diff --git a/tools/testing/selftests/x86/unwind_vdso.c b/tools/testing/selftests/x86/unwind_vdso.c index 0075ccd65407bb..4c311e1af4c7a8 100644 --- a/tools/testing/selftests/x86/unwind_vdso.c +++ b/tools/testing/selftests/x86/unwind_vdso.c @@ -11,6 +11,8 @@ #include #include +#include "helpers.h" + #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16 int main() @@ -53,27 +55,6 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), err(1, "sigaction"); } -#ifdef __x86_64__ -# define WIDTH "q" -#else -# define WIDTH "l" -#endif - -static unsigned long get_eflags(void) -{ - unsigned long eflags; - asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); - return eflags; -} - -static void set_eflags(unsigned long eflags) -{ - asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH - : : "rm" (eflags) : "flags"); -} - -#define X86_EFLAGS_TF (1UL << 8) - static volatile sig_atomic_t nerrs; static unsigned long sysinfo; static bool got_sysinfo = false;